1
1
use crate :: autoderef:: Autoderef ;
2
2
use crate :: constrained_generic_params:: { identify_constrained_generic_params, Parameter } ;
3
+ use crate :: errors;
3
4
4
5
use hir:: def:: DefKind ;
5
6
use rustc_ast as ast;
@@ -15,6 +16,7 @@ use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
15
16
use rustc_middle:: mir:: ConstraintCategory ;
16
17
use rustc_middle:: ty:: query:: Providers ;
17
18
use rustc_middle:: ty:: trait_def:: TraitSpecializationKind ;
19
+ use rustc_middle:: ty:: visit:: TypeVisitableExt ;
18
20
use rustc_middle:: ty:: {
19
21
self , ir:: TypeVisitor , AdtKind , DefIdTree , GenericParamDefKind , Ty , TyCtxt , TypeFoldable ,
20
22
TypeSuperVisitable ,
@@ -278,6 +280,62 @@ fn check_trait_item(tcx: TyCtxt<'_>, trait_item: &hir::TraitItem<'_>) {
278
280
check_object_unsafe_self_trait_by_name ( tcx, trait_item) ;
279
281
check_associated_item ( tcx, def_id, span, method_sig) ;
280
282
283
+ struct FindImplTraitInTrait < ' tcx > ( TyCtxt < ' tcx > ) ;
284
+ impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for FindImplTraitInTrait < ' tcx > {
285
+ type BreakTy = DefId ;
286
+ fn visit_ty ( & mut self , ty : Ty < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
287
+ if let ty:: Alias ( ty:: Projection , alias_ty) = * ty. kind ( )
288
+ && self . 0 . def_kind ( alias_ty. def_id ) == DefKind :: ImplTraitPlaceholder
289
+ {
290
+ return ControlFlow :: Break ( alias_ty. def_id ) ;
291
+ } else if ty. has_projections ( ) {
292
+ ty. super_visit_with ( self )
293
+ } else {
294
+ ControlFlow :: Continue ( ( ) )
295
+ }
296
+ }
297
+ }
298
+ if let hir:: TraitItemKind :: Fn ( _, hir:: TraitFn :: Provided ( body_id) ) = trait_item. kind
299
+ && let ControlFlow :: Break ( def_id) = tcx
300
+ . fn_sig ( def_id)
301
+ . skip_binder ( )
302
+ . output ( )
303
+ . visit_with ( & mut FindImplTraitInTrait ( tcx) )
304
+ {
305
+ let hir:: ItemKind :: OpaqueTy ( opaque) = & tcx. hir ( ) . expect_item ( def_id. expect_local ( ) ) . kind else {
306
+ bug ! ( ) ;
307
+ } ;
308
+ match opaque. origin {
309
+ hir:: OpaqueTyOrigin :: FnReturn ( _) => {
310
+ let mut diag = tcx. sess . create_err (
311
+ errors:: DefaultRpititMethodNotAllowed :: ReturnPositionImplTrait {
312
+ body_span : tcx. hir ( ) . span ( body_id. hir_id ) . shrink_to_lo ( ) ,
313
+ rpitit_span : tcx. def_span ( def_id) ,
314
+ } ,
315
+ ) ;
316
+ if tcx. features ( ) . return_position_impl_trait_in_trait {
317
+ diag. emit ( ) ;
318
+ } else {
319
+ diag. delay_as_bug ( ) ;
320
+ }
321
+ }
322
+ hir:: OpaqueTyOrigin :: AsyncFn ( _) => {
323
+ let mut diag =
324
+ tcx. sess . create_err ( errors:: DefaultRpititMethodNotAllowed :: AsyncFn {
325
+ body_span : tcx. hir ( ) . span ( body_id. hir_id ) . shrink_to_lo ( ) ,
326
+ } ) ;
327
+ if tcx. features ( ) . async_fn_in_trait {
328
+ diag. emit ( ) ;
329
+ } else {
330
+ diag. delay_as_bug ( ) ;
331
+ }
332
+ }
333
+ hir:: OpaqueTyOrigin :: TyAlias => {
334
+ // TAIT comes from alias expansion, so it's fine.
335
+ }
336
+ }
337
+ }
338
+
281
339
let encl_trait_def_id = tcx. local_parent ( def_id) ;
282
340
let encl_trait = tcx. hir ( ) . expect_item ( encl_trait_def_id) ;
283
341
let encl_trait_def_id = encl_trait. owner_id . to_def_id ( ) ;
0 commit comments