Skip to content

Commit 06d61a7

Browse files
committed
handle unsized consts with type str in v0 symbol mangling
1 parent 23b04c0 commit 06d61a7

File tree

2 files changed

+54
-20
lines changed

2 files changed

+54
-20
lines changed

compiler/rustc_symbol_mangling/src/v0.rs

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,31 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
574574

575575
let start = self.out.len();
576576

577+
let print_str = |this: &mut Self| {
578+
let tcx = this.tcx();
579+
let ref_ty = if matches!(ct_ty.kind(), ty::Str) {
580+
// HACK(jaic1): hide the `str` type behind a reference
581+
// for the following transformation from valtree to raw bytes
582+
Ty::new_imm_ref(tcx, tcx.lifetimes.re_static, ct_ty)
583+
} else {
584+
ct_ty
585+
};
586+
let slice = valtree.try_to_raw_bytes(tcx, ref_ty).unwrap_or_else(|| {
587+
bug!("expected to get raw bytes from valtree {:?} for type {:}", valtree, ct_ty)
588+
});
589+
let s = std::str::from_utf8(slice).expect("non utf8 str from MIR interpreter");
590+
591+
// "e" for str as a basic type
592+
this.push("e");
593+
594+
// FIXME(eddyb) use a specialized hex-encoding loop.
595+
for byte in s.bytes() {
596+
let _ = write!(this.out, "{byte:02x}");
597+
}
598+
599+
this.push("_");
600+
};
601+
577602
match ct_ty.kind() {
578603
ty::Uint(_) | ty::Int(_) | ty::Bool | ty::Char => {
579604
ct_ty.print(self)?;
@@ -593,6 +618,9 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
593618
let _ = write!(self.out, "{bits:x}_");
594619
}
595620

621+
// Handle `str` as partial support for unsized constants
622+
ty::Str => print_str(self),
623+
596624
// FIXME(valtrees): Remove the special case for `str`
597625
// here and fully support unsized constants.
598626
ty::Ref(_, inner_ty, mutbl) => {
@@ -602,26 +630,9 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
602630
});
603631

604632
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("_");
633+
ty::Str => {
634+
assert!(mutbl.is_not(), "&mut str is not expected");
635+
print_str(self);
625636
}
626637
_ => {
627638
let pointee_ty = ct_ty
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//@ check-pass
2+
#![allow(incomplete_features)]
3+
#![feature(unsized_const_params)]
4+
5+
// Regression test for #116303
6+
7+
#[derive(PartialEq, Eq)]
8+
struct MyStr(str);
9+
impl std::marker::UnsizedConstParamTy for MyStr {}
10+
11+
fn function_with_my_str<const S: &'static MyStr>() -> &'static MyStr {
12+
S
13+
}
14+
15+
impl MyStr {
16+
const fn new(s: &'static str) -> &'static MyStr {
17+
unsafe { std::mem::transmute(s) }
18+
}
19+
}
20+
21+
pub fn main() {
22+
let f = function_with_my_str::<{ MyStr::new("hello") }>();
23+
}

0 commit comments

Comments
 (0)