@@ -38,12 +38,13 @@ fn associated_type_bounds<'tcx>(
38
38
let icx = ItemCtxt :: new( tcx, assoc_item_def_id) ;
39
39
let mut bounds = Vec :: new( ) ;
40
40
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
+
42
42
match filter {
43
43
PredicateFilter :: All
44
44
| PredicateFilter :: SelfOnly
45
45
| PredicateFilter :: SelfTraitThatDefines ( _)
46
46
| PredicateFilter :: SelfAndAssociatedTypeBounds => {
47
+ // Implicit bounds are added to associated types unless a `?Trait` bound is found.
47
48
icx. lowerer( ) . add_sizedness_bounds(
48
49
& mut bounds,
49
50
item_ty,
@@ -53,37 +54,48 @@ fn associated_type_bounds<'tcx>(
53
54
span,
54
55
) ;
55
56
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
+ ) ) ;
56
76
}
57
77
// `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
+ }
59
87
}
60
88
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) ;
78
90
debug!(
79
91
"associated_type_bounds({}) = {:?}" ,
80
92
tcx. def_path_str( assoc_item_def_id. to_def_id( ) ) ,
81
- all_bounds
93
+ bounds
82
94
) ;
83
95
84
- assert_only_contains_predicates_from( filter, all_bounds , item_ty) ;
96
+ assert_only_contains_predicates_from( filter, bounds , item_ty) ;
85
97
86
- all_bounds
98
+ bounds
87
99
} )
88
100
}
89
101
0 commit comments