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
|
/// ### Example
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
|
/// #![feature(type_alias_impl_trait)]
|
||||||
|
///
|
||||||
/// trait Duh {}
|
/// trait Duh {}
|
||||||
///
|
///
|
||||||
/// impl Duh for i32 {}
|
/// impl Duh for i32 {}
|
||||||
@ -41,7 +43,9 @@ declare_lint! {
|
|||||||
/// type Assoc = F;
|
/// type Assoc = F;
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// fn test() -> impl Trait<Assoc = impl Sized> {
|
/// type Tait = impl Sized;
|
||||||
|
///
|
||||||
|
/// fn test() -> impl Trait<Assoc = Tait> {
|
||||||
/// 42
|
/// 42
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
@ -54,7 +58,7 @@ declare_lint! {
|
|||||||
///
|
///
|
||||||
/// Although the hidden type, `i32` does satisfy this bound, we do not
|
/// 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
|
/// 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,
|
pub OPAQUE_HIDDEN_INFERRED_BOUND,
|
||||||
Warn,
|
Warn,
|
||||||
"detects the use of nested `impl Trait` types in associated type bounds that are not general enough"
|
"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 {
|
impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
|
||||||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
|
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 def_id = item.owner_id.def_id.to_def_id();
|
||||||
let infcx = &cx.tcx.infer_ctxt().build();
|
let infcx = &cx.tcx.infer_ctxt().build();
|
||||||
// For every projection predicate in the opaque type's explicit bounds,
|
// 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.
|
// have opaques in them anyways.
|
||||||
let Some(proj_term) = proj.term.ty() else { continue };
|
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 =
|
let proj_ty =
|
||||||
cx.tcx.mk_projection(proj.projection_ty.def_id, proj.projection_ty.substs);
|
cx.tcx.mk_projection(proj.projection_ty.def_id, proj.projection_ty.substs);
|
||||||
// For every instance of the projection type in the bounds,
|
// 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,
|
// Lazy TAIT would error out, but we inserted a hack to make it work again,
|
||||||
// keeping backwards compatibility.
|
// keeping backwards compatibility.
|
||||||
fn foo() -> impl Trait<Assoc = impl Send> {
|
fn foo() -> impl Trait<Assoc = impl Send> {
|
||||||
//~^ WARN opaque type `impl Trait<Assoc = impl Send>` does not satisfy its associated type bounds
|
|
||||||
|| 42
|
|| 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> {
|
fn foo() -> impl Trait<Assoc = impl Send> {
|
||||||
//~^ WARN opaque type `impl Trait<Assoc = impl Send>` does not satisfy its associated type bounds
|
|
||||||
42
|
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