diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs index 957a6bb348109..0544c5ca86619 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -1,7 +1,7 @@ use rustc_errors::StashKey; use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::{self as hir, Expr, ImplItem, Item, Node, TraitItem}; +use rustc_hir::{self as hir, def, Expr, ImplItem, Item, Node, TraitItem}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::DUMMY_SP; @@ -74,9 +74,14 @@ pub(super) fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: Local hidden.ty } else { + let mut parent_def_id = def_id; + while tcx.def_kind(parent_def_id) == def::DefKind::OpaqueTy { + // Account for `type Alias = impl Trait;` (#116031) + parent_def_id = tcx.local_parent(parent_def_id); + } let reported = tcx.sess.emit_err(UnconstrainedOpaqueType { span: tcx.def_span(def_id), - name: tcx.item_name(tcx.local_parent(def_id).to_def_id()), + name: tcx.item_name(parent_def_id.to_def_id()), what: match tcx.hir().get(scope) { _ if scope == hir::CRATE_HIR_ID => "module", Node::Item(hir::Item { kind: hir::ItemKind::Mod(_), .. }) => "module", diff --git a/tests/ui/type-alias-impl-trait/nested-impl-trait-in-tait.rs b/tests/ui/type-alias-impl-trait/nested-impl-trait-in-tait.rs new file mode 100644 index 0000000000000..fec0fdc46fbb6 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/nested-impl-trait-in-tait.rs @@ -0,0 +1,9 @@ +#![feature(type_alias_impl_trait)] + +pub type Tait = impl Iterator; +//~^ ERROR use of undeclared lifetime name `'db` +//~| ERROR cannot find type `Key` in this scope +//~| ERROR unconstrained opaque type +//~| ERROR unconstrained opaque type + +pub fn main() {} diff --git a/tests/ui/type-alias-impl-trait/nested-impl-trait-in-tait.stderr b/tests/ui/type-alias-impl-trait/nested-impl-trait-in-tait.stderr new file mode 100644 index 0000000000000..d4aeace4ae707 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/nested-impl-trait-in-tait.stderr @@ -0,0 +1,47 @@ +error[E0261]: use of undeclared lifetime name `'db` + --> $DIR/nested-impl-trait-in-tait.rs:3:40 + | +LL | pub type Tait = impl Iterator; + | ^^^ undeclared lifetime + | + = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html +help: consider making the bound lifetime-generic with a new `'db` lifetime + | +LL | pub type Tait = impl for<'db> Iterator; + | ++++++++ +help: consider introducing lifetime `'db` here + | +LL | pub type Tait<'db> = impl Iterator; + | +++++ + +error[E0412]: cannot find type `Key` in this scope + --> $DIR/nested-impl-trait-in-tait.rs:3:44 + | +LL | pub type Tait = impl Iterator; + | ^^^ not found in this scope + | +help: consider importing this struct + | +LL + use std::thread::local_impl::Key; + | + +error: unconstrained opaque type + --> $DIR/nested-impl-trait-in-tait.rs:3:17 + | +LL | pub type Tait = impl Iterator; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `Tait` must be used in combination with a concrete type within the same module + +error: unconstrained opaque type + --> $DIR/nested-impl-trait-in-tait.rs:3:49 + | +LL | pub type Tait = impl Iterator; + | ^^^^^^^^^^^^^ + | + = note: `Tait` must be used in combination with a concrete type within the same module + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0261, E0412. +For more information about an error, try `rustc --explain E0261`.