@@ -4,6 +4,13 @@ use rustc_data_structures::stable_set::FxHashSet;
44use rustc_middle:: ty:: { self , Ty } ;
55use rustc_span:: Span ;
66
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.
714pub ( super ) struct StructuralPredicateElaborator < ' a , ' tcx > {
815 stack : Vec < Ty < ' tcx > > ,
916 seen : FxHashSet < Ty < ' tcx > > ,
@@ -19,18 +26,8 @@ impl<'a, 'tcx> StructuralPredicateElaborator<'a, 'tcx> {
1926 StructuralPredicateElaborator { seen, stack, fcx, span }
2027 }
2128
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 > > {
3431 match * t. kind ( ) {
3532 ty:: Projection ( ..) => {
3633 bug ! ( "this type should be handled separately: {:?}" , t)
@@ -100,10 +97,12 @@ impl<'tcx> Iterator for StructuralPredicateElaborator<'_, 'tcx> {
10097 while let Some ( ty) = self . stack . pop ( ) {
10198 if let ty:: Projection ( projection_ty) = * ty. kind ( ) {
10299 let mut normalized_ty = self . fcx . normalize_associated_types_in ( self . span , ty) ;
100+ // Try to resolve the projection type
103101 if normalized_ty. is_ty_var ( ) {
104102 self . fcx . select_obligations_where_possible ( false , |_| { } ) ;
105103 normalized_ty = self . fcx . resolve_vars_if_possible ( normalized_ty) ;
106104 }
105+ // If we have a normalized type, then stash it
107106 if !normalized_ty. is_ty_var ( ) && normalized_ty != ty {
108107 if self . seen . insert ( normalized_ty) {
109108 self . stack . push ( normalized_ty) ;
@@ -115,7 +114,7 @@ impl<'tcx> Iterator for StructuralPredicateElaborator<'_, 'tcx> {
115114 }
116115 } else {
117116 let structural: Vec < _ > = self
118- . constituent_types_for_auto_trait ( ty)
117+ . constituent_types ( ty)
119118 . into_iter ( )
120119 . map ( |ty| self . fcx . resolve_vars_if_possible ( ty) )
121120 . filter ( |ty| self . seen . insert ( ty) )
0 commit comments