Skip to content

Commit df5a899

Browse files
committed
Auto merge of rust-lang#125487 - michaelwoerister:skippable_v0, r=<try>
[do not merge] Proof of concept implementation of forward compatible v0 symbols (MCP 737) This PR changes v0 symbol names to enable graceful degradation for demanglers that don't support newer language features yet (as described in [MCP 737](rust-lang/compiler-team#737)). The corresponding changes in rustc-demangle are at https://github.com/michaelwoerister/rustc-demangle/tree/skip_unknown. This proof-of-concept implementation is meant to help evaluating if MCP 737 is viable. r? `@ghost`
2 parents 4649877 + 17c7fc4 commit df5a899

14 files changed

+132
-39
lines changed

Cargo.lock

+11-6
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ dependencies = [
293293
"libc",
294294
"miniz_oxide",
295295
"object 0.32.2",
296-
"rustc-demangle",
296+
"rustc-demangle 0.1.24",
297297
]
298298

299299
[[package]]
@@ -840,7 +840,7 @@ dependencies = [
840840
"md-5",
841841
"miniz_oxide",
842842
"regex",
843-
"rustc-demangle",
843+
"rustc-demangle 0.1.25",
844844
]
845845

846846
[[package]]
@@ -3246,7 +3246,7 @@ name = "rust-demangler"
32463246
version = "0.0.1"
32473247
dependencies = [
32483248
"regex",
3249-
"rustc-demangle",
3249+
"rustc-demangle 0.1.24",
32503250
]
32513251

32523252
[[package]]
@@ -3280,6 +3280,11 @@ dependencies = [
32803280
"rustc-std-workspace-core",
32813281
]
32823282

3283+
[[package]]
3284+
name = "rustc-demangle"
3285+
version = "0.1.25"
3286+
source = "git+https://github.com/michaelwoerister/rustc-demangle.git?branch=skip_unknown#7e674e483a7c61803edc8d59f2641a4ad52a1a30"
3287+
32833288
[[package]]
32843289
name = "rustc-hash"
32853290
version = "1.1.0"
@@ -3551,7 +3556,7 @@ dependencies = [
35513556
"libc",
35523557
"measureme",
35533558
"object 0.32.2",
3554-
"rustc-demangle",
3559+
"rustc-demangle 0.1.25",
35553560
"rustc_ast",
35563561
"rustc_attr",
35573562
"rustc_codegen_ssa",
@@ -4553,7 +4558,7 @@ name = "rustc_symbol_mangling"
45534558
version = "0.0.0"
45544559
dependencies = [
45554560
"punycode",
4556-
"rustc-demangle",
4561+
"rustc-demangle 0.1.25",
45574562
"rustc_data_structures",
45584563
"rustc_errors",
45594564
"rustc_hir",
@@ -5147,7 +5152,7 @@ dependencies = [
51475152
"r-efi-alloc",
51485153
"rand",
51495154
"rand_xorshift",
5150-
"rustc-demangle",
5155+
"rustc-demangle 0.1.24",
51515156
"std_detect",
51525157
"unwind",
51535158
"wasi",

compiler/rustc_codegen_llvm/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ itertools = "0.12"
1313
libc = "0.2"
1414
measureme = "11"
1515
object = { version = "0.32.0", default-features = false, features = ["std", "read"] }
16-
rustc-demangle = "0.1.21"
16+
rustc-demangle = { git = "https://github.com/michaelwoerister/rustc-demangle.git", branch = "skip_unknown" }
1717
rustc_ast = { path = "../rustc_ast" }
1818
rustc_attr = { path = "../rustc_attr" }
1919
rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }

compiler/rustc_session/src/config.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1178,7 +1178,7 @@ impl Options {
11781178
}
11791179

11801180
pub fn get_symbol_mangling_version(&self) -> SymbolManglingVersion {
1181-
self.cg.symbol_mangling_version.unwrap_or(SymbolManglingVersion::Legacy)
1181+
self.cg.symbol_mangling_version.unwrap_or(SymbolManglingVersion::V0)
11821182
}
11831183
}
11841184

compiler/rustc_symbol_mangling/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ edition = "2021"
66
[dependencies]
77
# tidy-alphabetical-start
88
punycode = "0.4.0"
9-
rustc-demangle = "0.1.21"
9+
rustc-demangle = { git = "https://github.com/michaelwoerister/rustc-demangle.git", branch = "skip_unknown" }
1010
rustc_data_structures = { path = "../rustc_data_structures" }
1111
rustc_errors = { path = "../rustc_errors" }
1212
rustc_hir = { path = "../rustc_hir" }

compiler/rustc_symbol_mangling/src/v0.rs

+89-2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ pub(super) fn mangle<'tcx>(
3939
consts: FxHashMap::default(),
4040
binders: vec![],
4141
out: String::from(prefix),
42+
wrapper_level: GrammarFeatureLevel::BASE_LINE,
4243
};
4344

4445
// Append `::{shim:...#0}` to shims that can coexist with a non-shim instance.
@@ -79,11 +80,13 @@ pub(super) fn mangle_typeid_for_trait_ref<'tcx>(
7980
consts: FxHashMap::default(),
8081
binders: vec![],
8182
out: String::new(),
83+
wrapper_level: GrammarFeatureLevel::BASE_LINE,
8284
};
8385
cx.print_def_path(trait_ref.def_id(), &[]).unwrap();
8486
std::mem::take(&mut cx.out)
8587
}
8688

89+
#[derive(Clone)]
8790
struct BinderLevel {
8891
/// The range of distances from the root of what's
8992
/// being printed, to the lifetimes in a binder.
@@ -98,6 +101,15 @@ struct BinderLevel {
98101
lifetime_depths: Range<u32>,
99102
}
100103

104+
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
105+
struct GrammarFeatureLevel(usize);
106+
107+
impl GrammarFeatureLevel {
108+
const BASE_LINE: GrammarFeatureLevel = GrammarFeatureLevel(0);
109+
const COMPLEX_CONST_GENERICS: GrammarFeatureLevel = GrammarFeatureLevel(1);
110+
}
111+
112+
#[derive(Clone)]
101113
struct SymbolMangler<'tcx> {
102114
tcx: TyCtxt<'tcx>,
103115
binders: Vec<BinderLevel>,
@@ -109,6 +121,8 @@ struct SymbolMangler<'tcx> {
109121
paths: FxHashMap<(DefId, &'tcx [GenericArg<'tcx>]), usize>,
110122
types: FxHashMap<Ty<'tcx>, usize>,
111123
consts: FxHashMap<ty::Const<'tcx>, usize>,
124+
125+
wrapper_level: GrammarFeatureLevel,
112126
}
113127

114128
impl<'tcx> SymbolMangler<'tcx> {
@@ -192,6 +206,75 @@ impl<'tcx> SymbolMangler<'tcx> {
192206

193207
Ok(())
194208
}
209+
210+
fn required_feature_level_for_const(&self, ct: ty::Const<'tcx>) -> GrammarFeatureLevel {
211+
let ct = ct.normalize(self.tcx, ty::ParamEnv::reveal_all());
212+
match ct.kind() {
213+
ty::ConstKind::Value(_) => {}
214+
215+
ty::ConstKind::Unevaluated(_)
216+
| ty::ConstKind::Expr(_)
217+
| ty::ConstKind::Param(_)
218+
| ty::ConstKind::Infer(_)
219+
| ty::ConstKind::Bound(..)
220+
| ty::ConstKind::Placeholder(_)
221+
| ty::ConstKind::Error(_) => {
222+
return GrammarFeatureLevel::BASE_LINE;
223+
}
224+
}
225+
226+
let ty = ct.ty();
227+
228+
match ty.kind() {
229+
ty::Uint(_) | ty::Int(_) | ty::Bool | ty::Char => GrammarFeatureLevel::BASE_LINE,
230+
_ => GrammarFeatureLevel::COMPLEX_CONST_GENERICS,
231+
}
232+
}
233+
234+
fn wrapped(
235+
&mut self,
236+
level: GrammarFeatureLevel,
237+
f: &mut dyn FnMut(&mut Self) -> Result<(), PrintError>,
238+
) -> Result<(), PrintError> {
239+
if self.wrapper_level >= level {
240+
return f(self);
241+
}
242+
243+
self.out.push('C');
244+
let backup = self.clone();
245+
246+
let mut digit_count = 2;
247+
248+
for _iteration in 0..10 {
249+
self.wrapper_level = level;
250+
let digit_range = self.out.len()..self.out.len() + digit_count;
251+
for _ in 0..digit_count {
252+
self.out.push('#');
253+
}
254+
255+
self.out.push('_');
256+
257+
let start = self.out.len();
258+
259+
f(self)?;
260+
261+
let end = self.out.len();
262+
let fragment_length = format!("{}", end - start);
263+
264+
// FIXME: Add check if any back references to interior were made. If
265+
// not, we can just shift everything without remangling.
266+
if fragment_length.len() == digit_count {
267+
self.out.replace_range(digit_range, &fragment_length);
268+
self.wrapper_level = backup.wrapper_level;
269+
return Ok(());
270+
}
271+
272+
*self = backup.clone();
273+
digit_count = fragment_length.len();
274+
}
275+
276+
Err(PrintError::default())
277+
}
195278
}
196279

197280
impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
@@ -813,8 +896,12 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
813896
ty.print(self)?;
814897
}
815898
GenericArgKind::Const(c) => {
816-
self.push("K");
817-
c.print(self)?;
899+
let required_feature_level = self.required_feature_level_for_const(c);
900+
901+
self.wrapped(required_feature_level, &mut |this| {
902+
this.push("K");
903+
c.print(this)
904+
})?;
818905
}
819906
}
820907
}

src/tools/coverage-dump/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ leb128 = "0.2.5"
1111
md5 = { package = "md-5" , version = "0.10.5" }
1212
miniz_oxide = "0.7.1"
1313
regex = "1.8.4"
14-
rustc-demangle = "0.1.23"
14+
rustc-demangle = { git = "https://github.com/michaelwoerister/rustc-demangle.git", branch = "skip_unknown" }

tests/assembly/closure-inherit-target-feature.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//@ ignore-sgx Tests incompatible with LVI mitigations
33
//@ assembly-output: emit-asm
44
// make sure the feature is not enabled at compile-time
5-
//@ compile-flags: -C opt-level=3 -C target-feature=-sse4.1 -C llvm-args=-x86-asm-syntax=intel
5+
//@ compile-flags: -C opt-level=3 -C target-feature=-sse4.1 -C llvm-args=-x86-asm-syntax=intel -Csymbol-mangling-version=legacy -Zunstable-options
66

77
#![feature(target_feature_11)]
88
#![crate_type = "rlib"]

tests/codegen/precondition-checks.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@
1313

1414
use std::ptr::NonNull;
1515

16-
// CHECK-LABEL: ; core::ptr::non_null::NonNull<T>::new_unchecked
16+
// CHECK-LABEL: ; <core::ptr::non_null::NonNull<u8>>::new_unchecked
1717
// CHECK-NOT: call
1818
// CHECK: }
1919

2020
// CHECK-LABEL: @nonnull_new
2121
#[no_mangle]
2222
pub unsafe fn nonnull_new(ptr: *mut u8) -> NonNull<u8> {
23-
// CHECK: ; call core::ptr::non_null::NonNull<T>::new_unchecked
23+
// CHECK: ; call <core::ptr::non_null::NonNull<u8>>::new_unchecked
2424
unsafe {
2525
NonNull::new_unchecked(ptr)
2626
}

tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-drop-in-place.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Verifies that type metadata identifiers for drop functions are emitted correctly.
22
//
33
//@ needs-sanitizer-cfi
4-
//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static
4+
//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static -Csymbol-mangling-version=legacy -Zunstable-options
55

66
#![crate_type="lib"]
77

tests/crashes/118603.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//@ known-bug: #118603
2-
//@ compile-flags: -Copt-level=0
2+
//@ compile-flags: -Copt-level=0 -Csymbol-mangling-version=legacy
33
// ignore-tidy-linelength
4+
//@ ignore-test
45

56
#![feature(generic_const_exprs)]
67
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
thread 'main' panicked at $DIR/short-ice-remove-middle-frames-2.rs:56:5:
22
debug!!!
33
stack backtrace:
4-
0: std::panicking::begin_panic
4+
0: std::panicking::begin_panic::<&str>
55
1: short_ice_remove_middle_frames_2::eight
6-
2: short_ice_remove_middle_frames_2::seven::{{closure}}
6+
2: short_ice_remove_middle_frames_2::seven::{closure#0}
77
[... omitted 3 frames ...]
88
3: short_ice_remove_middle_frames_2::fifth
9-
4: short_ice_remove_middle_frames_2::fourth::{{closure}}
9+
4: short_ice_remove_middle_frames_2::fourth::{closure#0}
1010
[... omitted 4 frames ...]
1111
5: short_ice_remove_middle_frames_2::first
1212
6: short_ice_remove_middle_frames_2::main
13-
7: core::ops::function::FnOnce::call_once
13+
7: <fn() as core::ops::function::FnOnce<()>>::call_once
1414
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
thread 'main' panicked at $DIR/short-ice-remove-middle-frames.rs:52:5:
22
debug!!!
33
stack backtrace:
4-
0: std::panicking::begin_panic
4+
0: std::panicking::begin_panic::<&str>
55
1: short_ice_remove_middle_frames::seven
66
2: short_ice_remove_middle_frames::sixth
7-
3: short_ice_remove_middle_frames::fifth::{{closure}}
7+
3: short_ice_remove_middle_frames::fifth::{closure#0}
88
[... omitted 4 frames ...]
99
4: short_ice_remove_middle_frames::second
10-
5: short_ice_remove_middle_frames::first::{{closure}}
10+
5: short_ice_remove_middle_frames::first::{closure#0}
1111
6: short_ice_remove_middle_frames::first
1212
7: short_ice_remove_middle_frames::main
13-
8: core::ops::function::FnOnce::call_once
13+
8: <fn() as core::ops::function::FnOnce<()>>::call_once
1414
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

tests/ui/symbol-names/const-generics-str-demangling.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: symbol-name(_RMCsCRATE_HASH_1cINtB<REF>_3StrKRe616263_E)
1+
error: symbol-name(_RMCsCRATE_HASH_1cINtB<REF>_3StrC10_KRe616263_E)
22
--> $DIR/const-generics-str-demangling.rs:9:1
33
|
44
LL | #[rustc_symbol_name]
@@ -16,7 +16,7 @@ error: demangling-alt(<c::Str<"abc">>)
1616
LL | #[rustc_symbol_name]
1717
| ^^^^^^^^^^^^^^^^^^^^
1818

19-
error: symbol-name(_RMs_CsCRATE_HASH_1cINtB<REF>_3StrKRe27_E)
19+
error: symbol-name(_RMs_CsCRATE_HASH_1cINtB<REF>_3StrC6_KRe27_E)
2020
--> $DIR/const-generics-str-demangling.rs:15:1
2121
|
2222
LL | #[rustc_symbol_name]
@@ -34,7 +34,7 @@ error: demangling-alt(<c::Str<"'">>)
3434
LL | #[rustc_symbol_name]
3535
| ^^^^^^^^^^^^^^^^^^^^
3636

37-
error: symbol-name(_RMs0_CsCRATE_HASH_1cINtB<REF>_3StrKRe090a_E)
37+
error: symbol-name(_RMs0_CsCRATE_HASH_1cINtB<REF>_3StrC8_KRe090a_E)
3838
--> $DIR/const-generics-str-demangling.rs:21:1
3939
|
4040
LL | #[rustc_symbol_name]
@@ -52,7 +52,7 @@ error: demangling-alt(<c::Str<"\t\n">>)
5252
LL | #[rustc_symbol_name]
5353
| ^^^^^^^^^^^^^^^^^^^^
5454

55-
error: symbol-name(_RMs1_CsCRATE_HASH_1cINtB<REF>_3StrKRee28882c3bc_E)
55+
error: symbol-name(_RMs1_CsCRATE_HASH_1cINtB<REF>_3StrC14_KRee28882c3bc_E)
5656
--> $DIR/const-generics-str-demangling.rs:27:1
5757
|
5858
LL | #[rustc_symbol_name]
@@ -70,7 +70,7 @@ error: demangling-alt(<c::Str<"∂ü">>)
7070
LL | #[rustc_symbol_name]
7171
| ^^^^^^^^^^^^^^^^^^^^
7272

73-
error: symbol-name(_RMs2_CsCRATE_HASH_1cINtB<REF>_3StrKRee183a1e18390e183ade1839be18394e1839ae18390e183935fe18392e18394e1839be183a0e18398e18394e1839ae183985fe183a1e18390e18393e18398e1839ae18398_E)
73+
error: symbol-name(_RMs2_CsCRATE_HASH_1cINtB<REF>_3StrC140_KRee183a1e18390e183ade1839be18394e1839ae18390e183935fe18392e18394e1839be183a0e18398e18394e1839ae183985fe183a1e18390e18393e18398e1839ae18398_E)
7474
--> $DIR/const-generics-str-demangling.rs:33:1
7575
|
7676
LL | #[rustc_symbol_name]
@@ -88,7 +88,7 @@ error: demangling-alt(<c::Str<"საჭმელად_გემრიელი
8888
LL | #[rustc_symbol_name]
8989
| ^^^^^^^^^^^^^^^^^^^^
9090

91-
error: symbol-name(_RMs3_CsCRATE_HASH_1cINtB<REF>_3StrKRef09f908af09fa688f09fa686f09f90ae20c2a720f09f90b6f09f9192e29895f09f94a520c2a720f09fa7a1f09f929bf09f929af09f9299f09f929c_E)
91+
error: symbol-name(_RMs3_CsCRATE_HASH_1cINtB<REF>_3StrC122_KRef09f908af09fa688f09fa686f09f90ae20c2a720f09f90b6f09f9192e29895f09f94a520c2a720f09fa7a1f09f929bf09f929af09f9299f09f929c_E)
9292
--> $DIR/const-generics-str-demangling.rs:39:1
9393
|
9494
LL | #[rustc_symbol_name]

0 commit comments

Comments
 (0)