@@ -843,50 +843,31 @@ impl ObjectSafetyViolation {
843843 }
844844 }
845845
846- pub fn solution ( & self , err : & mut Diagnostic ) {
846+ pub fn solution ( & self ) -> ObjectSafetyViolationSolution {
847847 match self {
848848 ObjectSafetyViolation :: SizedSelf ( _)
849849 | ObjectSafetyViolation :: SupertraitSelf ( _)
850- | ObjectSafetyViolation :: SupertraitNonLifetimeBinder ( ..) => { }
850+ | ObjectSafetyViolation :: SupertraitNonLifetimeBinder ( ..) => {
851+ ObjectSafetyViolationSolution :: None
852+ }
851853 ObjectSafetyViolation :: Method (
852854 name,
853855 MethodViolationCode :: StaticMethod ( Some ( ( add_self_sugg, make_sized_sugg) ) ) ,
854856 _,
855- ) => {
856- err. span_suggestion (
857- add_self_sugg. 1 ,
858- format ! (
859- "consider turning `{name}` into a method by giving it a `&self` argument"
860- ) ,
861- add_self_sugg. 0 . to_string ( ) ,
862- Applicability :: MaybeIncorrect ,
863- ) ;
864- err. span_suggestion (
865- make_sized_sugg. 1 ,
866- format ! (
867- "alternatively, consider constraining `{name}` so it does not apply to \
868- trait objects"
869- ) ,
870- make_sized_sugg. 0 . to_string ( ) ,
871- Applicability :: MaybeIncorrect ,
872- ) ;
873- }
857+ ) => ObjectSafetyViolationSolution :: AddSelfOrMakeSized {
858+ name : * name,
859+ add_self_sugg : add_self_sugg. clone ( ) ,
860+ make_sized_sugg : make_sized_sugg. clone ( ) ,
861+ } ,
874862 ObjectSafetyViolation :: Method (
875863 name,
876864 MethodViolationCode :: UndispatchableReceiver ( Some ( span) ) ,
877865 _,
878- ) => {
879- err. span_suggestion (
880- * span,
881- format ! ( "consider changing method `{name}`'s `self` parameter to be `&self`" ) ,
882- "&Self" ,
883- Applicability :: MachineApplicable ,
884- ) ;
885- }
866+ ) => ObjectSafetyViolationSolution :: ChangeToRefSelf ( * name, * span) ,
886867 ObjectSafetyViolation :: AssocConst ( name, _)
887868 | ObjectSafetyViolation :: GAT ( name, _)
888869 | ObjectSafetyViolation :: Method ( name, ..) => {
889- err . help ( format ! ( "consider moving `{ name}` to another trait" ) ) ;
870+ ObjectSafetyViolationSolution :: MoveToAnotherTrait ( * name)
890871 }
891872 }
892873 }
@@ -910,6 +891,60 @@ impl ObjectSafetyViolation {
910891 }
911892}
912893
894+ #[ derive( Clone , Debug , PartialEq , Eq , Hash , PartialOrd , Ord ) ]
895+ pub enum ObjectSafetyViolationSolution {
896+ None ,
897+ AddSelfOrMakeSized {
898+ name : Symbol ,
899+ add_self_sugg : ( String , Span ) ,
900+ make_sized_sugg : ( String , Span ) ,
901+ } ,
902+ ChangeToRefSelf ( Symbol , Span ) ,
903+ MoveToAnotherTrait ( Symbol ) ,
904+ }
905+
906+ impl ObjectSafetyViolationSolution {
907+ pub fn add_to ( self , err : & mut Diagnostic ) {
908+ match self {
909+ ObjectSafetyViolationSolution :: None => { }
910+ ObjectSafetyViolationSolution :: AddSelfOrMakeSized {
911+ name,
912+ add_self_sugg,
913+ make_sized_sugg,
914+ } => {
915+ err. span_suggestion (
916+ add_self_sugg. 1 ,
917+ format ! (
918+ "consider turning `{name}` into a method by giving it a `&self` argument"
919+ ) ,
920+ add_self_sugg. 0 ,
921+ Applicability :: MaybeIncorrect ,
922+ ) ;
923+ err. span_suggestion (
924+ make_sized_sugg. 1 ,
925+ format ! (
926+ "alternatively, consider constraining `{name}` so it does not apply to \
927+ trait objects"
928+ ) ,
929+ make_sized_sugg. 0 ,
930+ Applicability :: MaybeIncorrect ,
931+ ) ;
932+ }
933+ ObjectSafetyViolationSolution :: ChangeToRefSelf ( name, span) => {
934+ err. span_suggestion (
935+ span,
936+ format ! ( "consider changing method `{name}`'s `self` parameter to be `&self`" ) ,
937+ "&Self" ,
938+ Applicability :: MachineApplicable ,
939+ ) ;
940+ }
941+ ObjectSafetyViolationSolution :: MoveToAnotherTrait ( name) => {
942+ err. help ( format ! ( "consider moving `{name}` to another trait" ) ) ;
943+ }
944+ }
945+ }
946+ }
947+
913948/// Reasons a method might not be object-safe.
914949#[ derive( Clone , Debug , PartialEq , Eq , Hash , HashStable , PartialOrd , Ord ) ]
915950pub enum MethodViolationCode {
0 commit comments