@@ -4,6 +4,13 @@ use rustc_data_structures::stable_set::FxHashSet;
4
4
use rustc_middle:: ty:: { self , Ty } ;
5
5
use rustc_span:: Span ;
6
6
7
+ /// This helper walks through generator-interior types, collecting projection types,
8
+ /// and creating ProjectionPredicates that we can use in the param-env when checking
9
+ /// auto traits later on.
10
+ ///
11
+ /// We walk through the constituent types of a type, and when we encounter a projection,
12
+ /// normalize that projection. If that normalization was successful, then create a
13
+ /// ProjectionPredicate out of the old projection type and its normalized ty.
7
14
pub ( super ) struct StructuralPredicateElaborator < ' a , ' tcx > {
8
15
stack : Vec < Ty < ' tcx > > ,
9
16
seen : FxHashSet < Ty < ' tcx > > ,
@@ -19,18 +26,8 @@ impl<'a, 'tcx> StructuralPredicateElaborator<'a, 'tcx> {
19
26
StructuralPredicateElaborator { seen, stack, fcx, span }
20
27
}
21
28
22
- /// For default impls, we need to break apart a type into its
23
- /// "constituent types" -- meaning, the types that it contains.
24
- ///
25
- /// Here are some (simple) examples:
26
- ///
27
- /// ```
28
- /// (i32, u32) -> [i32, u32]
29
- /// Foo where struct Foo { x: i32, y: u32 } -> [i32, u32]
30
- /// Bar<i32> where struct Bar<T> { x: T, y: u32 } -> [i32, u32]
31
- /// Zed<i32> where enum Zed { A(T), B(u32) } -> [i32, u32]
32
- /// ```
33
- fn constituent_types_for_auto_trait ( & self , t : Ty < ' tcx > ) -> Vec < Ty < ' tcx > > {
29
+ // Ripped from confirmation code, lol.
30
+ fn constituent_types ( & self , t : Ty < ' tcx > ) -> Vec < Ty < ' tcx > > {
34
31
match * t. kind ( ) {
35
32
ty:: Projection ( ..) => {
36
33
bug ! ( "this type should be handled separately: {:?}" , t)
@@ -100,10 +97,12 @@ impl<'tcx> Iterator for StructuralPredicateElaborator<'_, 'tcx> {
100
97
while let Some ( ty) = self . stack . pop ( ) {
101
98
if let ty:: Projection ( projection_ty) = * ty. kind ( ) {
102
99
let mut normalized_ty = self . fcx . normalize_associated_types_in ( self . span , ty) ;
100
+ // Try to resolve the projection type
103
101
if normalized_ty. is_ty_var ( ) {
104
102
self . fcx . select_obligations_where_possible ( false , |_| { } ) ;
105
103
normalized_ty = self . fcx . resolve_vars_if_possible ( normalized_ty) ;
106
104
}
105
+ // If we have a normalized type, then stash it
107
106
if !normalized_ty. is_ty_var ( ) && normalized_ty != ty {
108
107
if self . seen . insert ( normalized_ty) {
109
108
self . stack . push ( normalized_ty) ;
@@ -115,7 +114,7 @@ impl<'tcx> Iterator for StructuralPredicateElaborator<'_, 'tcx> {
115
114
}
116
115
} else {
117
116
let structural: Vec < _ > = self
118
- . constituent_types_for_auto_trait ( ty)
117
+ . constituent_types ( ty)
119
118
. into_iter ( )
120
119
. map ( |ty| self . fcx . resolve_vars_if_possible ( ty) )
121
120
. filter ( |ty| self . seen . insert ( ty) )
0 commit comments