@@ -49,9 +49,10 @@ pub trait AstConv<'tcx> {
4949
5050 fn default_constness_for_trait_bounds ( & self ) -> Constness ;
5151
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.
5556 ///
5657 /// This is used for one specific purpose: resolving "short-hand"
5758 /// associated type references like `T::Item`. In principle, we
@@ -60,7 +61,12 @@ pub trait AstConv<'tcx> {
6061 /// but this can lead to cycle errors. The problem is that we have
6162 /// to do this resolution *in order to create the predicates in
6263 /// 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 > ;
6470
6571 /// Returns the lifetime to use when a lifetime is omitted (and not elided).
6672 fn re_infer ( & self , param : Option < & ty:: GenericParamDef > , span : Span )
@@ -792,7 +798,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
792798 }
793799
794800 // 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 {
796802 let tcx = self . tcx ( ) ;
797803
798804 // Try to find an unbound in bounds.
@@ -850,7 +856,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
850856 fn add_bounds (
851857 & self ,
852858 param_ty : Ty < ' tcx > ,
853- ast_bounds : & [ hir:: GenericBound < ' _ > ] ,
859+ ast_bounds : & [ & hir:: GenericBound < ' _ > ] ,
854860 bounds : & mut Bounds < ' tcx > ,
855861 ) {
856862 let constness = self . default_constness_for_trait_bounds ( ) ;
@@ -865,7 +871,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
865871 hir:: GenericBound :: Trait ( _, hir:: TraitBoundModifier :: Maybe ) => { }
866872 hir:: GenericBound :: LangItemTrait ( lang_item, span, hir_id, args) => self
867873 . 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,
869875 ) ,
870876 hir:: GenericBound :: Outlives ( ref l) => bounds
871877 . region_bounds
@@ -896,6 +902,42 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
896902 ast_bounds : & [ hir:: GenericBound < ' _ > ] ,
897903 sized_by_default : SizedByDefault ,
898904 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 ,
899941 ) -> Bounds < ' tcx > {
900942 let mut bounds = Bounds :: default ( ) ;
901943
@@ -1098,7 +1140,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
10981140 // parameter to have a skipped binder.
10991141 let param_ty =
11001142 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) ;
11021145 }
11031146 }
11041147 Ok ( ( ) )
@@ -1413,21 +1456,24 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
14131456 ty_param_def_id, assoc_name, span,
14141457 ) ;
14151458
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 ;
14181462
14191463 debug ! ( "find_bound_for_assoc_item: predicates={:#?}" , predicates) ;
14201464
14211465 let param_hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( ty_param_def_id) ;
14221466 let param_name = tcx. hir ( ) . ty_param_name ( param_hir_id) ;
14231467 self . one_bound_for_assoc_type (
14241468 || {
1425- traits:: transitive_bounds (
1469+ traits:: transitive_bounds_that_define_assoc_type (
14261470 tcx,
14271471 predicates. iter ( ) . filter_map ( |( p, _) | {
14281472 p. to_opt_poly_trait_ref ( ) . map ( |trait_ref| trait_ref. value )
14291473 } ) ,
1474+ assoc_name,
14301475 )
1476+ . into_iter ( )
14311477 } ,
14321478 || param_name. to_string ( ) ,
14331479 assoc_name,
0 commit comments