@@ -969,90 +969,103 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
969
969
trait_ref : & ty:: PolyTraitRef < ' _ > ,
970
970
body_id : hir:: HirId ,
971
971
) {
972
- let node = self . tcx . hir ( )
973
- . find ( self . tcx . hir ( ) . get_parent_item ( body_id) )
974
- . or_else ( || self . tcx . hir ( ) . find ( body_id) ) ;
975
972
debug ! (
976
- "suggest_restricting_param_bound node={:?} - trait_ref={:?} ty={:?} ({:?})" ,
977
- node,
973
+ "suggest_restricting_param_bound trait_ref={:?} ty={:?} ({:?})" ,
978
974
trait_ref,
979
975
trait_ref. self_ty( ) ,
980
976
trait_ref. self_ty( ) . kind,
981
977
) ;
982
- if let ty:: Param ( param_ty) = & trait_ref. self_ty ( ) . kind {
983
- let restrict_msg = "consider further restricting this bound" ;
984
- let param_name = param_ty . name . as_str ( ) ;
985
-
986
- if let Some ( hir :: Node :: Item ( hir :: Item {
987
- kind : hir :: ItemKind :: Struct ( _ , generics ) , span , ..
988
- } ) ) |
989
- Some ( hir :: Node :: Item ( hir :: Item {
990
- kind : hir :: ItemKind :: Enum ( _ , generics ) , span , ..
991
- } ) ) |
992
- Some ( hir :: Node :: Item ( hir :: Item {
993
- kind : hir:: ItemKind :: Union ( _, generics) , span, ..
994
- } ) ) |
995
- Some ( hir:: Node :: Item ( hir:: Item {
996
- kind : hir:: ItemKind :: Trait ( _ , _ , generics , .. ) , span , ..
997
- } ) ) |
998
- Some ( hir :: Node :: Item ( hir :: Item {
999
- kind : hir:: ItemKind :: Impl ( _ , _ , _ , generics , .. ) , span , ..
1000
- } ) ) |
1001
- Some ( hir :: Node :: Item ( hir :: Item {
1002
- kind : hir:: ItemKind :: Fn ( _ , _ , generics , _ ) , span , ..
1003
- } ) ) = & node {
1004
- for param in & generics . params {
1005
- if param_name == param . name . ident ( ) . as_str ( ) {
1006
- if param_name . starts_with ( "impl " ) {
1007
- err . span_suggestion (
1008
- param . span ,
1009
- restrict_msg ,
1010
- // `impl CurrentTrait + MissingTrait`
1011
- format ! ( "{} + {}" , param . name . ident ( ) , trait_ref ) ,
1012
- Applicability :: MachineApplicable ,
1013
- ) ;
1014
- } else {
1015
- if generics. where_clause . predicates . is_empty ( ) &&
1016
- param. bounds . is_empty ( )
1017
- {
978
+ let param_ty = if let ty:: Param ( param_ty) = & trait_ref. self_ty ( ) . kind {
979
+ param_ty
980
+ } else {
981
+ err . help ( & format ! ( "consider adding a `where {}` bound" , trait_ref . to_predicate ( ) ) ) ;
982
+ return ;
983
+ } ;
984
+
985
+ let mut hir_id = body_id ;
986
+ while let Some ( node ) = self . tcx . hir ( ) . find ( hir_id ) {
987
+ debug ! ( "suggest_restricting_param_bound node={:?}" , node ) ;
988
+ match node {
989
+ hir :: Node :: Item ( hir :: Item { kind : hir:: ItemKind :: Struct ( _, generics) , span, .. } ) |
990
+ hir :: Node :: Item ( hir :: Item { kind : hir :: ItemKind :: Enum ( _ , generics ) , span , .. } ) |
991
+ hir:: Node :: Item ( hir:: Item { kind : hir :: ItemKind :: Union ( _ , generics ) , span , .. } ) |
992
+ hir:: Node :: Item ( hir :: Item {
993
+ kind : hir :: ItemKind :: Trait ( _ , _ , generics , .. ) , span , ..
994
+ } ) |
995
+ hir:: Node :: Item ( hir :: Item {
996
+ kind : hir :: ItemKind :: Impl ( _ , _ , _ , generics , .. ) , span , ..
997
+ } ) |
998
+ hir:: Node :: Item ( hir :: Item {
999
+ kind : hir :: ItemKind :: Fn ( _ , _ , generics , _ ) , span , ..
1000
+ } ) |
1001
+ hir :: Node :: Item ( hir :: Item {
1002
+ kind : hir :: ItemKind :: TyAlias ( _ , generics ) , span , ..
1003
+ } ) |
1004
+ hir :: Node :: Item ( hir :: Item {
1005
+ kind : hir :: ItemKind :: OpaqueTy ( hir :: OpaqueTy { generics , .. } ) , span , ..
1006
+ } ) |
1007
+ hir :: Node :: TraitItem ( hir :: TraitItem { generics , span , .. } ) |
1008
+ hir :: Node :: ImplItem ( hir :: ImplItem { generics , span , .. } ) => {
1009
+ let restrict_msg = "consider further restricting this bound" ;
1010
+ let param_name = param_ty . name . as_str ( ) ;
1011
+ for param in & generics. params {
1012
+ if param_name == param. name . ident ( ) . as_str ( ) {
1013
+ if param_name . starts_with ( "impl " ) {
1018
1014
err. span_suggestion (
1019
1015
param. span ,
1020
- "consider restricting this bound" ,
1021
- format ! ( "{}" , trait_ref. to_predicate( ) ) ,
1022
- Applicability :: MachineApplicable ,
1023
- ) ;
1024
- } else if !generics. where_clause . predicates . is_empty ( ) {
1025
- err. span_suggestion (
1026
- generics. where_clause . span ( ) . unwrap ( ) . shrink_to_hi ( ) ,
1027
- & format ! (
1028
- "consider further restricting type parameter `{}`" ,
1029
- param_ty,
1030
- ) ,
1031
- format ! ( ", {}" , trait_ref. to_predicate( ) ) ,
1016
+ restrict_msg,
1017
+ // `impl CurrentTrait + MissingTrait`
1018
+ format ! ( "{} + {}" , param. name. ident( ) , trait_ref) ,
1032
1019
Applicability :: MachineApplicable ,
1033
1020
) ;
1034
1021
} else {
1035
- let sp = param. span . with_hi ( span. hi ( ) ) ;
1036
- let span = self . tcx . sess . source_map ( ) . span_through_char ( sp, ':' ) ;
1037
- if sp != param. span && sp != span {
1038
- // Only suggest if we have high certainty that the span covers
1039
- // the colon in `foo<T: Trait>`.
1040
- err. span_suggestion ( span, restrict_msg, format ! (
1041
- "{} + " ,
1042
- trait_ref. to_predicate( ) ,
1043
- ) , Applicability :: MachineApplicable ) ;
1022
+ if generics. where_clause . predicates . is_empty ( ) &&
1023
+ param. bounds . is_empty ( )
1024
+ {
1025
+ err. span_suggestion (
1026
+ param. span ,
1027
+ "consider restricting this bound" ,
1028
+ format ! ( "{}" , trait_ref. to_predicate( ) ) ,
1029
+ Applicability :: MachineApplicable ,
1030
+ ) ;
1031
+ } else if !generics. where_clause . predicates . is_empty ( ) {
1032
+ err. span_suggestion (
1033
+ generics. where_clause . span ( ) . unwrap ( ) . shrink_to_hi ( ) ,
1034
+ & format ! (
1035
+ "consider further restricting type parameter `{}`" ,
1036
+ param_ty,
1037
+ ) ,
1038
+ format ! ( ", {}" , trait_ref. to_predicate( ) ) ,
1039
+ Applicability :: MachineApplicable ,
1040
+ ) ;
1044
1041
} else {
1045
- err. span_label ( param. span , & format ! (
1046
- "consider adding a `where {}` bound" ,
1047
- trait_ref. to_predicate( ) ,
1048
- ) ) ;
1042
+ let sp = param. span . with_hi ( span. hi ( ) ) ;
1043
+ let span = self . tcx . sess . source_map ( )
1044
+ . span_through_char ( sp, ':' ) ;
1045
+ if sp != param. span && sp != span {
1046
+ // Only suggest if we have high certainty that the span
1047
+ // covers the colon in `foo<T: Trait>`.
1048
+ err. span_suggestion ( span, restrict_msg, format ! (
1049
+ "{} + " ,
1050
+ trait_ref. to_predicate( ) ,
1051
+ ) , Applicability :: MachineApplicable ) ;
1052
+ } else {
1053
+ err. span_label ( param. span , & format ! (
1054
+ "consider adding a `where {}` bound" ,
1055
+ trait_ref. to_predicate( ) ,
1056
+ ) ) ;
1057
+ }
1049
1058
}
1050
1059
}
1060
+ return ;
1051
1061
}
1052
- return ;
1053
1062
}
1054
1063
}
1064
+ hir:: Node :: Crate => return ,
1065
+ _ => { }
1055
1066
}
1067
+
1068
+ hir_id = self . tcx . hir ( ) . get_parent_item ( hir_id) ;
1056
1069
}
1057
1070
// FIXME: Add special check for `?Sized` so we don't suggest `T: Sized + ?Sized`.
1058
1071
0 commit comments