@@ -38,12 +38,13 @@ fn associated_type_bounds<'tcx>(
3838 let icx = ItemCtxt :: new( tcx, assoc_item_def_id) ;
3939 let mut bounds = Vec :: new( ) ;
4040 icx. lowerer( ) . lower_bounds( item_ty, hir_bounds, & mut bounds, ty:: List :: empty( ) , filter) ;
41- // Implicit bounds are added to associated types unless a `?Trait` bound is found
41+
4242 match filter {
4343 PredicateFilter :: All
4444 | PredicateFilter :: SelfOnly
4545 | PredicateFilter :: SelfTraitThatDefines ( _)
4646 | PredicateFilter :: SelfAndAssociatedTypeBounds => {
47+ // Implicit bounds are added to associated types unless a `?Trait` bound is found.
4748 icx. lowerer( ) . add_sizedness_bounds(
4849 & mut bounds,
4950 item_ty,
@@ -53,37 +54,48 @@ fn associated_type_bounds<'tcx>(
5354 span,
5455 ) ;
5556 icx. lowerer( ) . add_default_traits( & mut bounds, item_ty, hir_bounds, None , span) ;
57+
58+ // Also collect `where Self::Assoc: Trait` from the parent trait's where clauses.
59+ let trait_def_id = tcx. local_parent( assoc_item_def_id) ;
60+ let trait_predicates = tcx. trait_explicit_predicates_and_bounds( trait_def_id) ;
61+
62+ let item_trait_ref =
63+ ty:: TraitRef :: identity( tcx, tcx. parent( assoc_item_def_id. to_def_id( ) ) ) ;
64+ bounds. extend( trait_predicates. predicates. iter( ) . copied( ) . filter_map(
65+ |( clause, span) | {
66+ remap_gat_vars_and_recurse_into_nested_projections(
67+ tcx,
68+ filter,
69+ item_trait_ref,
70+ assoc_item_def_id,
71+ span,
72+ clause,
73+ )
74+ } ,
75+ ) ) ;
5676 }
5777 // `ConstIfConst` is only interested in `[const]` bounds.
58- PredicateFilter :: ConstIfConst | PredicateFilter :: SelfConstIfConst => { }
78+ PredicateFilter :: ConstIfConst | PredicateFilter :: SelfConstIfConst => {
79+ // FIXME(const_trait_impl): We *could* uplift the
80+ // `where Self::Assoc: [const] Trait` bounds from the parent trait
81+ // here too, but we'd need to split `const_conditions` into two
82+ // queries (like we do for `trait_explicit_predicates_and_bounds`)
83+ // since we need to also filter the predicates *out* of the const
84+ // conditions or they lead to cycles in the trait solver when
85+ // utilizing these bounds. For now, let's do nothing.
86+ }
5987 }
6088
61- let trait_def_id = tcx. local_parent( assoc_item_def_id) ;
62- let trait_predicates = tcx. trait_explicit_predicates_and_bounds( trait_def_id) ;
63-
64- let item_trait_ref = ty:: TraitRef :: identity( tcx, tcx. parent( assoc_item_def_id. to_def_id( ) ) ) ;
65- let bounds_from_parent =
66- trait_predicates. predicates. iter( ) . copied( ) . filter_map( |( clause, span) | {
67- remap_gat_vars_and_recurse_into_nested_projections(
68- tcx,
69- filter,
70- item_trait_ref,
71- assoc_item_def_id,
72- span,
73- clause,
74- )
75- } ) ;
76-
77- let all_bounds = tcx. arena. alloc_from_iter( bounds. into_iter( ) . chain( bounds_from_parent) ) ;
89+ let bounds = tcx. arena. alloc_from_iter( bounds) ;
7890 debug!(
7991 "associated_type_bounds({}) = {:?}" ,
8092 tcx. def_path_str( assoc_item_def_id. to_def_id( ) ) ,
81- all_bounds
93+ bounds
8294 ) ;
8395
84- assert_only_contains_predicates_from( filter, all_bounds , item_ty) ;
96+ assert_only_contains_predicates_from( filter, bounds , item_ty) ;
8597
86- all_bounds
98+ bounds
8799 } )
88100}
89101
0 commit comments