@@ -2,7 +2,7 @@ use rustc_hir as hir;
2
2
use rustc_infer:: infer:: TyCtxtInferExt ;
3
3
use rustc_macros:: { LintDiagnostic , Subdiagnostic } ;
4
4
use rustc_middle:: ty:: {
5
- self , fold:: BottomUpFolder , print:: TraitPredPrintModifiersAndPath , Ty , TypeFoldable ,
5
+ self , fold:: BottomUpFolder , print:: TraitPredPrintModifiersAndPath , DefIdTree , Ty , TypeFoldable ,
6
6
} ;
7
7
use rustc_span:: Span ;
8
8
use rustc_trait_selection:: traits;
@@ -27,6 +27,8 @@ declare_lint! {
27
27
/// ### Example
28
28
///
29
29
/// ```rust
30
+ /// #![feature(type_alias_impl_trait)]
31
+ ///
30
32
/// trait Duh {}
31
33
///
32
34
/// impl Duh for i32 {}
@@ -41,7 +43,9 @@ declare_lint! {
41
43
/// type Assoc = F;
42
44
/// }
43
45
///
44
- /// fn test() -> impl Trait<Assoc = impl Sized> {
46
+ /// type Tait = impl Sized;
47
+ ///
48
+ /// fn test() -> impl Trait<Assoc = Tait> {
45
49
/// 42
46
50
/// }
47
51
/// ```
@@ -54,7 +58,7 @@ declare_lint! {
54
58
///
55
59
/// Although the hidden type, `i32` does satisfy this bound, we do not
56
60
/// 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`.
58
62
pub OPAQUE_HIDDEN_INFERRED_BOUND ,
59
63
Warn ,
60
64
"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]);
64
68
65
69
impl < ' tcx > LateLintPass < ' tcx > for OpaqueHiddenInferredBound {
66
70
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 ; } ;
68
72
let def_id = item. owner_id . def_id . to_def_id ( ) ;
69
73
let infcx = & cx. tcx . infer_ctxt ( ) . build ( ) ;
70
74
// For every projection predicate in the opaque type's explicit bounds,
@@ -81,6 +85,17 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
81
85
// have opaques in them anyways.
82
86
let Some ( proj_term) = proj. term . ty ( ) else { continue } ;
83
87
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
+
84
99
let proj_ty =
85
100
cx. tcx . mk_projection ( proj. projection_ty . def_id , proj. projection_ty . substs ) ;
86
101
// For every instance of the projection type in the bounds,
0 commit comments