diff --git a/config.toml.example b/config.toml.example index 35f69cd05b607..087dc418e2dce 100644 --- a/config.toml.example +++ b/config.toml.example @@ -82,6 +82,10 @@ # passed to prefer linking to shared libraries. #link-shared = false +# When building llvm, this configures what is being appended to the version. +# If absent, we let the version as-is. +#version-suffix = "-rust" + # On MSVC you can compile LLVM with clang-cl, but the test suite doesn't pass # with clang-cl, so this is special in that it only compiles LLVM with clang-cl #clang-cl = '/path/to/clang-cl.exe' diff --git a/src/Cargo.lock b/src/Cargo.lock index fc2dfcfd8604c..9828966fa9539 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -138,7 +138,7 @@ dependencies = [ "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "petgraph 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1471,7 +1471,7 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3243,7 +3243,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0fce5d8b5cc33983fc74f78ad552b5522ab41442c4ca91606e4236eb4b5ceefc" "checksum pest_derive 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ab94faafeb93f4c5e3ce81ca0e5a779529a602ad5d09ae6d21996bfb8b6a52bf" -"checksum petgraph 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "8b30dc85588cd02b9b76f5e386535db546d21dc68506cff2abebee0b6445e8e4" +"checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" "checksum phf 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "7d37a244c75a9748e049225155f56dbcb98fe71b192fd25fd23cb914b5ad62f2" "checksum phf_codegen 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "4e4048fe7dd7a06b8127ecd6d3803149126e9b33c7558879846da3a63f734f2b" "checksum phf_generator 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "05a079dd052e7b674d21cb31cbb6c05efd56a2cd2827db7692e2f1a507ebd998" diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 57a526038041e..3e91c2b3e86c8 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -47,7 +47,7 @@ serde_json = "1.0.2" toml = "0.4" lazy_static = "0.2" time = "0.1" -petgraph = "0.4.12" +petgraph = "0.4.13" [dev-dependencies] pretty_assertions = "0.5" diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index bf4d39c4947e5..70b21a1567b0f 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -86,6 +86,7 @@ pub struct Config { pub llvm_targets: Option, pub llvm_experimental_targets: String, pub llvm_link_jobs: Option, + pub llvm_version_suffix: Option, pub lld_enabled: bool, pub lldb_enabled: bool, @@ -256,6 +257,7 @@ struct Llvm { experimental_targets: Option, link_jobs: Option, link_shared: Option, + version_suffix: Option, clang_cl: Option } @@ -516,6 +518,7 @@ impl Config { config.llvm_experimental_targets = llvm.experimental_targets.clone() .unwrap_or("WebAssembly;RISCV".to_string()); config.llvm_link_jobs = llvm.link_jobs; + config.llvm_version_suffix = llvm.version_suffix.clone(); config.llvm_clang_cl = llvm.clang_cl.clone(); } diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 167e4a78edaf8..2d94704fda7d6 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -2056,7 +2056,8 @@ impl Step for Lldb { drop(fs::remove_dir_all(&image)); // Prepare the image directory - let dst = image.join("bin"); + let root = image.join("lib/rustlib").join(&*target); + let dst = root.join("bin"); t!(fs::create_dir_all(&dst)); for program in &["lldb", "lldb-argdumper", "lldb-mi", "lldb-server"] { let exe = bindir.join(exe(program, &target)); @@ -2065,7 +2066,7 @@ impl Step for Lldb { // The libraries. let libdir = builder.llvm_out(target).join("lib"); - let dst = image.join("lib"); + let dst = root.join("lib"); t!(fs::create_dir_all(&dst)); for entry in t!(fs::read_dir(&libdir)) { let entry = entry.unwrap(); @@ -2093,7 +2094,7 @@ impl Step for Lldb { let entry = t!(entry); if let Ok(name) = entry.file_name().into_string() { if name.starts_with("python") { - let dst = image.join(libdir_name) + let dst = root.join(libdir_name) .join(entry.file_name()); t!(fs::create_dir_all(&dst)); builder.cp_r(&entry.path(), &dst); diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index caf38d766f54e..828a7d14c0437 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -239,6 +239,10 @@ impl Step for Llvm { cfg.define("LLVM_NATIVE_BUILD", builder.llvm_out(builder.config.build).join("build")); } + if let Some(ref suffix) = builder.config.llvm_version_suffix { + cfg.define("LLVM_VERSION_SUFFIX", suffix); + } + if let Some(ref python) = builder.config.python { cfg.define("PYTHON_EXECUTABLE", python); } diff --git a/src/doc/book b/src/doc/book index 16c9dee7666c2..cff0930664b68 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit 16c9dee7666c2b2766fd98d89003e028679d1207 +Subproject commit cff0930664b688f1dd22aefb3d16944eb4cdbfd5 diff --git a/src/doc/nomicon b/src/doc/nomicon index ae42ad7aa4d79..7fd493465b7dd 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit ae42ad7aa4d7907cca941371c9eee8de8c2ee40d +Subproject commit 7fd493465b7dd6cf3476f0b834884059bbdd1d93 diff --git a/src/doc/reference b/src/doc/reference index 219e261ddb833..821355a6fd642 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 219e261ddb833a5683627b0a9be87a0f4486abb9 +Subproject commit 821355a6fd642b71988a2f88a3162fb358732012 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index e3719fc78ff4a..e459fb3f07f2b 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit e3719fc78ff4a21dfd13cfcc9e2ca42cb5de29f4 +Subproject commit e459fb3f07f2b930ccd25d348671b8eae233fd64 diff --git a/src/etc/rust-lldb b/src/etc/rust-lldb index 6a2849b55485e..6ed8210349e17 100755 --- a/src/etc/rust-lldb +++ b/src/etc/rust-lldb @@ -12,27 +12,35 @@ # Exit if anything fails set -e -LLDB_VERSION=`lldb --version 2>/dev/null | head -1 | cut -d. -f1` +# Find out where to look for the pretty printer Python module +RUSTC_SYSROOT=`rustc --print sysroot` + +# Find the host triple so we can find lldb in rustlib. +host=`rustc -vV | sed -n -e 's/^host: //p'` + +lldb=lldb +if [ -f "$RUSTC_SYSROOT/lib/rustlib/$host/bin/lldb" ]; then + lldb="$RUSTC_SYSROOT/lib/rustlib/$host/bin/lldb" +else + LLDB_VERSION=`"$lldb" --version 2>/dev/null | head -1 | cut -d. -f1` -if [ "$LLDB_VERSION" = "lldb-350" ] -then - echo "***" + if [ "$LLDB_VERSION" = "lldb-350" ] + then + echo "***" echo \ "WARNING: This version of LLDB has known issues with Rust and cannot \ display the contents of local variables!" - echo "***" + echo "***" + fi fi -# Find out where to look for the pretty printer Python module -RUSTC_SYSROOT=`rustc --print sysroot` - # Prepare commands that will be loaded before any file on the command line has been loaded script_import="command script import \"$RUSTC_SYSROOT/lib/rustlib/etc/lldb_rust_formatters.py\"" category_definition="type summary add --no-value --python-function lldb_rust_formatters.print_val -x \".*\" --category Rust" category_enable="type category enable Rust" # Call LLDB with the commands added to the argument list -exec lldb --one-line-before-file="$script_import" \ +exec "$lldb" --one-line-before-file="$script_import" \ --one-line-before-file="$category_definition" \ --one-line-before-file="$category_enable" \ "$@" diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index dfe0a395ca140..d15568af6aebe 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -574,6 +574,7 @@ define_dep_nodes!( <'tcx> [] IsPanicRuntime(CrateNum), [] IsCompilerBuiltins(CrateNum), [] HasGlobalAllocator(CrateNum), + [] HasPanicHandler(CrateNum), [input] ExternCrate(DefId), [eval_always] LintLevels, [] Specializes { impl1: DefId, impl2: DefId }, diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index 4df0fc443a27c..f5a46060759dd 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -39,10 +39,12 @@ pub struct DepGraph { fingerprints: Lrc>> } -newtype_index!(DepNodeIndex); +newtype_index! { + pub struct DepNodeIndex { .. } +} impl DepNodeIndex { - const INVALID: DepNodeIndex = DepNodeIndex(::std::u32::MAX); + const INVALID: DepNodeIndex = DepNodeIndex::MAX; } #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] @@ -1125,14 +1127,16 @@ impl DepNodeColorMap { match self.values[index] { COMPRESSED_NONE => None, COMPRESSED_RED => Some(DepNodeColor::Red), - value => Some(DepNodeColor::Green(DepNodeIndex(value - COMPRESSED_FIRST_GREEN))) + value => Some(DepNodeColor::Green(DepNodeIndex::from_u32( + value - COMPRESSED_FIRST_GREEN + ))) } } fn insert(&mut self, index: SerializedDepNodeIndex, color: DepNodeColor) { self.values[index] = match color { DepNodeColor::Red => COMPRESSED_RED, - DepNodeColor::Green(index) => index.0 + COMPRESSED_FIRST_GREEN, + DepNodeColor::Green(index) => index.as_u32() + COMPRESSED_FIRST_GREEN, } } } diff --git a/src/librustc/dep_graph/serialized.rs b/src/librustc/dep_graph/serialized.rs index 60fc813a25d51..4c896a33e59c1 100644 --- a/src/librustc/dep_graph/serialized.rs +++ b/src/librustc/dep_graph/serialized.rs @@ -14,7 +14,9 @@ use dep_graph::DepNode; use ich::Fingerprint; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; -newtype_index!(SerializedDepNodeIndex); +newtype_index! { + pub struct SerializedDepNodeIndex { .. } +} /// Data for use when recompiling the **current crate**. #[derive(Debug, RustcEncodable, RustcDecodable)] diff --git a/src/librustc/hir/def_id.rs b/src/librustc/hir/def_id.rs index be37ea18457f1..420ffbcfee6cd 100644 --- a/src/librustc/hir/def_id.rs +++ b/src/librustc/hir/def_id.rs @@ -15,8 +15,8 @@ use serialize; use std::fmt; use std::u32; -newtype_index!(CrateNum - { +newtype_index! { + pub struct CrateNum { ENCODABLE = custom DEBUG_FORMAT = "crate{}", @@ -27,32 +27,20 @@ newtype_index!(CrateNum /// Virtual crate for builtin macros // FIXME(jseyfried): this is also used for custom derives until proc-macro crates get // `CrateNum`s. - const BUILTIN_MACROS_CRATE = u32::MAX, + const BUILTIN_MACROS_CRATE = CrateNum::MAX_AS_U32, /// A CrateNum value that indicates that something is wrong. - const INVALID_CRATE = u32::MAX - 1, + const INVALID_CRATE = CrateNum::MAX_AS_U32 - 1, /// A special CrateNum that we use for the tcx.rcache when decoding from /// the incr. comp. cache. - const RESERVED_FOR_INCR_COMP_CACHE = u32::MAX - 2, - }); + const RESERVED_FOR_INCR_COMP_CACHE = CrateNum::MAX_AS_U32 - 2, + } +} impl CrateNum { pub fn new(x: usize) -> CrateNum { - assert!(x < (u32::MAX as usize)); - CrateNum(x as u32) - } - - pub fn from_u32(x: u32) -> CrateNum { - CrateNum(x) - } - - pub fn as_usize(&self) -> usize { - self.0 as usize - } - - pub fn as_u32(&self) -> u32 { - self.0 + CrateNum::from_usize(x) } pub fn as_def_id(&self) -> DefId { DefId { krate: *self, index: CRATE_DEF_INDEX } } @@ -60,7 +48,7 @@ impl CrateNum { impl fmt::Display for CrateNum { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(&self.0, f) + fmt::Display::fmt(&self.as_u32(), f) } } diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs index f11e448796462..8b7438cbe6325 100644 --- a/src/librustc/ich/impls_mir.rs +++ b/src/librustc/ich/impls_mir.rs @@ -102,7 +102,6 @@ impl<'a> HashStable> for mir::Local { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - use rustc_data_structures::indexed_vec::Idx; self.index().hash_stable(hcx, hasher); } } @@ -112,7 +111,6 @@ impl<'a> HashStable> for mir::BasicBlock { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - use rustc_data_structures::indexed_vec::Idx; self.index().hash_stable(hcx, hasher); } } @@ -122,7 +120,6 @@ impl<'a> HashStable> for mir::Field { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - use rustc_data_structures::indexed_vec::Idx; self.index().hash_stable(hcx, hasher); } } @@ -133,7 +130,6 @@ for mir::SourceScope { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - use rustc_data_structures::indexed_vec::Idx; self.index().hash_stable(hcx, hasher); } } @@ -143,7 +139,6 @@ impl<'a> HashStable> for mir::Promoted { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - use rustc_data_structures::indexed_vec::Idx; self.index().hash_stable(hcx, hasher); } } diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 68320dfddefbc..e90c4f62f59d5 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -143,7 +143,6 @@ impl<'a> HashStable> for ty::RegionVid { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - use rustc_data_structures::indexed_vec::Idx; self.index().hash_stable(hcx, hasher); } } @@ -153,7 +152,6 @@ impl<'gcx> HashStable> for ty::CanonicalVar { fn hash_stable(&self, hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher) { - use rustc_data_structures::indexed_vec::Idx; self.index().hash_stable(hcx, hasher); } } @@ -774,7 +772,6 @@ impl_stable_hash_for!(enum ty::cast::CastKind { FnPtrAddrCast }); -impl_stable_hash_for!(tuple_struct ::middle::region::FirstStatementIndex { idx }); impl_stable_hash_for!(struct ::middle::region::Scope { id, code }); impl<'a> ToStableHashKey> for region::Scope { diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index ac6a7f0c2baa8..eabcf1ce41363 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -73,8 +73,6 @@ use syntax::ast::DUMMY_NODE_ID; use syntax_pos::{Pos, Span}; use errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString}; -use rustc_data_structures::indexed_vec::Idx; - mod note; mod need_type_info; diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index 296808cea2bd7..d8f3b9a05bd40 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -16,7 +16,7 @@ use self::CombineMapType::*; use super::{MiscVariable, RegionVariableOrigin, SubregionOrigin}; use super::unify_key; -use rustc_data_structures::indexed_vec::{IndexVec, Idx}; +use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::unify as ut; use ty::{self, Ty, TyCtxt}; diff --git a/src/librustc/infer/unify_key.rs b/src/librustc/infer/unify_key.rs index a1145572b79d9..cdc92877a5ae8 100644 --- a/src/librustc/infer/unify_key.rs +++ b/src/librustc/infer/unify_key.rs @@ -49,8 +49,8 @@ impl UnifyValue for RegionVidKey { impl UnifyKey for ty::RegionVid { type Value = RegionVidKey; - fn index(&self) -> u32 { self.0 } - fn from_index(i: u32) -> ty::RegionVid { ty::RegionVid(i) } + fn index(&self) -> u32 { u32::from(*self) } + fn from_index(i: u32) -> ty::RegionVid { ty::RegionVid::from(i) } fn tag() -> &'static str { "RegionVid" } } diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index e281cbf948893..f6a8f8dc172d4 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -159,11 +159,13 @@ pub struct BlockRemainder { pub first_statement_index: FirstStatementIndex, } -newtype_index!(FirstStatementIndex - { - pub idx +newtype_index! { + pub struct FirstStatementIndex { MAX = SCOPE_DATA_REMAINDER_MAX - }); + } +} + +impl_stable_hash_for!(struct ::middle::region::FirstStatementIndex { private }); impl From for Scope { #[inline] diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index f66be6dc54d37..c6a1281061fe4 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -131,9 +131,6 @@ pub struct Mir<'tcx> { cache: cache::Cache, } -/// where execution begins -pub const START_BLOCK: BasicBlock = BasicBlock(0); - impl<'tcx> Mir<'tcx> { pub fn new( basic_blocks: IndexVec>, @@ -239,7 +236,7 @@ impl<'tcx> Mir<'tcx> { #[inline] pub fn local_kind(&self, local: Local) -> LocalKind { - let index = local.0 as usize; + let index = local.as_usize(); if index == 0 { debug_assert!( self.local_decls[local].mutability == Mutability::Mut, @@ -523,11 +520,12 @@ impl BorrowKind { /////////////////////////////////////////////////////////////////////////// // Variables and temps -newtype_index!(Local - { +newtype_index! { + pub struct Local { DEBUG_FORMAT = "_{}", const RETURN_PLACE = 0, - }); + } +} /// Classifies locals into categories. See `Mir::local_kind`. #[derive(PartialEq, Eq, Debug)] @@ -852,7 +850,12 @@ pub struct UpvarDecl { /////////////////////////////////////////////////////////////////////////// // BasicBlock -newtype_index!(BasicBlock { DEBUG_FORMAT = "bb{}" }); +newtype_index! { + pub struct BasicBlock { + DEBUG_FORMAT = "bb{}", + const START_BLOCK = 0, + } +} impl BasicBlock { pub fn start_location(self) -> Location { @@ -1822,7 +1825,11 @@ pub type PlaceProjection<'tcx> = Projection<'tcx, Place<'tcx>, Local, Ty<'tcx>>; /// and the index is a local. pub type PlaceElem<'tcx> = ProjectionElem<'tcx, Local, Ty<'tcx>>; -newtype_index!(Field { DEBUG_FORMAT = "field[{}]" }); +newtype_index! { + pub struct Field { + DEBUG_FORMAT = "field[{}]" + } +} impl<'tcx> Place<'tcx> { pub fn field(self, f: Field, ty: Ty<'tcx>) -> Place<'tcx> { @@ -1895,11 +1902,12 @@ impl<'tcx> Debug for Place<'tcx> { /////////////////////////////////////////////////////////////////////////// // Scopes -newtype_index!(SourceScope - { +newtype_index! { + pub struct SourceScope { DEBUG_FORMAT = "scope[{}]", const OUTERMOST_SOURCE_SCOPE = 0, - }); + } +} #[derive(Clone, Debug, RustcEncodable, RustcDecodable)] pub struct SourceScopeData { @@ -2271,7 +2279,11 @@ pub struct Constant<'tcx> { pub literal: &'tcx ty::Const<'tcx>, } -newtype_index!(Promoted { DEBUG_FORMAT = "promoted[{}]" }); +newtype_index! { + pub struct Promoted { + DEBUG_FORMAT = "promoted[{}]" + } +} impl<'tcx> Debug for Constant<'tcx> { fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 778c388c7dec7..272967282e03b 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -159,6 +159,9 @@ pub struct Session { /// Metadata about the allocators for the current crate being compiled pub has_global_allocator: Once, + /// Metadata about the panic handlers for the current crate being compiled + pub has_panic_handler: Once, + /// Cap lint level specified by a driver specifically. pub driver_lint_caps: FxHashMap, } @@ -1160,6 +1163,7 @@ pub fn build_session_( (*GLOBAL_JOBSERVER).clone() }, has_global_allocator: Once::new(), + has_panic_handler: Once::new(), driver_lint_caps: FxHashMap(), }; diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index 837354bfcaf36..2bbf5aacc1aca 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -464,6 +464,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::has_global_allocator<'tcx> { } } +impl<'tcx> QueryDescription<'tcx> for queries::has_panic_handler<'tcx> { + fn describe(_: TyCtxt, _: CrateNum) -> String { + "checking if the crate has_panic_handler".to_string() + } +} + impl<'tcx> QueryDescription<'tcx> for queries::extern_crate<'tcx> { fn describe(_: TyCtxt, _: DefId) -> String { "getting crate's ExternCrateData".to_string() diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 993ba2fd13d0d..f0ca168e9e467 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -381,6 +381,7 @@ define_queries! { <'tcx> [fatal_cycle] fn is_panic_runtime: IsPanicRuntime(CrateNum) -> bool, [fatal_cycle] fn is_compiler_builtins: IsCompilerBuiltins(CrateNum) -> bool, [fatal_cycle] fn has_global_allocator: HasGlobalAllocator(CrateNum) -> bool, + [fatal_cycle] fn has_panic_handler: HasPanicHandler(CrateNum) -> bool, [fatal_cycle] fn is_sanitizer_runtime: IsSanitizerRuntime(CrateNum) -> bool, [fatal_cycle] fn is_profiler_runtime: IsProfilerRuntime(CrateNum) -> bool, [fatal_cycle] fn panic_strategy: GetPanicStrategy(CrateNum) -> PanicStrategy, diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 215fba54499b7..3c26732fbac67 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -1168,6 +1168,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::IsPanicRuntime => { force!(is_panic_runtime, krate!()); } DepKind::IsCompilerBuiltins => { force!(is_compiler_builtins, krate!()); } DepKind::HasGlobalAllocator => { force!(has_global_allocator, krate!()); } + DepKind::HasPanicHandler => { force!(has_panic_handler, krate!()); } DepKind::ExternCrate => { force!(extern_crate, def_id!()); } DepKind::LintLevels => { force!(lint_levels, LOCAL_CRATE); } DepKind::InScopeTraits => { force!(in_scope_traits_map, def_id!().index); } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 7c7ee9b330ecc..b5ec1ad36ab7e 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1034,11 +1034,12 @@ impl<'a, 'gcx, 'tcx> ParamTy { /// is the outer fn. /// /// [dbi]: http://en.wikipedia.org/wiki/De_Bruijn_index -newtype_index!(DebruijnIndex - { +newtype_index! { + pub struct DebruijnIndex { DEBUG_FORMAT = "DebruijnIndex({})", const INNERMOST = 0, - }); + } +} pub type Region<'tcx> = &'tcx RegionKind; @@ -1176,11 +1177,11 @@ pub struct FloatVid { pub index: u32, } -newtype_index!(RegionVid - { - pub idx +newtype_index! { + pub struct RegionVid { DEBUG_FORMAT = custom, - }); + } +} impl Atom for RegionVid { fn index(self) -> usize { @@ -1188,18 +1189,6 @@ impl Atom for RegionVid { } } -impl From for RegionVid { - fn from(i: usize) -> RegionVid { - RegionVid::new(i) - } -} - -impl From for usize { - fn from(vid: RegionVid) -> usize { - Idx::index(vid) - } -} - #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)] pub enum InferTy { TyVar(TyVid), @@ -1217,7 +1206,9 @@ pub enum InferTy { CanonicalTy(CanonicalVar), } -newtype_index!(CanonicalVar); +newtype_index! { + pub struct CanonicalVar { .. } +} /// A `ProjectionPredicate` for an `ExistentialTraitRef`. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)] @@ -1282,8 +1273,8 @@ impl DebruijnIndex { /// /// you would need to shift the index for `'a` into 1 new binder. #[must_use] - pub const fn shifted_in(self, amount: u32) -> DebruijnIndex { - DebruijnIndex(self.0 + amount) + pub fn shifted_in(self, amount: u32) -> DebruijnIndex { + DebruijnIndex::from_u32(self.as_u32() + amount) } /// Update this index in place by shifting it "in" through @@ -1295,8 +1286,8 @@ impl DebruijnIndex { /// Returns the resulting index when this value is moved out from /// `amount` number of new binders. #[must_use] - pub const fn shifted_out(self, amount: u32) -> DebruijnIndex { - DebruijnIndex(self.0 - amount) + pub fn shifted_out(self, amount: u32) -> DebruijnIndex { + DebruijnIndex::from_u32(self.as_u32() - amount) } /// Update in place by shifting out from `amount` binders. @@ -1325,11 +1316,11 @@ impl DebruijnIndex { /// bound by one of the binders we are shifting out of, that is an /// error (and should fail an assertion failure). pub fn shifted_out_to_binder(self, to_binder: DebruijnIndex) -> Self { - self.shifted_out((to_binder.0 - INNERMOST.0) as u32) + self.shifted_out(to_binder.as_u32() - INNERMOST.as_u32()) } } -impl_stable_hash_for!(tuple_struct DebruijnIndex { index }); +impl_stable_hash_for!(struct DebruijnIndex { private }); /// Region utilities impl RegionKind { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 0f15c75c2fb36..e8236e21e2463 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -26,7 +26,6 @@ use std::cell::Cell; use std::fmt; use std::usize; -use rustc_data_structures::indexed_vec::Idx; use rustc_target::spec::abi::Abi; use syntax::ast::CRATE_NODE_ID; use syntax::symbol::{Symbol, InternedString}; diff --git a/src/librustc_codegen_llvm/mir/mod.rs b/src/librustc_codegen_llvm/mir/mod.rs index 9e65144bd60a1..258fe643c3067 100644 --- a/src/librustc_codegen_llvm/mir/mod.rs +++ b/src/librustc_codegen_llvm/mir/mod.rs @@ -32,7 +32,7 @@ use syntax::symbol::keywords; use std::iter; use rustc_data_structures::bitvec::BitArray; -use rustc_data_structures::indexed_vec::{IndexVec, Idx}; +use rustc_data_structures::indexed_vec::IndexVec; pub use self::constant::codegen_static_initializer; diff --git a/src/librustc_codegen_llvm/mir/operand.rs b/src/librustc_codegen_llvm/mir/operand.rs index 419e7298588c5..bfa0e0a451e6f 100644 --- a/src/librustc_codegen_llvm/mir/operand.rs +++ b/src/librustc_codegen_llvm/mir/operand.rs @@ -13,7 +13,6 @@ use rustc::mir; use rustc::mir::interpret::{ConstValue, ScalarMaybeUndef}; use rustc::ty; use rustc::ty::layout::{self, Align, LayoutOf, TyLayout}; -use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::sync::Lrc; use base; diff --git a/src/librustc_codegen_llvm/mir/place.rs b/src/librustc_codegen_llvm/mir/place.rs index 833dca8c75fd5..4baab1763c310 100644 --- a/src/librustc_codegen_llvm/mir/place.rs +++ b/src/librustc_codegen_llvm/mir/place.rs @@ -13,7 +13,6 @@ use rustc::ty::{self, Ty}; use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, Size}; use rustc::mir; use rustc::mir::tcx::PlaceTy; -use rustc_data_structures::indexed_vec::Idx; use base; use builder::Builder; use common::{CodegenCx, C_undef, C_usize, C_u8, C_u32, C_uint, C_null, C_uint_big}; diff --git a/src/librustc_data_structures/indexed_vec.rs b/src/librustc_data_structures/indexed_vec.rs index c358f2f852e18..186bc6d43ccc5 100644 --- a/src/librustc_data_structures/indexed_vec.rs +++ b/src/librustc_data_structures/indexed_vec.rs @@ -48,25 +48,42 @@ impl Idx for u32 { fn index(self) -> usize { self as usize } } +/// Creates a struct type `S` that can be used as an index with +/// `IndexVec` and so on. +/// +/// There are two ways of interacting with these indices: +/// +/// - The `From` impls are the preferred way. So you can do +/// `S::from(v)` with a `usize` or `u32`. And you can convert back +/// to an integer with `u32::from(s)`. +/// +/// - Alternatively, you can use the methods `S::new(v)` and `s.index()` +/// to create/return a value. +/// +/// Internally, the index uses a u32, so the index must not exceed +/// `u32::MAX`. You can also customize things like the `Debug` impl, +/// what traits are derived, and so forth via the macro. #[macro_export] macro_rules! newtype_index { // ---- public rules ---- // Use default constants - ($name:ident) => ( + ($v:vis struct $name:ident { .. }) => ( newtype_index!( // Leave out derives marker so we can use its absence to ensure it comes first @type [$name] - @max [::std::u32::MAX] + @max [::std::u32::MAX - 1] + @vis [$v] @debug_format ["{}"]); ); // Define any constants - ($name:ident { $($tokens:tt)+ }) => ( + ($v:vis struct $name:ident { $($tokens:tt)+ }) => ( newtype_index!( // Leave out derives marker so we can use its absence to ensure it comes first @type [$name] - @max [::std::u32::MAX] + @max [::std::u32::MAX - 1] + @vis [$v] @debug_format ["{}"] $($tokens)+); ); @@ -75,27 +92,92 @@ macro_rules! newtype_index { // Base case, user-defined constants (if any) have already been defined (@derives [$($derives:ident,)*] - @pub [$($pub:tt)*] @type [$type:ident] @max [$max:expr] + @vis [$v:vis] @debug_format [$debug_format:tt]) => ( #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, $($derives),*)] - pub struct $type($($pub)* u32); + $v struct $type { + private: u32 + } + + impl $type { + $v const MAX_AS_U32: u32 = $max; + + $v const MAX: $type = $type::from_u32_const($max); + + #[inline] + $v fn from_usize(value: usize) -> Self { + assert!(value <= ($max as usize)); + unsafe { + $type::from_u32_unchecked(value as u32) + } + } + + #[inline] + $v fn from_u32(value: u32) -> Self { + assert!(value <= $max); + unsafe { + $type::from_u32_unchecked(value) + } + } + + /// Hacky variant of `from_u32` for use in constants. + /// This version checks the "max" constraint by using an + /// invalid array dereference. + #[inline] + $v const fn from_u32_const(value: u32) -> Self { + // This will fail at const eval time unless `value <= + // max` is true (in which case we get the index 0). + // It will also fail at runtime, of course, but in a + // kind of wacky way. + let _ = ["out of range value used"][ + !(value <= $max) as usize + ]; + + unsafe { + $type { private: value } + } + } + + #[inline] + $v const unsafe fn from_u32_unchecked(value: u32) -> Self { + $type { private: value } + } + + /// Extract value of this index as an integer. + #[inline] + $v fn index(self) -> usize { + self.as_usize() + } + + /// Extract value of this index as a usize. + #[inline] + $v fn as_u32(self) -> u32 { + self.private + } + + /// Extract value of this index as a u32. + #[inline] + $v fn as_usize(self) -> usize { + self.as_u32() as usize + } + } impl Idx for $type { #[inline] fn new(value: usize) -> Self { - assert!(value < ($max) as usize); - $type(value as u32) + Self::from(value) } #[inline] fn index(self) -> usize { - self.0 as usize + usize::from(self) } } impl ::std::iter::Step for $type { + #[inline] fn steps_between(start: &Self, end: &Self) -> Option { ::steps_between( &Idx::index(*start), @@ -103,27 +185,60 @@ macro_rules! newtype_index { ) } + #[inline] fn replace_one(&mut self) -> Self { ::std::mem::replace(self, Self::new(1)) } + #[inline] fn replace_zero(&mut self) -> Self { ::std::mem::replace(self, Self::new(0)) } + #[inline] fn add_one(&self) -> Self { Self::new(Idx::index(*self) + 1) } + #[inline] fn sub_one(&self) -> Self { Self::new(Idx::index(*self) - 1) } + #[inline] fn add_usize(&self, u: usize) -> Option { Idx::index(*self).checked_add(u).map(Self::new) } } + impl From<$type> for u32 { + #[inline] + fn from(v: $type) -> u32 { + v.as_u32() + } + } + + impl From<$type> for usize { + #[inline] + fn from(v: $type) -> usize { + v.as_usize() + } + } + + impl From for $type { + #[inline] + fn from(value: usize) -> Self { + $type::from_usize(value) + } + } + + impl From for $type { + #[inline] + fn from(value: u32) -> Self { + $type::from_u32(value) + } + } + newtype_index!( @handle_debug @derives [$($derives,)*] @@ -144,7 +259,7 @@ macro_rules! newtype_index { @debug_format [$debug_format:tt]) => ( impl ::std::fmt::Debug for $type { fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - write!(fmt, $debug_format, self.0) + write!(fmt, $debug_format, self.as_u32()) } } ); @@ -167,44 +282,17 @@ macro_rules! newtype_index { @debug_format [$debug_format]); ); - // Handle the case where someone wants to make the internal field public - (@type [$type:ident] - @max [$max:expr] - @debug_format [$debug_format:tt] - pub idx - $($tokens:tt)*) => ( - newtype_index!( - @pub [pub] - @type [$type] - @max [$max] - @debug_format [$debug_format] - $($tokens)*); - ); - - // The default case is that the internal field is private - (@type [$type:ident] - @max [$max:expr] - @debug_format [$debug_format:tt] - $($tokens:tt)*) => ( - newtype_index!( - @pub [] - @type [$type] - @max [$max] - @debug_format [$debug_format] - $($tokens)*); - ); - // Append comma to end of derives list if it's missing - (@pub [$($pub:tt)*] - @type [$type:ident] + (@type [$type:ident] @max [$max:expr] + @vis [$v:vis] @debug_format [$debug_format:tt] derive [$($derives:ident),*] $($tokens:tt)*) => ( newtype_index!( - @pub [$($pub)*] @type [$type] @max [$max] + @vis [$v] @debug_format [$debug_format] derive [$($derives,)*] $($tokens)*); @@ -212,154 +300,154 @@ macro_rules! newtype_index { // By not including the @derives marker in this list nor in the default args, we can force it // to come first if it exists. When encodable is custom, just use the derives list as-is. - (@pub [$($pub:tt)*] - @type [$type:ident] + (@type [$type:ident] @max [$max:expr] + @vis [$v:vis] @debug_format [$debug_format:tt] derive [$($derives:ident,)+] ENCODABLE = custom $($tokens:tt)*) => ( newtype_index!( @derives [$($derives,)+] - @pub [$($pub)*] @type [$type] @max [$max] + @vis [$v] @debug_format [$debug_format] $($tokens)*); ); // By not including the @derives marker in this list nor in the default args, we can force it // to come first if it exists. When encodable isn't custom, add serialization traits by default. - (@pub [$($pub:tt)*] - @type [$type:ident] + (@type [$type:ident] @max [$max:expr] + @vis [$v:vis] @debug_format [$debug_format:tt] derive [$($derives:ident,)+] $($tokens:tt)*) => ( newtype_index!( @derives [$($derives,)+ RustcDecodable, RustcEncodable,] - @pub [$($pub)*] @type [$type] @max [$max] + @vis [$v] @debug_format [$debug_format] $($tokens)*); ); // The case where no derives are added, but encodable is overridden. Don't // derive serialization traits - (@pub [$($pub:tt)*] - @type [$type:ident] + (@type [$type:ident] @max [$max:expr] + @vis [$v:vis] @debug_format [$debug_format:tt] ENCODABLE = custom $($tokens:tt)*) => ( newtype_index!( @derives [] - @pub [$($pub)*] @type [$type] @max [$max] + @vis [$v] @debug_format [$debug_format] $($tokens)*); ); // The case where no derives are added, add serialization derives by default - (@pub [$($pub:tt)*] - @type [$type:ident] + (@type [$type:ident] @max [$max:expr] + @vis [$v:vis] @debug_format [$debug_format:tt] $($tokens:tt)*) => ( newtype_index!( @derives [RustcDecodable, RustcEncodable,] - @pub [$($pub)*] @type [$type] @max [$max] + @vis [$v] @debug_format [$debug_format] $($tokens)*); ); // Rewrite final without comma to one that includes comma (@derives [$($derives:ident,)*] - @pub [$($pub:tt)*] @type [$type:ident] @max [$max:expr] + @vis [$v:vis] @debug_format [$debug_format:tt] $name:ident = $constant:expr) => ( newtype_index!( @derives [$($derives,)*] - @pub [$($pub)*] @type [$type] @max [$max] + @vis [$v] @debug_format [$debug_format] $name = $constant,); ); // Rewrite final const without comma to one that includes comma (@derives [$($derives:ident,)*] - @pub [$($pub:tt)*] @type [$type:ident] @max [$_max:expr] + @vis [$v:vis] @debug_format [$debug_format:tt] $(#[doc = $doc:expr])* const $name:ident = $constant:expr) => ( newtype_index!( @derives [$($derives,)*] - @pub [$($pub)*] @type [$type] @max [$max] + @vis [$v] @debug_format [$debug_format] $(#[doc = $doc])* const $name = $constant,); ); // Replace existing default for max (@derives [$($derives:ident,)*] - @pub [$($pub:tt)*] @type [$type:ident] @max [$_max:expr] + @vis [$v:vis] @debug_format [$debug_format:tt] MAX = $max:expr, $($tokens:tt)*) => ( newtype_index!( @derives [$($derives,)*] - @pub [$($pub)*] @type [$type] @max [$max] + @vis [$v] @debug_format [$debug_format] $($tokens)*); ); // Replace existing default for debug_format (@derives [$($derives:ident,)*] - @pub [$($pub:tt)*] @type [$type:ident] @max [$max:expr] + @vis [$v:vis] @debug_format [$_debug_format:tt] DEBUG_FORMAT = $debug_format:tt, $($tokens:tt)*) => ( newtype_index!( @derives [$($derives,)*] - @pub [$($pub)*] @type [$type] @max [$max] + @vis [$v] @debug_format [$debug_format] $($tokens)*); ); // Assign a user-defined constant (@derives [$($derives:ident,)*] - @pub [$($pub:tt)*] @type [$type:ident] @max [$max:expr] + @vis [$v:vis] @debug_format [$debug_format:tt] $(#[doc = $doc:expr])* const $name:ident = $constant:expr, $($tokens:tt)*) => ( $(#[doc = $doc])* - pub const $name: $type = $type($constant); + pub const $name: $type = $type::from_u32_const($constant); newtype_index!( @derives [$($derives,)*] - @pub [$($pub)*] @type [$type] @max [$max] + @vis [$v] @debug_format [$debug_format] $($tokens)*); ); diff --git a/src/librustc_data_structures/stable_hasher.rs b/src/librustc_data_structures/stable_hasher.rs index c70a0abe8c7e4..215c44dec6913 100644 --- a/src/librustc_data_structures/stable_hasher.rs +++ b/src/librustc_data_structures/stable_hasher.rs @@ -217,6 +217,14 @@ impl_stable_hash_via_hash!(i128); impl_stable_hash_via_hash!(char); impl_stable_hash_via_hash!(()); +impl HashStable for ::std::num::NonZeroU32 { + fn hash_stable(&self, + ctx: &mut CTX, + hasher: &mut StableHasher) { + self.get().hash_stable(ctx, hasher) + } +} + impl HashStable for f32 { fn hash_stable(&self, ctx: &mut CTX, diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 175422975e006..57c00f252ef16 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -183,8 +183,13 @@ fn test_env_with_pool( }); } -const D1: ty::DebruijnIndex = ty::INNERMOST; -const D2: ty::DebruijnIndex = D1.shifted_in(1); +fn d1() -> ty::DebruijnIndex { + ty::INNERMOST +} + +fn d2() -> ty::DebruijnIndex { + d1().shifted_in(1) +} impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { pub fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> { @@ -337,7 +342,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { } pub fn t_rptr_late_bound(&self, id: u32) -> Ty<'tcx> { - let r = self.re_late_bound_with_debruijn(id, D1); + let r = self.re_late_bound_with_debruijn(id, d1()); self.infcx.tcx.mk_imm_ref(r, self.tcx().types.isize) } @@ -494,7 +499,7 @@ fn subst_ty_renumber_bound() { // t_expected = fn(&'a isize) let t_expected = { - let t_ptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, D2); + let t_ptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, d2()); env.t_fn(&[t_ptr_bound2], env.t_nil()) }; @@ -531,7 +536,7 @@ fn subst_ty_renumber_some_bounds() { // // but not that the Debruijn index is different in the different cases. let t_expected = { - let t_rptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, D2); + let t_rptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, d2()); env.t_pair(t_rptr_bound1, env.t_fn(&[t_rptr_bound2], env.t_nil())) }; @@ -559,10 +564,10 @@ fn escaping() { let t_rptr_free1 = env.t_rptr_free(1); assert!(!t_rptr_free1.has_escaping_regions()); - let t_rptr_bound1 = env.t_rptr_late_bound_with_debruijn(1, D1); + let t_rptr_bound1 = env.t_rptr_late_bound_with_debruijn(1, d1()); assert!(t_rptr_bound1.has_escaping_regions()); - let t_rptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, D2); + let t_rptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, d2()); assert!(t_rptr_bound2.has_escaping_regions()); // t_fn = fn(A) @@ -578,7 +583,7 @@ fn escaping() { #[test] fn subst_region_renumber_region() { test_env(EMPTY_SOURCE_STR, errors(&[]), |env| { - let re_bound1 = env.re_late_bound_with_debruijn(1, D1); + let re_bound1 = env.re_late_bound_with_debruijn(1, d1()); // type t_source<'a> = fn(&'a isize) let t_source = { @@ -593,7 +598,7 @@ fn subst_region_renumber_region() { // // but not that the Debruijn index is different in the different cases. let t_expected = { - let t_rptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, D2); + let t_rptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, d2()); env.t_fn(&[t_rptr_bound2], env.t_nil()) }; diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 5aa05270a2a0b..87a32b5a53e7a 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -173,6 +173,7 @@ provide! { <'tcx> tcx, def_id, other, cdata, is_panic_runtime => { cdata.root.panic_runtime } is_compiler_builtins => { cdata.root.compiler_builtins } has_global_allocator => { cdata.root.has_global_allocator } + has_panic_handler => { cdata.root.has_panic_handler } is_sanitizer_runtime => { cdata.root.sanitizer_runtime } is_profiler_runtime => { cdata.root.profiler_runtime } panic_strategy => { cdata.root.panic_strategy } diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 0fd43c592c853..aae45c17c6771 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -484,6 +484,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let is_proc_macro = tcx.sess.crate_types.borrow().contains(&CrateType::ProcMacro); let has_default_lib_allocator = attr::contains_name(&attrs, "default_lib_allocator"); let has_global_allocator = *tcx.sess.has_global_allocator.get(); + let has_panic_handler = *tcx.sess.has_panic_handler.try_get().unwrap_or(&false); let root = self.lazy(&CrateRoot { name: tcx.crate_name(LOCAL_CRATE), @@ -494,6 +495,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { panic_strategy: tcx.sess.panic_strategy(), edition: hygiene::default_edition(), has_global_allocator: has_global_allocator, + has_panic_handler: has_panic_handler, has_default_lib_allocator: has_default_lib_allocator, plugin_registrar_fn: tcx.sess .plugin_registrar_fn diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index 8e454ddc0adc4..ab22a8e4db919 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -193,6 +193,7 @@ pub struct CrateRoot { pub panic_strategy: PanicStrategy, pub edition: Edition, pub has_global_allocator: bool, + pub has_panic_handler: bool, pub has_default_lib_allocator: bool, pub plugin_registrar_fn: Option, pub macro_derive_registrar: Option, diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index a0b0aabf73e02..3f8cd03660c43 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -16,7 +16,6 @@ use rustc::mir::{LocalDecl, LocalKind, Location, Operand, Place}; use rustc::mir::{ProjectionElem, Rvalue, Statement, StatementKind}; use rustc::ty; use rustc_data_structures::fx::FxHashSet; -use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::sync::Lrc; use rustc_errors::DiagnosticBuilder; use syntax_pos::Span; diff --git a/src/librustc_mir/borrow_check/location.rs b/src/librustc_mir/borrow_check/location.rs index 28da1b2d73357..91008e8f9690e 100644 --- a/src/librustc_mir/borrow_check/location.rs +++ b/src/librustc_mir/borrow_check/location.rs @@ -27,7 +27,11 @@ crate struct LocationTable { statements_before_block: IndexVec, } -newtype_index!(LocationIndex { DEBUG_FORMAT = "LocationIndex({})" }); +newtype_index! { + pub struct LocationIndex { + DEBUG_FORMAT = "LocationIndex({})" + } +} #[derive(Copy, Clone, Debug)] crate enum RichLocation { diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 272f5024f9f1a..5050b5ab2b414 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -1605,10 +1605,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { place_span: (&Place<'tcx>, Span), flow_state: &Flows<'cx, 'gcx, 'tcx>, ) { - // FIXME: analogous code in check_loans first maps `place` to - // its base_path ... but is that what we want here? - let place = self.base_path(place_span.0); - let maybe_uninits = &flow_state.uninits; // Bad scenarios: @@ -1646,8 +1642,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { // // This code covers scenarios 1, 2, and 3. - debug!("check_if_full_path_is_moved place: {:?}", place); - match self.move_path_closest_to(place) { + debug!("check_if_full_path_is_moved place: {:?}", place_span.0); + match self.move_path_closest_to(place_span.0) { Ok(mpi) => { if maybe_uninits.contains(&mpi) { self.report_use_of_moved_or_uninitialized( @@ -1677,10 +1673,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { place_span: (&Place<'tcx>, Span), flow_state: &Flows<'cx, 'gcx, 'tcx>, ) { - // FIXME: analogous code in check_loans first maps `place` to - // its base_path ... but is that what we want here? - let place = self.base_path(place_span.0); - let maybe_uninits = &flow_state.uninits; // Bad scenarios: @@ -1709,8 +1701,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { // // This code covers scenario 1. - debug!("check_if_path_or_subpath_is_moved place: {:?}", place); - if let Some(mpi) = self.move_path_for_place(place) { + debug!("check_if_path_or_subpath_is_moved place: {:?}", place_span.0); + if let Some(mpi) = self.move_path_for_place(place_span.0) { if let Some(child_mpi) = maybe_uninits.has_any_child_of(mpi) { self.report_use_of_moved_or_uninitialized( context, @@ -1813,11 +1805,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { let tcx = self.tcx; match base.ty(self.mir, tcx).to_ty(tcx).sty { ty::Adt(def, _) if def.has_dtor(tcx) => { - - // FIXME: analogous code in - // check_loans.rs first maps - // `base` to its base_path. - self.check_if_path_or_subpath_is_moved( context, InitializationRequiringAction::Assignment, (base, span), flow_state); @@ -2190,35 +2177,6 @@ enum Overlap { Disjoint, } -impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { - // FIXME (#16118): function intended to allow the borrow checker - // to be less precise in its handling of Box while still allowing - // moves out of a Box. They should be removed when/if we stop - // treating Box specially (e.g. when/if DerefMove is added...) - - fn base_path<'d>(&self, place: &'d Place<'tcx>) -> &'d Place<'tcx> { - //! Returns the base of the leftmost (deepest) dereference of an - //! Box in `place`. If there is no dereference of an Box - //! in `place`, then it just returns `place` itself. - - let mut cursor = place; - let mut deepest = place; - loop { - let proj = match *cursor { - Place::Promoted(_) | - Place::Local(..) | Place::Static(..) => return deepest, - Place::Projection(ref proj) => proj, - }; - if proj.elem == ProjectionElem::Deref - && place.ty(self.mir, self.tcx).to_ty(self.tcx).is_box() - { - deepest = &proj.base; - } - cursor = &proj.base; - } - } -} - #[derive(Copy, Clone, PartialEq, Eq, Debug)] struct Context { kind: ContextKind, diff --git a/src/librustc_mir/borrow_check/move_errors.rs b/src/librustc_mir/borrow_check/move_errors.rs index 497e8e07853fb..290c703238805 100644 --- a/src/librustc_mir/borrow_check/move_errors.rs +++ b/src/librustc_mir/borrow_check/move_errors.rs @@ -12,7 +12,6 @@ use core::unicode::property::Pattern_White_Space; use rustc::mir::*; use rustc::ty; use rustc_errors::DiagnosticBuilder; -use rustc_data_structures::indexed_vec::Idx; use syntax_pos::Span; use borrow_check::MirBorrowckCtxt; diff --git a/src/librustc_mir/borrow_check/nll/constraints/mod.rs b/src/librustc_mir/borrow_check/nll/constraints/mod.rs index 9a8b0f391de9d..41c846509cddb 100644 --- a/src/librustc_mir/borrow_check/nll/constraints/mod.rs +++ b/src/librustc_mir/borrow_check/nll/constraints/mod.rs @@ -99,6 +99,14 @@ impl fmt::Debug for OutlivesConstraint { } } -newtype_index!(ConstraintIndex { DEBUG_FORMAT = "ConstraintIndex({})" }); +newtype_index! { + pub struct ConstraintIndex { + DEBUG_FORMAT = "ConstraintIndex({})" + } +} -newtype_index!(ConstraintSccIndex { DEBUG_FORMAT = "ConstraintSccIndex({})" }); +newtype_index! { + pub struct ConstraintSccIndex { + DEBUG_FORMAT = "ConstraintSccIndex({})" + } +} diff --git a/src/librustc_mir/borrow_check/nll/facts.rs b/src/librustc_mir/borrow_check/nll/facts.rs index 8eb052f88e124..465707ecc17dd 100644 --- a/src/librustc_mir/borrow_check/nll/facts.rs +++ b/src/librustc_mir/borrow_check/nll/facts.rs @@ -100,18 +100,6 @@ impl Atom for LocationIndex { } } -impl From for LocationIndex { - fn from(i: usize) -> LocationIndex { - LocationIndex::new(i) - } -} - -impl From for usize { - fn from(vid: LocationIndex) -> usize { - Idx::index(vid) - } -} - struct FactWriter<'w> { location_table: &'w LocationTable, dir: &'w Path, diff --git a/src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs b/src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs index dd508084d7dec..34e893d2a59f2 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs @@ -15,7 +15,6 @@ use super::*; use borrow_check::nll::constraints::OutlivesConstraint; use dot::{self, IntoCow}; -use rustc_data_structures::indexed_vec::Idx; use std::borrow::Cow; use std::io::{self, Write}; diff --git a/src/librustc_mir/borrow_check/nll/region_infer/values.rs b/src/librustc_mir/borrow_check/nll/region_infer/values.rs index ae5d57906739b..3dafab2f5a9f4 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/values.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/values.rs @@ -123,13 +123,17 @@ impl RegionValueElements { /// A single integer representing a `Location` in the MIR control-flow /// graph. Constructed efficiently from `RegionValueElements`. -newtype_index!(PointIndex { DEBUG_FORMAT = "PointIndex({})" }); +newtype_index! { + pub struct PointIndex { DEBUG_FORMAT = "PointIndex({})" } +} /// A single integer representing a (non-zero) `UniverseIndex`. /// Computed just by subtracting one from `UniverseIndex`; this is /// because the `0` value for `UniverseIndex` represents the root /// universe, and we don't need/want a bit for that one. -newtype_index!(PlaceholderIndex { DEBUG_FORMAT = "PlaceholderIndex({})" }); +newtype_index! { + pub struct PlaceholderIndex { DEBUG_FORMAT = "PlaceholderIndex({})" } +} /// An individual element in a region value -- the value of a /// particular region variable consists of a set of these elements. diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/liveness_map.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/liveness_map.rs index 15affbbc27a20..467554dc38a67 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/liveness_map.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/liveness_map.rs @@ -97,6 +97,6 @@ impl NllLivenessMap { /// compute liveness information. For many locals, we are able to /// skip liveness information: for example, those variables whose /// types contain no regions. -newtype_index!( - LiveVar -); +newtype_index! { + pub struct LiveVar { .. } +} diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs index 73d285c2f2eb8..4b39d58cd96a8 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs @@ -48,7 +48,9 @@ struct Appearance { next: Option, } -newtype_index!(AppearanceIndex); +newtype_index! { + pub struct AppearanceIndex { .. } +} impl vll::LinkElem for Appearance { type LinkIndex = AppearanceIndex; diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 61c99832448c5..82158acc9e6ab 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -42,7 +42,6 @@ use syntax_pos::{Span, DUMMY_SP}; use transform::{MirPass, MirSource}; use rustc_data_structures::fx::FxHashSet; -use rustc_data_structures::indexed_vec::Idx; macro_rules! span_mirbug { ($context:expr, $elem:expr, $($message:tt)*) => ({ diff --git a/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs b/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs index deb972ee04611..8ffce9c94926f 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs @@ -20,7 +20,7 @@ use rustc::ty::relate::{self, Relate, RelateResult, TypeRelation}; use rustc::ty::subst::Kind; use rustc::ty::{self, CanonicalTy, CanonicalVar, RegionVid, Ty, TyCtxt}; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::indexed_vec::{Idx, IndexVec}; +use rustc_data_structures::indexed_vec::IndexVec; use std::mem; pub(super) fn sub_types<'tcx>( diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index f178ea8bdbab1..322a6977bedd0 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -402,7 +402,9 @@ struct CFG<'tcx> { basic_blocks: IndexVec>, } -newtype_index!(ScopeId); +newtype_index! { + pub struct ScopeId { .. } +} /////////////////////////////////////////////////////////////////////////// /// The `BlockAnd` "monad" packages up the new basic block along with a diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index 8e99a45c87fdc..38e0854bcd61e 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -95,7 +95,6 @@ use rustc::hir; use rustc::hir::def_id::LOCAL_CRATE; use rustc::mir::*; use syntax_pos::{Span}; -use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::fx::FxHashMap; #[derive(Debug)] diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 92ddd8777f733..154830c2e77e0 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -19,7 +19,7 @@ use rustc::mir; use rustc::ty::{self, TyCtxt, Instance, query::TyCtxtAt}; use rustc::ty::layout::{LayoutOf, TyLayout}; use rustc::ty::subst::Subst; -use rustc_data_structures::indexed_vec::{IndexVec, Idx}; +use rustc_data_structures::indexed_vec::IndexVec; use syntax::ast::Mutability; use syntax::source_map::Span; diff --git a/src/librustc_mir/dataflow/at_location.rs b/src/librustc_mir/dataflow/at_location.rs index d97c0c9b43019..1dc91cd05b33e 100644 --- a/src/librustc_mir/dataflow/at_location.rs +++ b/src/librustc_mir/dataflow/at_location.rs @@ -13,7 +13,6 @@ use rustc::mir::{BasicBlock, Location}; use rustc_data_structures::indexed_set::{HybridIdxSet, IdxSet, Iter}; -use rustc_data_structures::indexed_vec::Idx; use dataflow::{BitDenotation, BlockSets, DataflowResults}; use dataflow::move_paths::{HasMoveData, MovePathIndex}; diff --git a/src/librustc_mir/dataflow/graphviz.rs b/src/librustc_mir/dataflow/graphviz.rs index 1d35bb85a21a1..2b5d26c748704 100644 --- a/src/librustc_mir/dataflow/graphviz.rs +++ b/src/librustc_mir/dataflow/graphviz.rs @@ -13,7 +13,6 @@ use syntax::ast::NodeId; use rustc::mir::{BasicBlock, Mir}; use rustc_data_structures::bitslice::bits_to_string; -use rustc_data_structures::indexed_vec::Idx; use dot; use dot::IntoCow; diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index cb551df910627..995e70fb382fc 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -21,7 +21,7 @@ use rustc::ty::{RegionKind, RegionVid}; use rustc::ty::RegionKind::ReScope; use rustc_data_structures::bitslice::{BitwiseOperator, Word}; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexed_set::IdxSet; use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::sync::Lrc; @@ -53,6 +53,13 @@ pub struct Borrows<'a, 'gcx: 'tcx, 'tcx: 'a> { _nonlexical_regioncx: Rc>, } +struct StackEntry { + bb: mir::BasicBlock, + lo: usize, + hi: usize, + first_part_only: bool +} + fn precompute_borrows_out_of_scope<'tcx>( mir: &Mir<'tcx>, regioncx: &Rc>, @@ -61,48 +68,79 @@ fn precompute_borrows_out_of_scope<'tcx>( borrow_region: RegionVid, location: Location, ) { - // Keep track of places we've locations to check and locations that we have checked. - let mut stack = vec![ location ]; - let mut visited = FxHashSet(); - visited.insert(location); - - debug!( - "borrow {:?} has region {:?} with value {:?}", - borrow_index, - borrow_region, - regioncx.region_value_str(borrow_region), - ); - debug!("borrow {:?} starts at {:?}", borrow_index, location); - while let Some(location) = stack.pop() { - // If region does not contain a point at the location, then add to list and skip - // successor locations. - if !regioncx.region_contains(borrow_region, location) { - debug!("borrow {:?} gets killed at {:?}", borrow_index, location); - borrows_out_of_scope_at_location - .entry(location) - .or_default() - .push(borrow_index); - continue; + // We visit one BB at a time. The complication is that we may start in the + // middle of the first BB visited (the one containing `location`), in which + // case we may have to later on process the first part of that BB if there + // is a path back to its start. + + // For visited BBs, we record the index of the first statement processed. + // (In fully processed BBs this index is 0.) Note also that we add BBs to + // `visited` once they are added to `stack`, before they are actually + // processed, because this avoids the need to look them up again on + // completion. + let mut visited = FxHashMap(); + visited.insert(location.block, location.statement_index); + + let mut stack = vec![]; + stack.push(StackEntry { + bb: location.block, + lo: location.statement_index, + hi: mir[location.block].statements.len(), + first_part_only: false, + }); + + while let Some(StackEntry { bb, lo, hi, first_part_only }) = stack.pop() { + let mut finished_early = first_part_only; + for i in lo ..= hi { + let location = Location { block: bb, statement_index: i }; + // If region does not contain a point at the location, then add to list and skip + // successor locations. + if !regioncx.region_contains(borrow_region, location) { + debug!("borrow {:?} gets killed at {:?}", borrow_index, location); + borrows_out_of_scope_at_location + .entry(location) + .or_default() + .push(borrow_index); + finished_early = true; + break; + } } - let bb_data = &mir[location.block]; - // If this is the last statement in the block, then add the - // terminator successors next. - if location.statement_index == bb_data.statements.len() { - // Add successors to locations to visit, if not visited before. - if let Some(ref terminator) = bb_data.terminator { - for block in terminator.successors() { - let loc = block.start_location(); - if visited.insert(loc) { - stack.push(loc); - } - } - } - } else { - // Visit next statement in block. - let loc = location.successor_within_block(); - if visited.insert(loc) { - stack.push(loc); + if !finished_early { + // Add successor BBs to the work list, if necessary. + let bb_data = &mir[bb]; + assert!(hi == bb_data.statements.len()); + for &succ_bb in bb_data.terminator.as_ref().unwrap().successors() { + visited.entry(succ_bb) + .and_modify(|lo| { + // `succ_bb` has been seen before. If it wasn't + // fully processed, add its first part to `stack` + // for processing. + if *lo > 0 { + stack.push(StackEntry { + bb: succ_bb, + lo: 0, + hi: *lo - 1, + first_part_only: true, + }); + } + // And update this entry with 0, to represent the + // whole BB being processed. + *lo = 0; + }) + .or_insert_with(|| { + // succ_bb hasn't been seen before. Add it to + // `stack` for processing. + stack.push(StackEntry { + bb: succ_bb, + lo: 0, + hi: mir[succ_bb].statements.len(), + first_part_only: false, + }); + // Insert 0 for this BB, to represent the whole BB + // being processed. + 0 + }); } } } diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 4093a6304b360..461285ff9bc10 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -16,7 +16,7 @@ use std::convert::TryInto; use rustc::{mir, ty}; use rustc::ty::layout::{self, Size, LayoutOf, TyLayout, HasDataLayout, IntegerExt}; -use rustc_data_structures::indexed_vec::Idx; + use rustc::mir::interpret::{ GlobalId, AllocId, ConstValue, Pointer, Scalar, ScalarMaybeUndef, diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 51a4294452719..d01593ca5e91c 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -18,7 +18,6 @@ use rustc::ich::StableHashingContext; use rustc::mir; use rustc::ty::{self, Ty}; use rustc::ty::layout::{self, Size, Align, LayoutOf, TyLayout, HasDataLayout}; -use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; use rustc::mir::interpret::{ diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index be04f75c7260c..d4024981c3754 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -24,6 +24,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(box_syntax)] #![feature(crate_visibility_modifier)] #![feature(core_intrinsics)] +#![feature(const_fn)] #![feature(decl_macro)] #![cfg_attr(stage0, feature(macro_vis_matcher))] #![feature(exhaustive_patterns)] diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index e2b1a255eaca2..4d19e9dfbf98a 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -26,7 +26,7 @@ use interpret::{self, Value, OpTy, MemoryKind}; use transform::{MirPass, MirSource}; use syntax::source_map::{Span, DUMMY_SP}; use rustc::ty::subst::Substs; -use rustc_data_structures::indexed_vec::{IndexVec, Idx}; +use rustc_data_structures::indexed_vec::IndexVec; use rustc::ty::ParamEnv; use rustc::ty::layout::{ LayoutOf, TyLayout, LayoutError, @@ -133,7 +133,6 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> { self.ecx.tcx.span = source_info.span; let lint_root = match self.mir.source_scope_local_data { ClearCrossCrate::Set(ref ivs) => { - use rustc_data_structures::indexed_vec::Idx; //FIXME(#51314): remove this check if source_info.scope.index() >= ivs.len() { return None; diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs index 225de03a32965..bf538112e41ed 100644 --- a/src/librustc_mir/transform/elaborate_drops.rs +++ b/src/librustc_mir/transform/elaborate_drops.rs @@ -19,7 +19,6 @@ use rustc::ty::{self, TyCtxt}; use rustc::mir::*; use rustc::util::nodemap::FxHashMap; use rustc_data_structures::indexed_set::IdxSet; -use rustc_data_structures::indexed_vec::Idx; use transform::{MirPass, MirSource}; use util::patch::MirPatch; use util::elaborate_drops::{DropFlagState, Unwind, elaborate_drop}; diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 050901b9b508a..81fc235c23346 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -16,7 +16,7 @@ use rustc_data_structures::bitvec::BitArray; use rustc_data_structures::indexed_set::IdxSet; -use rustc_data_structures::indexed_vec::{IndexVec, Idx}; +use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::fx::FxHashSet; use rustc::hir; use rustc::hir::def_id::DefId; diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs index eda7de0fd79d4..9faaeea3f5b70 100644 --- a/src/librustc_mir/transform/rustc_peek.rs +++ b/src/librustc_mir/transform/rustc_peek.rs @@ -15,7 +15,6 @@ use syntax_pos::Span; use rustc::ty::{self, TyCtxt}; use rustc::mir::{self, Mir, Location}; use rustc_data_structures::indexed_set::IdxSet; -use rustc_data_structures::indexed_vec::Idx; use transform::{MirPass, MirSource}; use dataflow::{do_dataflow, DebugFormatted}; diff --git a/src/librustc_mir/util/graphviz.rs b/src/librustc_mir/util/graphviz.rs index 22e2b1b0b09c9..0b883f68bff40 100644 --- a/src/librustc_mir/util/graphviz.rs +++ b/src/librustc_mir/util/graphviz.rs @@ -15,8 +15,6 @@ use rustc::ty::TyCtxt; use std::fmt::Debug; use std::io::{self, Write}; -use rustc_data_structures::indexed_vec::Idx; - use super::pretty::dump_mir_def_ids; /// Write a graphviz DOT graph of a list of MIRs. diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 73c9af0d11c47..a72ee7ae3794c 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -1147,7 +1147,15 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { None => continue, }; - if binding.is_import() || binding.is_macro_def() { + // Don't reexport `uniform_path` canaries. + let non_canary_import = match binding.kind { + NameBindingKind::Import { directive, .. } => { + !directive.is_uniform_paths_canary + } + _ => false, + }; + + if non_canary_import || binding.is_macro_def() { let def = binding.def(); if def != Def::Err { if !def.def_id().is_local() { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 804aad3c0ecce..65dd71de1443f 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -25,10 +25,11 @@ use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable}; use rustc::ty::{GenericParamDef, GenericParamDefKind}; use rustc::ty::wf::object_region_bounds; use rustc_target::spec::abi; +use std::collections::BTreeSet; use std::slice; use require_c_abi_if_variadic; use util::common::ErrorReported; -use util::nodemap::{FxHashSet, FxHashMap}; +use util::nodemap::FxHashMap; use errors::{FatalError, DiagnosticId}; use lint; @@ -996,7 +997,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { return tcx.types.err; } - let mut associated_types = FxHashSet::default(); + // use a btreeset to keep output in a more consistent order + let mut associated_types = BTreeSet::default(); + for tr in traits::supertraits(tcx, principal) { associated_types.extend(tcx.associated_items(tr.def_id()) .filter(|item| item.kind == ty::AssociatedKind::Type) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index a45e5c8ec2a45..a1e4c85f82141 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1138,6 +1138,11 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, if let Some(panic_impl_did) = fcx.tcx.lang_items().panic_impl() { if panic_impl_did == fcx.tcx.hir.local_def_id(fn_id) { if let Some(panic_info_did) = fcx.tcx.lang_items().panic_info() { + // at this point we don't care if there are duplicate handlers or if the handler has + // the wrong signature as this value we'll be used when writing metadata and that + // only happens if compilation succeeded + fcx.tcx.sess.has_panic_handler.try_set_same(true); + if declared_ret_ty.sty != ty::Never { fcx.tcx.sess.span_err( decl.output.span(), diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs index fa152b386a825..5967bd1ba3eea 100644 --- a/src/librustc_typeck/check_unused.rs +++ b/src/librustc_typeck/check_unused.rs @@ -117,6 +117,7 @@ fn unused_crates_lint<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) { !tcx.is_compiler_builtins(cnum) && !tcx.is_panic_runtime(cnum) && !tcx.has_global_allocator(cnum) + && !tcx.has_panic_handler(cnum) }) .cloned() .collect(); diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs index 60bb5a0fec2cd..416be50bfe9ea 100644 --- a/src/libserialize/serialize.rs +++ b/src/libserialize/serialize.rs @@ -361,6 +361,18 @@ impl Decodable for u32 { } } +impl Encodable for ::std::num::NonZeroU32 { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + s.emit_u32(self.get()) + } +} + +impl Decodable for ::std::num::NonZeroU32 { + fn decode(d: &mut D) -> Result { + d.read_u32().map(|d| ::std::num::NonZeroU32::new(d).unwrap()) + } +} + impl Encodable for u64 { fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_u64(*self) @@ -895,3 +907,4 @@ impl Decodable for T { impl<'a, T: ?Sized + Encodable> UseSpecializedEncodable for &'a T {} impl UseSpecializedEncodable for Box {} impl UseSpecializedDecodable for Box {} + diff --git a/src/libstd/sys/unix/fd.rs b/src/libstd/sys/unix/fd.rs index 12e14734ff515..db2ea6b660a7a 100644 --- a/src/libstd/sys/unix/fd.rs +++ b/src/libstd/sys/unix/fd.rs @@ -11,7 +11,7 @@ #![unstable(reason = "not public", issue = "0", feature = "fd")] use cmp; -use io::{self, Read}; +use io::{self, Read, Initializer}; use libc::{self, c_int, c_void, ssize_t}; use mem; use sync::atomic::{AtomicBool, Ordering}; @@ -270,6 +270,11 @@ impl<'a> Read for &'a FileDesc { fn read(&mut self, buf: &mut [u8]) -> io::Result { (**self).read(buf) } + + #[inline] + unsafe fn initializer(&self) -> Initializer { + Initializer::nop() + } } impl AsInner for FileDesc { diff --git a/src/test/run-make-fulldeps/issue-53964/Makefile b/src/test/run-make-fulldeps/issue-53964/Makefile new file mode 100644 index 0000000000000..c56beb52fdd61 --- /dev/null +++ b/src/test/run-make-fulldeps/issue-53964/Makefile @@ -0,0 +1,5 @@ +-include ../tools.mk + +all: + $(RUSTC) panic.rs + $(RUSTC) -C panic=abort --emit=obj app.rs -L $(TMPDIR) diff --git a/src/test/run-make-fulldeps/issue-53964/app.rs b/src/test/run-make-fulldeps/issue-53964/app.rs new file mode 100644 index 0000000000000..8127b9578bfee --- /dev/null +++ b/src/test/run-make-fulldeps/issue-53964/app.rs @@ -0,0 +1,8 @@ +#![crate_type = "bin"] +#![no_main] +#![no_std] + +#![deny(unused_extern_crates)] + +// `panic` provides a `panic_handler` so it shouldn't trip the `unused_extern_crates` lint +extern crate panic; diff --git a/src/test/run-make-fulldeps/issue-53964/panic.rs b/src/test/run-make-fulldeps/issue-53964/panic.rs new file mode 100644 index 0000000000000..87c7b218822a0 --- /dev/null +++ b/src/test/run-make-fulldeps/issue-53964/panic.rs @@ -0,0 +1,20 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "lib"] +#![feature(panic_handler)] +#![no_std] + +use core::panic::PanicInfo; + +#[panic_handler] +fn panic(_: &PanicInfo) -> ! { + loop {} +} diff --git a/src/test/run-pass/uniform-paths/auxiliary/issue-53691.rs b/src/test/run-pass/uniform-paths/auxiliary/issue-53691.rs new file mode 100644 index 0000000000000..5845afd72fbe7 --- /dev/null +++ b/src/test/run-pass/uniform-paths/auxiliary/issue-53691.rs @@ -0,0 +1,19 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// edition:2018 + +#![feature(uniform_paths)] + +mod m { pub fn f() {} } +mod n { pub fn g() {} } + +pub use m::f; +pub use n::g; diff --git a/src/test/run-pass/uniform-paths/issue-53691.rs b/src/test/run-pass/uniform-paths/issue-53691.rs new file mode 100644 index 0000000000000..62be31d6b85fe --- /dev/null +++ b/src/test/run-pass/uniform-paths/issue-53691.rs @@ -0,0 +1,18 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:issue-53691.rs + +extern crate issue_53691; + +fn main() { + issue_53691::f(); + issue_53691::g(); +} diff --git a/src/test/ui/borrowck/borrowck-box-insensitivity.nll.stderr b/src/test/ui/borrowck/borrowck-box-insensitivity.nll.stderr index 601f05b499c75..0e380e90e7591 100644 --- a/src/test/ui/borrowck/borrowck-box-insensitivity.nll.stderr +++ b/src/test/ui/borrowck/borrowck-box-insensitivity.nll.stderr @@ -1,25 +1,14 @@ -error[E0382]: use of moved value: `a.y` - --> $DIR/borrowck-box-insensitivity.rs:46:14 - | -LL | let _x = a.x; - | --- value moved here -LL | //~^ value moved here -LL | let _y = a.y; //~ ERROR use of moved - | ^^^ value used here after move - | - = note: move occurs because `a.x` has type `std::boxed::Box`, which does not implement the `Copy` trait - -error[E0382]: use of moved value: `a.y` - --> $DIR/borrowck-box-insensitivity.rs:108:14 - | -LL | let _x = a.x.x; - | ----- value moved here -LL | //~^ value moved here -LL | let _y = a.y; //~ ERROR use of collaterally moved - | ^^^ value used here after move - | - = note: move occurs because `a.x.x` has type `std::boxed::Box`, which does not implement the `Copy` trait +error: compilation successful + --> $DIR/borrowck-box-insensitivity.rs:160:1 + | +LL | / fn main() { +LL | | copy_after_move(); +LL | | move_after_move(); +LL | | borrow_after_move(); +... | +LL | | mut_borrow_after_borrow_nested(); +LL | | } + | |_^ -error: aborting due to 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/borrowck/borrowck-box-insensitivity.rs b/src/test/ui/borrowck/borrowck-box-insensitivity.rs index 75bf6bce04b39..eabb8d7bca3fa 100644 --- a/src/test/ui/borrowck/borrowck-box-insensitivity.rs +++ b/src/test/ui/borrowck/borrowck-box-insensitivity.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(box_syntax)] +#![feature(box_syntax, rustc_attrs)] struct A { x: Box, @@ -156,6 +156,7 @@ fn mut_borrow_after_borrow_nested() { //~^ mutable borrow occurs here } +#[rustc_error] fn main() { copy_after_move(); move_after_move(); diff --git a/src/test/ui/removing-extern-crate.rs b/src/test/ui/removing-extern-crate.rs index 3905d285becb5..9762db38a1ca6 100644 --- a/src/test/ui/removing-extern-crate.rs +++ b/src/test/ui/removing-extern-crate.rs @@ -16,12 +16,12 @@ #![warn(rust_2018_idioms)] #![allow(unused_imports)] -extern crate std as foo; +extern crate removing_extern_crate as foo; extern crate core; mod another { - extern crate std as foo; - extern crate std; + extern crate removing_extern_crate as foo; + extern crate core; } fn main() {} diff --git a/src/test/ui/removing-extern-crate.stderr b/src/test/ui/removing-extern-crate.stderr index f2eed27a26693..758ec67d17823 100644 --- a/src/test/ui/removing-extern-crate.stderr +++ b/src/test/ui/removing-extern-crate.stderr @@ -1,8 +1,8 @@ warning: unused extern crate --> $DIR/removing-extern-crate.rs:19:1 | -LL | extern crate std as foo; - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it +LL | extern crate removing_extern_crate as foo; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it | note: lint level defined here --> $DIR/removing-extern-crate.rs:16:9 @@ -20,12 +20,12 @@ LL | extern crate core; warning: unused extern crate --> $DIR/removing-extern-crate.rs:23:5 | -LL | extern crate std as foo; - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it +LL | extern crate removing_extern_crate as foo; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it warning: unused extern crate --> $DIR/removing-extern-crate.rs:24:5 | -LL | extern crate std; - | ^^^^^^^^^^^^^^^^^ help: remove it +LL | extern crate core; + | ^^^^^^^^^^^^^^^^^^ help: remove it