@@ -49,9 +49,10 @@ pub trait AstConv<'tcx> {
49
49
50
50
fn default_constness_for_trait_bounds ( & self ) -> Constness ;
51
51
52
- /// Returns predicates in scope of the form `X: Foo`, where `X` is
53
- /// a type parameter `X` with the given id `def_id`. This is a
54
- /// subset of the full set of predicates.
52
+ /// Returns predicates in scope of the form `X: Foo<T>`, where `X`
53
+ /// is a type parameter `X` with the given id `def_id` and T
54
+ /// matches `assoc_name`. This is a subset of the full set of
55
+ /// predicates.
55
56
///
56
57
/// This is used for one specific purpose: resolving "short-hand"
57
58
/// associated type references like `T::Item`. In principle, we
@@ -60,7 +61,12 @@ pub trait AstConv<'tcx> {
60
61
/// but this can lead to cycle errors. The problem is that we have
61
62
/// to do this resolution *in order to create the predicates in
62
63
/// the first place*. Hence, we have this "special pass".
63
- fn get_type_parameter_bounds ( & self , span : Span , def_id : DefId ) -> ty:: GenericPredicates < ' tcx > ;
64
+ fn get_type_parameter_bounds (
65
+ & self ,
66
+ span : Span ,
67
+ def_id : DefId ,
68
+ assoc_name : Ident ,
69
+ ) -> ty:: GenericPredicates < ' tcx > ;
64
70
65
71
/// Returns the lifetime to use when a lifetime is omitted (and not elided).
66
72
fn re_infer ( & self , param : Option < & ty:: GenericParamDef > , span : Span )
@@ -762,7 +768,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
762
768
}
763
769
764
770
// Returns `true` if a bounds list includes `?Sized`.
765
- pub fn is_unsized ( & self , ast_bounds : & [ hir:: GenericBound < ' _ > ] , span : Span ) -> bool {
771
+ pub fn is_unsized ( & self , ast_bounds : & [ & hir:: GenericBound < ' _ > ] , span : Span ) -> bool {
766
772
let tcx = self . tcx ( ) ;
767
773
768
774
// Try to find an unbound in bounds.
@@ -820,7 +826,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
820
826
fn add_bounds (
821
827
& self ,
822
828
param_ty : Ty < ' tcx > ,
823
- ast_bounds : & [ hir:: GenericBound < ' _ > ] ,
829
+ ast_bounds : & [ & hir:: GenericBound < ' _ > ] ,
824
830
bounds : & mut Bounds < ' tcx > ,
825
831
) {
826
832
let constness = self . default_constness_for_trait_bounds ( ) ;
@@ -835,7 +841,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
835
841
hir:: GenericBound :: Trait ( _, hir:: TraitBoundModifier :: Maybe ) => { }
836
842
hir:: GenericBound :: LangItemTrait ( lang_item, span, hir_id, args) => self
837
843
. instantiate_lang_item_trait_ref (
838
- lang_item, span, hir_id, args, param_ty, bounds,
844
+ * lang_item, * span, * hir_id, args, param_ty, bounds,
839
845
) ,
840
846
hir:: GenericBound :: Outlives ( ref l) => {
841
847
bounds. region_bounds . push ( ( self . ast_region_to_region ( l, None ) , l. span ) )
@@ -866,6 +872,42 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
866
872
ast_bounds : & [ hir:: GenericBound < ' _ > ] ,
867
873
sized_by_default : SizedByDefault ,
868
874
span : Span ,
875
+ ) -> Bounds < ' tcx > {
876
+ let ast_bounds: Vec < _ > = ast_bounds. iter ( ) . collect ( ) ;
877
+ self . compute_bounds_inner ( param_ty, & ast_bounds, sized_by_default, span)
878
+ }
879
+
880
+ /// Convert the bounds in `ast_bounds` that refer to traits which define an associated type
881
+ /// named `assoc_name` into ty::Bounds. Ignore the rest.
882
+ pub fn compute_bounds_that_match_assoc_type (
883
+ & self ,
884
+ param_ty : Ty < ' tcx > ,
885
+ ast_bounds : & [ hir:: GenericBound < ' _ > ] ,
886
+ sized_by_default : SizedByDefault ,
887
+ span : Span ,
888
+ assoc_name : Ident ,
889
+ ) -> Bounds < ' tcx > {
890
+ let mut result = Vec :: new ( ) ;
891
+
892
+ for ast_bound in ast_bounds {
893
+ if let Some ( trait_ref) = ast_bound. trait_ref ( ) {
894
+ if let Some ( trait_did) = trait_ref. trait_def_id ( ) {
895
+ if self . tcx ( ) . trait_may_define_assoc_type ( trait_did, assoc_name) {
896
+ result. push ( ast_bound) ;
897
+ }
898
+ }
899
+ }
900
+ }
901
+
902
+ self . compute_bounds_inner ( param_ty, & result, sized_by_default, span)
903
+ }
904
+
905
+ fn compute_bounds_inner (
906
+ & self ,
907
+ param_ty : Ty < ' tcx > ,
908
+ ast_bounds : & [ & hir:: GenericBound < ' _ > ] ,
909
+ sized_by_default : SizedByDefault ,
910
+ span : Span ,
869
911
) -> Bounds < ' tcx > {
870
912
let mut bounds = Bounds :: default ( ) ;
871
913
@@ -1035,7 +1077,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1035
1077
// Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty`
1036
1078
// parameter to have a skipped binder.
1037
1079
let param_ty = tcx. mk_projection ( assoc_ty. def_id , candidate. skip_binder ( ) . substs ) ;
1038
- self . add_bounds ( param_ty, ast_bounds, bounds) ;
1080
+ let ast_bounds: Vec < _ > = ast_bounds. iter ( ) . collect ( ) ;
1081
+ self . add_bounds ( param_ty, & ast_bounds, bounds) ;
1039
1082
}
1040
1083
}
1041
1084
Ok ( ( ) )
@@ -1352,21 +1395,24 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1352
1395
ty_param_def_id, assoc_name, span,
1353
1396
) ;
1354
1397
1355
- let predicates =
1356
- & self . get_type_parameter_bounds ( span, ty_param_def_id. to_def_id ( ) ) . predicates ;
1398
+ let predicates = & self
1399
+ . get_type_parameter_bounds ( span, ty_param_def_id. to_def_id ( ) , assoc_name)
1400
+ . predicates ;
1357
1401
1358
1402
debug ! ( "find_bound_for_assoc_item: predicates={:#?}" , predicates) ;
1359
1403
1360
1404
let param_hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( ty_param_def_id) ;
1361
1405
let param_name = tcx. hir ( ) . ty_param_name ( param_hir_id) ;
1362
1406
self . one_bound_for_assoc_type (
1363
1407
|| {
1364
- traits:: transitive_bounds (
1408
+ traits:: transitive_bounds_that_define_assoc_type (
1365
1409
tcx,
1366
1410
predicates. iter ( ) . filter_map ( |( p, _) | {
1367
1411
p. to_opt_poly_trait_ref ( ) . map ( |trait_ref| trait_ref. value )
1368
1412
} ) ,
1413
+ assoc_name,
1369
1414
)
1415
+ . into_iter ( )
1370
1416
} ,
1371
1417
|| param_name. to_string ( ) ,
1372
1418
assoc_name,
0 commit comments