@@ -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 )
@@ -792,7 +798,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
792
798
}
793
799
794
800
// Returns `true` if a bounds list includes `?Sized`.
795
- pub fn is_unsized ( & self , ast_bounds : & [ hir:: GenericBound < ' _ > ] , span : Span ) -> bool {
801
+ pub fn is_unsized ( & self , ast_bounds : & [ & hir:: GenericBound < ' _ > ] , span : Span ) -> bool {
796
802
let tcx = self . tcx ( ) ;
797
803
798
804
// Try to find an unbound in bounds.
@@ -850,7 +856,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
850
856
fn add_bounds (
851
857
& self ,
852
858
param_ty : Ty < ' tcx > ,
853
- ast_bounds : & [ hir:: GenericBound < ' _ > ] ,
859
+ ast_bounds : & [ & hir:: GenericBound < ' _ > ] ,
854
860
bounds : & mut Bounds < ' tcx > ,
855
861
) {
856
862
let constness = self . default_constness_for_trait_bounds ( ) ;
@@ -865,7 +871,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
865
871
hir:: GenericBound :: Trait ( _, hir:: TraitBoundModifier :: Maybe ) => { }
866
872
hir:: GenericBound :: LangItemTrait ( lang_item, span, hir_id, args) => self
867
873
. instantiate_lang_item_trait_ref (
868
- lang_item, span, hir_id, args, param_ty, bounds,
874
+ * lang_item, * span, * hir_id, args, param_ty, bounds,
869
875
) ,
870
876
hir:: GenericBound :: Outlives ( ref l) => bounds
871
877
. region_bounds
@@ -896,6 +902,42 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
896
902
ast_bounds : & [ hir:: GenericBound < ' _ > ] ,
897
903
sized_by_default : SizedByDefault ,
898
904
span : Span ,
905
+ ) -> Bounds < ' tcx > {
906
+ let ast_bounds: Vec < _ > = ast_bounds. iter ( ) . collect ( ) ;
907
+ self . compute_bounds_inner ( param_ty, & ast_bounds, sized_by_default, span)
908
+ }
909
+
910
+ /// Convert the bounds in `ast_bounds` that refer to traits which define an associated type
911
+ /// named `assoc_name` into ty::Bounds. Ignore the rest.
912
+ pub fn compute_bounds_that_match_assoc_type (
913
+ & self ,
914
+ param_ty : Ty < ' tcx > ,
915
+ ast_bounds : & [ hir:: GenericBound < ' _ > ] ,
916
+ sized_by_default : SizedByDefault ,
917
+ span : Span ,
918
+ assoc_name : Ident ,
919
+ ) -> Bounds < ' tcx > {
920
+ let mut result = Vec :: new ( ) ;
921
+
922
+ for ast_bound in ast_bounds {
923
+ if let Some ( trait_ref) = ast_bound. trait_ref ( ) {
924
+ if let Some ( trait_did) = trait_ref. trait_def_id ( ) {
925
+ if self . tcx ( ) . trait_may_define_assoc_type ( trait_did, assoc_name) {
926
+ result. push ( ast_bound) ;
927
+ }
928
+ }
929
+ }
930
+ }
931
+
932
+ self . compute_bounds_inner ( param_ty, & result, sized_by_default, span)
933
+ }
934
+
935
+ fn compute_bounds_inner (
936
+ & self ,
937
+ param_ty : Ty < ' tcx > ,
938
+ ast_bounds : & [ & hir:: GenericBound < ' _ > ] ,
939
+ sized_by_default : SizedByDefault ,
940
+ span : Span ,
899
941
) -> Bounds < ' tcx > {
900
942
let mut bounds = Bounds :: default ( ) ;
901
943
@@ -1098,7 +1140,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1098
1140
// parameter to have a skipped binder.
1099
1141
let param_ty =
1100
1142
tcx. mk_projection ( assoc_ty. def_id , projection_ty. skip_binder ( ) . substs ) ;
1101
- self . add_bounds ( param_ty, ast_bounds, bounds) ;
1143
+ let ast_bounds: Vec < _ > = ast_bounds. iter ( ) . collect ( ) ;
1144
+ self . add_bounds ( param_ty, & ast_bounds, bounds) ;
1102
1145
}
1103
1146
}
1104
1147
Ok ( ( ) )
@@ -1413,21 +1456,24 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1413
1456
ty_param_def_id, assoc_name, span,
1414
1457
) ;
1415
1458
1416
- let predicates =
1417
- & self . get_type_parameter_bounds ( span, ty_param_def_id. to_def_id ( ) ) . predicates ;
1459
+ let predicates = & self
1460
+ . get_type_parameter_bounds ( span, ty_param_def_id. to_def_id ( ) , assoc_name)
1461
+ . predicates ;
1418
1462
1419
1463
debug ! ( "find_bound_for_assoc_item: predicates={:#?}" , predicates) ;
1420
1464
1421
1465
let param_hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( ty_param_def_id) ;
1422
1466
let param_name = tcx. hir ( ) . ty_param_name ( param_hir_id) ;
1423
1467
self . one_bound_for_assoc_type (
1424
1468
|| {
1425
- traits:: transitive_bounds (
1469
+ traits:: transitive_bounds_that_define_assoc_type (
1426
1470
tcx,
1427
1471
predicates. iter ( ) . filter_map ( |( p, _) | {
1428
1472
p. to_opt_poly_trait_ref ( ) . map ( |trait_ref| trait_ref. value )
1429
1473
} ) ,
1474
+ assoc_name,
1430
1475
)
1476
+ . into_iter ( )
1431
1477
} ,
1432
1478
|| param_name. to_string ( ) ,
1433
1479
assoc_name,
0 commit comments