1
Fork 0

Auto merge of #68118 - skinny121:eager_lit_eval, r=varkor

perf: Eagerly convert literals to consts

Previousely even literal constants were being converted to an `Unevaluted` constant for evaluation later. This seems unecessary as no more information is needed to be able to convert the literal to a mir constant.

Hopefully this will also minimise the performance impact of #67717, as far less constant evaluations are needed.
This commit is contained in:
bors 2020-01-15 00:56:53 +00:00
commit 4b172cc73f
19 changed files with 173 additions and 115 deletions

View file

@ -52,7 +52,7 @@
use crate::hir::map::DefPathHash; use crate::hir::map::DefPathHash;
use crate::ich::{Fingerprint, StableHashingContext}; use crate::ich::{Fingerprint, StableHashingContext};
use crate::mir; use crate::mir;
use crate::mir::interpret::GlobalId; use crate::mir::interpret::{GlobalId, LitToConstInput};
use crate::traits; use crate::traits;
use crate::traits::query::{ use crate::traits::query::{
CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal, CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,

View file

@ -119,7 +119,7 @@ use crate::mir;
use crate::ty::codec::TyDecoder; use crate::ty::codec::TyDecoder;
use crate::ty::layout::{self, Size}; use crate::ty::layout::{self, Size};
use crate::ty::subst::GenericArgKind; 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 byteorder::{BigEndian, LittleEndian, ReadBytesExt, WriteBytesExt};
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::{HashMapExt, Lock}; use rustc_data_structures::sync::{HashMapExt, Lock};
@ -131,6 +131,7 @@ use std::fmt;
use std::io; use std::io;
use std::num::NonZeroU32; use std::num::NonZeroU32;
use std::sync::atomic::{AtomicU32, Ordering}; use std::sync::atomic::{AtomicU32, Ordering};
use syntax::ast::LitKind;
/// Uniquely identifies one of the following: /// Uniquely identifies one of the following:
/// - A constant /// - A constant
@ -147,6 +148,24 @@ pub struct GlobalId<'tcx> {
pub promoted: Option<mir::Promoted>, 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)] #[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd, Debug)]
pub struct AllocId(pub u64); pub struct AllocId(pub u64);

View file

@ -1,6 +1,6 @@
use crate::dep_graph::{DepKind, DepNode, RecoverKey, SerializedDepNodeIndex}; use crate::dep_graph::{DepKind, DepNode, RecoverKey, SerializedDepNodeIndex};
use crate::mir; use crate::mir;
use crate::mir::interpret::GlobalId; use crate::mir::interpret::{GlobalId, LitToConstInput};
use crate::traits; use crate::traits;
use crate::traits::query::{ use crate::traits::query::{
CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal, CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,
@ -518,6 +518,13 @@ rustc_queries! {
no_force no_force
desc { "get a &core::panic::Location referring to a span" } 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 { TypeChecking {

View file

@ -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 { impl Key for CrateNum {
fn query_crate(&self) -> CrateNum { fn query_crate(&self) -> CrateNum {
*self *self

View file

@ -15,6 +15,7 @@ use crate::middle::stability::{self, DeprecationEntry};
use crate::mir; use crate::mir;
use crate::mir::interpret::GlobalId; use crate::mir::interpret::GlobalId;
use crate::mir::interpret::{ConstEvalRawResult, ConstEvalResult}; use crate::mir::interpret::{ConstEvalRawResult, ConstEvalResult};
use crate::mir::interpret::{LitToConstError, LitToConstInput};
use crate::mir::mono::CodegenUnit; use crate::mir::mono::CodegenUnit;
use crate::session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion}; use crate::session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
use crate::session::CrateDisambiguator; use crate::session::CrateDisambiguator;

View file

@ -62,5 +62,5 @@ pub fn provide(providers: &mut Providers<'_>) {
providers.destructure_const = |tcx, param_env_and_value| { providers.destructure_const = |tcx, param_env_and_value| {
let (param_env, value) = param_env_and_value.into_parts(); let (param_env, value) = param_env_and_value.into_parts();
const_eval::destructure_const(tcx, param_env, value) const_eval::destructure_const(tcx, param_env, value)
} };
} }

View file

@ -1,21 +1,15 @@
use rustc::mir::interpret::{ConstValue, Scalar}; use rustc::mir::interpret::{
use rustc::ty::{self, layout::Size, ParamEnv, Ty, TyCtxt}; truncate, Allocation, ConstValue, LitToConstError, LitToConstInput, Scalar,
};
use rustc::ty::{self, layout::Size, ParamEnv, TyCtxt};
use rustc_span::symbol::Symbol; use rustc_span::symbol::Symbol;
use syntax::ast; use syntax::ast;
#[derive(PartialEq)]
crate enum LitToConstError {
UnparseableFloat,
Reported,
}
crate fn lit_to_const<'tcx>( crate fn lit_to_const<'tcx>(
lit: &'tcx ast::LitKind,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
ty: Ty<'tcx>, lit_input: LitToConstInput<'tcx>,
neg: bool,
) -> Result<&'tcx ty::Const<'tcx>, LitToConstError> { ) -> Result<&'tcx ty::Const<'tcx>, LitToConstError> {
use syntax::ast::*; let LitToConstInput { lit, ty, neg } = lit_input;
let trunc = |n| { let trunc = |n| {
let param_ty = ParamEnv::reveal_all().and(ty); 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))) Ok(ConstValue::Scalar(Scalar::from_uint(result, width)))
}; };
use rustc::mir::interpret::*;
let lit = match *lit { let lit = match *lit {
LitKind::Str(ref s, _) => { ast::LitKind::Str(ref s, _) => {
let s = s.as_str(); let s = s.as_str();
let allocation = Allocation::from_byte_aligned_bytes(s.as_bytes()); let allocation = Allocation::from_byte_aligned_bytes(s.as_bytes());
let allocation = tcx.intern_const_alloc(allocation); let allocation = tcx.intern_const_alloc(allocation);
ConstValue::Slice { data: allocation, start: 0, end: s.len() } ConstValue::Slice { data: allocation, start: 0, end: s.len() }
} }
LitKind::ByteStr(ref data) => { ast::LitKind::ByteStr(ref data) => {
let id = tcx.allocate_bytes(data); if let ty::Ref(_, ref_ty, _) = ty.kind {
ConstValue::Scalar(Scalar::Ptr(id.into())) 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))), ast::LitKind::Byte(n) => ConstValue::Scalar(Scalar::from_uint(n, Size::from_bytes(1))),
LitKind::Int(n, _) if neg => { ast::LitKind::Int(n, _) if neg => {
let n = n as i128; let n = n as i128;
let n = n.overflowing_neg().0; let n = n.overflowing_neg().0;
trunc(n as u128)? trunc(n as u128)?
} }
LitKind::Int(n, _) => trunc(n)?, ast::LitKind::Int(n, _) => trunc(n)?,
LitKind::Float(n, _) => { ast::LitKind::Float(n, _) => {
let fty = match ty.kind { let fty = match ty.kind {
ty::Float(fty) => fty, ty::Float(fty) => fty,
_ => bug!(), _ => bug!(),
}; };
parse_float(n, fty, neg).map_err(|_| LitToConstError::UnparseableFloat)? parse_float(n, fty, neg).map_err(|_| LitToConstError::UnparseableFloat)?
} }
LitKind::Bool(b) => ConstValue::Scalar(Scalar::from_bool(b)), ast::LitKind::Bool(b) => ConstValue::Scalar(Scalar::from_bool(b)),
LitKind::Char(c) => ConstValue::Scalar(Scalar::from_char(c)), ast::LitKind::Char(c) => ConstValue::Scalar(Scalar::from_char(c)),
LitKind::Err(_) => unreachable!(), ast::LitKind::Err(_) => return Err(LitToConstError::Reported),
}; };
Ok(tcx.mk_const(ty::Const { val: ty::ConstKind::Value(lit), ty })) Ok(tcx.mk_const(ty::Const { val: ty::ConstKind::Value(lit), ty }))
} }

View file

@ -5,9 +5,9 @@
use crate::hair::util::UserAnnotatedTyHelpers; use crate::hair::util::UserAnnotatedTyHelpers;
use crate::hair::*; use crate::hair::*;
use crate::hair::constant::{lit_to_const, LitToConstError};
use rustc::infer::InferCtxt; use rustc::infer::InferCtxt;
use rustc::middle::region; use rustc::middle::region;
use rustc::mir::interpret::{LitToConstError, LitToConstInput};
use rustc::ty::layout::VariantIdx; use rustc::ty::layout::VariantIdx;
use rustc::ty::subst::Subst; use rustc::ty::subst::Subst;
use rustc::ty::subst::{GenericArg, InternalSubsts}; use rustc::ty::subst::{GenericArg, InternalSubsts};
@ -136,7 +136,7 @@ impl<'a, 'tcx> Cx<'a, 'tcx> {
) -> &'tcx ty::Const<'tcx> { ) -> &'tcx ty::Const<'tcx> {
trace!("const_eval_literal: {:#?}, {:?}, {:?}, {:?}", lit, ty, sp, neg); 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, Ok(c) => c,
Err(LitToConstError::UnparseableFloat) => { Err(LitToConstError::UnparseableFloat) => {
// FIXME(#31407) this is only necessary because float parsing is buggy // FIXME(#31407) this is only necessary because float parsing is buggy

View file

@ -16,7 +16,7 @@ use rustc_hir as hir;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_span::Span; use rustc_span::Span;
mod constant; crate mod constant;
crate mod cx; crate mod cx;
crate mod pattern; crate mod pattern;

View file

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

View file

@ -22,5 +22,6 @@ use rustc::ty::query::Providers;
pub fn provide(providers: &mut Providers<'_>) { pub fn provide(providers: &mut Providers<'_>) {
providers.check_match = hair::pattern::check_match; providers.check_match = hair::pattern::check_match;
providers.lit_to_const = hair::constant::lit_to_const;
providers.mir_built = build::mir_built; providers.mir_built = build::mir_built;
} }

View file

@ -1,3 +1,4 @@
// ignore-tidy-filelength FIXME(#67418) Split up this file.
//! Conversion from AST representation of types to the `ty.rs` representation. //! 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 //! The main routine here is `ast_ty_to_ty()`; each use is parameterized by an
//! instance of `AstConv`. //! instance of `AstConv`.
@ -37,6 +38,7 @@ use std::collections::BTreeSet;
use std::iter; use std::iter;
use std::slice; use std::slice;
use rustc::mir::interpret::LitToConstInput;
use rustc_error_codes::*; use rustc_error_codes::*;
#[derive(Debug)] #[derive(Debug)]
@ -2699,17 +2701,28 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let tcx = self.tcx(); let tcx = self.tcx();
let def_id = tcx.hir().local_def_id(ast_const.hir_id); let def_id = tcx.hir().local_def_id(ast_const.hir_id);
let mut const_ = ty::Const { let expr = &tcx.hir().body(ast_const.body).value;
val: ty::ConstKind::Unevaluated(
def_id, let lit_input = match expr.kind {
InternalSubsts::identity_for_item(tcx, def_id), hir::ExprKind::Lit(ref lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
None, hir::ExprKind::Unary(hir::UnOp::UnNeg, ref expr) => match expr.kind {
), hir::ExprKind::Lit(ref lit) => {
ty, Some(LitToConstInput { lit: &lit.node, ty, neg: true })
}
_ => None,
},
_ => None,
}; };
let expr = &tcx.hir().body(ast_const.body).value; if let Some(lit_input) = lit_input {
if let Some(def_id) = self.const_param_def_id(expr) { // 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 // Find the name and index of the const parameter by indexing the generics of the
// parent item and construct a `ParamConst`. // parent item and construct a `ParamConst`.
let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); 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 generics = tcx.generics_of(item_def_id);
let index = generics.param_def_id_to_index[&tcx.hir().local_def_id(hir_id)]; let index = generics.param_def_id_to_index[&tcx.hir().local_def_id(hir_id)];
let name = tcx.hir().name(hir_id); let name = tcx.hir().name(hir_id);
const_.val = ty::ConstKind::Param(ty::ParamConst::new(index, name)); 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(const_) };
tcx.mk_const(ty::Const { val: kind, ty })
} }
pub fn impl_trait_ty_to_ty( pub fn impl_trait_ty_to_ty(

View file

@ -1441,8 +1441,8 @@ pub struct MacroDef {
pub legacy: bool, pub legacy: bool,
} }
// Clippy uses Hash and PartialEq #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, Hash, Eq, PartialEq)]
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, Hash, PartialEq, HashStable_Generic)] #[derive(HashStable_Generic)]
pub enum StrStyle { pub enum StrStyle {
/// A regular string, like `"foo"`. /// A regular string, like `"foo"`.
Cooked, Cooked,
@ -1491,9 +1491,9 @@ impl StrLit {
} }
} }
// Clippy uses Hash and PartialEq
/// Type of the integer literal based on provided suffix. /// 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 { pub enum LitIntType {
/// e.g. `42_i32`. /// e.g. `42_i32`.
Signed(IntTy), Signed(IntTy),
@ -1504,7 +1504,8 @@ pub enum LitIntType {
} }
/// Type of the float literal based on provided suffix. /// 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 { pub enum LitFloatType {
/// A float literal with a suffix (`1f32` or `1E10f32`). /// A float literal with a suffix (`1f32` or `1E10f32`).
Suffixed(FloatTy), Suffixed(FloatTy),
@ -1515,8 +1516,7 @@ pub enum LitFloatType {
/// Literal kind. /// Literal kind.
/// ///
/// E.g., `"foo"`, `42`, `12.34`, or `bool`. /// E.g., `"foo"`, `42`, `12.34`, or `bool`.
// Clippy uses Hash and PartialEq #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq, HashStable_Generic)]
pub enum LitKind { pub enum LitKind {
/// A string literal (`"foo"`). /// A string literal (`"foo"`).
Str(Symbol, StrStyle), Str(Symbol, StrStyle),

View file

@ -11,7 +11,7 @@ pub struct Simd<T, const WIDTH: usize> {
inner: T, 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> { impl Add for Simd<u8, 16> {
type Output = Self; type Output = Self;

View file

@ -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 | | 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 | | // Use address-of-element for pointer arithmetic. This could wrap around to NULL!
LL | | let out_of_bounds_ptr = &ptr[255]; 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 | | mem::transmute(out_of_bounds_ptr)
LL | | } }; LL | | } };
| |____- | |____-

View file

@ -59,7 +59,7 @@ error[E0223]: ambiguous associated type
--> $DIR/bad-assoc-ty.rs:1:10 --> $DIR/bad-assoc-ty.rs:1:10
| |
LL | type A = [u8; 4]::AssocTy; 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 error[E0223]: ambiguous associated type
--> $DIR/bad-assoc-ty.rs:5:10 --> $DIR/bad-assoc-ty.rs:5:10

View file

@ -1,71 +1,71 @@
error: symbol-name(_ZN5impl13foo3Foo3bar17h92cf46db76791039E) error: symbol-name(_ZN5impl13foo3Foo3bar17h92cf46db76791039E)
--> $DIR/impl1.rs:14:9 --> $DIR/impl1.rs:16:9
| |
LL | #[rustc_symbol_name] LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
error: demangling(impl1::foo::Foo::bar::h92cf46db76791039) error: demangling(impl1::foo::Foo::bar::h92cf46db76791039)
--> $DIR/impl1.rs:14:9 --> $DIR/impl1.rs:16:9
| |
LL | #[rustc_symbol_name] LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
error: demangling-alt(impl1::foo::Foo::bar) error: demangling-alt(impl1::foo::Foo::bar)
--> $DIR/impl1.rs:14:9 --> $DIR/impl1.rs:16:9
| |
LL | #[rustc_symbol_name] LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
error: def-path(foo::Foo::bar) error: def-path(foo::Foo::bar)
--> $DIR/impl1.rs:21:9 --> $DIR/impl1.rs:23:9
| |
LL | #[rustc_def_path] LL | #[rustc_def_path]
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
error: symbol-name(_ZN5impl13bar33_$LT$impl$u20$impl1..foo..Foo$GT$3baz17h90c4a800b1aa0df0E) 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] LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
error: demangling(impl1::bar::<impl impl1::foo::Foo>::baz::h90c4a800b1aa0df0) error: demangling(impl1::bar::<impl impl1::foo::Foo>::baz::h90c4a800b1aa0df0)
--> $DIR/impl1.rs:32:9 --> $DIR/impl1.rs:34:9
| |
LL | #[rustc_symbol_name] LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
error: demangling-alt(impl1::bar::<impl impl1::foo::Foo>::baz) error: demangling-alt(impl1::bar::<impl impl1::foo::Foo>::baz)
--> $DIR/impl1.rs:32:9 --> $DIR/impl1.rs:34:9
| |
LL | #[rustc_symbol_name] LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
error: def-path(bar::<impl foo::Foo>::baz) error: def-path(bar::<impl foo::Foo>::baz)
--> $DIR/impl1.rs:39:9 --> $DIR/impl1.rs:41:9
| |
LL | #[rustc_def_path] 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) 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:62:13 --> $DIR/impl1.rs:64:13
| |
LL | #[rustc_symbol_name] LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
error: demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method::hf07584432cd4d8be) error: demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; 3] as impl1::main::{{closure}}::Bar>::method::SYMBOL_HASH)
--> $DIR/impl1.rs:62:13 --> $DIR/impl1.rs:64:13
| |
LL | #[rustc_symbol_name] LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
error: demangling-alt(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method) error: demangling-alt(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; 3] as impl1::main::{{closure}}::Bar>::method)
--> $DIR/impl1.rs:62:13 --> $DIR/impl1.rs:64:13
| |
LL | #[rustc_symbol_name] LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
error: def-path(<[&dyn Foo<Assoc = for<'r> extern "C" fn(&'r u8, ...)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method) error: def-path(<[&dyn Foo<Assoc = for<'r> extern "C" fn(&'r u8, ...)> + AutoTrait; 3] as main::{{closure}}#1::Bar>::method)
--> $DIR/impl1.rs:69:13 --> $DIR/impl1.rs:71:13
| |
LL | #[rustc_def_path] LL | #[rustc_def_path]
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^

View file

@ -3,6 +3,8 @@
// revisions: legacy v0 // revisions: legacy v0
//[legacy]compile-flags: -Z symbol-mangling-version=legacy //[legacy]compile-flags: -Z symbol-mangling-version=legacy
//[v0]compile-flags: -Z symbol-mangling-version=v0 //[v0]compile-flags: -Z symbol-mangling-version=v0
//[legacy]normalize-stderr-32bit: "hdb62078998ce7ea8" -> "SYMBOL_HASH"
//[legacy]normalize-stderr-64bit: "h62e540f14f879d56" -> "SYMBOL_HASH"
#![feature(optin_builtin_traits, rustc_attrs)] #![feature(optin_builtin_traits, rustc_attrs)]
#![allow(dead_code)] #![allow(dead_code)]
@ -60,15 +62,15 @@ fn main() {
// Test type mangling, by putting them in an `impl` header. // Test type mangling, by putting them in an `impl` header.
impl Bar for [&'_ (dyn Foo<Assoc = extern fn(&u8, ...)> + AutoTrait); 3] { impl Bar for [&'_ (dyn Foo<Assoc = extern fn(&u8, ...)> + AutoTrait); 3] {
#[rustc_symbol_name] #[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 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; _] as impl1::main::{{closure}}::Bar>::method //[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; _] 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 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(<[&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) //[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] #[rustc_def_path]
//[legacy]~^ 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; _] 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) {} fn method(&self) {}
} }
}; };

View file

@ -1,71 +1,71 @@
error: symbol-name(_RNvMNtCs4fqI2P2rA04_5impl13fooNtB2_3Foo3bar) error: symbol-name(_RNvMNtCs4fqI2P2rA04_5impl13fooNtB2_3Foo3bar)
--> $DIR/impl1.rs:14:9 --> $DIR/impl1.rs:16:9
| |
LL | #[rustc_symbol_name] LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
error: demangling(<impl1[317d481089b8c8fe]::foo::Foo>::bar) error: demangling(<impl1[317d481089b8c8fe]::foo::Foo>::bar)
--> $DIR/impl1.rs:14:9 --> $DIR/impl1.rs:16:9
| |
LL | #[rustc_symbol_name] LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
error: demangling-alt(<impl1::foo::Foo>::bar) error: demangling-alt(<impl1::foo::Foo>::bar)
--> $DIR/impl1.rs:14:9 --> $DIR/impl1.rs:16:9
| |
LL | #[rustc_symbol_name] LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
error: def-path(foo::Foo::bar) error: def-path(foo::Foo::bar)
--> $DIR/impl1.rs:21:9 --> $DIR/impl1.rs:23:9
| |
LL | #[rustc_def_path] LL | #[rustc_def_path]
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
error: symbol-name(_RNvMNtCs4fqI2P2rA04_5impl13barNtNtB4_3foo3Foo3baz) error: symbol-name(_RNvMNtCs4fqI2P2rA04_5impl13barNtNtB4_3foo3Foo3baz)
--> $DIR/impl1.rs:32:9 --> $DIR/impl1.rs:34:9
| |
LL | #[rustc_symbol_name] LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
error: demangling(<impl1[317d481089b8c8fe]::foo::Foo>::baz) error: demangling(<impl1[317d481089b8c8fe]::foo::Foo>::baz)
--> $DIR/impl1.rs:32:9 --> $DIR/impl1.rs:34:9
| |
LL | #[rustc_symbol_name] LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
error: demangling-alt(<impl1::foo::Foo>::baz) error: demangling-alt(<impl1::foo::Foo>::baz)
--> $DIR/impl1.rs:32:9 --> $DIR/impl1.rs:34:9
| |
LL | #[rustc_symbol_name] LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
error: def-path(bar::<impl foo::Foo>::baz) error: def-path(bar::<impl foo::Foo>::baz)
--> $DIR/impl1.rs:39:9 --> $DIR/impl1.rs:41:9
| |
LL | #[rustc_def_path] LL | #[rustc_def_path]
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
error: symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG_KCRL0_hvEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method) 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] 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) 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] 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) 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] LL | #[rustc_symbol_name]
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
error: def-path(<[&dyn Foo<Assoc = for<'r> extern "C" fn(&'r u8, ...)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method) error: def-path(<[&dyn Foo<Assoc = for<'r> extern "C" fn(&'r u8, ...)> + AutoTrait; 3] as main::{{closure}}#1::Bar>::method)
--> $DIR/impl1.rs:69:13 --> $DIR/impl1.rs:71:13
| |
LL | #[rustc_def_path] LL | #[rustc_def_path]
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^