about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2025-05-07 20:52:08 +0200
committerJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2025-05-07 22:17:29 +0200
commit5913e55dfc3c473f6c28f5a341850574aff1f685 (patch)
treec3cd7b8e64f4657800bbc0a0d9f1f7e3df815e00
parentdb0e836148accac8a22532e3596ac612b63c2d8e (diff)
downloadrust-5913e55dfc3c473f6c28f5a341850574aff1f685.tar.gz
rust-5913e55dfc3c473f6c28f5a341850574aff1f685.zip
Add `DefPathData::OpaqueLifetime` to avoid conflicts for remapped opaque lifetimes
-rw-r--r--compiler/rustc_hir/src/definitions.rs15
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs10
-rw-r--r--compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs1
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.rs16
-rw-r--r--tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.stderr26
6 files changed, 57 insertions, 12 deletions
diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs
index 98b41187f11..f93b9e5af53 100644
--- a/compiler/rustc_hir/src/definitions.rs
+++ b/compiler/rustc_hir/src/definitions.rs
@@ -309,6 +309,8 @@ pub enum DefPathData {
     /// An existential `impl Trait` type node.
     /// Argument position `impl Trait` have a `TypeNs` with their pretty-printed name.
     OpaqueTy,
+    /// Used for remapped captured lifetimes in an existential `impl Trait` type node.
+    OpaqueLifetime(Symbol),
     /// An anonymous associated type from an RPITIT. The symbol refers to the name of the method
     /// that defined the type.
     AnonAssocTy(Symbol),
@@ -445,7 +447,8 @@ impl DefPathData {
     pub fn get_opt_name(&self) -> Option<Symbol> {
         use self::DefPathData::*;
         match *self {
-            TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name),
+            TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name)
+            | OpaqueLifetime(name) => Some(name),
 
             Impl
             | ForeignMod
@@ -465,9 +468,8 @@ impl DefPathData {
     fn hashed_symbol(&self) -> Option<Symbol> {
         use self::DefPathData::*;
         match *self {
-            TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) | AnonAssocTy(name) => {
-                Some(name)
-            }
+            TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) | AnonAssocTy(name)
+            | OpaqueLifetime(name) => Some(name),
 
             Impl
             | ForeignMod
@@ -486,9 +488,8 @@ impl DefPathData {
     pub fn name(&self) -> DefPathDataName {
         use self::DefPathData::*;
         match *self {
-            TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => {
-                DefPathDataName::Named(name)
-            }
+            TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name)
+            | OpaqueLifetime(name) => DefPathDataName::Named(name),
             // Note that this does not show up in user print-outs.
             CrateRoot => DefPathDataName::Anon { namespace: kw::Crate },
             Impl => DefPathDataName::Anon { namespace: kw::Impl },
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index a89160785eb..709446d09cd 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -14,7 +14,7 @@ use rustc_ast::visit::walk_list;
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::definitions::DisambiguatorState;
+use rustc_hir::definitions::{DefPathData, DisambiguatorState};
 use rustc_hir::intravisit::{self, InferKind, Visitor, VisitorExt};
 use rustc_hir::{
     self as hir, AmbigArg, GenericArg, GenericParam, GenericParamKind, HirId, LifetimeKind, Node,
@@ -1470,14 +1470,14 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
             let mut captures = captures.borrow_mut();
             let remapped = *captures.entry(lifetime).or_insert_with(|| {
                 // `opaque_def_id` is unique to the `BoundVarContext` pass which is executed once
-                // per `resolve_bound_vars` query. This is the only location that creates nested
-                // lifetime inside a opaque type. `<opaque_def_id>::LifetimeNs(..)` is thus unique
+                // per `resolve_bound_vars` query. This is the only location that creates
+                // `OpaqueLifetime` paths. `<opaque_def_id>::OpaqueLifetime(..)` is thus unique
                 // to this query and duplicates within the query are handled by `self.disambiguator`.
                 let feed = self.tcx.create_def(
                     opaque_def_id,
-                    Some(ident.name),
-                    DefKind::LifetimeParam,
                     None,
+                    DefKind::LifetimeParam,
+                    Some(DefPathData::OpaqueLifetime(ident.name)),
                     &mut self.disambiguator,
                 );
                 feed.def_span(ident.span);
diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
index f7f354d12e8..47831f2f418 100644
--- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
+++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
@@ -722,6 +722,7 @@ fn encode_ty_name(tcx: TyCtxt<'_>, def_id: DefId) -> String {
             | hir::definitions::DefPathData::Use
             | hir::definitions::DefPathData::GlobalAsm
             | hir::definitions::DefPathData::MacroNs(..)
+            | hir::definitions::DefPathData::OpaqueLifetime(..)
             | hir::definitions::DefPathData::LifetimeNs(..)
             | hir::definitions::DefPathData::AnonAssocTy(..) => {
                 bug!("encode_ty_name: unexpected `{:?}`", disambiguated_data.data);
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index 1f45440eecf..4a99ce09b39 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -890,6 +890,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
             | DefPathData::Impl
             | DefPathData::MacroNs(_)
             | DefPathData::LifetimeNs(_)
+            | DefPathData::OpaqueLifetime(_)
             | DefPathData::AnonAssocTy(..) => {
                 bug!("symbol_names: unexpected DefPathData: {:?}", disambiguated_data.data)
             }
diff --git a/tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.rs b/tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.rs
new file mode 100644
index 00000000000..bfaa48585ef
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.rs
@@ -0,0 +1,16 @@
+// https://github.com/rust-lang/rust/issues/140731
+// This tests that there's no def path conflict between the
+// remapped lifetime and the lifetime present in the source.
+
+#![feature(impl_trait_in_assoc_type)]
+
+trait Trait<'a> {}
+
+impl<'a> Trait<'a> for u32 {
+    type Opq2 = impl for<'a> Trait<'a>;
+    //~^ ERROR: unconstrained opaque type
+    //~| ERROR: type `Opq2` is not a member of trait `Trait`
+    //~| ERROR: lifetime name `'a` shadows a lifetime name that is already in scope
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.stderr b/tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.stderr
new file mode 100644
index 00000000000..e1544c5911b
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/lifetime-def-path-conflict-40731.stderr
@@ -0,0 +1,26 @@
+error[E0437]: type `Opq2` is not a member of trait `Trait`
+  --> $DIR/lifetime-def-path-conflict-40731.rs:10:5
+   |
+LL |     type Opq2 = impl for<'a> Trait<'a>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a member of trait `Trait`
+
+error[E0496]: lifetime name `'a` shadows a lifetime name that is already in scope
+  --> $DIR/lifetime-def-path-conflict-40731.rs:10:26
+   |
+LL | impl<'a> Trait<'a> for u32 {
+   |      -- first declared here
+LL |     type Opq2 = impl for<'a> Trait<'a>;
+   |                          ^^ lifetime `'a` already in scope
+
+error: unconstrained opaque type
+  --> $DIR/lifetime-def-path-conflict-40731.rs:10:17
+   |
+LL |     type Opq2 = impl for<'a> Trait<'a>;
+   |                 ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `Opq2` must be used in combination with a concrete type within the same impl
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0437, E0496.
+For more information about an error, try `rustc --explain E0437`.