@@ -832,50 +832,31 @@ impl ObjectSafetyViolation {
832832 }
833833 }
834834
835- pub fn solution ( & self , err : & mut Diagnostic ) {
835+ pub fn solution ( & self ) -> ObjectSafetyViolationSolution {
836836 match self {
837837 ObjectSafetyViolation :: SizedSelf ( _)
838838 | ObjectSafetyViolation :: SupertraitSelf ( _)
839- | ObjectSafetyViolation :: SupertraitNonLifetimeBinder ( ..) => { }
839+ | ObjectSafetyViolation :: SupertraitNonLifetimeBinder ( ..) => {
840+ ObjectSafetyViolationSolution :: None
841+ }
840842 ObjectSafetyViolation :: Method (
841843 name,
842844 MethodViolationCode :: StaticMethod ( Some ( ( add_self_sugg, make_sized_sugg) ) ) ,
843845 _,
844- ) => {
845- err. span_suggestion (
846- add_self_sugg. 1 ,
847- format ! (
848- "consider turning `{name}` into a method by giving it a `&self` argument"
849- ) ,
850- add_self_sugg. 0 . to_string ( ) ,
851- Applicability :: MaybeIncorrect ,
852- ) ;
853- err. span_suggestion (
854- make_sized_sugg. 1 ,
855- format ! (
856- "alternatively, consider constraining `{name}` so it does not apply to \
857- trait objects"
858- ) ,
859- make_sized_sugg. 0 . to_string ( ) ,
860- Applicability :: MaybeIncorrect ,
861- ) ;
862- }
846+ ) => ObjectSafetyViolationSolution :: AddSelfOrMakeSized {
847+ name : * name,
848+ add_self_sugg : add_self_sugg. clone ( ) ,
849+ make_sized_sugg : make_sized_sugg. clone ( ) ,
850+ } ,
863851 ObjectSafetyViolation :: Method (
864852 name,
865853 MethodViolationCode :: UndispatchableReceiver ( Some ( span) ) ,
866854 _,
867- ) => {
868- err. span_suggestion (
869- * span,
870- format ! ( "consider changing method `{name}`'s `self` parameter to be `&self`" ) ,
871- "&Self" ,
872- Applicability :: MachineApplicable ,
873- ) ;
874- }
855+ ) => ObjectSafetyViolationSolution :: ChangeToRefSelf ( * name, * span) ,
875856 ObjectSafetyViolation :: AssocConst ( name, _)
876857 | ObjectSafetyViolation :: GAT ( name, _)
877858 | ObjectSafetyViolation :: Method ( name, ..) => {
878- err . help ( format ! ( "consider moving `{ name}` to another trait" ) ) ;
859+ ObjectSafetyViolationSolution :: MoveToAnotherTrait ( * name)
879860 }
880861 }
881862 }
@@ -899,6 +880,60 @@ impl ObjectSafetyViolation {
899880 }
900881}
901882
883+ #[ derive( Clone , Debug , PartialEq , Eq , Hash , PartialOrd , Ord ) ]
884+ pub enum ObjectSafetyViolationSolution {
885+ None ,
886+ AddSelfOrMakeSized {
887+ name : Symbol ,
888+ add_self_sugg : ( String , Span ) ,
889+ make_sized_sugg : ( String , Span ) ,
890+ } ,
891+ ChangeToRefSelf ( Symbol , Span ) ,
892+ MoveToAnotherTrait ( Symbol ) ,
893+ }
894+
895+ impl ObjectSafetyViolationSolution {
896+ pub fn add_to ( self , err : & mut Diagnostic ) {
897+ match self {
898+ ObjectSafetyViolationSolution :: None => { }
899+ ObjectSafetyViolationSolution :: AddSelfOrMakeSized {
900+ name,
901+ add_self_sugg,
902+ make_sized_sugg,
903+ } => {
904+ err. span_suggestion (
905+ add_self_sugg. 1 ,
906+ format ! (
907+ "consider turning `{name}` into a method by giving it a `&self` argument"
908+ ) ,
909+ add_self_sugg. 0 ,
910+ Applicability :: MaybeIncorrect ,
911+ ) ;
912+ err. span_suggestion (
913+ make_sized_sugg. 1 ,
914+ format ! (
915+ "alternatively, consider constraining `{name}` so it does not apply to \
916+ trait objects"
917+ ) ,
918+ make_sized_sugg. 0 ,
919+ Applicability :: MaybeIncorrect ,
920+ ) ;
921+ }
922+ ObjectSafetyViolationSolution :: ChangeToRefSelf ( name, span) => {
923+ err. span_suggestion (
924+ span,
925+ format ! ( "consider changing method `{name}`'s `self` parameter to be `&self`" ) ,
926+ "&Self" ,
927+ Applicability :: MachineApplicable ,
928+ ) ;
929+ }
930+ ObjectSafetyViolationSolution :: MoveToAnotherTrait ( name) => {
931+ err. help ( format ! ( "consider moving `{name}` to another trait" ) ) ;
932+ }
933+ }
934+ }
935+ }
936+
902937/// Reasons a method might not be object-safe.
903938#[ derive( Clone , Debug , PartialEq , Eq , Hash , HashStable , PartialOrd , Ord ) ]
904939pub enum MethodViolationCode {
0 commit comments