Skip to content

perf: Eagerly convert literals to consts #68118

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 15, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
@@ -52,7 +52,7 @@
use crate::hir::map::DefPathHash;
use crate::ich::{Fingerprint, StableHashingContext};
use crate::mir;
use crate::mir::interpret::GlobalId;
use crate::mir::interpret::{GlobalId, LitToConstInput};
use crate::traits;
use crate::traits::query::{
CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,
21 changes: 20 additions & 1 deletion src/librustc/mir/interpret/mod.rs
Original file line number Diff line number Diff line change
@@ -119,7 +119,7 @@ use crate::mir;
use crate::ty::codec::TyDecoder;
use crate::ty::layout::{self, Size};
use crate::ty::subst::GenericArgKind;
use crate::ty::{self, Instance, TyCtxt};
use crate::ty::{self, Instance, Ty, TyCtxt};
use byteorder::{BigEndian, LittleEndian, ReadBytesExt, WriteBytesExt};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::{HashMapExt, Lock};
@@ -131,6 +131,7 @@ use std::fmt;
use std::io;
use std::num::NonZeroU32;
use std::sync::atomic::{AtomicU32, Ordering};
use syntax::ast::LitKind;

/// Uniquely identifies one of the following:
/// - A constant
@@ -147,6 +148,24 @@ pub struct GlobalId<'tcx> {
pub promoted: Option<mir::Promoted>,
}

/// Input argument for `tcx.lit_to_const`.
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, HashStable)]
pub struct LitToConstInput<'tcx> {
/// The absolute value of the resultant constant.
pub lit: &'tcx LitKind,
/// The type of the constant.
pub ty: Ty<'tcx>,
/// If the constant is negative.
pub neg: bool,
}

/// Error type for `tcx.lit_to_const`.
#[derive(Copy, Clone, Debug, Eq, PartialEq, HashStable)]
pub enum LitToConstError {
UnparseableFloat,
Reported,
}

#[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd, Debug)]
pub struct AllocId(pub u64);

9 changes: 8 additions & 1 deletion src/librustc/query/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::dep_graph::{DepKind, DepNode, RecoverKey, SerializedDepNodeIndex};
use crate::mir;
use crate::mir::interpret::GlobalId;
use crate::mir::interpret::{GlobalId, LitToConstInput};
use crate::traits;
use crate::traits::query::{
CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,
@@ -518,6 +518,13 @@ rustc_queries! {
no_force
desc { "get a &core::panic::Location referring to a span" }
}

query lit_to_const(
key: LitToConstInput<'tcx>
) -> Result<&'tcx ty::Const<'tcx>, LitToConstError> {
no_force
desc { "converting literal to const" }
}
}

TypeChecking {
10 changes: 10 additions & 0 deletions src/librustc/ty/query/keys.rs
Original file line number Diff line number Diff line change
@@ -52,6 +52,16 @@ impl<'tcx> Key for mir::interpret::GlobalId<'tcx> {
}
}

impl<'tcx> Key for mir::interpret::LitToConstInput<'tcx> {
fn query_crate(&self) -> CrateNum {
LOCAL_CRATE
}

fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
DUMMY_SP
}
}

impl Key for CrateNum {
fn query_crate(&self) -> CrateNum {
*self
1 change: 1 addition & 0 deletions src/librustc/ty/query/mod.rs
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@ use crate::middle::stability::{self, DeprecationEntry};
use crate::mir;
use crate::mir::interpret::GlobalId;
use crate::mir::interpret::{ConstEvalRawResult, ConstEvalResult};
use crate::mir::interpret::{LitToConstError, LitToConstInput};
use crate::mir::mono::CodegenUnit;
use crate::session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
use crate::session::CrateDisambiguator;
2 changes: 1 addition & 1 deletion src/librustc_mir/lib.rs
Original file line number Diff line number Diff line change
@@ -62,5 +62,5 @@ pub fn provide(providers: &mut Providers<'_>) {
providers.destructure_const = |tcx, param_env_and_value| {
let (param_env, value) = param_env_and_value.into_parts();
const_eval::destructure_const(tcx, param_env, value)
}
};
}
57 changes: 33 additions & 24 deletions src/librustc_mir_build/hair/constant.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
use rustc::mir::interpret::{ConstValue, Scalar};
use rustc::ty::{self, layout::Size, ParamEnv, Ty, TyCtxt};
use rustc::mir::interpret::{
truncate, Allocation, ConstValue, LitToConstError, LitToConstInput, Scalar,
};
use rustc::ty::{self, layout::Size, ParamEnv, TyCtxt};
use rustc_span::symbol::Symbol;
use syntax::ast;

#[derive(PartialEq)]
crate enum LitToConstError {
UnparseableFloat,
Reported,
}

crate fn lit_to_const<'tcx>(
lit: &'tcx ast::LitKind,
tcx: TyCtxt<'tcx>,
ty: Ty<'tcx>,
neg: bool,
lit_input: LitToConstInput<'tcx>,
) -> Result<&'tcx ty::Const<'tcx>, LitToConstError> {
use syntax::ast::*;
let LitToConstInput { lit, ty, neg } = lit_input;

let trunc = |n| {
let param_ty = ParamEnv::reveal_all().and(ty);
@@ -26,35 +20,50 @@ crate fn lit_to_const<'tcx>(
Ok(ConstValue::Scalar(Scalar::from_uint(result, width)))
};

use rustc::mir::interpret::*;
let lit = match *lit {
LitKind::Str(ref s, _) => {
ast::LitKind::Str(ref s, _) => {
let s = s.as_str();
let allocation = Allocation::from_byte_aligned_bytes(s.as_bytes());
let allocation = tcx.intern_const_alloc(allocation);
ConstValue::Slice { data: allocation, start: 0, end: s.len() }
}
LitKind::ByteStr(ref data) => {
let id = tcx.allocate_bytes(data);
ConstValue::Scalar(Scalar::Ptr(id.into()))
ast::LitKind::ByteStr(ref data) => {
if let ty::Ref(_, ref_ty, _) = ty.kind {
match ref_ty.kind {
ty::Slice(_) => {
let allocation = Allocation::from_byte_aligned_bytes(data as &Vec<u8>);
let allocation = tcx.intern_const_alloc(allocation);
ConstValue::Slice { data: allocation, start: 0, end: data.len() }
}
ty::Array(_, _) => {
let id = tcx.allocate_bytes(data);
ConstValue::Scalar(Scalar::Ptr(id.into()))
}
_ => {
bug!("bytestring should have type of either &[u8] or &[u8; _], not {}", ty)
}
}
} else {
bug!("bytestring should have type of either &[u8] or &[u8; _], not {}", ty)
}
}
LitKind::Byte(n) => ConstValue::Scalar(Scalar::from_uint(n, Size::from_bytes(1))),
LitKind::Int(n, _) if neg => {
ast::LitKind::Byte(n) => ConstValue::Scalar(Scalar::from_uint(n, Size::from_bytes(1))),
ast::LitKind::Int(n, _) if neg => {
let n = n as i128;
let n = n.overflowing_neg().0;
trunc(n as u128)?
}
LitKind::Int(n, _) => trunc(n)?,
LitKind::Float(n, _) => {
ast::LitKind::Int(n, _) => trunc(n)?,
ast::LitKind::Float(n, _) => {
let fty = match ty.kind {
ty::Float(fty) => fty,
_ => bug!(),
};
parse_float(n, fty, neg).map_err(|_| LitToConstError::UnparseableFloat)?
}
LitKind::Bool(b) => ConstValue::Scalar(Scalar::from_bool(b)),
LitKind::Char(c) => ConstValue::Scalar(Scalar::from_char(c)),
LitKind::Err(_) => unreachable!(),
ast::LitKind::Bool(b) => ConstValue::Scalar(Scalar::from_bool(b)),
ast::LitKind::Char(c) => ConstValue::Scalar(Scalar::from_char(c)),
ast::LitKind::Err(_) => return Err(LitToConstError::Reported),
};
Ok(tcx.mk_const(ty::Const { val: ty::ConstKind::Value(lit), ty }))
}
4 changes: 2 additions & 2 deletions src/librustc_mir_build/hair/cx/mod.rs
Original file line number Diff line number Diff line change
@@ -5,9 +5,9 @@
use crate::hair::util::UserAnnotatedTyHelpers;
use crate::hair::*;

use crate::hair::constant::{lit_to_const, LitToConstError};
use rustc::infer::InferCtxt;
use rustc::middle::region;
use rustc::mir::interpret::{LitToConstError, LitToConstInput};
use rustc::ty::layout::VariantIdx;
use rustc::ty::subst::Subst;
use rustc::ty::subst::{GenericArg, InternalSubsts};
@@ -136,7 +136,7 @@ impl<'a, 'tcx> Cx<'a, 'tcx> {
) -> &'tcx ty::Const<'tcx> {
trace!("const_eval_literal: {:#?}, {:?}, {:?}, {:?}", lit, ty, sp, neg);

match lit_to_const(lit, self.tcx, ty, neg) {
match self.tcx.at(sp).lit_to_const(LitToConstInput { lit, ty, neg }) {
Ok(c) => c,
Err(LitToConstError::UnparseableFloat) => {
// FIXME(#31407) this is only necessary because float parsing is buggy
2 changes: 1 addition & 1 deletion src/librustc_mir_build/hair/mod.rs
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_span::Span;

mod constant;
crate mod constant;
crate mod cx;

crate mod pattern;
49 changes: 22 additions & 27 deletions src/librustc_mir_build/hair/pattern/mod.rs
Original file line number Diff line number Diff line change
@@ -6,10 +6,10 @@ mod const_to_pat;

pub(crate) use self::check_match::check_match;

use crate::hair::constant::*;
use crate::hair::util::UserAnnotatedTyHelpers;

use rustc::mir::interpret::{get_slice_bytes, sign_extend, ConstValue, ErrorHandled};
use rustc::mir::interpret::{LitToConstError, LitToConstInput};
use rustc::mir::UserTypeProjection;
use rustc::mir::{BorrowKind, Field, Mutability};
use rustc::ty::layout::VariantIdx;
@@ -822,35 +822,30 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
/// which would overflow if we tried to evaluate `128_i8` and then negate
/// afterwards.
fn lower_lit(&mut self, expr: &'tcx hir::Expr<'tcx>) -> PatKind<'tcx> {
match expr.kind {
hir::ExprKind::Lit(ref lit) => {
let ty = self.tables.expr_ty(expr);
match lit_to_const(&lit.node, self.tcx, ty, false) {
Ok(val) => *self.const_to_pat(val, expr.hir_id, lit.span).kind,
Err(LitToConstError::UnparseableFloat) => {
self.errors.push(PatternError::FloatBug);
PatKind::Wild
}
Err(LitToConstError::Reported) => PatKind::Wild,
if let hir::ExprKind::Path(ref qpath) = expr.kind {
*self.lower_path(qpath, expr.hir_id, expr.span).kind
} else {
let (lit, neg) = match expr.kind {
hir::ExprKind::Lit(ref lit) => (lit, false),
hir::ExprKind::Unary(hir::UnOp::UnNeg, ref expr) => {
let lit = match expr.kind {
hir::ExprKind::Lit(ref lit) => lit,
_ => span_bug!(expr.span, "not a literal: {:?}", expr),
};
(lit, true)
}
}
hir::ExprKind::Path(ref qpath) => *self.lower_path(qpath, expr.hir_id, expr.span).kind,
hir::ExprKind::Unary(hir::UnOp::UnNeg, ref expr) => {
let ty = self.tables.expr_ty(expr);
let lit = match expr.kind {
hir::ExprKind::Lit(ref lit) => lit,
_ => span_bug!(expr.span, "not a literal: {:?}", expr),
};
match lit_to_const(&lit.node, self.tcx, ty, true) {
Ok(val) => *self.const_to_pat(val, expr.hir_id, lit.span).kind,
Err(LitToConstError::UnparseableFloat) => {
self.errors.push(PatternError::FloatBug);
PatKind::Wild
}
Err(LitToConstError::Reported) => PatKind::Wild,
_ => span_bug!(expr.span, "not a literal: {:?}", expr),
};

let lit_input = LitToConstInput { lit: &lit.node, ty: self.tables.expr_ty(expr), neg };
match self.tcx.at(expr.span).lit_to_const(lit_input) {
Ok(val) => *self.const_to_pat(val, expr.hir_id, lit.span).kind,
Err(LitToConstError::UnparseableFloat) => {
self.errors.push(PatternError::FloatBug);
PatKind::Wild
}
Err(LitToConstError::Reported) => PatKind::Wild,
}
_ => span_bug!(expr.span, "not a literal: {:?}", expr),
}
}
}
1 change: 1 addition & 0 deletions src/librustc_mir_build/lib.rs
Original file line number Diff line number Diff line change
@@ -22,5 +22,6 @@ use rustc::ty::query::Providers;

pub fn provide(providers: &mut Providers<'_>) {
providers.check_match = hair::pattern::check_match;
providers.lit_to_const = hair::constant::lit_to_const;
providers.mir_built = build::mir_built;
}
40 changes: 27 additions & 13 deletions src/librustc_typeck/astconv.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// ignore-tidy-filelength FIXME(#67418) Split up this file.
//! Conversion from AST representation of types to the `ty.rs` representation.
//! The main routine here is `ast_ty_to_ty()`; each use is parameterized by an
//! instance of `AstConv`.
@@ -37,6 +38,7 @@ use std::collections::BTreeSet;
use std::iter;
use std::slice;

use rustc::mir::interpret::LitToConstInput;
use rustc_error_codes::*;

#[derive(Debug)]
@@ -2699,17 +2701,28 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let tcx = self.tcx();
let def_id = tcx.hir().local_def_id(ast_const.hir_id);

let mut const_ = ty::Const {
val: ty::ConstKind::Unevaluated(
def_id,
InternalSubsts::identity_for_item(tcx, def_id),
None,
),
ty,
let expr = &tcx.hir().body(ast_const.body).value;

let lit_input = match expr.kind {
hir::ExprKind::Lit(ref lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
hir::ExprKind::Unary(hir::UnOp::UnNeg, ref expr) => match expr.kind {
hir::ExprKind::Lit(ref lit) => {
Some(LitToConstInput { lit: &lit.node, ty, neg: true })
}
_ => None,
},
_ => None,
};

let expr = &tcx.hir().body(ast_const.body).value;
if let Some(def_id) = self.const_param_def_id(expr) {
if let Some(lit_input) = lit_input {
// If an error occurred, ignore that it's a literal and leave reporting the error up to
// mir.
if let Ok(c) = tcx.at(expr.span).lit_to_const(lit_input) {
return c;
}
}

let kind = if let Some(def_id) = self.const_param_def_id(expr) {
// Find the name and index of the const parameter by indexing the generics of the
// parent item and construct a `ParamConst`.
let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
@@ -2718,10 +2731,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let generics = tcx.generics_of(item_def_id);
let index = generics.param_def_id_to_index[&tcx.hir().local_def_id(hir_id)];
let name = tcx.hir().name(hir_id);
const_.val = ty::ConstKind::Param(ty::ParamConst::new(index, name));
}

tcx.mk_const(const_)
ty::ConstKind::Param(ty::ParamConst::new(index, name))
} else {
ty::ConstKind::Unevaluated(def_id, InternalSubsts::identity_for_item(tcx, def_id), None)
};
tcx.mk_const(ty::Const { val: kind, ty })
}

pub fn impl_trait_ty_to_ty(
14 changes: 7 additions & 7 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
@@ -1441,8 +1441,8 @@ pub struct MacroDef {
pub legacy: bool,
}

// Clippy uses Hash and PartialEq
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, Hash, PartialEq, HashStable_Generic)]
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, Hash, Eq, PartialEq)]
#[derive(HashStable_Generic)]
pub enum StrStyle {
/// A regular string, like `"foo"`.
Cooked,
@@ -1491,9 +1491,9 @@ impl StrLit {
}
}

// Clippy uses Hash and PartialEq
/// Type of the integer literal based on provided suffix.
#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq, HashStable_Generic)]
#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, Eq, PartialEq)]
#[derive(HashStable_Generic)]
pub enum LitIntType {
/// e.g. `42_i32`.
Signed(IntTy),
@@ -1504,7 +1504,8 @@ pub enum LitIntType {
}

/// Type of the float literal based on provided suffix.
#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq, HashStable_Generic)]
#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, Eq, PartialEq)]
#[derive(HashStable_Generic)]
pub enum LitFloatType {
/// A float literal with a suffix (`1f32` or `1E10f32`).
Suffixed(FloatTy),
@@ -1515,8 +1516,7 @@ pub enum LitFloatType {
/// Literal kind.
///
/// E.g., `"foo"`, `42`, `12.34`, or `bool`.
// Clippy uses Hash and PartialEq
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq, HashStable_Generic)]
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
pub enum LitKind {
/// A string literal (`"foo"`).
Str(Symbol, StrStyle),
2 changes: 1 addition & 1 deletion src/test/rustdoc/const-generics/add-impl.rs
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ pub struct Simd<T, const WIDTH: usize> {
inner: T,
}

// @has foo/struct.Simd.html '//div[@id="implementations-list"]/h3/code' 'impl Add<Simd<u8, 16>> for Simd<u8, 16>'
// @has foo/struct.Simd.html '//div[@id="implementations-list"]/h3/code' 'impl Add<Simd<u8, 16usize>> for Simd<u8, 16>'
impl Add for Simd<u8, 16> {
type Output = Self;

2 changes: 1 addition & 1 deletion src/test/ui/consts/const-eval/ub-nonnull.stderr
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@ LL | / const OUT_OF_BOUNDS_PTR: NonNull<u8> = { unsafe {
LL | | let ptr: &[u8; 256] = mem::transmute(&0u8); // &0 gets promoted so it does not dangle
LL | | // Use address-of-element for pointer arithmetic. This could wrap around to NULL!
LL | | let out_of_bounds_ptr = &ptr[255];
| | ^^^^^^^^^ Memory access failed: pointer must be in-bounds at offset 256, but is outside bounds of allocation 9 which has size 1
| | ^^^^^^^^^ Memory access failed: pointer must be in-bounds at offset 256, but is outside bounds of allocation 8 which has size 1
LL | | mem::transmute(out_of_bounds_ptr)
LL | | } };
| |____-
2 changes: 1 addition & 1 deletion src/test/ui/did_you_mean/bad-assoc-ty.stderr
Original file line number Diff line number Diff line change
@@ -59,7 +59,7 @@ error[E0223]: ambiguous associated type
--> $DIR/bad-assoc-ty.rs:1:10
|
LL | type A = [u8; 4]::AssocTy;
| ^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<[u8; _] as Trait>::AssocTy`
| ^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<[u8; 4] as Trait>::AssocTy`

error[E0223]: ambiguous associated type
--> $DIR/bad-assoc-ty.rs:5:10
32 changes: 16 additions & 16 deletions src/test/ui/symbol-names/impl1.legacy.stderr
Original file line number Diff line number Diff line change
@@ -1,71 +1,71 @@
error: symbol-name(_ZN5impl13foo3Foo3bar17h92cf46db76791039E)
--> $DIR/impl1.rs:14:9
--> $DIR/impl1.rs:16:9
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^

error: demangling(impl1::foo::Foo::bar::h92cf46db76791039)
--> $DIR/impl1.rs:14:9
--> $DIR/impl1.rs:16:9
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^

error: demangling-alt(impl1::foo::Foo::bar)
--> $DIR/impl1.rs:14:9
--> $DIR/impl1.rs:16:9
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^

error: def-path(foo::Foo::bar)
--> $DIR/impl1.rs:21:9
--> $DIR/impl1.rs:23:9
|
LL | #[rustc_def_path]
| ^^^^^^^^^^^^^^^^^

error: symbol-name(_ZN5impl13bar33_$LT$impl$u20$impl1..foo..Foo$GT$3baz17h90c4a800b1aa0df0E)
--> $DIR/impl1.rs:32:9
--> $DIR/impl1.rs:34:9
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^

error: demangling(impl1::bar::<impl impl1::foo::Foo>::baz::h90c4a800b1aa0df0)
--> $DIR/impl1.rs:32:9
--> $DIR/impl1.rs:34:9
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^

error: demangling-alt(impl1::bar::<impl impl1::foo::Foo>::baz)
--> $DIR/impl1.rs:32:9
--> $DIR/impl1.rs:34:9
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^

error: def-path(bar::<impl foo::Foo>::baz)
--> $DIR/impl1.rs:39:9
--> $DIR/impl1.rs:41:9
|
LL | #[rustc_def_path]
| ^^^^^^^^^^^^^^^^^

error: symbol-name(_ZN209_$LT$$u5b$$RF$dyn$u20$impl1..Foo$u2b$Assoc$u20$$u3d$$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RF$u8$C$$u20$...$RP$$u2b$impl1..AutoTrait$u3b$$u20$_$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method17hf07584432cd4d8beE)
--> $DIR/impl1.rs:62:13
error: symbol-name(_ZN209_$LT$$u5b$$RF$dyn$u20$impl1..Foo$u2b$Assoc$u20$$u3d$$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RF$u8$C$$u20$...$RP$$u2b$impl1..AutoTrait$u3b$$u20$3$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method17SYMBOL_HASHE)
--> $DIR/impl1.rs:64:13
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^

error: demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method::hf07584432cd4d8be)
--> $DIR/impl1.rs:62:13
error: demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; 3] as impl1::main::{{closure}}::Bar>::method::SYMBOL_HASH)
--> $DIR/impl1.rs:64:13
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^

error: demangling-alt(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method)
--> $DIR/impl1.rs:62:13
error: demangling-alt(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; 3] as impl1::main::{{closure}}::Bar>::method)
--> $DIR/impl1.rs:64:13
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^

error: def-path(<[&dyn Foo<Assoc = for<'r> extern "C" fn(&'r u8, ...)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method)
--> $DIR/impl1.rs:69:13
error: def-path(<[&dyn Foo<Assoc = for<'r> extern "C" fn(&'r u8, ...)> + AutoTrait; 3] as main::{{closure}}#1::Bar>::method)
--> $DIR/impl1.rs:71:13
|
LL | #[rustc_def_path]
| ^^^^^^^^^^^^^^^^^
12 changes: 7 additions & 5 deletions src/test/ui/symbol-names/impl1.rs
Original file line number Diff line number Diff line change
@@ -3,6 +3,8 @@
// revisions: legacy v0
//[legacy]compile-flags: -Z symbol-mangling-version=legacy
//[v0]compile-flags: -Z symbol-mangling-version=v0
//[legacy]normalize-stderr-32bit: "hdb62078998ce7ea8" -> "SYMBOL_HASH"
//[legacy]normalize-stderr-64bit: "h62e540f14f879d56" -> "SYMBOL_HASH"
Comment on lines +6 to +7
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we care about hashes, you could probably use regex to always normalize away h[0-9a-f]{16}.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(this scared me when I first saw it, but these are for the target, not the host, and symbol names don't have to be constant between targets)


#![feature(optin_builtin_traits, rustc_attrs)]
#![allow(dead_code)]
@@ -60,15 +62,15 @@ fn main() {
// Test type mangling, by putting them in an `impl` header.
impl Bar for [&'_ (dyn Foo<Assoc = extern fn(&u8, ...)> + AutoTrait); 3] {
#[rustc_symbol_name]
//[legacy]~^ ERROR symbol-name(_ZN209_$LT$$u5b$$RF$dyn$u20$impl1..Foo$u2b$Assoc$u20$$u3d$$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RF$u8$C$$u20$...$RP$$u2b$impl1..AutoTrait$u3b$$u20$_$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method
//[legacy]~| ERROR demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method
//[legacy]~| ERROR demangling-alt(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method)
//[legacy]~^ ERROR symbol-name(_ZN209_$LT$$u5b$$RF$dyn$u20$impl1..Foo$u2b$Assoc$u20$$u3d$$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RF$u8$C$$u20$...$RP$$u2b$impl1..AutoTrait$u3b$$u20$3$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method
//[legacy]~| ERROR demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; 3] as impl1::main::{{closure}}::Bar>::method
//[legacy]~| ERROR demangling-alt(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; 3] as impl1::main::{{closure}}::Bar>::method)
//[v0]~^^^^ ERROR symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG_KCRL0_hvEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method)
//[v0]~| ERROR demangling(<[&dyn impl1[317d481089b8c8fe]::Foo<Assoc = for<'a> extern "C" fn(&'a u8, ...)> + impl1[317d481089b8c8fe]::AutoTrait; 3: usize] as impl1[317d481089b8c8fe]::main::{closure#1}::Bar>::method)
//[v0]~| ERROR demangling-alt(<[&dyn impl1::Foo<Assoc = for<'a> extern "C" fn(&'a u8, ...)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method)
#[rustc_def_path]
//[legacy]~^ ERROR def-path(<[&dyn Foo<Assoc = for<'r> extern "C" fn(&'r u8, ...)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method)
//[v0]~^^ ERROR def-path(<[&dyn Foo<Assoc = for<'r> extern "C" fn(&'r u8, ...)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method)
//[legacy]~^ ERROR def-path(<[&dyn Foo<Assoc = for<'r> extern "C" fn(&'r u8, ...)> + AutoTrait; 3] as main::{{closure}}#1::Bar>::method)
//[v0]~^^ ERROR def-path(<[&dyn Foo<Assoc = for<'r> extern "C" fn(&'r u8, ...)> + AutoTrait; 3] as main::{{closure}}#1::Bar>::method)
fn method(&self) {}
}
};
26 changes: 13 additions & 13 deletions src/test/ui/symbol-names/impl1.v0.stderr
Original file line number Diff line number Diff line change
@@ -1,71 +1,71 @@
error: symbol-name(_RNvMNtCs4fqI2P2rA04_5impl13fooNtB2_3Foo3bar)
--> $DIR/impl1.rs:14:9
--> $DIR/impl1.rs:16:9
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^

error: demangling(<impl1[317d481089b8c8fe]::foo::Foo>::bar)
--> $DIR/impl1.rs:14:9
--> $DIR/impl1.rs:16:9
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^

error: demangling-alt(<impl1::foo::Foo>::bar)
--> $DIR/impl1.rs:14:9
--> $DIR/impl1.rs:16:9
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^

error: def-path(foo::Foo::bar)
--> $DIR/impl1.rs:21:9
--> $DIR/impl1.rs:23:9
|
LL | #[rustc_def_path]
| ^^^^^^^^^^^^^^^^^

error: symbol-name(_RNvMNtCs4fqI2P2rA04_5impl13barNtNtB4_3foo3Foo3baz)
--> $DIR/impl1.rs:32:9
--> $DIR/impl1.rs:34:9
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^

error: demangling(<impl1[317d481089b8c8fe]::foo::Foo>::baz)
--> $DIR/impl1.rs:32:9
--> $DIR/impl1.rs:34:9
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^

error: demangling-alt(<impl1::foo::Foo>::baz)
--> $DIR/impl1.rs:32:9
--> $DIR/impl1.rs:34:9
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^

error: def-path(bar::<impl foo::Foo>::baz)
--> $DIR/impl1.rs:39:9
--> $DIR/impl1.rs:41:9
|
LL | #[rustc_def_path]
| ^^^^^^^^^^^^^^^^^

error: symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG_KCRL0_hvEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method)
--> $DIR/impl1.rs:62:13
--> $DIR/impl1.rs:64:13
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^

error: demangling(<[&dyn impl1[317d481089b8c8fe]::Foo<Assoc = for<'a> extern "C" fn(&'a u8, ...)> + impl1[317d481089b8c8fe]::AutoTrait; 3: usize] as impl1[317d481089b8c8fe]::main::{closure#1}::Bar>::method)
--> $DIR/impl1.rs:62:13
--> $DIR/impl1.rs:64:13
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^

error: demangling-alt(<[&dyn impl1::Foo<Assoc = for<'a> extern "C" fn(&'a u8, ...)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method)
--> $DIR/impl1.rs:62:13
--> $DIR/impl1.rs:64:13
|
LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^

error: def-path(<[&dyn Foo<Assoc = for<'r> extern "C" fn(&'r u8, ...)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method)
--> $DIR/impl1.rs:69:13
error: def-path(<[&dyn Foo<Assoc = for<'r> extern "C" fn(&'r u8, ...)> + AutoTrait; 3] as main::{{closure}}#1::Bar>::method)
--> $DIR/impl1.rs:71:13
|
LL | #[rustc_def_path]
| ^^^^^^^^^^^^^^^^^