@@ -13,6 +13,7 @@ use crate::mir::interpret::ErrorHandled;
1313use crate :: ty:: subst:: SubstsRef ;
1414use crate :: ty:: { self , AdtKind , Ty , TyCtxt } ;
1515
16+ use rustc_errors:: { Applicability , DiagnosticBuilder } ;
1617use rustc_hir as hir;
1718use rustc_hir:: def_id:: DefId ;
1819use rustc_span:: symbol:: Symbol ;
@@ -646,13 +647,13 @@ impl ObjectSafetyViolation {
646647 ObjectSafetyViolation :: SizedSelf ( _) => "it requires `Self: Sized`" . into ( ) ,
647648 ObjectSafetyViolation :: SupertraitSelf ( ref spans) => {
648649 if spans. iter ( ) . any ( |sp| * sp != DUMMY_SP ) {
649- "it uses `Self` as a type parameter in this " . into ( )
650+ "it uses `Self` as a type parameter" . into ( )
650651 } else {
651652 "it cannot use `Self` as a type parameter in a supertrait or `where`-clause"
652653 . into ( )
653654 }
654655 }
655- ObjectSafetyViolation :: Method ( name, MethodViolationCode :: StaticMethod ( _) , _) => {
656+ ObjectSafetyViolation :: Method ( name, MethodViolationCode :: StaticMethod ( _, _ , _ ) , _) => {
656657 format ! ( "associated function `{}` has no `self` parameter" , name) . into ( )
657658 }
658659 ObjectSafetyViolation :: Method (
@@ -686,32 +687,65 @@ impl ObjectSafetyViolation {
686687 }
687688 }
688689
689- pub fn solution ( & self ) -> Option < ( String , Option < ( String , Span ) > ) > {
690- Some ( match * self {
691- ObjectSafetyViolation :: SizedSelf ( _) | ObjectSafetyViolation :: SupertraitSelf ( _) => {
692- return None ;
690+ pub fn solution ( & self , err : & mut DiagnosticBuilder < ' _ > ) {
691+ match * self {
692+ ObjectSafetyViolation :: SizedSelf ( _) | ObjectSafetyViolation :: SupertraitSelf ( _) => { }
693+ ObjectSafetyViolation :: Method (
694+ name,
695+ MethodViolationCode :: StaticMethod ( sugg, self_span, has_args) ,
696+ _,
697+ ) => {
698+ err. span_suggestion (
699+ self_span,
700+ & format ! (
701+ "consider turning `{}` into a method by giving it a `&self` argument" ,
702+ name
703+ ) ,
704+ format ! ( "&self{}" , if has_args { ", " } else { "" } ) ,
705+ Applicability :: MaybeIncorrect ,
706+ ) ;
707+ match sugg {
708+ Some ( ( sugg, span) ) => {
709+ err. span_suggestion (
710+ span,
711+ & format ! (
712+ "alternatively, consider constraining `{}` so it does not apply to \
713+ trait objects",
714+ name
715+ ) ,
716+ sugg. to_string ( ) ,
717+ Applicability :: MaybeIncorrect ,
718+ ) ;
719+ }
720+ None => {
721+ err. help ( & format ! (
722+ "consider turning `{}` into a method by giving it a `&self` \
723+ argument or constraining it so it does not apply to trait objects",
724+ name
725+ ) ) ;
726+ }
727+ }
693728 }
694- ObjectSafetyViolation :: Method ( name, MethodViolationCode :: StaticMethod ( sugg) , _) => (
695- format ! (
696- "consider turning `{}` into a method by giving it a `&self` argument or \
697- constraining it so it does not apply to trait objects",
698- name
699- ) ,
700- sugg. map ( |( sugg, sp) | ( sugg. to_string ( ) , sp) ) ,
701- ) ,
702729 ObjectSafetyViolation :: Method (
703730 name,
704731 MethodViolationCode :: UndispatchableReceiver ,
705732 span,
706- ) => (
707- format ! ( "consider changing method `{}`'s `self` parameter to be `&self`" , name) ,
708- Some ( ( "&Self" . to_string ( ) , span) ) ,
709- ) ,
733+ ) => {
734+ err. span_suggestion (
735+ span,
736+ & format ! (
737+ "consider changing method `{}`'s `self` parameter to be `&self`" ,
738+ name
739+ ) ,
740+ "&Self" . to_string ( ) ,
741+ Applicability :: MachineApplicable ,
742+ ) ;
743+ }
710744 ObjectSafetyViolation :: AssocConst ( name, _)
711745 | ObjectSafetyViolation :: Method ( name, ..) => {
712- ( format ! ( "consider moving `{}` to another trait" , name) , None )
746+ err . help ( & format ! ( "consider moving `{}` to another trait" , name) ) ;
713747 }
714- } )
748+ }
715749 }
716750
717751 pub fn spans ( & self ) -> SmallVec < [ Span ; 1 ] > {
@@ -735,7 +769,7 @@ impl ObjectSafetyViolation {
735769#[ derive( Copy , Clone , Debug , PartialEq , Eq , Hash , HashStable ) ]
736770pub enum MethodViolationCode {
737771 /// e.g., `fn foo()`
738- StaticMethod ( Option < ( & ' static str , Span ) > ) ,
772+ StaticMethod ( Option < ( & ' static str , Span ) > , Span , bool /* has args */ ) ,
739773
740774 /// e.g., `fn foo(&self, x: Self)`
741775 ReferencesSelfInput ( usize ) ,
0 commit comments