@@ -2,7 +2,7 @@ use rustc_hir as hir;
22use rustc_infer:: infer:: TyCtxtInferExt ;
33use rustc_macros:: { LintDiagnostic , Subdiagnostic } ;
44use rustc_middle:: ty:: {
5- self , fold:: BottomUpFolder , print:: TraitPredPrintModifiersAndPath , Ty , TypeFoldable ,
5+ self , fold:: BottomUpFolder , print:: TraitPredPrintModifiersAndPath , DefIdTree , Ty , TypeFoldable ,
66} ;
77use rustc_span:: Span ;
88use rustc_trait_selection:: traits;
@@ -27,6 +27,8 @@ declare_lint! {
2727 /// ### Example
2828 ///
2929 /// ```rust
30+ /// #![feature(type_alias_impl_trait)]
31+ ///
3032 /// trait Duh {}
3133 ///
3234 /// impl Duh for i32 {}
@@ -41,7 +43,9 @@ declare_lint! {
4143 /// type Assoc = F;
4244 /// }
4345 ///
44- /// fn test() -> impl Trait<Assoc = impl Sized> {
46+ /// type Tait = impl Sized;
47+ ///
48+ /// fn test() -> impl Trait<Assoc = Tait> {
4549 /// 42
4650 /// }
4751 /// ```
@@ -54,7 +58,7 @@ declare_lint! {
5458 ///
5559 /// Although the hidden type, `i32` does satisfy this bound, we do not
5660 /// consider the return type to be well-formed with this lint. It can be
57- /// fixed by changing `impl Sized` into `impl Sized + Send`.
61+ /// fixed by changing `Tait = impl Sized` into `Tait = impl Sized + Send`.
5862 pub OPAQUE_HIDDEN_INFERRED_BOUND ,
5963 Warn ,
6064 "detects the use of nested `impl Trait` types in associated type bounds that are not general enough"
@@ -64,7 +68,7 @@ declare_lint_pass!(OpaqueHiddenInferredBound => [OPAQUE_HIDDEN_INFERRED_BOUND]);
6468
6569impl < ' tcx > LateLintPass < ' tcx > for OpaqueHiddenInferredBound {
6670 fn check_item ( & mut self , cx : & LateContext < ' tcx > , item : & ' tcx hir:: Item < ' tcx > ) {
67- let hir:: ItemKind :: OpaqueTy ( _ ) = & item. kind else { return ; } ;
71+ let hir:: ItemKind :: OpaqueTy ( opaque ) = & item. kind else { return ; } ;
6872 let def_id = item. owner_id . def_id . to_def_id ( ) ;
6973 let infcx = & cx. tcx . infer_ctxt ( ) . build ( ) ;
7074 // For every projection predicate in the opaque type's explicit bounds,
@@ -81,6 +85,17 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
8185 // have opaques in them anyways.
8286 let Some ( proj_term) = proj. term . ty ( ) else { continue } ;
8387
88+ // HACK: `impl Trait<Assoc = impl Trait2>` from an RPIT is "ok"...
89+ if let ty:: Alias ( ty:: Opaque , opaque_ty) = * proj_term. kind ( )
90+ && cx. tcx . parent ( opaque_ty. def_id ) == def_id
91+ && matches ! (
92+ opaque. origin,
93+ hir:: OpaqueTyOrigin :: FnReturn ( _) | hir:: OpaqueTyOrigin :: AsyncFn ( _)
94+ )
95+ {
96+ continue ;
97+ }
98+
8499 let proj_ty =
85100 cx. tcx . mk_projection ( proj. projection_ty . def_id , proj. projection_ty . substs ) ;
86101 // For every instance of the projection type in the bounds,
0 commit comments