about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNicholas Nethercote <n.nethercote@gmail.com>2025-08-07 12:04:58 +1000
committerNicholas Nethercote <n.nethercote@gmail.com>2025-08-07 12:46:33 +1000
commit8074e672f05b134bea95783ceeac83bceec3956a (patch)
treebcb806d3384076a6e198ac76a141ecc5f656aa9e
parent0f353363965ebf05e0757f7679c800b39c51a07e (diff)
Reimplement `print_region` in `type_name.rs`.
Broken by #144776; this is reachable after all.

Fixes #144994.

The commit also adds a lot more cases to the `type-name-basic.rs`,
because it's currently very anaemic. This includes some cases where
region omission does very badly; these are marked with FIXME.
-rw-r--r--compiler/rustc_const_eval/src/util/type_name.rs4
-rw-r--r--compiler/rustc_symbol_mangling/src/legacy.rs4
-rw-r--r--tests/ui/type/type-name-basic.rs81
3 files changed, 83 insertions, 6 deletions
diff --git a/compiler/rustc_const_eval/src/util/type_name.rs b/compiler/rustc_const_eval/src/util/type_name.rs
index e6b9759819f..2dc746754f8 100644
--- a/compiler/rustc_const_eval/src/util/type_name.rs
+++ b/compiler/rustc_const_eval/src/util/type_name.rs
@@ -18,7 +18,9 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
     }
 
     fn print_region(&mut self, _region: ty::Region<'_>) -> Result<(), PrintError> {
-        unreachable!(); // because `<Self As PrettyPrinter>::should_print_region` returns false
+        // This is reachable (via `pretty_print_dyn_existential`) even though
+        // `<Self As PrettyPrinter>::should_print_region` returns false. See #144994.
+        Ok(())
     }
 
     fn print_type(&mut self, ty: Ty<'tcx>) -> Result<(), PrintError> {
diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs
index aa8292c0504..a7f64085bd9 100644
--- a/compiler/rustc_symbol_mangling/src/legacy.rs
+++ b/compiler/rustc_symbol_mangling/src/legacy.rs
@@ -234,7 +234,9 @@ impl<'tcx> Printer<'tcx> for SymbolPrinter<'tcx> {
     }
 
     fn print_region(&mut self, _region: ty::Region<'_>) -> Result<(), PrintError> {
-        unreachable!(); // because `<Self As PrettyPrinter>::should_print_region` returns false
+        // This might be reachable (via `pretty_print_dyn_existential`) even though
+        // `<Self As PrettyPrinter>::should_print_region` returns false. See #144994.
+        Ok(())
     }
 
     fn print_type(&mut self, ty: Ty<'tcx>) -> Result<(), PrintError> {
diff --git a/tests/ui/type/type-name-basic.rs b/tests/ui/type/type-name-basic.rs
index 9381cb82578..6a9f772e542 100644
--- a/tests/ui/type/type-name-basic.rs
+++ b/tests/ui/type/type-name-basic.rs
@@ -6,12 +6,85 @@
 #![allow(dead_code)]
 
 use std::any::type_name;
+use std::borrow::Cow;
 
-struct Foo<T> {
-    x: T,
+struct Foo<T>(T);
+
+struct Bar<'a>(&'a u32);
+
+struct Baz<'a, T>(&'a T);
+
+trait TrL<'a> {}
+trait TrLA<'a> {
+    type A;
+}
+trait TrLT<'a, T> {}
+trait TrLTA<'a, T> {
+    type A;
+}
+
+macro_rules! t {
+    ($ty:ty, $str:literal) => {
+        assert_eq!(type_name::<$ty>(), $str);
+    }
 }
 
 pub fn main() {
-    assert_eq!(type_name::<isize>(), "isize");
-    assert_eq!(type_name::<Foo<usize>>(), "type_name_basic::Foo<usize>");
+    t!(bool, "bool");
+    t!(char, "char");
+
+    t!(u8, "u8");
+    t!(u16, "u16");
+    t!(u32, "u32");
+    t!(u64, "u64");
+    t!(u128, "u128");
+    t!(usize, "usize");
+
+    t!(i8, "i8");
+    t!(i16, "i16");
+    t!(i32, "i32");
+    t!(i64, "i64");
+    t!(i128, "i128");
+    t!(isize, "isize");
+
+    t!(String, "alloc::string::String");
+    t!(str, "str");
+    t!(&str, "&str");
+    t!(&'static str, "&str");
+
+    t!((u16, u32, u64), "(u16, u32, u64)");
+    t!([usize; 4], "[usize; 4]");
+    t!([usize], "[usize]");
+    t!(&[usize], "&[usize]");
+
+    t!(*const bool, "*const bool");
+    t!(*mut u64, "*mut u64");
+
+    t!(Vec<Vec<u32>>, "alloc::vec::Vec<alloc::vec::Vec<u32>>");
+    t!(Foo<usize>, "type_name_basic::Foo<usize>");
+    t!(Bar<'static>, "type_name_basic::Bar");
+    t!(Baz<'static, u32>, "type_name_basic::Baz<u32>");
+
+    // FIXME: lifetime omission means these all print badly.
+    t!(dyn TrL<'static>, "dyn type_name_basic::TrL<>");
+    t!(dyn TrLA<'static, A = u32>, "dyn type_name_basic::TrLA<, A = u32>");
+    t!(
+        dyn TrLT<'static, Cow<'static, ()>>,
+        "dyn type_name_basic::TrLT<, alloc::borrow::Cow<()>>"
+    );
+    t!(
+        dyn TrLTA<'static, u32, A = Cow<'static, ()>>,
+        "dyn type_name_basic::TrLTA<, u32, A = alloc::borrow::Cow<()>>"
+    );
+
+    t!(fn(i32) -> i32, "fn(i32) -> i32");
+    t!(dyn for<'a> Fn(&'a u32), "dyn core::ops::function::Fn(&u32)");
+
+    struct S<'a, T>(&'a T);
+    impl<'a, T: Clone> S<'a, T> {
+        fn test() {
+            t!(Cow<'a, T>, "alloc::borrow::Cow<u32>");
+        }
+    }
+    S::<u32>::test();
 }