@@ -969,9 +969,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
969969 trait_ref : & ty:: PolyTraitRef < ' _ > ,
970970 body_id : hir:: HirId ,
971971 ) {
972- let ( param_ty, projection) = match & trait_ref. self_ty ( ) . kind {
973- ty:: Param ( param_ty) => ( Some ( param_ty) , None ) ,
974- ty:: Projection ( projection) => ( None , Some ( projection) ) ,
972+ let self_ty = trait_ref. self_ty ( ) ;
973+ let ( param_ty, projection) = match & self_ty. kind {
974+ ty:: Param ( _) => ( true , None ) ,
975+ ty:: Projection ( projection) => ( false , Some ( projection) ) ,
975976 _ => return ,
976977 } ;
977978
@@ -997,17 +998,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
997998 let mut hir_id = body_id;
998999 while let Some ( node) = self . tcx . hir ( ) . find ( hir_id) {
9991000 match node {
1000- hir:: Node :: Item ( hir:: Item {
1001- kind : hir:: ItemKind :: Fn ( _, _, generics, _) , ..
1002- } ) |
10031001 hir:: Node :: TraitItem ( hir:: TraitItem {
10041002 generics,
10051003 kind : hir:: TraitItemKind :: Method ( ..) , ..
1006- } ) |
1007- hir:: Node :: ImplItem ( hir:: ImplItem {
1008- generics,
1009- kind : hir:: ImplItemKind :: Method ( ..) , ..
1010- } ) if param_ty. map_or ( false , |p| p. name . as_str ( ) == "Self" ) => {
1004+ } ) if param_ty && self_ty == self . tcx . types . self_param => {
10111005 // Restricting `Self` for a single method.
10121006 suggest_restriction ( & generics, "`Self`" ) ;
10131007 return ;
@@ -1058,12 +1052,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
10581052 } ) |
10591053 hir:: Node :: TraitItem ( hir:: TraitItem { generics, span, .. } ) |
10601054 hir:: Node :: ImplItem ( hir:: ImplItem { generics, span, .. } )
1061- if param_ty. is_some ( ) => {
1055+ if param_ty => {
10621056 // Missing generic type parameter bound.
10631057 let restrict_msg = "consider further restricting this bound" ;
1064- let param_name = param_ty . unwrap ( ) . name . as_str ( ) ;
1058+ let param_name = self_ty . to_string ( ) ;
10651059 for param in generics. params . iter ( ) . filter ( |p| {
1066- param_name == p. name . ident ( ) . as_str ( )
1060+ & param_name == p. name . ident ( ) . as_str ( )
10671061 } ) {
10681062 if param_name. starts_with ( "impl " ) {
10691063 // `impl Trait` in argument:
@@ -1075,53 +1069,51 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
10751069 format ! ( "{} + {}" , param. name. ident( ) , trait_ref) ,
10761070 Applicability :: MachineApplicable ,
10771071 ) ;
1078- } else {
1079- if generics. where_clause . predicates . is_empty ( ) &&
1072+ } else if generics. where_clause . predicates . is_empty ( ) &&
10801073 param. bounds . is_empty ( )
1081- {
1082- // If there are no bounds whatsoever, suggest adding a constraint
1083- // to the type parameter:
1084- // `fn foo<T>(t: T) {}` → `fn foo<T: Trait>(t: T) {}`
1085- err. span_suggestion (
1086- param. span ,
1087- "consider restricting this bound" ,
1088- format ! ( "{}" , trait_ref. to_predicate( ) ) ,
1089- Applicability :: MachineApplicable ,
1090- ) ;
1091- } else if !generics. where_clause . predicates . is_empty ( ) {
1092- // There is a `where` clause, so suggest expanding it:
1093- // `fn foo<T>(t: T) where T: Debug {}` →
1094- // `fn foo<T(t: T) where T: Debug, Trait {}`
1095- err. span_suggestion (
1096- generics. where_clause . span ( ) . unwrap ( ) . shrink_to_hi ( ) ,
1097- & format ! (
1098- "consider further restricting type parameter `{}`" ,
1099- param_name,
1100- ) ,
1101- format ! ( ", {}" , trait_ref. to_predicate( ) ) ,
1102- Applicability :: MachineApplicable ,
1103- ) ;
1074+ {
1075+ // If there are no bounds whatsoever, suggest adding a constraint
1076+ // to the type parameter:
1077+ // `fn foo<T>(t: T) {}` → `fn foo<T: Trait>(t: T) {}`
1078+ err. span_suggestion (
1079+ param. span ,
1080+ "consider restricting this bound" ,
1081+ format ! ( "{}" , trait_ref. to_predicate( ) ) ,
1082+ Applicability :: MachineApplicable ,
1083+ ) ;
1084+ } else if !generics. where_clause . predicates . is_empty ( ) {
1085+ // There is a `where` clause, so suggest expanding it:
1086+ // `fn foo<T>(t: T) where T: Debug {}` →
1087+ // `fn foo<T>(t: T) where T: Debug, T: Trait {}`
1088+ err. span_suggestion (
1089+ generics. where_clause . span ( ) . unwrap ( ) . shrink_to_hi ( ) ,
1090+ & format ! (
1091+ "consider further restricting type parameter `{}`" ,
1092+ param_name,
1093+ ) ,
1094+ format ! ( ", {}" , trait_ref. to_predicate( ) ) ,
1095+ Applicability :: MachineApplicable ,
1096+ ) ;
1097+ } else {
1098+ // If there is no `where` clause lean towards constraining to the
1099+ // type parameter:
1100+ // `fn foo<X: Bar, T>(t: T, x: X) {}` → `fn foo<T: Trait>(t: T) {}`
1101+ // `fn foo<T: Bar>(t: T) {}` → `fn foo<T: Bar + Trait>(t: T) {}`
1102+ let sp = param. span . with_hi ( span. hi ( ) ) ;
1103+ let span = self . tcx . sess . source_map ( )
1104+ . span_through_char ( sp, ':' ) ;
1105+ if sp != param. span && sp != span {
1106+ // Only suggest if we have high certainty that the span
1107+ // covers the colon in `foo<T: Trait>`.
1108+ err. span_suggestion ( span, restrict_msg, format ! (
1109+ "{} + " ,
1110+ trait_ref. to_predicate( ) ,
1111+ ) , Applicability :: MachineApplicable ) ;
11041112 } else {
1105- // If there is no `where` clause lean towards constraining to the
1106- // type parameter:
1107- // `fn foo<X: Bar, T>(t: T, x: X) {}` → `fn foo<T: Trait>(t: T) {}`
1108- // `fn foo<T: Bar>(t: T) {}` → `fn foo<T: Bar + Trait>(t: T) {}`
1109- let sp = param. span . with_hi ( span. hi ( ) ) ;
1110- let span = self . tcx . sess . source_map ( )
1111- . span_through_char ( sp, ':' ) ;
1112- if sp != param. span && sp != span {
1113- // Only suggest if we have high certainty that the span
1114- // covers the colon in `foo<T: Trait>`.
1115- err. span_suggestion ( span, restrict_msg, format ! (
1116- "{} + " ,
1117- trait_ref. to_predicate( ) ,
1118- ) , Applicability :: MachineApplicable ) ;
1119- } else {
1120- err. span_label ( param. span , & format ! (
1121- "consider adding a `where {}` bound" ,
1122- trait_ref. to_predicate( ) ,
1123- ) ) ;
1124- }
1113+ err. span_label ( param. span , & format ! (
1114+ "consider adding a `where {}` bound" ,
1115+ trait_ref. to_predicate( ) ,
1116+ ) ) ;
11251117 }
11261118 }
11271119 return ;
0 commit comments