Skip to content

Commit

Permalink
handle unsized consts with type str in v0 symbol mangling
Browse files Browse the repository at this point in the history
  • Loading branch information
Jaic1 committed Sep 20, 2024
1 parent 506f22b commit 02f52b0
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 32 deletions.
59 changes: 27 additions & 32 deletions compiler/rustc_symbol_mangling/src/v0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(_) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//@ check-pass
//@ compiler-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") }>();
}

0 comments on commit 02f52b0

Please sign in to comment.