Nested impl traits trigger opaque_hidden_inferred_bound too much
This commit is contained in:
parent
1c771fec33
commit
e5189cc7e4
@ -27,6 +27,8 @@ declare_lint! {
|
||||
/// ### Example
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(type_alias_impl_trait)]
|
||||
///
|
||||
/// trait Duh {}
|
||||
///
|
||||
/// impl Duh for i32 {}
|
||||
@ -41,7 +43,9 @@ declare_lint! {
|
||||
/// type Assoc = F;
|
||||
/// }
|
||||
///
|
||||
/// fn test() -> impl Trait<Assoc = impl Sized> {
|
||||
/// type Tait = impl Sized;
|
||||
///
|
||||
/// fn test() -> impl Trait<Assoc = Tait> {
|
||||
/// 42
|
||||
/// }
|
||||
/// ```
|
||||
@ -54,7 +58,7 @@ declare_lint! {
|
||||
///
|
||||
/// Although the hidden type, `i32` does satisfy this bound, we do not
|
||||
/// consider the return type to be well-formed with this lint. It can be
|
||||
/// fixed by changing `impl Sized` into `impl Sized + Send`.
|
||||
/// fixed by changing `Tait = impl Sized` into `Tait = impl Sized + Send`.
|
||||
pub OPAQUE_HIDDEN_INFERRED_BOUND,
|
||||
Warn,
|
||||
"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]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
|
||||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
|
||||
let hir::ItemKind::OpaqueTy(_) = &item.kind else { return; };
|
||||
let hir::ItemKind::OpaqueTy(opaque) = &item.kind else { return; };
|
||||
let def_id = item.owner_id.def_id.to_def_id();
|
||||
let infcx = &cx.tcx.infer_ctxt().build();
|
||||
// For every projection predicate in the opaque type's explicit bounds,
|
||||
@ -81,6 +85,17 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
|
||||
// have opaques in them anyways.
|
||||
let Some(proj_term) = proj.term.ty() else { continue };
|
||||
|
||||
// HACK: `impl Trait<Assoc = impl Trait2>` from an RPIT is "ok"...
|
||||
if let ty::Alias(ty::Opaque, opaque_ty) = *proj_term.kind()
|
||||
&& cx.tcx.parent(opaque_ty.def_id) == def_id
|
||||
&& matches!(
|
||||
opaque.origin,
|
||||
hir::OpaqueTyOrigin::FnReturn(_) | hir::OpaqueTyOrigin::AsyncFn(_)
|
||||
)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
let proj_ty =
|
||||
cx.tcx.mk_projection(proj.projection_ty.def_id, proj.projection_ty.substs);
|
||||
// For every instance of the projection type in the bounds,
|
||||
|
@ -26,7 +26,6 @@ impl<R: Duh, F: FnMut() -> R> Trait for F {
|
||||
// Lazy TAIT would error out, but we inserted a hack to make it work again,
|
||||
// keeping backwards compatibility.
|
||||
fn foo() -> impl Trait<Assoc = impl Send> {
|
||||
//~^ WARN opaque type `impl Trait<Assoc = impl Send>` does not satisfy its associated type bounds
|
||||
|| 42
|
||||
}
|
||||
|
||||
|
@ -1,17 +0,0 @@
|
||||
warning: opaque type `impl Trait<Assoc = impl Send>` does not satisfy its associated type bounds
|
||||
--> $DIR/nested-return-type2.rs:28:24
|
||||
|
|
||||
LL | type Assoc: Duh;
|
||||
| --- this associated type bound is unsatisfied for `impl Send`
|
||||
...
|
||||
LL | fn foo() -> impl Trait<Assoc = impl Send> {
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(opaque_hidden_inferred_bound)]` on by default
|
||||
help: add this bound
|
||||
|
|
||||
LL | fn foo() -> impl Trait<Assoc = impl Send + Duh> {
|
||||
| +++++
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
@ -13,7 +13,6 @@ impl<F: Duh> Trait for F {
|
||||
}
|
||||
|
||||
fn foo() -> impl Trait<Assoc = impl Send> {
|
||||
//~^ WARN opaque type `impl Trait<Assoc = impl Send>` does not satisfy its associated type bounds
|
||||
42
|
||||
}
|
||||
|
||||
|
@ -1,17 +0,0 @@
|
||||
warning: opaque type `impl Trait<Assoc = impl Send>` does not satisfy its associated type bounds
|
||||
--> $DIR/nested-return-type3.rs:15:24
|
||||
|
|
||||
LL | type Assoc: Duh;
|
||||
| --- this associated type bound is unsatisfied for `impl Send`
|
||||
...
|
||||
LL | fn foo() -> impl Trait<Assoc = impl Send> {
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(opaque_hidden_inferred_bound)]` on by default
|
||||
help: add this bound
|
||||
|
|
||||
LL | fn foo() -> impl Trait<Assoc = impl Send + Duh> {
|
||||
| +++++
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
Loading…
x
Reference in New Issue
Block a user