Skip to content

Commit c2ccd89

Browse files
committed
handle unsized consts with type str in v0 symbol mangling
1 parent 506f22b commit c2ccd89

File tree

2 files changed

+51
-32
lines changed

2 files changed

+51
-32
lines changed

compiler/rustc_symbol_mangling/src/v0.rs

+27-32
Original file line numberDiff line numberDiff line change
@@ -593,45 +593,40 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
593593
let _ = write!(self.out, "{bits:x}_");
594594
}
595595

596+
// Handle `str` as partial support for unsized constants
597+
ty::Str => {
598+
let tcx = self.tcx();
599+
// HACK(jaic1): hide the `str` type behind a reference
600+
// for the following transformation from valtree to raw bytes
601+
let ref_ty = Ty::new_imm_ref(tcx, tcx.lifetimes.re_static, ct_ty);
602+
let slice = valtree.try_to_raw_bytes(tcx, ref_ty).unwrap_or_else(|| {
603+
bug!("expected to get raw bytes from valtree {:?} for type {:}", valtree, ct_ty)
604+
});
605+
let s = std::str::from_utf8(slice).expect("non utf8 str from MIR interpreter");
606+
607+
// "e" for str as a basic type
608+
self.push("e");
609+
610+
// FIXME(eddyb) use a specialized hex-encoding loop.
611+
for byte in s.bytes() {
612+
let _ = write!(self.out, "{byte:02x}");
613+
}
614+
615+
self.push("_");
616+
}
617+
596618
// FIXME(valtrees): Remove the special case for `str`
597619
// here and fully support unsized constants.
598-
ty::Ref(_, inner_ty, mutbl) => {
620+
ty::Ref(_, _, mutbl) => {
599621
self.push(match mutbl {
600622
hir::Mutability::Not => "R",
601623
hir::Mutability::Mut => "Q",
602624
});
603625

604-
match inner_ty.kind() {
605-
ty::Str if mutbl.is_not() => {
606-
let slice =
607-
valtree.try_to_raw_bytes(self.tcx(), ct_ty).unwrap_or_else(|| {
608-
bug!(
609-
"expected to get raw bytes from valtree {:?} for type {:}",
610-
valtree,
611-
ct_ty
612-
)
613-
});
614-
let s =
615-
std::str::from_utf8(slice).expect("non utf8 str from MIR interpreter");
616-
617-
self.push("e");
618-
619-
// FIXME(eddyb) use a specialized hex-encoding loop.
620-
for byte in s.bytes() {
621-
let _ = write!(self.out, "{byte:02x}");
622-
}
623-
624-
self.push("_");
625-
}
626-
_ => {
627-
let pointee_ty = ct_ty
628-
.builtin_deref(true)
629-
.expect("tried to dereference on non-ptr type");
630-
let dereferenced_const =
631-
ty::Const::new_value(self.tcx, valtree, pointee_ty);
632-
dereferenced_const.print(self)?;
633-
}
634-
}
626+
let pointee_ty =
627+
ct_ty.builtin_deref(true).expect("tried to dereference on non-ptr type");
628+
let dereferenced_const = ty::Const::new_value(self.tcx, valtree, pointee_ty);
629+
dereferenced_const.print(self)?;
635630
}
636631

637632
ty::Array(..) | ty::Tuple(..) | ty::Adt(..) | ty::Slice(_) => {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//@ check-pass
2+
//@ compile-flags: -Csymbol-mangling-version=v0
3+
#![allow(incomplete_features)]
4+
#![feature(unsized_const_params)]
5+
6+
// Regression test for #116303
7+
8+
#[derive(PartialEq, Eq)]
9+
struct MyStr(str);
10+
impl std::marker::UnsizedConstParamTy for MyStr {}
11+
12+
fn function_with_my_str<const S: &'static MyStr>() -> &'static MyStr {
13+
S
14+
}
15+
16+
impl MyStr {
17+
const fn new(s: &'static str) -> &'static MyStr {
18+
unsafe { std::mem::transmute(s) }
19+
}
20+
}
21+
22+
pub fn main() {
23+
let f = function_with_my_str::<{ MyStr::new("hello") }>();
24+
}

0 commit comments

Comments
 (0)