@@ -118,6 +118,69 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
118118 }
119119 TaitInBodyFinder { collector : self } . visit_expr ( body) ;
120120 }
121+
122+ fn visit_opaque_ty ( & mut self , alias_ty : & ty:: AliasTy < ' tcx > ) {
123+ if !self . seen . insert ( alias_ty. def_id . expect_local ( ) ) {
124+ return ;
125+ }
126+
127+ // TAITs outside their defining scopes are ignored.
128+ let origin = self . tcx . opaque_type_origin ( alias_ty. def_id . expect_local ( ) ) ;
129+ trace ! ( ?origin) ;
130+ match origin {
131+ rustc_hir:: OpaqueTyOrigin :: FnReturn ( _) | rustc_hir:: OpaqueTyOrigin :: AsyncFn ( _) => { }
132+ rustc_hir:: OpaqueTyOrigin :: TyAlias { in_assoc_ty } => {
133+ if !in_assoc_ty {
134+ if !self . check_tait_defining_scope ( alias_ty. def_id . expect_local ( ) ) {
135+ return ;
136+ }
137+ }
138+ }
139+ }
140+
141+ self . opaques . push ( alias_ty. def_id . expect_local ( ) ) ;
142+
143+ let parent_count = self . tcx . generics_of ( alias_ty. def_id ) . parent_count ;
144+ // Only check that the parent generics of the TAIT/RPIT are unique.
145+ // the args owned by the opaque are going to always be duplicate
146+ // lifetime params for RPITs, and empty for TAITs.
147+ match self
148+ . tcx
149+ . uses_unique_generic_params ( & alias_ty. args [ ..parent_count] , CheckRegions :: FromFunction )
150+ {
151+ Ok ( ( ) ) => {
152+ // FIXME: implement higher kinded lifetime bounds on nested opaque types. They are not
153+ // supported at all, so this is sound to do, but once we want to support them, you'll
154+ // start seeing the error below.
155+
156+ // Collect opaque types nested within the associated type bounds of this opaque type.
157+ // We use identity args here, because we already know that the opaque type uses
158+ // only generic parameters, and thus substituting would not give us more information.
159+ for ( pred, span) in self
160+ . tcx
161+ . explicit_item_bounds ( alias_ty. def_id )
162+ . instantiate_identity_iter_copied ( )
163+ {
164+ trace ! ( ?pred) ;
165+ self . visit_spanned ( span, pred) ;
166+ }
167+ }
168+ Err ( NotUniqueParam :: NotParam ( arg) ) => {
169+ self . tcx . dcx ( ) . emit_err ( NotParam {
170+ arg,
171+ span : self . span ( ) ,
172+ opaque_span : self . tcx . def_span ( alias_ty. def_id ) ,
173+ } ) ;
174+ }
175+ Err ( NotUniqueParam :: DuplicateParam ( arg) ) => {
176+ self . tcx . dcx ( ) . emit_err ( DuplicateArg {
177+ arg,
178+ span : self . span ( ) ,
179+ opaque_span : self . tcx . def_span ( alias_ty. def_id ) ,
180+ } ) ;
181+ }
182+ }
183+ }
121184}
122185
123186impl < ' tcx > super :: sig_types:: SpannedTypeVisitor < ' tcx > for OpaqueTypeCollector < ' tcx > {
@@ -134,67 +197,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
134197 t. super_visit_with ( self ) ?;
135198 match t. kind ( ) {
136199 ty:: Alias ( ty:: Opaque , alias_ty) if alias_ty. def_id . is_local ( ) => {
137- if !self . seen . insert ( alias_ty. def_id . expect_local ( ) ) {
138- return ControlFlow :: Continue ( ( ) ) ;
139- }
140-
141- // TAITs outside their defining scopes are ignored.
142- let origin = self . tcx . opaque_type_origin ( alias_ty. def_id . expect_local ( ) ) ;
143- trace ! ( ?origin) ;
144- match origin {
145- rustc_hir:: OpaqueTyOrigin :: FnReturn ( _)
146- | rustc_hir:: OpaqueTyOrigin :: AsyncFn ( _) => { }
147- rustc_hir:: OpaqueTyOrigin :: TyAlias { in_assoc_ty } => {
148- if !in_assoc_ty {
149- if !self . check_tait_defining_scope ( alias_ty. def_id . expect_local ( ) ) {
150- return ControlFlow :: Continue ( ( ) ) ;
151- }
152- }
153- }
154- }
155-
156- self . opaques . push ( alias_ty. def_id . expect_local ( ) ) ;
157-
158- let parent_count = self . tcx . generics_of ( alias_ty. def_id ) . parent_count ;
159- // Only check that the parent generics of the TAIT/RPIT are unique.
160- // the args owned by the opaque are going to always be duplicate
161- // lifetime params for RPITs, and empty for TAITs.
162- match self . tcx . uses_unique_generic_params (
163- & alias_ty. args [ ..parent_count] ,
164- CheckRegions :: FromFunction ,
165- ) {
166- Ok ( ( ) ) => {
167- // FIXME: implement higher kinded lifetime bounds on nested opaque types. They are not
168- // supported at all, so this is sound to do, but once we want to support them, you'll
169- // start seeing the error below.
170-
171- // Collect opaque types nested within the associated type bounds of this opaque type.
172- // We use identity args here, because we already know that the opaque type uses
173- // only generic parameters, and thus substituting would not give us more information.
174- for ( pred, span) in self
175- . tcx
176- . explicit_item_bounds ( alias_ty. def_id )
177- . instantiate_identity_iter_copied ( )
178- {
179- trace ! ( ?pred) ;
180- self . visit_spanned ( span, pred) ;
181- }
182- }
183- Err ( NotUniqueParam :: NotParam ( arg) ) => {
184- self . tcx . dcx ( ) . emit_err ( NotParam {
185- arg,
186- span : self . span ( ) ,
187- opaque_span : self . tcx . def_span ( alias_ty. def_id ) ,
188- } ) ;
189- }
190- Err ( NotUniqueParam :: DuplicateParam ( arg) ) => {
191- self . tcx . dcx ( ) . emit_err ( DuplicateArg {
192- arg,
193- span : self . span ( ) ,
194- opaque_span : self . tcx . def_span ( alias_ty. def_id ) ,
195- } ) ;
196- }
197- }
200+ self . visit_opaque_ty ( alias_ty) ;
198201 }
199202 ty:: Alias ( ty:: Weak , alias_ty) if alias_ty. def_id . is_local ( ) => {
200203 self . tcx
0 commit comments