@@ -82,10 +82,12 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
82
82
// start seeing the error below.
83
83
84
84
// Collect opaque types nested within the associated type bounds of this opaque type.
85
+ // We use identity substs here, because we already know that the opaque type uses
86
+ // only generic parameters, and thus substituting would not give us more information.
85
87
for ( pred, span) in self
86
88
. tcx
87
89
. explicit_item_bounds ( alias_ty. def_id )
88
- . subst_iter_copied ( self . tcx , alias_ty . substs )
90
+ . subst_identity_iter_copied ( )
89
91
{
90
92
trace ! ( ?pred) ;
91
93
self . visit_spanned ( span, pred) ;
@@ -158,6 +160,25 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
158
160
}
159
161
}
160
162
}
163
+ ty:: Adt ( def, _) if def. did ( ) . is_local ( ) => {
164
+ if !self . seen . insert ( def. did ( ) . expect_local ( ) ) {
165
+ return ControlFlow :: Continue ( ( ) ) ;
166
+ }
167
+ for variant in def. variants ( ) . iter ( ) {
168
+ for field in variant. fields . iter ( ) {
169
+ // Don't use the `ty::Adt` substs, we either
170
+ // * found the opaque in the substs
171
+ // * will find the opaque in the unsubstituted fields
172
+ // The only other situation that can occur is that after substituting,
173
+ // some projection resolves to an opaque that we would have otherwise
174
+ // not found. While we could substitute and walk those, that would mean we
175
+ // would have to walk all substitutions of an Adt, which can quickly
176
+ // degenerate into looking at an exponential number of types.
177
+ let ty = self . tcx . type_of ( field. did ) . subst_identity ( ) ;
178
+ self . visit_spanned ( self . tcx . def_span ( field. did ) , ty) ;
179
+ }
180
+ }
181
+ }
161
182
_ => trace ! ( kind=?t. kind( ) ) ,
162
183
}
163
184
ControlFlow :: Continue ( ( ) )
0 commit comments