@@ -24,6 +24,7 @@ pub struct VerifyBoundCx<'cx, 'tcx> {
24
24
/// setting `'?0` to `'empty`.
25
25
implicit_region_bound : Option < ty:: Region < ' tcx > > ,
26
26
caller_bounds : & ' cx [ ty:: PolyTypeOutlivesPredicate < ' tcx > ] ,
27
+ projection_predicates : & ' cx [ ty:: PolyTypeProjectionPredicate < ' tcx > ] ,
27
28
}
28
29
29
30
impl < ' cx , ' tcx > VerifyBoundCx < ' cx , ' tcx > {
@@ -32,12 +33,23 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
32
33
region_bound_pairs : & ' cx RegionBoundPairs < ' tcx > ,
33
34
implicit_region_bound : Option < ty:: Region < ' tcx > > ,
34
35
caller_bounds : & ' cx [ ty:: PolyTypeOutlivesPredicate < ' tcx > ] ,
36
+ projection_predicates : & ' cx [ ty:: PolyTypeProjectionPredicate < ' tcx > ] ,
35
37
) -> Self {
36
- Self { tcx, region_bound_pairs, implicit_region_bound, caller_bounds }
38
+ Self {
39
+ tcx,
40
+ region_bound_pairs,
41
+ implicit_region_bound,
42
+ caller_bounds,
43
+ projection_predicates,
44
+ }
37
45
}
38
46
39
47
#[ instrument( level = "debug" , skip( self ) ) ]
40
- pub fn param_or_placeholder_bound ( & self , ty : Ty < ' tcx > ) -> VerifyBound < ' tcx > {
48
+ pub fn param_or_placeholder_bound (
49
+ & self ,
50
+ ty : Ty < ' tcx > ,
51
+ visited : & mut SsoHashSet < GenericArg < ' tcx > > ,
52
+ ) -> VerifyBound < ' tcx > {
41
53
// Start with anything like `T: 'a` we can scrape from the
42
54
// environment. If the environment contains something like
43
55
// `for<'a> T: 'a`, then we know that `T` outlives everything.
@@ -56,6 +68,28 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
56
68
}
57
69
}
58
70
71
+ // A parameter or placeholder bound can also be aliased to an associated type
72
+ // so we need to inspect in the "reverse"
73
+ for & predicate in self . projection_predicates {
74
+ let ty:: ProjectionPredicate { term, projection_ty } =
75
+ self . tcx . erase_regions ( predicate) . skip_binder ( ) ;
76
+ if let Some ( term) = term. ty ( )
77
+ && ty == term
78
+ {
79
+ debug ! ( ?term, ?projection_ty, "found a matching predicate" ) ;
80
+ let alias_ty_as_ty = projection_ty. to_ty ( self . tcx ) ;
81
+ let mut components = smallvec ! [ ] ;
82
+ compute_alias_components_recursive (
83
+ self . tcx ,
84
+ alias_ty_as_ty,
85
+ & mut components,
86
+ visited,
87
+ ) ;
88
+ debug ! ( ?components) ;
89
+ param_bounds. push ( self . bound_from_components ( & components, visited) ) ;
90
+ }
91
+ }
92
+
59
93
// Add in the default bound of fn body that applies to all in
60
94
// scope type parameters:
61
95
if let Some ( r) = self . implicit_region_bound {
@@ -163,10 +197,11 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
163
197
) -> VerifyBound < ' tcx > {
164
198
match * component {
165
199
Component :: Region ( lt) => VerifyBound :: OutlivedBy ( lt) ,
166
- Component :: Param ( param_ty) => self . param_or_placeholder_bound ( param_ty. to_ty ( self . tcx ) ) ,
167
- Component :: Placeholder ( placeholder_ty) => {
168
- self . param_or_placeholder_bound ( Ty :: new_placeholder ( self . tcx , placeholder_ty) )
200
+ Component :: Param ( param_ty) => {
201
+ self . param_or_placeholder_bound ( param_ty. to_ty ( self . tcx ) , visited)
169
202
}
203
+ Component :: Placeholder ( placeholder_ty) => self
204
+ . param_or_placeholder_bound ( Ty :: new_placeholder ( self . tcx , placeholder_ty) , visited) ,
170
205
Component :: Alias ( alias_ty) => self . alias_bound ( alias_ty, visited) ,
171
206
Component :: EscapingAlias ( ref components) => {
172
207
self . bound_from_components ( components, visited)
0 commit comments