about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs59
-rw-r--r--tests/ui/const-generics/unsized_const_params/symbol_mangling_v0_str.rs24
2 files changed, 51 insertions, 32 deletions
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index ba35a37c32c..1e8d7697fb7 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -593,45 +593,40 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
                 let _ = write!(self.out, "{bits:x}_");
             }
 
+            // Handle `str` as partial support for unsized constants
+            ty::Str => {
+                let tcx = self.tcx();
+                // HACK(jaic1): hide the `str` type behind a reference
+                // for the following transformation from valtree to raw bytes
+                let ref_ty = Ty::new_imm_ref(tcx, tcx.lifetimes.re_static, ct_ty);
+                let slice = valtree.try_to_raw_bytes(tcx, ref_ty).unwrap_or_else(|| {
+                    bug!("expected to get raw bytes from valtree {:?} for type {:}", valtree, ct_ty)
+                });
+                let s = std::str::from_utf8(slice).expect("non utf8 str from MIR interpreter");
+
+                // "e" for str as a basic type
+                self.push("e");
+
+                // FIXME(eddyb) use a specialized hex-encoding loop.
+                for byte in s.bytes() {
+                    let _ = write!(self.out, "{byte:02x}");
+                }
+
+                self.push("_");
+            }
+
             // FIXME(valtrees): Remove the special case for `str`
             // here and fully support unsized constants.
-            ty::Ref(_, inner_ty, mutbl) => {
+            ty::Ref(_, _, mutbl) => {
                 self.push(match mutbl {
                     hir::Mutability::Not => "R",
                     hir::Mutability::Mut => "Q",
                 });
 
-                match inner_ty.kind() {
-                    ty::Str if mutbl.is_not() => {
-                        let slice =
-                            valtree.try_to_raw_bytes(self.tcx(), ct_ty).unwrap_or_else(|| {
-                                bug!(
-                                    "expected to get raw bytes from valtree {:?} for type {:}",
-                                    valtree,
-                                    ct_ty
-                                )
-                            });
-                        let s =
-                            std::str::from_utf8(slice).expect("non utf8 str from MIR interpreter");
-
-                        self.push("e");
-
-                        // FIXME(eddyb) use a specialized hex-encoding loop.
-                        for byte in s.bytes() {
-                            let _ = write!(self.out, "{byte:02x}");
-                        }
-
-                        self.push("_");
-                    }
-                    _ => {
-                        let pointee_ty = ct_ty
-                            .builtin_deref(true)
-                            .expect("tried to dereference on non-ptr type");
-                        let dereferenced_const =
-                            ty::Const::new_value(self.tcx, valtree, pointee_ty);
-                        dereferenced_const.print(self)?;
-                    }
-                }
+                let pointee_ty =
+                    ct_ty.builtin_deref(true).expect("tried to dereference on non-ptr type");
+                let dereferenced_const = ty::Const::new_value(self.tcx, valtree, pointee_ty);
+                dereferenced_const.print(self)?;
             }
 
             ty::Array(..) | ty::Tuple(..) | ty::Adt(..) | ty::Slice(_) => {
diff --git a/tests/ui/const-generics/unsized_const_params/symbol_mangling_v0_str.rs b/tests/ui/const-generics/unsized_const_params/symbol_mangling_v0_str.rs
new file mode 100644
index 00000000000..359126f1251
--- /dev/null
+++ b/tests/ui/const-generics/unsized_const_params/symbol_mangling_v0_str.rs
@@ -0,0 +1,24 @@
+//@ check-pass
+//@ compile-flags: -Csymbol-mangling-version=v0
+#![allow(incomplete_features)]
+#![feature(unsized_const_params)]
+
+// Regression test for #116303
+
+#[derive(PartialEq, Eq)]
+struct MyStr(str);
+impl std::marker::UnsizedConstParamTy for MyStr {}
+
+fn function_with_my_str<const S: &'static MyStr>() -> &'static MyStr {
+    S
+}
+
+impl MyStr {
+    const fn new(s: &'static str) -> &'static MyStr {
+        unsafe { std::mem::transmute(s) }
+    }
+}
+
+pub fn main() {
+    let f = function_with_my_str::<{ MyStr::new("hello") }>();
+}