Rollup merge of #130344 - Jaic1:fix-116306, r=BoxyUwU

Handle unsized consts with type `str`  in v0 symbol mangling

This PR fixes #116303 by handling consts with type `str` in v0 symbol mangling as partial support for unsized consts.

This PR is related to `#![feature(adt_const_params)]` (#95174) and `#![feature(unsized_const_params)]` (#128028).

r? ``@BoxyUwU``
This commit is contained in:
Matthias Krüger 2024-09-23 06:45:33 +02:00 committed by GitHub
commit 23393de793
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 51 additions and 32 deletions

View File

@ -607,45 +607,40 @@ fn print_const(&mut self, ct: ty::Const<'tcx>) -> Result<(), PrintError> {
let _ = write!(self.out, "{bits:x}_"); 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` // FIXME(valtrees): Remove the special case for `str`
// here and fully support unsized constants. // here and fully support unsized constants.
ty::Ref(_, inner_ty, mutbl) => { ty::Ref(_, _, mutbl) => {
self.push(match mutbl { self.push(match mutbl {
hir::Mutability::Not => "R", hir::Mutability::Not => "R",
hir::Mutability::Mut => "Q", hir::Mutability::Mut => "Q",
}); });
match inner_ty.kind() { let pointee_ty =
ty::Str if mutbl.is_not() => { ct_ty.builtin_deref(true).expect("tried to dereference on non-ptr type");
let slice = let dereferenced_const = ty::Const::new_value(self.tcx, valtree, pointee_ty);
valtree.try_to_raw_bytes(self.tcx(), ct_ty).unwrap_or_else(|| { dereferenced_const.print(self)?;
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)?;
}
}
} }
ty::Array(..) | ty::Tuple(..) | ty::Adt(..) | ty::Slice(_) => { ty::Array(..) | ty::Tuple(..) | ty::Adt(..) | ty::Slice(_) => {

View File

@ -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") }>();
}