From 9261fd0983daf700525861358deabbdcc0878709 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 27 Feb 2023 20:47:06 +0000 Subject: [PATCH] Nested impl traits trigger opaque_hidden_inferred_bound too much --- .../src/opaque_hidden_inferred_bound.rs | 23 +++++++++++++++---- tests/ui/impl-trait/nested-return-type2.rs | 1 - .../ui/impl-trait/nested-return-type2.stderr | 17 -------------- tests/ui/impl-trait/nested-return-type3.rs | 1 - .../ui/impl-trait/nested-return-type3.stderr | 17 -------------- 5 files changed, 19 insertions(+), 40 deletions(-) delete mode 100644 tests/ui/impl-trait/nested-return-type2.stderr delete mode 100644 tests/ui/impl-trait/nested-return-type3.stderr diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index 883a56cb3ce6b..bff8fc236544f 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -2,7 +2,7 @@ use rustc_hir as hir; use rustc_infer::infer::TyCtxtInferExt; use rustc_macros::{LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::{ - self, fold::BottomUpFolder, print::TraitPredPrintModifiersAndPath, Ty, TypeFoldable, + self, fold::BottomUpFolder, print::TraitPredPrintModifiersAndPath, DefIdTree, Ty, TypeFoldable, }; use rustc_span::Span; use rustc_trait_selection::traits; @@ -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 { + /// type Tait = impl Sized; + /// + /// fn test() -> impl Trait { /// 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` 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, diff --git a/tests/ui/impl-trait/nested-return-type2.rs b/tests/ui/impl-trait/nested-return-type2.rs index fe883ce6fc8ed..e1d5511379e7a 100644 --- a/tests/ui/impl-trait/nested-return-type2.rs +++ b/tests/ui/impl-trait/nested-return-type2.rs @@ -26,7 +26,6 @@ impl 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 { - //~^ WARN opaque type `impl Trait` does not satisfy its associated type bounds || 42 } diff --git a/tests/ui/impl-trait/nested-return-type2.stderr b/tests/ui/impl-trait/nested-return-type2.stderr deleted file mode 100644 index 09ad3bd05c1b3..0000000000000 --- a/tests/ui/impl-trait/nested-return-type2.stderr +++ /dev/null @@ -1,17 +0,0 @@ -warning: opaque type `impl Trait` 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 { - | ^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(opaque_hidden_inferred_bound)]` on by default -help: add this bound - | -LL | fn foo() -> impl Trait { - | +++++ - -warning: 1 warning emitted - diff --git a/tests/ui/impl-trait/nested-return-type3.rs b/tests/ui/impl-trait/nested-return-type3.rs index 5a764fc4c285a..74b4dae22ebfd 100644 --- a/tests/ui/impl-trait/nested-return-type3.rs +++ b/tests/ui/impl-trait/nested-return-type3.rs @@ -13,7 +13,6 @@ impl Trait for F { } fn foo() -> impl Trait { - //~^ WARN opaque type `impl Trait` does not satisfy its associated type bounds 42 } diff --git a/tests/ui/impl-trait/nested-return-type3.stderr b/tests/ui/impl-trait/nested-return-type3.stderr deleted file mode 100644 index 632de71aa4c88..0000000000000 --- a/tests/ui/impl-trait/nested-return-type3.stderr +++ /dev/null @@ -1,17 +0,0 @@ -warning: opaque type `impl Trait` 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 { - | ^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(opaque_hidden_inferred_bound)]` on by default -help: add this bound - | -LL | fn foo() -> impl Trait { - | +++++ - -warning: 1 warning emitted -