From 5038faeccc0123bd05b934c9d57231a950f7eddb Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 16 Jul 2021 14:12:18 +0300 Subject: [PATCH 1/6] Pretty-print uninhabited const values more explicitly. --- compiler/rustc_middle/src/ty/print/pretty.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 21d5baced7687..988ddfd4abbac 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1217,8 +1217,15 @@ pub trait PrettyPrinter<'tcx>: } p!(")"); } - ty::Adt(def, substs) if def.variants.is_empty() => { - p!(print_value_path(def.did, substs)); + ty::Adt(def, _) if def.variants.is_empty() => { + self = self.typed_value( + |mut this| { + write!(this, "unreachable()")?; + Ok(this) + }, + |this| this.print_type(ty), + ": ", + )?; } ty::Adt(def, substs) => { let variant_id = From 3180312687cb1b3f3aa496dc6ecbe5067c9f330d Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 16 Jul 2021 15:34:29 +0300 Subject: [PATCH 2/6] rustc_symbol_mangling: never cache placeholders in print_const. --- compiler/rustc_symbol_mangling/src/v0.rs | 58 +++++++++++++++--------- 1 file changed, 36 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 14442806fc0b7..0c87600c8769e 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -545,39 +545,53 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { } fn print_const(mut self, ct: &'tcx ty::Const<'tcx>) -> Result { + // We only mangle a typed value if the const can be evaluated. + let ct = ct.eval(self.tcx, ty::ParamEnv::reveal_all()); + match ct.val { + ty::ConstKind::Value(_) => {} + + // Placeholders (should be demangled as `_`). + // NOTE(eddyb) despite `Unevaluated` having a `DefId` (and therefore + // a path), even for it we still need to encode a placeholder, as + // the path could refer back to e.g. an `impl` using the constant. + ty::ConstKind::Unevaluated(_) + | ty::ConstKind::Param(_) + | ty::ConstKind::Infer(_) + | ty::ConstKind::Bound(..) + | ty::ConstKind::Placeholder(_) + | ty::ConstKind::Error(_) => { + // Never cached (single-character). + self.push("p"); + return Ok(self); + } + } + if let Some(&i) = self.compress.as_ref().and_then(|c| c.consts.get(&ct)) { return self.print_backref(i); } let start = self.out.len(); - let mut neg = false; - let val = match ct.ty.kind() { - ty::Uint(_) | ty::Bool | ty::Char => { - ct.try_eval_bits(self.tcx, ty::ParamEnv::reveal_all(), ct.ty) - } - ty::Int(ity) => { - ct.try_eval_bits(self.tcx, ty::ParamEnv::reveal_all(), ct.ty).and_then(|b| { - let val = Integer::from_int_ty(&self.tcx, *ity).size().sign_extend(b) as i128; + match ct.ty.kind() { + ty::Uint(_) | ty::Int(_) | ty::Bool | ty::Char => { + self = ct.ty.print(self)?; + + let mut bits = ct.eval_bits(self.tcx, ty::ParamEnv::reveal_all(), ct.ty); + + // Negative integer values are mangled using `n` as a "sign prefix". + if let ty::Int(ity) = ct.ty.kind() { + let val = + Integer::from_int_ty(&self.tcx, *ity).size().sign_extend(bits) as i128; if val < 0 { - neg = true; + self.push("n"); } - Some(val.unsigned_abs()) - }) + bits = val.unsigned_abs(); + } + + let _ = write!(self.out, "{:x}_", bits); } _ => { bug!("symbol_names: unsupported constant of type `{}` ({:?})", ct.ty, ct); } - }; - - if let Some(bits) = val { - // We only print the type if the const can be evaluated. - self = ct.ty.print(self)?; - let _ = write!(self.out, "{}{:x}_", if neg { "n" } else { "" }, bits); - } else { - // NOTE(eddyb) despite having the path, we need to - // encode a placeholder, as the path could refer - // back to e.g. an `impl` using the constant. - self.push("p"); } // Only cache consts that do not refer to an enclosing From 7d2c3347e73bce974d6c5f3f4cef3b394418cce0 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 16 Jul 2021 15:40:33 +0300 Subject: [PATCH 3/6] Fix typo (variant_id should've been variant_idx). --- compiler/rustc_middle/src/ty/print/pretty.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 988ddfd4abbac..05b5000522f46 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1228,9 +1228,9 @@ pub trait PrettyPrinter<'tcx>: )?; } ty::Adt(def, substs) => { - let variant_id = - contents.variant.expect("destructed const of adt without variant id"); - let variant_def = &def.variants[variant_id]; + let variant_idx = + contents.variant.expect("destructed const of adt without variant idx"); + let variant_def = &def.variants[variant_idx]; p!(print_value_path(variant_def.def_id, substs)); match variant_def.ctor_kind { From 2e194536fdf0f9c539a3f59242d82786ca18a7e9 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 16 Jul 2021 18:21:41 +0300 Subject: [PATCH 4/6] rustc_symbol_mangling: support structural constants and &str in v0. --- compiler/rustc_symbol_mangling/src/lib.rs | 1 + compiler/rustc_symbol_mangling/src/v0.rs | 100 ++++++++++++++++++++++ 2 files changed, 101 insertions(+) diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index ba59ff96f6554..6b8da71aa3a75 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -91,6 +91,7 @@ #![feature(never_type)] #![feature(nll)] #![feature(in_band_lifetimes)] +#![feature(iter_zip)] #![recursion_limit = "256"] #[macro_use] diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 0c87600c8769e..499542ccc5738 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -1,8 +1,10 @@ use rustc_data_structures::base_n; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; +use rustc_hir::def::CtorKind; use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData}; +use rustc_middle::mir::interpret::ConstValue; use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::print::{Print, Printer}; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst}; @@ -11,6 +13,7 @@ use rustc_target::abi::Integer; use rustc_target::spec::abi::Abi; use std::fmt::Write; +use std::iter; use std::ops::Range; pub(super) fn mangle( @@ -589,6 +592,103 @@ impl Printer<'tcx> for SymbolMangler<'tcx> { let _ = write!(self.out, "{:x}_", bits); } + + // HACK(eddyb) because `ty::Const` only supports sized values (for now), + // we can't use `deref_const` + supporting `str`, we have to specially + // handle `&str` and include both `&` ("R") and `str` ("e") prefixes. + ty::Ref(_, ty, hir::Mutability::Not) if *ty == self.tcx.types.str_ => { + self.push("R"); + match ct.val { + ty::ConstKind::Value(ConstValue::Slice { data, start, end }) => { + // NOTE(eddyb) the following comment was kept from `ty::print::pretty`: + // The `inspect` here is okay since we checked the bounds, and there are no + // relocations (we have an active `str` reference here). We don't use this + // result to affect interpreter execution. + let slice = + data.inspect_with_uninit_and_ptr_outside_interpreter(start..end); + let s = std::str::from_utf8(slice).expect("non utf8 str from miri"); + + self.push("e"); + // FIXME(eddyb) use a specialized hex-encoding loop. + for byte in s.bytes() { + let _ = write!(self.out, "{:02x}", byte); + } + self.push("_"); + } + + _ => { + bug!("symbol_names: unsupported `&str` constant: {:?}", ct); + } + } + } + + ty::Ref(_, _, mutbl) => { + self.push(match mutbl { + hir::Mutability::Not => "R", + hir::Mutability::Mut => "Q", + }); + self = self.tcx.deref_const(ty::ParamEnv::reveal_all().and(ct)).print(self)?; + } + + ty::Array(..) | ty::Tuple(..) | ty::Adt(..) => { + let contents = self.tcx.destructure_const(ty::ParamEnv::reveal_all().and(ct)); + let fields = contents.fields.iter().copied(); + + let print_field_list = |mut this: Self, prefix| { + this.push(prefix); + for field in fields.clone() { + this = field.print(this)?; + } + this.push("E"); + Ok(this) + }; + + match *ct.ty.kind() { + ty::Array(..) => { + self = print_field_list(self, "A")?; + } + ty::Tuple(..) => { + self = print_field_list(self, "T")?; + } + ty::Adt(def, substs) => { + let variant_idx = + contents.variant.expect("destructed const of adt without variant idx"); + let variant_def = &def.variants[variant_idx]; + + self.push("V"); + self = self.print_def_path(variant_def.def_id, substs)?; + + match variant_def.ctor_kind { + CtorKind::Const => { + self.push("u"); + } + CtorKind::Fn => { + self = print_field_list(self, "T")?; + } + CtorKind::Fictive => { + for (field_def, field) in iter::zip(&variant_def.fields, fields) { + // HACK(eddyb) this mimics `path_append`, + // instead of simply using `field_def.ident`, + // just to be able to handle disambiguators. + let disambiguated_field = + self.tcx.def_key(field_def.did).disambiguated_data; + let field_name = + disambiguated_field.data.get_opt_name().map(|s| s.as_str()); + self.push_disambiguator( + disambiguated_field.disambiguator as u64, + ); + self.push_ident(&field_name.as_ref().map_or("", |s| &s[..])); + + self = field.print(self)?; + } + self.push("E"); + } + } + } + _ => unreachable!(), + } + } + _ => { bug!("symbol_names: unsupported constant of type `{}` ({:?})", ct.ty, ct); } From 212ab828d55eb0099d7eddabcd6912671d647bb5 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 16 Jul 2021 18:22:14 +0300 Subject: [PATCH 5/6] tests: support -Zsymbol-mangling-version=v0 being the default. --- src/test/debuginfo/function-call.rs | 2 +- src/test/debuginfo/function-names.rs | 2 +- ...stderr => issue-47429-short-backtraces.legacy.run.stderr} | 2 +- src/test/ui/panics/issue-47429-short-backtraces.rs | 5 +++++ .../ui/panics/issue-47429-short-backtraces.v0.run.stderr | 5 +++++ 5 files changed, 13 insertions(+), 3 deletions(-) rename src/test/ui/panics/{issue-47429-short-backtraces.run.stderr => issue-47429-short-backtraces.legacy.run.stderr} (91%) create mode 100644 src/test/ui/panics/issue-47429-short-backtraces.v0.run.stderr diff --git a/src/test/debuginfo/function-call.rs b/src/test/debuginfo/function-call.rs index a5d5942b53953..75334558b589d 100644 --- a/src/test/debuginfo/function-call.rs +++ b/src/test/debuginfo/function-call.rs @@ -1,5 +1,5 @@ // This test does not passed with gdb < 8.0. See #53497. -// min-gdb-version: 8.0 +// min-gdb-version: 10.1 // compile-flags:-g diff --git a/src/test/debuginfo/function-names.rs b/src/test/debuginfo/function-names.rs index 20a49f0bd26eb..94982fd79fb2b 100644 --- a/src/test/debuginfo/function-names.rs +++ b/src/test/debuginfo/function-names.rs @@ -1,5 +1,5 @@ // Function names are formatted differently in old versions of GDB -// min-gdb-version: 9.2 +// min-gdb-version: 10.1 // compile-flags:-g diff --git a/src/test/ui/panics/issue-47429-short-backtraces.run.stderr b/src/test/ui/panics/issue-47429-short-backtraces.legacy.run.stderr similarity index 91% rename from src/test/ui/panics/issue-47429-short-backtraces.run.stderr rename to src/test/ui/panics/issue-47429-short-backtraces.legacy.run.stderr index 3287963890706..fcdc070a4c39e 100644 --- a/src/test/ui/panics/issue-47429-short-backtraces.run.stderr +++ b/src/test/ui/panics/issue-47429-short-backtraces.legacy.run.stderr @@ -1,4 +1,4 @@ -thread 'main' panicked at 'explicit panic', $DIR/issue-47429-short-backtraces.rs:16:5 +thread 'main' panicked at 'explicit panic', $DIR/issue-47429-short-backtraces.rs:21:5 stack backtrace: 0: std::panicking::begin_panic 1: issue_47429_short_backtraces::main diff --git a/src/test/ui/panics/issue-47429-short-backtraces.rs b/src/test/ui/panics/issue-47429-short-backtraces.rs index 015ab8fdd80df..35ecfc0b27158 100644 --- a/src/test/ui/panics/issue-47429-short-backtraces.rs +++ b/src/test/ui/panics/issue-47429-short-backtraces.rs @@ -12,6 +12,11 @@ // ignore-emscripten no panic or subprocess support // ignore-sgx no subprocess support +// NOTE(eddyb) output differs between symbol mangling schemes +// revisions: legacy v0 +// [legacy] compile-flags: -Zsymbol-mangling-version=legacy +// [v0] compile-flags: -Zsymbol-mangling-version=v0 + fn main() { panic!() } diff --git a/src/test/ui/panics/issue-47429-short-backtraces.v0.run.stderr b/src/test/ui/panics/issue-47429-short-backtraces.v0.run.stderr new file mode 100644 index 0000000000000..1cbf11739bfc6 --- /dev/null +++ b/src/test/ui/panics/issue-47429-short-backtraces.v0.run.stderr @@ -0,0 +1,5 @@ +thread 'main' panicked at 'explicit panic', $DIR/issue-47429-short-backtraces.rs:21:5 +stack backtrace: + 0: std::panicking::begin_panic::<&str> + 1: issue_47429_short_backtraces::main +note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. From 083d4a3d8c62283dc19ece4eb4af89e49466b7f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Fri, 16 Jul 2021 00:00:00 +0000 Subject: [PATCH 6/6] Use Rust symbol mangling by default --- compiler/rustc_session/src/config.rs | 2 +- src/test/codegen/{vec-shrink-panic.rs => vec-shrink-panik.rs} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/test/codegen/{vec-shrink-panic.rs => vec-shrink-panik.rs} (100%) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index b444f66258a8e..6811c70de8e57 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -755,7 +755,7 @@ impl DebuggingOptions { } pub fn get_symbol_mangling_version(&self) -> SymbolManglingVersion { - self.symbol_mangling_version.unwrap_or(SymbolManglingVersion::Legacy) + self.symbol_mangling_version.unwrap_or(SymbolManglingVersion::V0) } } diff --git a/src/test/codegen/vec-shrink-panic.rs b/src/test/codegen/vec-shrink-panik.rs similarity index 100% rename from src/test/codegen/vec-shrink-panic.rs rename to src/test/codegen/vec-shrink-panik.rs