From a6c4025fac3c3a60581af72998230d46aa6f5ade Mon Sep 17 00:00:00 2001 From: Ben Lewis Date: Sat, 11 Jan 2020 15:22:36 +1300 Subject: [PATCH 1/4] perf: eagerly convert literals to consts, this avoids creating loads on unevaluated consts which requires a lot of unnecessary work to evaluate them further down the line. --- src/librustc/dep_graph/dep_node.rs | 2 +- src/librustc/mir/interpret/mod.rs | 21 ++++++- src/librustc/query/mod.rs | 9 ++- src/librustc/ty/query/keys.rs | 10 ++++ src/librustc/ty/query/mod.rs | 1 + src/librustc_mir/lib.rs | 2 +- src/librustc_mir_build/hair/constant.rs | 57 +++++++++++-------- src/librustc_mir_build/hair/cx/mod.rs | 4 +- src/librustc_mir_build/hair/mod.rs | 2 +- src/librustc_mir_build/hair/pattern/mod.rs | 52 ++++++++--------- src/librustc_mir_build/lib.rs | 1 + src/librustc_typeck/astconv.rs | 40 ++++++++----- src/libsyntax/ast.rs | 41 ++++++++++--- .../ui/consts/const-eval/ub-nonnull.stderr | 2 +- src/test/ui/did_you_mean/bad-assoc-ty.stderr | 2 +- src/test/ui/symbol-names/impl1.legacy.stderr | 8 +-- src/test/ui/symbol-names/impl1.rs | 10 ++-- src/test/ui/symbol-names/impl1.v0.stderr | 2 +- 18 files changed, 175 insertions(+), 91 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 858627a1e8962..9df8e28254cf5 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -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, diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index 99113d6ef1836..21cc54a6e6b2d 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -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, } +/// 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); diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 50ef115da2c42..f4c262fbac1d4 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -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 { diff --git a/src/librustc/ty/query/keys.rs b/src/librustc/ty/query/keys.rs index d64f27d9cc26c..cbf335ad607ef 100644 --- a/src/librustc/ty/query/keys.rs +++ b/src/librustc/ty/query/keys.rs @@ -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 diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 1d41871bb33a9..0f09a08b199f1 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -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; diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 1ff529181f705..1c25b269b18fd 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -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) - } + }; } diff --git a/src/librustc_mir_build/hair/constant.rs b/src/librustc_mir_build/hair/constant.rs index a4bedfa6490e2..266f4738c50a6 100644 --- a/src/librustc_mir_build/hair/constant.rs +++ b/src/librustc_mir_build/hair/constant.rs @@ -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); + 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 })) } diff --git a/src/librustc_mir_build/hair/cx/mod.rs b/src/librustc_mir_build/hair/cx/mod.rs index 5fc9a1ecad555..497c6610550f3 100644 --- a/src/librustc_mir_build/hair/cx/mod.rs +++ b/src/librustc_mir_build/hair/cx/mod.rs @@ -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 diff --git a/src/librustc_mir_build/hair/mod.rs b/src/librustc_mir_build/hair/mod.rs index 3257f282dc1cb..0f2c76152edae 100644 --- a/src/librustc_mir_build/hair/mod.rs +++ b/src/librustc_mir_build/hair/mod.rs @@ -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; diff --git a/src/librustc_mir_build/hair/pattern/mod.rs b/src/librustc_mir_build/hair/pattern/mod.rs index 9e00c4ea53a0f..8645abe5c1acc 100644 --- a/src/librustc_mir_build/hair/pattern/mod.rs +++ b/src/librustc_mir_build/hair/pattern/mod.rs @@ -6,10 +6,11 @@ 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::{ + get_slice_bytes, sign_extend, ConstValue, ErrorHandled, LitToConstError, LitToConstInput, +}; use rustc::mir::UserTypeProjection; use rustc::mir::{BorrowKind, Field, Mutability}; use rustc::ty::layout::VariantIdx; @@ -822,35 +823,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), } } } diff --git a/src/librustc_mir_build/lib.rs b/src/librustc_mir_build/lib.rs index 96032a732abd6..5a17f36e1da25 100644 --- a/src/librustc_mir_build/lib.rs +++ b/src/librustc_mir_build/lib.rs @@ -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; } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index dae394b8f4bd4..920ffaa4c3a0b 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -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( diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 33acba8eba010..ace12a7ffd208 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1441,8 +1441,17 @@ 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, + HashStable_Generic +)] pub enum StrStyle { /// A regular string, like `"foo"`. Cooked, @@ -1491,9 +1500,18 @@ 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, + HashStable_Generic +)] pub enum LitIntType { /// e.g. `42_i32`. Signed(IntTy), @@ -1504,7 +1522,17 @@ 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, + HashStable_Generic +)] pub enum LitFloatType { /// A float literal with a suffix (`1f32` or `1E10f32`). Suffixed(FloatTy), @@ -1515,8 +1543,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), diff --git a/src/test/ui/consts/const-eval/ub-nonnull.stderr b/src/test/ui/consts/const-eval/ub-nonnull.stderr index ea9fffa883ea5..c2446d1404019 100644 --- a/src/test/ui/consts/const-eval/ub-nonnull.stderr +++ b/src/test/ui/consts/const-eval/ub-nonnull.stderr @@ -13,7 +13,7 @@ LL | / const OUT_OF_BOUNDS_PTR: NonNull = { 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 | | } }; | |____- diff --git a/src/test/ui/did_you_mean/bad-assoc-ty.stderr b/src/test/ui/did_you_mean/bad-assoc-ty.stderr index 0ae64edcc0546..7d3c99bda6b6a 100644 --- a/src/test/ui/did_you_mean/bad-assoc-ty.stderr +++ b/src/test/ui/did_you_mean/bad-assoc-ty.stderr @@ -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 diff --git a/src/test/ui/symbol-names/impl1.legacy.stderr b/src/test/ui/symbol-names/impl1.legacy.stderr index affb5537b1856..8e498e4b39477 100644 --- a/src/test/ui/symbol-names/impl1.legacy.stderr +++ b/src/test/ui/symbol-names/impl1.legacy.stderr @@ -46,25 +46,25 @@ error: def-path(bar::::baz) 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$6method17h62e540f14f879d56E) --> $DIR/impl1.rs:62:13 | 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::h62e540f14f879d56) --> $DIR/impl1.rs:62:13 | 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 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: def-path(<[&dyn Foo extern "C" fn(&'r u8, ...)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method) +error: def-path(<[&dyn Foo extern "C" fn(&'r u8, ...)> + AutoTrait; 3] as main::{{closure}}#1::Bar>::method) --> $DIR/impl1.rs:69:13 | LL | #[rustc_def_path] diff --git a/src/test/ui/symbol-names/impl1.rs b/src/test/ui/symbol-names/impl1.rs index c1aaec5169d8b..b054c1373e66c 100644 --- a/src/test/ui/symbol-names/impl1.rs +++ b/src/test/ui/symbol-names/impl1.rs @@ -60,15 +60,15 @@ fn main() { // Test type mangling, by putting them in an `impl` header. impl Bar for [&'_ (dyn Foo + 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 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 extern "C" fn(&'a u8, ...)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method) #[rustc_def_path] - //[legacy]~^ ERROR def-path(<[&dyn Foo extern "C" fn(&'r u8, ...)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method) - //[v0]~^^ ERROR def-path(<[&dyn Foo extern "C" fn(&'r u8, ...)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method) + //[legacy]~^ ERROR def-path(<[&dyn Foo extern "C" fn(&'r u8, ...)> + AutoTrait; 3] as main::{{closure}}#1::Bar>::method) + //[v0]~^^ ERROR def-path(<[&dyn Foo extern "C" fn(&'r u8, ...)> + AutoTrait; 3] as main::{{closure}}#1::Bar>::method) fn method(&self) {} } }; diff --git a/src/test/ui/symbol-names/impl1.v0.stderr b/src/test/ui/symbol-names/impl1.v0.stderr index a931937d1a813..111c360b36080 100644 --- a/src/test/ui/symbol-names/impl1.v0.stderr +++ b/src/test/ui/symbol-names/impl1.v0.stderr @@ -64,7 +64,7 @@ error: demangling-alt(<[&dyn impl1::Foo extern "C" fn(&'a u8, .. LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: def-path(<[&dyn Foo extern "C" fn(&'r u8, ...)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method) +error: def-path(<[&dyn Foo extern "C" fn(&'r u8, ...)> + AutoTrait; 3] as main::{{closure}}#1::Bar>::method) --> $DIR/impl1.rs:69:13 | LL | #[rustc_def_path] From 02fffc1556e01c64d84d07d0a3ab059a9c7505f8 Mon Sep 17 00:00:00 2001 From: Ben Lewis Date: Sat, 11 Jan 2020 20:57:38 +1300 Subject: [PATCH 2/4] Code review changes and fix rustdoc test. --- src/librustc/mir/interpret/mod.rs | 10 +++--- src/librustc_mir_build/hair/pattern/mod.rs | 5 ++- src/librustc_typeck/astconv.rs | 4 +-- src/libsyntax/ast.rs | 39 ++++----------------- src/test/rustdoc/const-generics/add-impl.rs | 2 +- 5 files changed, 16 insertions(+), 44 deletions(-) diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index 21cc54a6e6b2d..47f067590b9d5 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -148,18 +148,18 @@ pub struct GlobalId<'tcx> { pub promoted: Option, } -/// Input argument for `tcx.lit_to_const` +/// 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 + /// The absolute value of the resultant constant. pub lit: &'tcx LitKind, - /// The type of the constant + /// The type of the constant. pub ty: Ty<'tcx>, - /// If the constant is negative + /// If the constant is negative. pub neg: bool, } -/// Error type for `tcx.lit_to_const` +/// Error type for `tcx.lit_to_const`. #[derive(Copy, Clone, Debug, Eq, PartialEq, HashStable)] pub enum LitToConstError { UnparseableFloat, diff --git a/src/librustc_mir_build/hair/pattern/mod.rs b/src/librustc_mir_build/hair/pattern/mod.rs index 8645abe5c1acc..205e25f7f8f0c 100644 --- a/src/librustc_mir_build/hair/pattern/mod.rs +++ b/src/librustc_mir_build/hair/pattern/mod.rs @@ -8,9 +8,8 @@ pub(crate) use self::check_match::check_match; use crate::hair::util::UserAnnotatedTyHelpers; -use rustc::mir::interpret::{ - get_slice_bytes, sign_extend, ConstValue, ErrorHandled, LitToConstError, LitToConstInput, -}; +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; diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 920ffaa4c3a0b..a3be264ddc128 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1,4 +1,4 @@ -// ignore-tidy-filelength FIXME(#67418) Split up this file +// 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`. @@ -2716,7 +2716,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { 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 + // mir. if let Ok(c) = tcx.at(expr.span).lit_to_const(lit_input) { return c; } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index ace12a7ffd208..331eb109ec0b4 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1441,17 +1441,8 @@ pub struct MacroDef { pub legacy: bool, } -#[derive( - Clone, - RustcEncodable, - RustcDecodable, - Debug, - Copy, - Hash, - Eq, - PartialEq, - HashStable_Generic -)] +#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, Hash, Eq, PartialEq)] +#[derive(HashStable_Generic)] pub enum StrStyle { /// A regular string, like `"foo"`. Cooked, @@ -1501,17 +1492,8 @@ impl StrLit { } /// Type of the integer literal based on provided suffix. -#[derive( - Clone, - Copy, - RustcEncodable, - RustcDecodable, - Debug, - Hash, - Eq, - PartialEq, - HashStable_Generic -)] +#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, Eq, PartialEq)] +#[derive(HashStable_Generic)] pub enum LitIntType { /// e.g. `42_i32`. Signed(IntTy), @@ -1522,17 +1504,8 @@ pub enum LitIntType { } /// Type of the float literal based on provided suffix. -#[derive( - Clone, - Copy, - RustcEncodable, - RustcDecodable, - Debug, - Hash, - Eq, - 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), diff --git a/src/test/rustdoc/const-generics/add-impl.rs b/src/test/rustdoc/const-generics/add-impl.rs index ed45d339728bc..54bdd768f8a73 100644 --- a/src/test/rustdoc/const-generics/add-impl.rs +++ b/src/test/rustdoc/const-generics/add-impl.rs @@ -11,7 +11,7 @@ pub struct Simd { inner: T, } -// @has foo/struct.Simd.html '//div[@id="implementations-list"]/h3/code' 'impl Add> for Simd' +// @has foo/struct.Simd.html '//div[@id="implementations-list"]/h3/code' 'impl Add> for Simd' impl Add for Simd { type Output = Self; From 30dba975400054424dd0ff31bea9fd312bc68d2c Mon Sep 17 00:00:00 2001 From: Ben Lewis Date: Tue, 14 Jan 2020 20:41:14 +1300 Subject: [PATCH 3/4] Normalize symbol hash in ui test for legacy symbol mangling, as it's dependent on the number of bits within consts. --- src/test/ui/symbol-names/impl1.legacy.stderr | 28 ++++++++++---------- src/test/ui/symbol-names/impl1.rs | 2 ++ src/test/ui/symbol-names/impl1.v0.stderr | 24 ++++++++--------- 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/test/ui/symbol-names/impl1.legacy.stderr b/src/test/ui/symbol-names/impl1.legacy.stderr index 8e498e4b39477..33cacaf212855 100644 --- a/src/test/ui/symbol-names/impl1.legacy.stderr +++ b/src/test/ui/symbol-names/impl1.legacy.stderr @@ -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::::baz::h90c4a800b1aa0df0) - --> $DIR/impl1.rs:32:9 + --> $DIR/impl1.rs:34:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(impl1::bar::::baz) - --> $DIR/impl1.rs:32:9 + --> $DIR/impl1.rs:34:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: def-path(bar::::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$3$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method17h62e540f14f879d56E) - --> $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; 3] as impl1::main::{{closure}}::Bar>::method::h62e540f14f879d56) - --> $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; 3] as impl1::main::{{closure}}::Bar>::method) - --> $DIR/impl1.rs:62:13 + --> $DIR/impl1.rs:64:13 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: def-path(<[&dyn Foo 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] | ^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/symbol-names/impl1.rs b/src/test/ui/symbol-names/impl1.rs index b054c1373e66c..8e53eac3e47c0 100644 --- a/src/test/ui/symbol-names/impl1.rs +++ b/src/test/ui/symbol-names/impl1.rs @@ -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-32-bit: "hdb62078998ce7ea8" -> "SYMBOL_HASH" +//[legacy]normalize-stderr-64bit: "h62e540f14f879d56" -> "SYMBOL_HASH" #![feature(optin_builtin_traits, rustc_attrs)] #![allow(dead_code)] diff --git a/src/test/ui/symbol-names/impl1.v0.stderr b/src/test/ui/symbol-names/impl1.v0.stderr index 111c360b36080..b6a35d9746925 100644 --- a/src/test/ui/symbol-names/impl1.v0.stderr +++ b/src/test/ui/symbol-names/impl1.v0.stderr @@ -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(::bar) - --> $DIR/impl1.rs:14:9 + --> $DIR/impl1.rs:16:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(::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(::baz) - --> $DIR/impl1.rs:32:9 + --> $DIR/impl1.rs:34:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(::baz) - --> $DIR/impl1.rs:32:9 + --> $DIR/impl1.rs:34:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: def-path(bar::::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 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 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 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] | ^^^^^^^^^^^^^^^^^ From 583a4fc827d1f4f491286218549a6048c0a9c9bf Mon Sep 17 00:00:00 2001 From: Ben Lewis Date: Wed, 15 Jan 2020 06:59:26 +1300 Subject: [PATCH 4/4] Fix normalizing 32bit symbol hash. --- src/test/ui/symbol-names/impl1.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/symbol-names/impl1.rs b/src/test/ui/symbol-names/impl1.rs index 8e53eac3e47c0..1f689a5bd2541 100644 --- a/src/test/ui/symbol-names/impl1.rs +++ b/src/test/ui/symbol-names/impl1.rs @@ -3,7 +3,7 @@ // revisions: legacy v0 //[legacy]compile-flags: -Z symbol-mangling-version=legacy //[v0]compile-flags: -Z symbol-mangling-version=v0 -//[legacy]normalize-stderr-32-bit: "hdb62078998ce7ea8" -> "SYMBOL_HASH" +//[legacy]normalize-stderr-32bit: "hdb62078998ce7ea8" -> "SYMBOL_HASH" //[legacy]normalize-stderr-64bit: "h62e540f14f879d56" -> "SYMBOL_HASH" #![feature(optin_builtin_traits, rustc_attrs)]