diff --git a/Cargo.lock b/Cargo.lock index b651faac90281..392f3e8e4bdce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2877,6 +2877,7 @@ dependencies = [ "rustc_errors 0.0.0", "rustc_target 0.0.0", "serialize 0.0.0", + "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "syntax 0.0.0", "syntax_ext 0.0.0", diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 024594517d988..97c2d8e7a8e79 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -253,15 +253,16 @@ impl Box { #[unstable(feature = "ptr_internals", issue = "0", reason = "use into_raw_non_null instead")] #[inline] #[doc(hidden)] - pub fn into_unique(mut b: Box) -> Unique { + pub fn into_unique(b: Box) -> Unique { + let mut unique = b.0; + mem::forget(b); // Box is kind-of a library type, but recognized as a "unique pointer" by // Stacked Borrows. This function here corresponds to "reborrowing to // a raw pointer", but there is no actual reborrow here -- so // without some care, the pointer we are returning here still carries - // the `Uniq` tag. We round-trip through a mutable reference to avoid that. - let unique = unsafe { b.0.as_mut() as *mut T }; - mem::forget(b); - unsafe { Unique::new_unchecked(unique) } + // the tag of `b`, with `Unique` permission. + // We round-trip through a mutable reference to avoid that. + unsafe { Unique::new_unchecked(unique.as_mut() as *mut T) } } /// Consumes and leaks the `Box`, returning a mutable reference, diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index 545332bcd6a2f..3307bdf94f985 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -1,5 +1,3 @@ -#![cfg(not(miri))] - use std::borrow::Cow; use std::mem::size_of; use std::{usize, isize}; @@ -763,6 +761,7 @@ fn from_into_inner() { it.next().unwrap(); let vec = it.collect::>(); assert_eq!(vec, [2, 3]); + #[cfg(not(miri))] // Miri does not support comparing dangling pointers assert!(ptr != vec.as_ptr()); } @@ -971,6 +970,7 @@ fn test_reserve_exact() { } #[test] +#[cfg(not(miri))] // Miri does not support signalling OOM fn test_try_reserve() { // These are the interesting cases: @@ -1073,6 +1073,7 @@ fn test_try_reserve() { } #[test] +#[cfg(not(miri))] // Miri does not support signalling OOM fn test_try_reserve_exact() { // This is exactly the same as test_try_reserve with the method changed. diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 073d3ab593703..dc661a267e2a6 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -1094,7 +1094,7 @@ impl Vec { let count = (*other).len(); self.reserve(count); let len = self.len(); - ptr::copy_nonoverlapping(other as *const T, self.get_unchecked_mut(len), count); + ptr::copy_nonoverlapping(other as *const T, self.as_mut_ptr().add(len), count); self.len += count; } diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index ce5e5f23a94b8..d6bec816e4ee6 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -486,9 +486,31 @@ impl DroplessArena { } } + #[inline] + unsafe fn write_from_iter>( + &self, + mut iter: I, + len: usize, + mem: *mut T, + ) -> &mut [T] { + let mut i = 0; + // Use a manual loop since LLVM manages to optimize it better for + // slice iterators + loop { + let value = iter.next(); + if i >= len || value.is_none() { + // We only return as many items as the iterator gave us, even + // though it was supposed to give us `len` + return slice::from_raw_parts_mut(mem, i); + } + ptr::write(mem.offset(i as isize), value.unwrap()); + i += 1; + } + } + #[inline] pub fn alloc_from_iter>(&self, iter: I) -> &mut [T] { - let mut iter = iter.into_iter(); + let iter = iter.into_iter(); assert!(mem::size_of::() != 0); assert!(!mem::needs_drop::()); @@ -505,10 +527,7 @@ impl DroplessArena { let size = len.checked_mul(mem::size_of::()).unwrap(); let mem = self.alloc_raw(size, mem::align_of::()) as *mut _ as *mut T; unsafe { - for i in 0..len { - ptr::write(mem.offset(i as isize), iter.next().unwrap()) - } - slice::from_raw_parts_mut(mem, len) + self.write_from_iter(iter, len, mem) } } (_, _) => { diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs index b48d81f2ef8f4..c179b05683d1c 100644 --- a/src/librustc/arena.rs +++ b/src/librustc/arena.rs @@ -6,6 +6,15 @@ use std::cell::RefCell; use std::marker::PhantomData; use smallvec::SmallVec; +/// This declares a list of types which can be allocated by `Arena`. +/// +/// The `few` modifier will cause allocation to use the shared arena and recording the destructor. +/// This is faster and more memory efficient if there's only a few allocations of the type. +/// Leaving `few` out will cause the type to get its own dedicated `TypedArena` which is +/// faster and more memory efficient if there is lots of allocations. +/// +/// Specifying the `decode` modifier will add decode impls for &T and &[T] where T is the type +/// listed. These impls will appear in the implement_ty_decoder! macro. #[macro_export] macro_rules! arena_types { ($macro:path, $args:tt, $tcx:lifetime) => ( @@ -14,7 +23,7 @@ macro_rules! arena_types { rustc::hir::def_id::DefId, rustc::ty::subst::SubstsRef<$tcx> )>, - [few] mir_keys: rustc::util::nodemap::DefIdSet, + [few, decode] mir_keys: rustc::util::nodemap::DefIdSet, [decode] specialization_graph: rustc::traits::specialization_graph::Graph, [] region_scope_tree: rustc::middle::region::ScopeTree, [] item_local_set: rustc::util::nodemap::ItemLocalSet, @@ -58,6 +67,40 @@ macro_rules! arena_types { rustc::infer::canonical::Canonical<'tcx, rustc::infer::canonical::QueryResponse<'tcx, rustc::ty::Ty<'tcx>> >, + [few] crate_inherent_impls: rustc::ty::CrateInherentImpls, + [decode] borrowck: rustc::middle::borrowck::BorrowCheckResult, + [few] upstream_monomorphizations: + rustc::util::nodemap::DefIdMap< + rustc_data_structures::fx::FxHashMap< + rustc::ty::subst::SubstsRef<'tcx>, + rustc::hir::def_id::CrateNum + > + >, + [few] resolve_lifetimes: rustc::middle::resolve_lifetime::ResolveLifetimes, + [decode] generic_predicates: rustc::ty::GenericPredicates<'tcx>, + [few] lint_levels: rustc::lint::LintLevelMap, + [few] stability_index: rustc::middle::stability::Index<'tcx>, + [few] features: syntax::feature_gate::Features, + [few] all_traits: Vec, + [few] privacy_access_levels: rustc::middle::privacy::AccessLevels, + [few] target_features_whitelist: rustc_data_structures::fx::FxHashMap< + String, + Option + >, + [few] wasm_import_module_map: rustc_data_structures::fx::FxHashMap< + rustc::hir::def_id::DefId, + String + >, + [few] get_lib_features: rustc::middle::lib_features::LibFeatures, + [few] defined_lib_features: rustc::middle::lang_items::LanguageItems, + [few] visible_parent_map: rustc::util::nodemap::DefIdMap, + [few] foreign_module: rustc::middle::cstore::ForeignModule, + [few] foreign_modules: Vec, + [few] reachable_non_generics: rustc::util::nodemap::DefIdMap< + rustc::middle::exported_symbols::SymbolExportLevel + >, + [few] crate_variances: rustc::ty::CrateVariancesMap<'tcx>, + [few] inferred_outlives_crate: rustc::ty::CratePredicatesMap<'tcx>, ], $tcx); ) } @@ -119,7 +162,7 @@ pub trait ArenaAllocatable {} impl ArenaAllocatable for T {} -pub unsafe trait ArenaField<'tcx>: Sized { +unsafe trait ArenaField<'tcx>: Sized { /// Returns a specific arena to allocate from. /// If None is returned, the DropArena will be used. fn arena<'a>(arena: &'a Arena<'tcx>) -> Option<&'a TypedArena>; diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 512e4d434434c..c3afca35303c9 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -21,7 +21,7 @@ pub use self::Level::*; pub use self::LintSource::*; -use rustc_data_structures::sync::{self, Lrc}; +use rustc_data_structures::sync; use crate::hir::def_id::{CrateNum, LOCAL_CRATE}; use crate::hir::intravisit; @@ -35,7 +35,7 @@ use crate::util::nodemap::NodeMap; use errors::{DiagnosticBuilder, DiagnosticId}; use std::{hash, ptr}; use syntax::ast; -use syntax::source_map::{MultiSpan, ExpnFormat}; +use syntax::source_map::{MultiSpan, ExpnFormat, CompilerDesugaringKind}; use syntax::early_buffered_lints::BufferedEarlyLintId; use syntax::edition::Edition; use syntax::symbol::{Symbol, sym}; @@ -767,7 +767,7 @@ pub fn maybe_lint_level_root(tcx: TyCtxt<'_, '_, '_>, id: hir::HirId) -> bool { } fn lint_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cnum: CrateNum) - -> Lrc + -> &'tcx LintLevelMap { assert_eq!(cnum, LOCAL_CRATE); let mut builder = LintLevelMapBuilder { @@ -784,7 +784,7 @@ fn lint_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cnum: CrateNum) intravisit::walk_crate(&mut builder, krate); builder.levels.pop(push); - Lrc::new(builder.levels.build_map()) + tcx.arena.alloc(builder.levels.build_map()) } struct LintLevelMapBuilder<'a, 'tcx: 'a> { @@ -887,21 +887,22 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool { }; match info.format { - ExpnFormat::MacroAttribute(..) => return true, // definitely a plugin - ExpnFormat::CompilerDesugaring(_) => return true, // well, it's "external" - ExpnFormat::MacroBang(..) => {} // check below - } - - let def_site = match info.def_site { - Some(span) => span, - // no span for the def_site means it's an external macro - None => return true, - }; + ExpnFormat::MacroAttribute(..) => true, // definitely a plugin + ExpnFormat::CompilerDesugaring(CompilerDesugaringKind::ForLoop) => false, + ExpnFormat::CompilerDesugaring(_) => true, // well, it's "external" + ExpnFormat::MacroBang(..) => { + let def_site = match info.def_site { + Some(span) => span, + // no span for the def_site means it's an external macro + None => return true, + }; - match sess.source_map().span_to_snippet(def_site) { - Ok(code) => !code.starts_with("macro_rules"), - // no snippet = external macro or compiler-builtin expansion - Err(_) => true, + match sess.source_map().span_to_snippet(def_site) { + Ok(code) => !code.starts_with("macro_rules"), + // no snippet = external macro or compiler-builtin expansion + Err(_) => true, + } + } } } diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index d22de6c647699..6f9abcd624f99 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -256,8 +256,8 @@ pub fn used_crates(tcx: TyCtxt<'_, '_, '_>, prefer: LinkagePreference) Some((cnum, path)) }) .collect::>(); - let mut ordering = tcx.postorder_cnums(LOCAL_CRATE); - Lrc::make_mut(&mut ordering).reverse(); + let mut ordering = tcx.postorder_cnums(LOCAL_CRATE).to_owned(); + ordering.reverse(); libs.sort_by_cached_key(|&(a, _)| { ordering.iter().position(|x| *x == a) }); diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 419cc5936862c..775da1de313fa 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -15,7 +15,6 @@ use crate::rustc::lint; use crate::session::Session; use crate::util::nodemap::{DefIdMap, FxHashMap, FxHashSet, HirIdMap, HirIdSet}; use errors::{Applicability, DiagnosticBuilder}; -use rustc_data_structures::sync::Lrc; use rustc_macros::HashStable; use std::borrow::Cow; use std::cell::Cell; @@ -211,10 +210,10 @@ struct NamedRegionMap { /// See [`NamedRegionMap`]. #[derive(Default)] pub struct ResolveLifetimes { - defs: FxHashMap>>, - late_bound: FxHashMap>>, + defs: FxHashMap>, + late_bound: FxHashMap>, object_lifetime_defaults: - FxHashMap>>>>, + FxHashMap>>, } impl_stable_hash_for!(struct crate::middle::resolve_lifetime::ResolveLifetimes { @@ -347,7 +346,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { named_region_map: |tcx, id| { let id = LocalDefId::from_def_id(DefId::local(id)); // (*) - tcx.resolve_lifetimes(LOCAL_CRATE).defs.get(&id).cloned() + tcx.resolve_lifetimes(LOCAL_CRATE).defs.get(&id) }, is_late_bound_map: |tcx, id| { @@ -355,7 +354,6 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { tcx.resolve_lifetimes(LOCAL_CRATE) .late_bound .get(&id) - .cloned() }, object_lifetime_defaults_map: |tcx, id| { @@ -363,7 +361,6 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { tcx.resolve_lifetimes(LOCAL_CRATE) .object_lifetime_defaults .get(&id) - .cloned() }, ..*providers @@ -379,7 +376,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { fn resolve_lifetimes<'tcx>( tcx: TyCtxt<'_, 'tcx, 'tcx>, for_krate: CrateNum, -) -> Lrc { +) -> &'tcx ResolveLifetimes { assert_eq!(for_krate, LOCAL_CRATE); let named_region_map = krate(tcx); @@ -388,24 +385,22 @@ fn resolve_lifetimes<'tcx>( for (hir_id, v) in named_region_map.defs { let map = rl.defs.entry(hir_id.owner_local_def_id()).or_default(); - Lrc::get_mut(map).unwrap().insert(hir_id.local_id, v); + map.insert(hir_id.local_id, v); } for hir_id in named_region_map.late_bound { let map = rl.late_bound .entry(hir_id.owner_local_def_id()) .or_default(); - Lrc::get_mut(map).unwrap().insert(hir_id.local_id); + map.insert(hir_id.local_id); } for (hir_id, v) in named_region_map.object_lifetime_defaults { let map = rl.object_lifetime_defaults .entry(hir_id.owner_local_def_id()) .or_default(); - Lrc::get_mut(map) - .unwrap() - .insert(hir_id.local_id, Lrc::new(v)); + map.insert(hir_id.local_id, v); } - Lrc::new(rl) + tcx.arena.alloc(rl) } fn krate<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> NamedRegionMap { diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index abcf164cda6d4..ac0e99137cbc3 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -883,7 +883,7 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { remaining_lib_features.remove(&Symbol::intern("test")); let check_features = - |remaining_lib_features: &mut FxHashMap<_, _>, defined_features: &Vec<_>| { + |remaining_lib_features: &mut FxHashMap<_, _>, defined_features: &[_]| { for &(feature, since) in defined_features { if let Some(since) = since { if let Some(span) = remaining_lib_features.get(&feature) { @@ -908,7 +908,7 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { if remaining_lib_features.is_empty() { break; } - check_features(&mut remaining_lib_features, &tcx.defined_lib_features(cnum)); + check_features(&mut remaining_lib_features, tcx.defined_lib_features(cnum)); } } diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 8825c94cdb81c..c03cd7e268ef5 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -61,13 +61,13 @@ rustc_queries! { /// predicate gets in the way of some checks, which are intended /// to operate over only the actual where-clauses written by the /// user.) - query predicates_of(_: DefId) -> Lrc> {} + query predicates_of(_: DefId) -> &'tcx ty::GenericPredicates<'tcx> {} query native_libraries(_: CrateNum) -> Lrc> { desc { "looking up the native libraries of a linked crate" } } - query lint_levels(_: CrateNum) -> Lrc { + query lint_levels(_: CrateNum) -> &'tcx lint::LintLevelMap { eval_always desc { "computing the lint levels for items in this crate" } } @@ -155,7 +155,7 @@ rustc_queries! { } Linking { - query wasm_import_module_map(_: CrateNum) -> Lrc> { + query wasm_import_module_map(_: CrateNum) -> &'tcx FxHashMap { desc { "wasm import module map" } } } @@ -166,11 +166,11 @@ rustc_queries! { /// equal to the `explicit_predicates_of` predicates plus the /// `inferred_outlives_of` predicates. query predicates_defined_on(_: DefId) - -> Lrc> {} + -> &'tcx ty::GenericPredicates<'tcx> {} /// Returns the predicates written explicitly by the user. query explicit_predicates_of(_: DefId) - -> Lrc> {} + -> &'tcx ty::GenericPredicates<'tcx> {} /// Returns the inferred outlives predicates (e.g., for `struct /// Foo<'a, T> { x: &'a T }`, this would return `T: 'a`). @@ -182,14 +182,14 @@ rustc_queries! { /// evaluate them even during type conversion, often before the /// full predicates are available (note that supertraits have /// additional acyclicity requirements). - query super_predicates_of(key: DefId) -> Lrc> { + query super_predicates_of(key: DefId) -> &'tcx ty::GenericPredicates<'tcx> { desc { |tcx| "computing the supertraits of `{}`", tcx.def_path_str(key) } } /// To avoid cycles within the predicates of a single item we compute /// per-type-parameter predicates for resolving `T::AssocTy`. query type_param_predicates(key: (DefId, DefId)) - -> Lrc> { + -> &'tcx ty::GenericPredicates<'tcx> { no_force desc { |tcx| "computing the bounds for type parameter `{}`", { let id = tcx.hir().as_local_hir_id(key.1).unwrap(); @@ -244,7 +244,7 @@ rustc_queries! { query static_mutability(_: DefId) -> Option {} /// Gets a map with the variance of every item; use `item_variance` instead. - query crate_variances(_: CrateNum) -> Lrc> { + query crate_variances(_: CrateNum) -> &'tcx ty::CrateVariancesMap<'tcx> { desc { "computing the variances for items in this crate" } } @@ -255,14 +255,14 @@ rustc_queries! { TypeChecking { /// Maps from thee `DefId` of a type to its (inferred) outlives. query inferred_outlives_crate(_: CrateNum) - -> Lrc> { + -> &'tcx ty::CratePredicatesMap<'tcx> { desc { "computing the inferred outlives predicates for items in this crate" } } } Other { /// Maps from an impl/trait `DefId to a list of the `DefId`s of its items. - query associated_item_def_ids(_: DefId) -> Lrc> {} + query associated_item_def_ids(_: DefId) -> &'tcx [DefId] {} /// Maps from a trait item to the trait item "descriptor". query associated_item(_: DefId) -> ty::AssociatedItem {} @@ -277,7 +277,7 @@ rustc_queries! { /// Maps a `DefId` of a type to a list of its inherent impls. /// Contains implementations of methods that are inherent to a type. /// Methods in these implementations don't need to be exported. - query inherent_impls(_: DefId) -> Lrc> { + query inherent_impls(_: DefId) -> &'tcx [DefId] { eval_always } } @@ -359,7 +359,7 @@ rustc_queries! { } Other { - query used_trait_imports(_: DefId) -> Lrc {} + query used_trait_imports(_: DefId) -> &'tcx DefIdSet {} } TypeChecking { @@ -371,7 +371,7 @@ rustc_queries! { } BorrowChecking { - query borrowck(_: DefId) -> Lrc {} + query borrowck(_: DefId) -> &'tcx BorrowCheckResult {} /// Borrow-checks the function body. If this is a closure, returns /// additional requirements that the closure's creator must verify. @@ -383,7 +383,7 @@ rustc_queries! { /// Not meant to be used directly outside of coherence. /// (Defined only for `LOCAL_CRATE`.) query crate_inherent_impls(k: CrateNum) - -> Lrc { + -> &'tcx CrateInherentImpls { eval_always desc { "all inherent impls defined in crate `{:?}`", k } } @@ -437,7 +437,7 @@ rustc_queries! { query check_match(_: DefId) -> () {} /// Performs part of the privacy check and computes "access levels". - query privacy_access_levels(_: CrateNum) -> Lrc { + query privacy_access_levels(_: CrateNum) -> &'tcx AccessLevels { eval_always desc { "privacy access levels" } } @@ -590,7 +590,7 @@ rustc_queries! { Other { query dylib_dependency_formats(_: CrateNum) - -> Lrc> { + -> &'tcx [(CrateNum, LinkagePreference)] { desc { "dylib dependency formats of crate" } } } @@ -625,7 +625,7 @@ rustc_queries! { desc { "test whether a crate has #![no_builtins]" } } - query extern_crate(_: DefId) -> Lrc> { + query extern_crate(_: DefId) -> Option<&'tcx ExternCrate> { eval_always desc { "getting crate's ExternCrateData" } } @@ -637,14 +637,14 @@ rustc_queries! { desc { "computing whether impls specialize one another" } } query in_scope_traits_map(_: DefIndex) - -> Option>>>> { + -> Option<&'tcx FxHashMap>> { eval_always desc { "traits in scope at a block" } } } Other { - query module_exports(_: DefId) -> Option>>> { + query module_exports(_: DefId) -> Option<&'tcx [Export]> { eval_always } } @@ -671,7 +671,7 @@ rustc_queries! { // Does not include external symbols that don't have a corresponding DefId, // like the compiler-generated `main` function and so on. query reachable_non_generics(_: CrateNum) - -> Lrc> { + -> &'tcx DefIdMap { desc { "looking up the exported symbols of a crate" } } query is_reachable_non_generic(_: DefId) -> bool {} @@ -681,15 +681,15 @@ rustc_queries! { Codegen { query upstream_monomorphizations( k: CrateNum - ) -> Lrc, CrateNum>>>> { + ) -> &'tcx DefIdMap, CrateNum>> { desc { "collecting available upstream monomorphizations `{:?}`", k } } query upstream_monomorphizations_for(_: DefId) - -> Option, CrateNum>>> {} + -> Option<&'tcx FxHashMap, CrateNum>> {} } Other { - query foreign_modules(_: CrateNum) -> Lrc> { + query foreign_modules(_: CrateNum) -> &'tcx [ForeignModule] { desc { "looking up the foreign modules of a linked crate" } } @@ -724,19 +724,19 @@ rustc_queries! { TypeChecking { query implementations_of_trait(_: (CrateNum, DefId)) - -> Lrc> { + -> &'tcx [DefId] { no_force desc { "looking up implementations of a trait in a crate" } } query all_trait_implementations(_: CrateNum) - -> Lrc> { + -> &'tcx [DefId] { desc { "looking up all (?) trait implementations" } } } Other { query dllimport_foreign_items(_: CrateNum) - -> Lrc> { + -> &'tcx FxHashSet { desc { "dllimport_foreign_items" } } query is_dllimport_foreign_item(_: DefId) -> bool {} @@ -754,19 +754,19 @@ rustc_queries! { BorrowChecking { // Lifetime resolution. See `middle::resolve_lifetimes`. - query resolve_lifetimes(_: CrateNum) -> Lrc { + query resolve_lifetimes(_: CrateNum) -> &'tcx ResolveLifetimes { desc { "resolving lifetimes" } } query named_region_map(_: DefIndex) -> - Option>> { + Option<&'tcx FxHashMap> { desc { "looking up a named region" } } query is_late_bound_map(_: DefIndex) -> - Option>> { + Option<&'tcx FxHashSet> { desc { "testing if a region is late bound" } } query object_lifetime_defaults_map(_: DefIndex) - -> Option>>>> { + -> Option<&'tcx FxHashMap>> { desc { "looking up lifetime defaults for a region" } } } @@ -784,29 +784,29 @@ rustc_queries! { eval_always desc { "fetching what a crate is named" } } - query item_children(_: DefId) -> Lrc>> {} + query item_children(_: DefId) -> &'tcx [Export] {} query extern_mod_stmt_cnum(_: DefId) -> Option {} - query get_lib_features(_: CrateNum) -> Lrc { + query get_lib_features(_: CrateNum) -> &'tcx LibFeatures { eval_always desc { "calculating the lib features map" } } query defined_lib_features(_: CrateNum) - -> Lrc)>> { + -> &'tcx [(Symbol, Option)] { desc { "calculating the lib features defined in a crate" } } - query get_lang_items(_: CrateNum) -> Lrc { + query get_lang_items(_: CrateNum) -> &'tcx LanguageItems { eval_always desc { "calculating the lang items map" } } - query defined_lang_items(_: CrateNum) -> Lrc> { + query defined_lang_items(_: CrateNum) -> &'tcx [(DefId, usize)] { desc { "calculating the lang items defined in a crate" } } - query missing_lang_items(_: CrateNum) -> Lrc> { + query missing_lang_items(_: CrateNum) -> &'tcx [LangItem] { desc { "calculating the missing lang items in a crate" } } query visible_parent_map(_: CrateNum) - -> Lrc> { + -> &'tcx DefIdMap { desc { "calculating the visible parent map" } } query missing_extern_crate_item(_: CrateNum) -> bool { @@ -817,19 +817,19 @@ rustc_queries! { eval_always desc { "looking at the source for a crate" } } - query postorder_cnums(_: CrateNum) -> Lrc> { + query postorder_cnums(_: CrateNum) -> &'tcx [CrateNum] { eval_always desc { "generating a postorder list of CrateNums" } } - query upvars(_: DefId) -> Option>> { + query upvars(_: DefId) -> Option<&'tcx [hir::Upvar]> { eval_always } query maybe_unused_trait_import(_: DefId) -> bool { eval_always } query maybe_unused_extern_crates(_: CrateNum) - -> Lrc> { + -> &'tcx [(DefId, Span)] { eval_always desc { "looking up all possibly unused extern crates" } } @@ -838,11 +838,11 @@ rustc_queries! { eval_always } - query stability_index(_: CrateNum) -> Lrc> { + query stability_index(_: CrateNum) -> &'tcx stability::Index<'tcx> { eval_always desc { "calculating the stability index for the local crate" } } - query all_crate_nums(_: CrateNum) -> Lrc> { + query all_crate_nums(_: CrateNum) -> &'tcx [CrateNum] { eval_always desc { "fetching all foreign CrateNum instances" } } @@ -850,7 +850,7 @@ rustc_queries! { /// A vector of every trait accessible in the whole crate /// (i.e., including those from subcrates). This is used only for /// error reporting. - query all_traits(_: CrateNum) -> Lrc> { + query all_traits(_: CrateNum) -> &'tcx [DefId] { desc { "fetching all foreign and local traits" } } } @@ -1050,7 +1050,7 @@ rustc_queries! { } Other { - query target_features_whitelist(_: CrateNum) -> Lrc>> { + query target_features_whitelist(_: CrateNum) -> &'tcx FxHashMap> { eval_always desc { "looking up the whitelist of target features" } } @@ -1062,7 +1062,7 @@ rustc_queries! { desc { |tcx| "estimating size for `{}`", tcx.def_path_str(def.def_id()) } } - query features_query(_: CrateNum) -> Lrc { + query features_query(_: CrateNum) -> &'tcx feature_gate::Features { eval_always desc { "looking up enabled feature gates" } } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index b5a17684c0ff2..d83b2ce842a88 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -201,6 +201,10 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> { } } +pub struct Common<'tcx> { + pub empty_predicates: ty::GenericPredicates<'tcx>, +} + pub struct CommonTypes<'tcx> { pub unit: Ty<'tcx>, pub bool: Ty<'tcx>, @@ -1045,6 +1049,9 @@ pub struct GlobalCtxt<'tcx> { pub dep_graph: DepGraph, + /// Common objects. + pub common: Common<'tcx>, + /// Common types, pre-interned for your convenience. pub types: CommonTypes<'tcx>, @@ -1057,11 +1064,11 @@ pub struct GlobalCtxt<'tcx> { /// Map indicating what traits are in scope for places where this /// is relevant; generated by resolve. trait_map: FxHashMap>>>>, + FxHashMap>>, /// Export map produced by name resolution. - export_map: FxHashMap>>>, + export_map: FxHashMap>>, hir_map: hir_map::Map<'tcx>, @@ -1074,7 +1081,7 @@ pub struct GlobalCtxt<'tcx> { // Records the captured variables referenced by every closure // expression. Do not track deps for this, just recompute it from // scratch every time. - upvars: FxHashMap>>, + upvars: FxHashMap>, maybe_unused_trait_imports: FxHashSet, maybe_unused_extern_crates: Vec<(DefId, Span)>, @@ -1252,6 +1259,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { s.fatal(&err); }); let interners = CtxtInterners::new(&arenas.interner); + let common = Common { + empty_predicates: ty::GenericPredicates { + parent: None, + predicates: vec![], + }, + }; let common_types = CommonTypes::new(&interners); let common_lifetimes = CommonLifetimes::new(&interners); let common_consts = CommonConsts::new(&interners, &common_types); @@ -1292,13 +1305,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { None }; - let mut trait_map: FxHashMap<_, Lrc>> = FxHashMap::default(); + let mut trait_map: FxHashMap<_, FxHashMap<_, _>> = FxHashMap::default(); for (k, v) in resolutions.trait_map { let hir_id = hir.node_to_hir_id(k); let map = trait_map.entry(hir_id.owner).or_default(); - Lrc::get_mut(map).unwrap() - .insert(hir_id.local_id, - Lrc::new(StableVec::new(v))); + map.insert(hir_id.local_id, StableVec::new(v)); } GlobalCtxt { @@ -1308,6 +1319,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { global_arenas: &arenas.global, global_interners: interners, dep_graph, + common, types: common_types, lifetimes: common_lifetimes, consts: common_consts, @@ -1316,13 +1328,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let exports: Vec<_> = v.into_iter().map(|e| { e.map_id(|id| hir.node_to_hir_id(id)) }).collect(); - (k, Lrc::new(exports)) + (k, exports) }).collect(), upvars: resolutions.upvars.into_iter().map(|(k, v)| { let vars: Vec<_> = v.into_iter().map(|e| { e.map_id(|id| hir.node_to_hir_id(id)) }).collect(); - (hir.local_def_id(k), Lrc::new(vars)) + (hir.local_def_id(k), vars) }).collect(), maybe_unused_trait_imports: resolutions.maybe_unused_trait_imports @@ -1364,11 +1376,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.sess.consider_optimizing(&cname, msg) } - pub fn lib_features(self) -> Lrc { + pub fn lib_features(self) -> &'gcx middle::lib_features::LibFeatures { self.get_lib_features(LOCAL_CRATE) } - pub fn lang_items(self) -> Lrc { + pub fn lang_items(self) -> &'gcx middle::lang_items::LanguageItems { self.get_lang_items(LOCAL_CRATE) } @@ -1406,15 +1418,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { else { None } } - pub fn stability(self) -> Lrc> { + pub fn stability(self) -> &'gcx stability::Index<'gcx> { self.stability_index(LOCAL_CRATE) } - pub fn crates(self) -> Lrc> { + pub fn crates(self) -> &'gcx [CrateNum] { self.all_crate_nums(LOCAL_CRATE) } - pub fn features(self) -> Lrc { + pub fn features(self) -> &'gcx feature_gate::Features { self.features_query(LOCAL_CRATE) } @@ -2965,9 +2977,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { lint::struct_lint_level(self.sess, lint, level, src, None, msg) } - pub fn in_scope_traits(self, id: HirId) -> Option>> { + pub fn in_scope_traits(self, id: HirId) -> Option<&'gcx StableVec> { self.in_scope_traits_map(id.owner) - .and_then(|map| map.get(&id.local_id).cloned()) + .and_then(|map| map.get(&id.local_id)) } pub fn named_region(self, id: HirId) -> Option { @@ -2982,10 +2994,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } pub fn object_lifetime_defaults(self, id: HirId) - -> Option>> + -> Option<&'gcx [ObjectLifetimeDefault]> { self.object_lifetime_defaults_map(id.owner) - .and_then(|map| map.get(&id.local_id).cloned()) + .and_then(|map| map.get(&id.local_id).map(|v| &**v)) } } @@ -3040,27 +3052,27 @@ fn ptr_eq(t: *const T, u: *const U) -> bool { } pub fn provide(providers: &mut ty::query::Providers<'_>) { - providers.in_scope_traits_map = |tcx, id| tcx.gcx.trait_map.get(&id).cloned(); - providers.module_exports = |tcx, id| tcx.gcx.export_map.get(&id).cloned(); + providers.in_scope_traits_map = |tcx, id| tcx.gcx.trait_map.get(&id); + providers.module_exports = |tcx, id| tcx.gcx.export_map.get(&id).map(|v| &v[..]); providers.crate_name = |tcx, id| { assert_eq!(id, LOCAL_CRATE); tcx.crate_name }; providers.get_lib_features = |tcx, id| { assert_eq!(id, LOCAL_CRATE); - Lrc::new(middle::lib_features::collect(tcx)) + tcx.arena.alloc(middle::lib_features::collect(tcx)) }; providers.get_lang_items = |tcx, id| { assert_eq!(id, LOCAL_CRATE); - Lrc::new(middle::lang_items::collect(tcx)) + tcx.arena.alloc(middle::lang_items::collect(tcx)) }; - providers.upvars = |tcx, id| tcx.gcx.upvars.get(&id).cloned(); + providers.upvars = |tcx, id| tcx.gcx.upvars.get(&id).map(|v| &v[..]); providers.maybe_unused_trait_import = |tcx, id| { tcx.maybe_unused_trait_imports.contains(&id) }; providers.maybe_unused_extern_crates = |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); - Lrc::new(tcx.maybe_unused_extern_crates.clone()) + &tcx.maybe_unused_extern_crates[..] }; providers.names_imported_by_glob_use = |tcx, id| { assert_eq!(id.krate, LOCAL_CRATE); @@ -3069,7 +3081,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { providers.stability_index = |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); - Lrc::new(stability::Index::new(tcx)) + tcx.arena.alloc(stability::Index::new(tcx)) }; providers.lookup_stability = |tcx, id| { assert_eq!(id.krate, LOCAL_CRATE); @@ -3087,11 +3099,11 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { }; providers.all_crate_nums = |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); - Lrc::new(tcx.cstore.crates_untracked()) + tcx.arena.alloc_slice(&tcx.cstore.crates_untracked()) }; providers.postorder_cnums = |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); - Lrc::new(tcx.cstore.postorder_cnums_untracked()) + tcx.arena.alloc_slice(&tcx.cstore.postorder_cnums_untracked()) }; providers.output_filenames = |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); @@ -3099,7 +3111,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { }; providers.features_query = |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); - Lrc::new(tcx.sess.features_untracked().clone()) + tcx.arena.alloc(tcx.sess.features_untracked().clone()) }; providers.is_panic_runtime = |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index a2c89489b95dc..99c3293168754 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2298,7 +2298,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { } #[inline] - pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Lrc> { + pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> &'tcx GenericPredicates<'gcx> { tcx.predicates_of(self.did) } @@ -3106,7 +3106,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub struct AssociatedItemsIterator<'a, 'gcx: 'tcx, 'tcx: 'a> { tcx: TyCtxt<'a, 'gcx, 'tcx>, - def_ids: Lrc>, + def_ids: &'gcx [DefId], next_index: usize, } @@ -3183,26 +3183,27 @@ fn adt_sized_constraint<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn associated_item_def_ids<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) - -> Lrc> { + -> &'tcx [DefId] { let id = tcx.hir().as_local_hir_id(def_id).unwrap(); let item = tcx.hir().expect_item_by_hir_id(id); - let vec: Vec<_> = match item.node { + match item.node { hir::ItemKind::Trait(.., ref trait_item_refs) => { - trait_item_refs.iter() - .map(|trait_item_ref| trait_item_ref.id) - .map(|id| tcx.hir().local_def_id_from_hir_id(id.hir_id)) - .collect() + tcx.arena.alloc_from_iter( + trait_item_refs.iter() + .map(|trait_item_ref| trait_item_ref.id) + .map(|id| tcx.hir().local_def_id_from_hir_id(id.hir_id)) + ) } hir::ItemKind::Impl(.., ref impl_item_refs) => { - impl_item_refs.iter() - .map(|impl_item_ref| impl_item_ref.id) - .map(|id| tcx.hir().local_def_id_from_hir_id(id.hir_id)) - .collect() + tcx.arena.alloc_from_iter( + impl_item_refs.iter() + .map(|impl_item_ref| impl_item_ref.id) + .map(|id| tcx.hir().local_def_id_from_hir_id(id.hir_id)) + ) } - hir::ItemKind::TraitAlias(..) => vec![], + hir::ItemKind::TraitAlias(..) => &[], _ => span_bug!(item.span, "associated_item_def_ids: not impl or trait") - }; - Lrc::new(vec) + } } fn def_span<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Span { @@ -3388,7 +3389,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { /// (constructing this map requires touching the entire crate). #[derive(Clone, Debug, Default, HashStable)] pub struct CrateInherentImpls { - pub inherent_impls: DefIdMap>>, + pub inherent_impls: DefIdMap>, } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable)] diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index 7a8d5d3bb9a67..06db4b9b65bca 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -253,8 +253,8 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>: // 2. for an extern inferred from a path or an indirect crate, // where there is no explicit `extern crate`, we just prepend // the crate name. - match *self.tcx().extern_crate(def_id) { - Some(ExternCrate { + match self.tcx().extern_crate(def_id) { + Some(&ExternCrate { src: ExternCrateSource::Extern(def_id), direct: true, span, diff --git a/src/librustc/ty/query/values.rs b/src/librustc/ty/query/values.rs index 2fb318a47befd..01d431b0ef0e7 100644 --- a/src/librustc/ty/query/values.rs +++ b/src/librustc/ty/query/values.rs @@ -14,12 +14,6 @@ impl<'tcx, T> Value<'tcx> for T { } } -impl<'tcx, T: Default> Value<'tcx> for T { - default fn from_cycle_error<'a>(_: TyCtxt<'a, 'tcx, 'tcx>) -> T { - T::default() - } -} - impl<'tcx> Value<'tcx> for Ty<'tcx> { fn from_cycle_error<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> { tcx.types.err diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 65a550b1b8914..7dca47485bb92 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -32,7 +32,6 @@ use std::borrow::Cow; use std::cell::{Cell, RefCell}; use std::fmt; use std::rc::Rc; -use rustc_data_structures::sync::Lrc; use std::hash::{Hash, Hasher}; use syntax::source_map::CompilerDesugaringKind; use syntax_pos::{MultiSpan, Span}; @@ -75,7 +74,7 @@ pub struct AnalysisData<'a, 'tcx: 'a> { } fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) - -> Lrc + -> &'tcx BorrowCheckResult { assert!(tcx.use_ast_borrowck() || tcx.migrate_borrowck()); @@ -89,7 +88,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) // those things (notably the synthesized constructors from // tuple structs/variants) do not have an associated body // and do not need borrowchecking. - return Lrc::new(BorrowCheckResult { + return tcx.arena.alloc(BorrowCheckResult { used_mut_nodes: Default::default(), signalled_any_error: SignalledError::NoErrorsSeen, }) @@ -136,7 +135,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) check_loans::check_loans(&mut bccx, &loan_dfcx, &flowed_moves, &all_loans, body); } - Lrc::new(BorrowCheckResult { + tcx.arena.alloc(BorrowCheckResult { used_mut_nodes: bccx.used_mut_nodes.into_inner(), signalled_any_error: bccx.signalled_any_error.into_inner(), }) diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index f26684d9ef04a..9d0e7dde34d13 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/src/librustc_codegen_llvm/attributes.rs @@ -10,7 +10,6 @@ use rustc::ty::{self, TyCtxt, PolyFnSig}; use rustc::ty::layout::HasTyCtxt; use rustc::ty::query::Providers; use rustc_data_structures::small_c_str::SmallCStr; -use rustc_data_structures::sync::Lrc; use rustc_data_structures::fx::FxHashMap; use rustc_target::spec::PanicStrategy; use rustc_codegen_ssa::traits::*; @@ -320,11 +319,11 @@ pub fn provide(providers: &mut Providers<'_>) { if tcx.sess.opts.actually_rustdoc { // rustdoc needs to be able to document functions that use all the features, so // whitelist them all - Lrc::new(llvm_util::all_known_features() + tcx.arena.alloc(llvm_util::all_known_features() .map(|(a, b)| (a.to_string(), b)) .collect()) } else { - Lrc::new(llvm_util::target_feature_whitelist(tcx.sess) + tcx.arena.alloc(llvm_util::target_feature_whitelist(tcx.sess) .iter() .map(|&(a, b)| (a.to_string(), b)) .collect()) @@ -364,7 +363,7 @@ pub fn provide_extern(providers: &mut Providers<'_>) { })); } - Lrc::new(ret) + tcx.arena.alloc(ret) }; } diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index a55f783df43a3..fb7ef87646296 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -1,4 +1,3 @@ -use rustc_data_structures::sync::Lrc; use std::sync::Arc; use rustc::ty::Instance; @@ -49,12 +48,12 @@ pub fn crates_export_threshold(crate_types: &[config::CrateType]) -> SymbolExpor fn reachable_non_generics_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cnum: CrateNum) - -> Lrc> + -> &'tcx DefIdMap { assert_eq!(cnum, LOCAL_CRATE); if !tcx.sess.opts.output_types.should_codegen() { - return Default::default(); + return tcx.arena.alloc(Default::default()); } // Check to see if this crate is a "special runtime crate". These @@ -155,7 +154,7 @@ fn reachable_non_generics_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, reachable_non_generics.insert(id, SymbolExportLevel::C); } - Lrc::new(reachable_non_generics) + tcx.arena.alloc(reachable_non_generics) } fn is_reachable_non_generic_provider_local<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -282,7 +281,7 @@ fn exported_symbols_provider_local<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn upstream_monomorphizations_provider<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, cnum: CrateNum) - -> Lrc, CrateNum>>>> + -> &'tcx DefIdMap, CrateNum>> { debug_assert!(cnum == LOCAL_CRATE); @@ -326,20 +325,16 @@ fn upstream_monomorphizations_provider<'a, 'tcx>( } } - Lrc::new(instances.into_iter() - .map(|(key, value)| (key, Lrc::new(value))) - .collect()) + tcx.arena.alloc(instances) } fn upstream_monomorphizations_for_provider<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) - -> Option, CrateNum>>> + -> Option<&'tcx FxHashMap, CrateNum>> { debug_assert!(!def_id.is_local()); - tcx.upstream_monomorphizations(LOCAL_CRATE) - .get(&def_id) - .cloned() + tcx.upstream_monomorphizations(LOCAL_CRATE).get(&def_id) } fn is_unreachable_local_definition_provider(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> bool { diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index 3cd47dfbb29fb..0b037f872475d 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -33,7 +33,6 @@ use rustc_mir::monomorphize::Instance; use rustc_mir::monomorphize::partitioning::{CodegenUnit, CodegenUnitExt}; use rustc::util::nodemap::FxHashMap; use rustc_data_structures::indexed_vec::Idx; -use rustc_data_structures::sync::Lrc; use rustc_codegen_utils::{symbol_names_test, check_for_rustc_errors_attr}; use rustc::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA}; use crate::mir::place::PlaceRef; @@ -916,7 +915,7 @@ pub fn provide_both(providers: &mut Providers<'_>) { .map(|id| &module_map[&id]) .flat_map(|module| module.foreign_items.iter().cloned()) .collect(); - Lrc::new(dllimports) + tcx.arena.alloc(dllimports) }; providers.is_dllimport_foreign_item = |tcx, def_id| { diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml index e234f4f880703..76aba33b6a404 100644 --- a/src/librustc_metadata/Cargo.toml +++ b/src/librustc_metadata/Cargo.toml @@ -13,6 +13,7 @@ crate-type = ["dylib"] flate2 = "1.0" log = "0.4" memmap = "0.6" +smallvec = { version = "0.6.7", features = ["union", "may_dangle"] } rustc = { path = "../librustc" } rustc_data_structures = { path = "../librustc_data_structures" } errors = { path = "../librustc_errors", package = "rustc_errors" } diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 49f93c4014dc0..fae4c244d6e14 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -21,6 +21,7 @@ use rustc::hir::map::definitions::DefPathTable; use rustc::util::nodemap::DefIdMap; use rustc_data_structures::svh::Svh; +use smallvec::SmallVec; use std::any::Any; use rustc_data_structures::sync::Lrc; use std::sync::Arc; @@ -95,9 +96,11 @@ provide! { <'tcx> tcx, def_id, other, cdata, generics_of => { tcx.alloc_generics(cdata.get_generics(def_id.index, tcx.sess)) } - predicates_of => { Lrc::new(cdata.get_predicates(def_id.index, tcx)) } - predicates_defined_on => { Lrc::new(cdata.get_predicates_defined_on(def_id.index, tcx)) } - super_predicates_of => { Lrc::new(cdata.get_super_predicates(def_id.index, tcx)) } + predicates_of => { tcx.arena.alloc(cdata.get_predicates(def_id.index, tcx)) } + predicates_defined_on => { + tcx.arena.alloc(cdata.get_predicates_defined_on(def_id.index, tcx)) + } + super_predicates_of => { tcx.arena.alloc(cdata.get_super_predicates(def_id.index, tcx)) } trait_def => { tcx.alloc_trait_def(cdata.get_trait_def(def_id.index, tcx.sess)) } @@ -108,10 +111,10 @@ provide! { <'tcx> tcx, def_id, other, cdata, } variances_of => { tcx.arena.alloc_from_iter(cdata.get_item_variances(def_id.index)) } associated_item_def_ids => { - let mut result = vec![]; + let mut result = SmallVec::<[_; 8]>::new(); cdata.each_child_of_item(def_id.index, |child| result.push(child.res.def_id()), tcx.sess); - Lrc::new(result) + tcx.arena.alloc_slice(&result) } associated_item => { cdata.get_associated_item(def_id.index) } impl_trait_ref => { cdata.get_impl_trait(def_id.index, tcx) } @@ -134,7 +137,7 @@ provide! { <'tcx> tcx, def_id, other, cdata, (cdata.mir_const_qualif(def_id.index), tcx.arena.alloc(BitSet::new_empty(0))) } fn_sig => { cdata.fn_sig(def_id.index, tcx) } - inherent_impls => { Lrc::new(cdata.get_inherent_implementations_for_type(def_id.index)) } + inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) } is_const_fn_raw => { cdata.is_const_fn_raw(def_id.index) } is_foreign_item => { cdata.is_foreign_item(def_id.index) } static_mutability => { cdata.static_mutability(def_id.index) } @@ -160,7 +163,7 @@ provide! { <'tcx> tcx, def_id, other, cdata, } is_mir_available => { cdata.is_item_mir_available(def_id.index) } - dylib_dependency_formats => { Lrc::new(cdata.get_dylib_dependency_formats()) } + dylib_dependency_formats => { cdata.get_dylib_dependency_formats(tcx) } is_panic_runtime => { cdata.root.panic_runtime } is_compiler_builtins => { cdata.root.compiler_builtins } has_global_allocator => { cdata.root.has_global_allocator } @@ -169,8 +172,8 @@ provide! { <'tcx> tcx, def_id, other, cdata, is_profiler_runtime => { cdata.root.profiler_runtime } panic_strategy => { cdata.root.panic_strategy } extern_crate => { - let r = Lrc::new(*cdata.extern_crate.lock()); - r + let r = *cdata.extern_crate.lock(); + r.map(|c| &*tcx.arena.alloc(c)) } is_no_builtins => { cdata.root.no_builtins } impl_defaultness => { cdata.get_impl_defaultness(def_id.index) } @@ -187,10 +190,10 @@ provide! { <'tcx> tcx, def_id, other, cdata, }) .collect(); - Lrc::new(reachable_non_generics) + tcx.arena.alloc(reachable_non_generics) } native_libraries => { Lrc::new(cdata.get_native_libraries(tcx.sess)) } - foreign_modules => { Lrc::new(cdata.get_foreign_modules(tcx.sess)) } + foreign_modules => { cdata.get_foreign_modules(tcx) } plugin_registrar_fn => { cdata.root.plugin_registrar_fn.map(|index| { DefId { krate: def_id.krate, index } @@ -207,18 +210,12 @@ provide! { <'tcx> tcx, def_id, other, cdata, extra_filename => { cdata.root.extra_filename.clone() } - implementations_of_trait => { - let mut result = vec![]; - let filter = Some(other); - cdata.get_implementations_for_trait(filter, &mut result); - Lrc::new(result) + cdata.get_implementations_for_trait(tcx, Some(other)) } all_trait_implementations => { - let mut result = vec![]; - cdata.get_implementations_for_trait(None, &mut result); - Lrc::new(result) + cdata.get_implementations_for_trait(tcx, None) } visibility => { cdata.get_visibility(def_id.index) } @@ -228,13 +225,13 @@ provide! { <'tcx> tcx, def_id, other, cdata, } crate_name => { cdata.name } item_children => { - let mut result = vec![]; + let mut result = SmallVec::<[_; 8]>::new(); cdata.each_child_of_item(def_id.index, |child| result.push(child), tcx.sess); - Lrc::new(result) + tcx.arena.alloc_slice(&result) } - defined_lib_features => { Lrc::new(cdata.get_lib_features()) } - defined_lang_items => { Lrc::new(cdata.get_lang_items()) } - missing_lang_items => { Lrc::new(cdata.get_missing_lang_items()) } + defined_lib_features => { cdata.get_lib_features(tcx) } + defined_lang_items => { cdata.get_lang_items(tcx) } + missing_lang_items => { cdata.get_missing_lang_items(tcx) } missing_extern_crate_item => { let r = match *cdata.extern_crate.borrow() { @@ -288,7 +285,7 @@ pub fn provide<'tcx>(providers: &mut Providers<'tcx>) { }, foreign_modules: |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); - Lrc::new(foreign_modules::collect(tcx)) + &tcx.arena.alloc(foreign_modules::collect(tcx))[..] }, link_args: |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); @@ -325,7 +322,7 @@ pub fn provide<'tcx>(providers: &mut Providers<'tcx>) { // which is to say, its not deterministic in general. But // we believe that libstd is consistently assigned crate // num 1, so it should be enough to resolve #46112. - let mut crates: Vec = (*tcx.crates()).clone(); + let mut crates: Vec = (*tcx.crates()).to_owned(); crates.sort(); for &cnum in crates.iter() { @@ -374,7 +371,7 @@ pub fn provide<'tcx>(providers: &mut Providers<'tcx>) { } } - Lrc::new(visible_parent_map) + tcx.arena.alloc(visible_parent_map) }, ..*providers diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index a89cfe42eaaf4..958c81989ffd6 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -708,26 +708,30 @@ impl<'a, 'tcx> CrateMetadata { } /// Iterates over all the stability attributes in the given crate. - pub fn get_lib_features(&self) -> Vec<(ast::Name, Option)> { + pub fn get_lib_features( + &self, + tcx: TyCtxt<'_, 'tcx, '_>, + ) -> &'tcx [(ast::Name, Option)] { // FIXME: For a proc macro crate, not sure whether we should return the "host" // features or an empty Vec. Both don't cause ICEs. - self.root + tcx.arena.alloc_from_iter(self.root .lib_features - .decode(self) - .collect() + .decode(self)) } /// Iterates over the language items in the given crate. - pub fn get_lang_items(&self) -> Vec<(DefId, usize)> { + pub fn get_lang_items( + &self, + tcx: TyCtxt<'_, 'tcx, '_>, + ) -> &'tcx [(DefId, usize)] { if self.proc_macros.is_some() { // Proc macro crates do not export any lang-items to the target. - vec![] + &[] } else { - self.root + tcx.arena.alloc_from_iter(self.root .lang_items .decode(self) - .map(|(def_index, index)| (self.local_def_id(def_index), index)) - .collect() + .map(|(def_index, index)| (self.local_def_id(def_index), index))) } } @@ -1013,39 +1017,45 @@ impl<'a, 'tcx> CrateMetadata { None } - pub fn get_inherent_implementations_for_type(&self, id: DefIndex) -> Vec { - self.entry(id) - .inherent_impls - .decode(self) - .map(|index| self.local_def_id(index)) - .collect() + pub fn get_inherent_implementations_for_type( + &self, + tcx: TyCtxt<'_, 'tcx, '_>, + id: DefIndex + ) -> &'tcx [DefId] { + tcx.arena.alloc_from_iter(self.entry(id) + .inherent_impls + .decode(self) + .map(|index| self.local_def_id(index))) } - pub fn get_implementations_for_trait(&self, - filter: Option, - result: &mut Vec) { + pub fn get_implementations_for_trait( + &self, + tcx: TyCtxt<'_, 'tcx, '_>, + filter: Option, + ) -> &'tcx [DefId] { if self.proc_macros.is_some() { // proc-macro crates export no trait impls. - return + return &[] } // Do a reverse lookup beforehand to avoid touching the crate_num // hash map in the loop below. let filter = match filter.map(|def_id| self.reverse_translate_def_id(def_id)) { Some(Some(def_id)) => Some((def_id.krate.as_u32(), def_id.index)), - Some(None) => return, + Some(None) => return &[], None => None, }; if let Some(filter) = filter { - if let Some(impls) = self.trait_impls - .get(&filter) { - result.extend(impls.decode(self).map(|idx| self.local_def_id(idx))); + if let Some(impls) = self.trait_impls.get(&filter) { + tcx.arena.alloc_from_iter(impls.decode(self).map(|idx| self.local_def_id(idx))) + } else { + &[] } } else { - for impls in self.trait_impls.values() { - result.extend(impls.decode(self).map(|idx| self.local_def_id(idx))); - } + tcx.arena.alloc_from_iter(self.trait_impls.values().flat_map(|impls| { + impls.decode(self).map(|idx| self.local_def_id(idx)) + })) } } @@ -1075,36 +1085,43 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn get_foreign_modules(&self, sess: &Session) -> Vec { + pub fn get_foreign_modules( + &self, + tcx: TyCtxt<'_, 'tcx, '_>, + ) -> &'tcx [ForeignModule] { if self.proc_macros.is_some() { // Proc macro crates do not have any *target* foreign modules. - vec![] + &[] } else { - self.root.foreign_modules.decode((self, sess)).collect() + tcx.arena.alloc_from_iter(self.root.foreign_modules.decode((self, tcx.sess))) } } - pub fn get_dylib_dependency_formats(&self) -> Vec<(CrateNum, LinkagePreference)> { - self.root + pub fn get_dylib_dependency_formats( + &self, + tcx: TyCtxt<'_, 'tcx, '_>, + ) -> &'tcx [(CrateNum, LinkagePreference)] { + tcx.arena.alloc_from_iter(self.root .dylib_dependency_formats .decode(self) .enumerate() .flat_map(|(i, link)| { let cnum = CrateNum::new(i + 1); link.map(|link| (self.cnum_map[cnum], link)) - }) - .collect() + })) } - pub fn get_missing_lang_items(&self) -> Vec { + pub fn get_missing_lang_items( + &self, + tcx: TyCtxt<'_, 'tcx, '_>, + ) -> &'tcx [lang_items::LangItem] { if self.proc_macros.is_some() { // Proc macro crates do not depend on any target weak lang-items. - vec![] + &[] } else { - self.root + tcx.arena.alloc_from_iter(self.root .lang_items_missing - .decode(self) - .collect() + .decode(self)) } } diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index d81e34a07aba9..1a9d996131dc0 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -673,7 +673,7 @@ impl EncodeContext<'_, 'tcx> { let data = ModData { reexports: match tcx.module_exports(def_id) { - Some(ref exports) => self.lazy_seq_ref(&exports[..]), + Some(exports) => self.lazy_seq_ref(exports), _ => LazySeq::empty(), }, }; diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 1df42a9504275..65b6a89aa0b4d 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -24,7 +24,6 @@ use rustc::ty::query::Providers; use rustc::ty::subst::InternalSubsts; use rustc::util::nodemap::HirIdSet; use rustc_data_structures::fx::FxHashSet; -use rustc_data_structures::sync::Lrc; use syntax::ast::Ident; use syntax::attr; use syntax::symbol::{kw, sym}; @@ -67,7 +66,7 @@ trait DefIdVisitor<'a, 'tcx: 'a> { fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> bool { self.skeleton().visit_trait(trait_ref) } - fn visit_predicates(&mut self, predicates: Lrc>) -> bool { + fn visit_predicates(&mut self, predicates: &ty::GenericPredicates<'tcx>) -> bool { self.skeleton().visit_predicates(predicates) } } @@ -89,8 +88,8 @@ impl<'a, 'tcx, V> DefIdVisitorSkeleton<'_, 'a, 'tcx, V> (!self.def_id_visitor.shallow() && substs.visit_with(self)) } - fn visit_predicates(&mut self, predicates: Lrc>) -> bool { - let ty::GenericPredicates { parent: _, predicates } = &*predicates; + fn visit_predicates(&mut self, predicates: &ty::GenericPredicates<'tcx>) -> bool { + let ty::GenericPredicates { parent: _, predicates } = predicates; for (predicate, _span) in predicates { match predicate { ty::Predicate::Trait(poly_predicate) => { @@ -1851,7 +1850,7 @@ fn check_mod_privacy<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) { fn privacy_access_levels<'tcx>( tcx: TyCtxt<'_, 'tcx, 'tcx>, krate: CrateNum, -) -> Lrc { +) -> &'tcx AccessLevels { assert_eq!(krate, LOCAL_CRATE); // Build up a set of all exported items in the AST. This is a set of all @@ -1872,7 +1871,7 @@ fn privacy_access_levels<'tcx>( } visitor.update(hir::CRATE_HIR_ID, Some(AccessLevel::Public)); - Lrc::new(visitor.access_levels) + tcx.arena.alloc(visitor.access_levels) } fn check_private_in_public<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, krate: CrateNum) { diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index d34f5633946bf..55471dbc00be5 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -24,7 +24,6 @@ use rustc::session::config::{CrateType, Input, OutputType}; use rustc::ty::{self, DefIdTree, TyCtxt}; use rustc::{bug, span_bug}; use rustc_codegen_utils::link::{filename_for_metadata, out_filename}; -use rustc_data_structures::sync::Lrc; use std::cell::Cell; use std::default::Default; @@ -110,8 +109,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { let mut result = Vec::with_capacity(self.tcx.crates().len()); for &n in self.tcx.crates().iter() { - let span = match *self.tcx.extern_crate(n.as_def_id()) { - Some(ExternCrate { span, .. }) => span, + let span = match self.tcx.extern_crate(n.as_def_id()) { + Some(&ExternCrate { span, .. }) => span, None => { debug!("Skipping crate {}, no data", n); continue; @@ -1120,7 +1119,7 @@ pub fn process_crate<'l, 'tcx, H: SaveHandler>( // fallback in case the access levels couldn't have been correctly computed. let access_levels = match tcx.sess.compile_status() { Ok(..) => tcx.privacy_access_levels(LOCAL_CRATE), - Err(..) => Lrc::new(AccessLevels::default()), + Err(..) => tcx.arena.alloc(AccessLevels::default()), }; let save_ctxt = SaveContext { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 4110a55840196..3a2b0178ce4d0 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -17,7 +17,6 @@ use rustc::ty::{GenericParamDef, GenericParamDefKind}; use rustc::ty::subst::{Kind, Subst, InternalSubsts, SubstsRef}; use rustc::ty::wf::object_region_bounds; use rustc::mir::interpret::ConstValue; -use rustc_data_structures::sync::Lrc; use rustc_target::spec::abi; use crate::require_c_abi_if_c_variadic; use smallvec::SmallVec; @@ -46,7 +45,7 @@ pub trait AstConv<'gcx, 'tcx> { /// Returns the set of bounds in scope for the type parameter with /// the given id. fn get_type_parameter_bounds(&self, span: Span, def_id: DefId) - -> Lrc>; + -> &'tcx ty::GenericPredicates<'tcx>; /// What lifetime should we use when a lifetime is omitted (and not elided)? fn re_infer(&self, span: Span, _def: Option<&ty::GenericParamDef>) diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 8d68179b495c6..a4e687b8f9080 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -306,11 +306,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { /// In addition of this check, it also checks between references mutability state. If the /// expected is mutable but the provided isn't, maybe we could just say "Hey, try with /// `&mut`!". - pub fn check_ref(&self, - expr: &hir::Expr, - checked_ty: Ty<'tcx>, - expected: Ty<'tcx>) - -> Option<(Span, &'static str, String)> { + pub fn check_ref( + &self, + expr: &hir::Expr, + checked_ty: Ty<'tcx>, + expected: Ty<'tcx>, + ) -> Option<(Span, &'static str, String)> { let cm = self.sess().source_map(); let sp = expr.span; if !cm.span_to_filename(sp).is_real() { @@ -397,6 +398,29 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } else { String::new() }; + if let Some(hir::Node::Expr(hir::Expr { + node: hir::ExprKind::Assign(left_expr, _), + .. + })) = self.tcx.hir().find_by_hir_id( + self.tcx.hir().get_parent_node_by_hir_id(expr.hir_id), + ) { + if mutability == hir::Mutability::MutMutable { + // Found the following case: + // fn foo(opt: &mut Option){ opt = None } + // --- ^^^^ + // | | + // consider dereferencing here: `*opt` | + // expected mutable reference, found enum `Option` + if let Ok(src) = cm.span_to_snippet(left_expr.span) { + return Some(( + left_expr.span, + "consider dereferencing here to assign to the mutable \ + borrowed piece of memory", + format!("*{}", src), + )); + } + } + } return Some(match mutability { hir::Mutability::MutMutable => ( sp, diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 77d2ffab8efb4..dfe21edee41f3 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -6,7 +6,6 @@ use crate::middle::lang_items::FnOnceTraitLangItem; use crate::namespace::Namespace; use crate::util::nodemap::FxHashSet; use errors::{Applicability, DiagnosticBuilder}; -use rustc_data_structures::sync::Lrc; use rustc::hir::{self, ExprKind, Node, QPath}; use rustc::hir::def::{Res, DefKind}; use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId}; @@ -844,7 +843,7 @@ fn compute_all_traits<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Vec pub fn provide(providers: &mut ty::query::Providers<'_>) { providers.all_traits = |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); - Lrc::new(compute_all_traits(tcx)) + &tcx.arena.alloc(compute_all_traits(tcx))[..] } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index a20a91b3e6f6d..655bf5722ae5a 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -97,7 +97,6 @@ use crate::namespace::Namespace; use rustc::infer::{self, InferCtxt, InferOk, InferResult}; use rustc::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse}; use rustc_data_structures::indexed_vec::Idx; -use rustc_data_structures::sync::Lrc; use rustc_target::spec::abi::Abi; use rustc::infer::opaque_types::OpaqueTypeDecl; use rustc::infer::type_variable::{TypeVariableOrigin}; @@ -808,8 +807,8 @@ fn has_typeck_tables<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn used_trait_imports<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) - -> Lrc { - tcx.typeck_tables_of(def_id).used_trait_imports.clone() + -> &'tcx DefIdSet { + &*tcx.typeck_tables_of(def_id).used_trait_imports } fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -1907,7 +1906,7 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx } fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) - -> Lrc> + -> &'tcx ty::GenericPredicates<'tcx> { let tcx = self.tcx; let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); @@ -1915,7 +1914,7 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> { let item_def_id = tcx.hir().local_def_id_from_hir_id(item_id); let generics = tcx.generics_of(item_def_id); let index = generics.param_def_id_to_index[&def_id]; - Lrc::new(ty::GenericPredicates { + tcx.arena.alloc(ty::GenericPredicates { parent: None, predicates: self.param_env.caller_bounds.iter().filter_map(|&predicate| { match predicate { diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs index d167c7fcafbe4..644d95963e652 100644 --- a/src/librustc_typeck/coherence/inherent_impls.rs +++ b/src/librustc_typeck/coherence/inherent_impls.rs @@ -13,14 +13,13 @@ use rustc::hir; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::ty::{self, CrateInherentImpls, TyCtxt}; -use rustc_data_structures::sync::Lrc; use syntax::ast; use syntax_pos::Span; /// On-demand query: yields a map containing all types mapped to their inherent impls. pub fn crate_inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) - -> Lrc { + -> &'tcx CrateInherentImpls { assert_eq!(crate_num, LOCAL_CRATE); let krate = tcx.hir().krate(); @@ -29,13 +28,13 @@ pub fn crate_inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impls_map: Default::default(), }; krate.visit_all_item_likes(&mut collect); - Lrc::new(collect.impls_map) + tcx.arena.alloc(collect.impls_map) } /// On-demand query: yields a vector of the inherent impls for a specific type. pub fn inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty_def_id: DefId) - -> Lrc> { + -> &'tcx [DefId] { assert!(ty_def_id.is_local()); // NB. Until we adopt the red-green dep-tracking algorithm (see @@ -53,15 +52,11 @@ pub fn inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // // [the plan]: https://github.com/rust-lang/rust-roadmap/issues/4 - thread_local! { - static EMPTY_DEF_ID_VEC: Lrc> = Lrc::new(vec![]) - } - let result = tcx.dep_graph.with_ignore(|| { let crate_map = tcx.crate_inherent_impls(ty_def_id.krate); match crate_map.inherent_impls.get(&ty_def_id) { - Some(v) => v.clone(), - None => EMPTY_DEF_ID_VEC.with(|v| v.clone()) + Some(v) => &v[..], + None => &[], } }); @@ -289,13 +284,8 @@ impl<'a, 'tcx> InherentCollect<'a, 'tcx> { // type def ID, if there is a base type for this implementation and // the implementation does not have any associated traits. let impl_def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id); - let mut rc_vec = self.impls_map.inherent_impls - .entry(def_id) - .or_default(); - - // At this point, there should not be any clones of the - // `Lrc`, so we can still safely push into it in place: - Lrc::get_mut(&mut rc_vec).unwrap().push(impl_def_id); + let vec = self.impls_map.inherent_impls.entry(def_id).or_default(); + vec.push(impl_def_id); } else { struct_span_err!(self.tcx.sess, item.span, diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 2a4d8f304b592..45380d757b97d 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -31,7 +31,6 @@ use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt}; use rustc::ty::{ReprOptions, ToPredicate}; use rustc::util::captures::Captures; use rustc::util::nodemap::FxHashMap; -use rustc_data_structures::sync::Lrc; use rustc_target::spec::abi; use syntax::ast; @@ -178,7 +177,7 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> { } fn get_type_parameter_bounds(&self, span: Span, def_id: DefId) - -> Lrc> { + -> &'tcx ty::GenericPredicates<'tcx> { self.tcx .at(span) .type_param_predicates((self.item_def_id, def_id)) @@ -243,7 +242,7 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> { fn type_param_predicates<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, (item_def_id, def_id): (DefId, DefId), -) -> Lrc> { +) -> &'tcx ty::GenericPredicates<'tcx> { use rustc::hir::*; // In the AST, bounds can derive from two places. Either @@ -264,16 +263,11 @@ fn type_param_predicates<'a, 'tcx>( tcx.generics_of(item_def_id).parent }; - let mut result = parent.map_or_else( - || Lrc::new(ty::GenericPredicates { - parent: None, - predicates: vec![], - }), - |parent| { - let icx = ItemCtxt::new(tcx, parent); - icx.get_type_parameter_bounds(DUMMY_SP, def_id) - }, - ); + let result = parent.map_or(&tcx.common.empty_predicates, |parent| { + let icx = ItemCtxt::new(tcx, parent); + icx.get_type_parameter_bounds(DUMMY_SP, def_id) + }); + let mut extend = None; let item_hir_id = tcx.hir().as_local_hir_id(item_def_id).unwrap(); let ast_generics = match tcx.hir().get_by_hir_id(item_hir_id) { @@ -298,9 +292,7 @@ fn type_param_predicates<'a, 'tcx>( // Implied `Self: Trait` and supertrait bounds. if param_id == item_hir_id { let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id); - Lrc::make_mut(&mut result) - .predicates - .push((identity_trait_ref.to_predicate(), item.span)); + extend = Some((identity_trait_ref.to_predicate(), item.span)); } generics } @@ -317,11 +309,12 @@ fn type_param_predicates<'a, 'tcx>( }; let icx = ItemCtxt::new(tcx, item_def_id); - Lrc::make_mut(&mut result) - .predicates - .extend(icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty, - OnlySelfBounds(true))); - result + let mut result = (*result).clone(); + result.predicates.extend(extend.into_iter()); + result.predicates + .extend(icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty, + OnlySelfBounds(true))); + tcx.arena.alloc(result) } impl<'a, 'tcx> ItemCtxt<'a, 'tcx> { @@ -690,7 +683,7 @@ fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::Ad fn super_predicates_of<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, trait_def_id: DefId, -) -> Lrc> { +) -> &'tcx ty::GenericPredicates<'tcx> { debug!("super_predicates(trait_def_id={:?})", trait_def_id); let trait_hir_id = tcx.hir().as_local_hir_id(trait_def_id).unwrap(); @@ -734,7 +727,7 @@ fn super_predicates_of<'a, 'tcx>( } } - Lrc::new(ty::GenericPredicates { + tcx.arena.alloc(ty::GenericPredicates { parent: None, predicates: superbounds, }) @@ -1842,7 +1835,7 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx>( fn predicates_defined_on<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, -) -> Lrc> { +) -> &'tcx ty::GenericPredicates<'tcx> { debug!("predicates_defined_on({:?})", def_id); let mut result = tcx.explicit_predicates_of(def_id); debug!( @@ -1858,9 +1851,9 @@ fn predicates_defined_on<'a, 'tcx>( def_id, inferred_outlives, ); - Lrc::make_mut(&mut result) - .predicates - .extend(inferred_outlives.iter().map(|&p| (p, span))); + let mut predicates = (*result).clone(); + predicates.predicates.extend(inferred_outlives.iter().map(|&p| (p, span))); + result = tcx.arena.alloc(predicates); } debug!("predicates_defined_on({:?}) = {:?}", def_id, result); result @@ -1872,7 +1865,7 @@ fn predicates_defined_on<'a, 'tcx>( fn predicates_of<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, -) -> Lrc> { +) -> &'tcx ty::GenericPredicates<'tcx> { let mut result = tcx.predicates_defined_on(def_id); if tcx.is_trait(def_id) { @@ -1889,9 +1882,9 @@ fn predicates_of<'a, 'tcx>( // used, and adding the predicate into this list ensures // that this is done. let span = tcx.def_span(def_id); - Lrc::make_mut(&mut result) - .predicates - .push((ty::TraitRef::identity(tcx, def_id).to_predicate(), span)); + let mut predicates = (*result).clone(); + predicates.predicates.push((ty::TraitRef::identity(tcx, def_id).to_predicate(), span)); + result = tcx.arena.alloc(predicates); } debug!("predicates_of(def_id={:?}) = {:?}", def_id, result); result @@ -1902,7 +1895,7 @@ fn predicates_of<'a, 'tcx>( fn explicit_predicates_of<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, -) -> Lrc> { +) -> &'tcx ty::GenericPredicates<'tcx> { use rustc::hir::*; use rustc_data_structures::fx::FxHashSet; @@ -2017,7 +2010,7 @@ fn explicit_predicates_of<'a, 'tcx>( if impl_trait_fn.is_some() { // impl Trait - return Lrc::new(ty::GenericPredicates { + return tcx.arena.alloc(ty::GenericPredicates { parent: None, predicates: bounds.predicates(tcx, opaque_ty), }); @@ -2228,7 +2221,7 @@ fn explicit_predicates_of<'a, 'tcx>( ); } - let result = Lrc::new(ty::GenericPredicates { + let result = tcx.arena.alloc(ty::GenericPredicates { parent: generics.parent, predicates, }); diff --git a/src/librustc_typeck/outlives/mod.rs b/src/librustc_typeck/outlives/mod.rs index a6b5b99982ec6..57787a75e4aef 100644 --- a/src/librustc_typeck/outlives/mod.rs +++ b/src/librustc_typeck/outlives/mod.rs @@ -4,7 +4,6 @@ use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::ty::query::Providers; use rustc::ty::subst::UnpackedKind; use rustc::ty::{self, CratePredicatesMap, TyCtxt}; -use rustc_data_structures::sync::Lrc; use syntax::symbol::sym; mod explicit; @@ -74,7 +73,7 @@ fn inferred_outlives_of<'a, 'tcx>( fn inferred_outlives_crate<'tcx>( tcx: TyCtxt<'_, 'tcx, 'tcx>, crate_num: CrateNum, -) -> Lrc> { +) -> &'tcx CratePredicatesMap<'tcx> { assert_eq!(crate_num, LOCAL_CRATE); // Compute a map from each struct/enum/union S to the **explicit** @@ -120,7 +119,7 @@ fn inferred_outlives_crate<'tcx>( (def_id, &*predicates) }).collect(); - Lrc::new(ty::CratePredicatesMap { + tcx.arena.alloc(ty::CratePredicatesMap { predicates, }) } diff --git a/src/librustc_typeck/variance/mod.rs b/src/librustc_typeck/variance/mod.rs index 88ee1d79f5435..47c4a9b39c865 100644 --- a/src/librustc_typeck/variance/mod.rs +++ b/src/librustc_typeck/variance/mod.rs @@ -9,7 +9,6 @@ use hir::Node; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::ty::{self, CrateVariancesMap, TyCtxt}; use rustc::ty::query::Providers; -use rustc_data_structures::sync::Lrc; /// Defines the `TermsContext` basically houses an arena where we can /// allocate terms. @@ -36,12 +35,12 @@ pub fn provide(providers: &mut Providers<'_>) { } fn crate_variances<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) - -> Lrc> { + -> &'tcx CrateVariancesMap<'tcx> { assert_eq!(crate_num, LOCAL_CRATE); let mut arena = arena::TypedArena::default(); let terms_cx = terms::determine_parameters_to_be_inferred(tcx, &mut arena); let constraints_cx = constraints::add_constraints_from_crate(terms_cx); - Lrc::new(solve::solve_constraints(constraints_cx)) + tcx.arena.alloc(solve::solve_constraints(constraints_cx)) } fn variances_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_def_id: DefId) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 11e8192521d79..8e2460a14b87a 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -104,8 +104,10 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { // Instead, we generate `impl !Send for Foo`, which better // expresses the fact that `Foo` never implements `Send`, // regardless of the choice of `T`. - let params = (self.cx.tcx.generics_of(param_env_def_id), &Default::default()) - .clean(self.cx).params; + let params = ( + self.cx.tcx.generics_of(param_env_def_id), + &&self.cx.tcx.common.empty_predicates, + ).clean(self.cx).params; Generics { params, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 1bbbe581c3ce1..9c3f522d8470f 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -10,7 +10,6 @@ mod auto_trait; mod blanket_impl; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; -use rustc_data_structures::sync::Lrc; use rustc_target::spec::abi::Abi; use rustc_typeck::hir_ty_to_ty; use rustc::infer::region_constraints::{RegionConstraintData, Constraint}; @@ -1687,7 +1686,7 @@ impl Clean for hir::Generics { } impl<'a, 'tcx> Clean for (&'a ty::Generics, - &'a Lrc>) { + &'a &'tcx ty::GenericPredicates<'tcx>) { fn clean(&self, cx: &DocContext<'_>) -> Generics { use self::WherePredicate as WP; @@ -4434,7 +4433,7 @@ pub fn path_to_def(tcx: TyCtxt<'_, '_, '_>, path: &[Symbol]) -> Option { loop { let segment = path_it.next()?; - for item in mem::replace(&mut items, Lrc::new(vec![])).iter() { + for item in mem::replace(&mut items, &[]).iter() { if item.ident.name == *segment { if path_it.peek().is_none() { return match item.res { diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs index d48fcbbd6720d..8ac5beb21b530 100644 --- a/src/libsyntax/parse/diagnostics.rs +++ b/src/libsyntax/parse/diagnostics.rs @@ -1,16 +1,19 @@ use crate::ast; -use crate::ast::{BlockCheckMode, Expr, ExprKind, Item, ItemKind, Pat, PatKind, QSelf, Ty, TyKind}; -use crate::parse::parser::{BlockMode, PathStyle, TokenType, SemiColonMode}; +use crate::ast::{ + BlockCheckMode, Expr, ExprKind, Item, ItemKind, Pat, PatKind, QSelf, Ty, TyKind, VariantData, +}; +use crate::parse::parser::{BlockMode, PathStyle, SemiColonMode, TokenType}; use crate::parse::token; use crate::parse::PResult; use crate::parse::Parser; use crate::print::pprust; use crate::ptr::P; +use crate::source_map::Spanned; use crate::symbol::kw; use crate::ThinVec; use errors::{Applicability, DiagnosticBuilder}; -use syntax_pos::Span; use log::debug; +use syntax_pos::Span; pub trait RecoverQPath: Sized + 'static { const PATH_STYLE: PathStyle = PathStyle::Expr; @@ -79,6 +82,44 @@ impl<'a> Parser<'a> { } } + crate fn maybe_report_invalid_custom_discriminants( + &mut self, + discriminant_spans: Vec, + variants: &[Spanned], + ) { + let has_fields = variants.iter().any(|variant| match variant.node.data { + VariantData::Tuple(..) | VariantData::Struct(..) => true, + VariantData::Unit(..) => false, + }); + + if !discriminant_spans.is_empty() && has_fields { + let mut err = self.struct_span_err( + discriminant_spans.clone(), + "custom discriminant values are not allowed in enums with fields", + ); + for sp in discriminant_spans { + err.span_label(sp, "invalid custom discriminant"); + } + for variant in variants.iter() { + if let VariantData::Struct(fields, ..) | VariantData::Tuple(fields, ..) = + &variant.node.data + { + let fields = if fields.len() > 1 { + "fields" + } else { + "a field" + }; + err.span_label( + variant.span, + &format!("variant with {fields} defined here", fields = fields), + ); + + } + } + err.emit(); + } + } + crate fn maybe_recover_from_bad_type_plus( &mut self, allow_plus: bool, diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ae3665c834bd3..df80151508230 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -7466,7 +7466,6 @@ impl<'a> Parser<'a> { /// Parses the part of an enum declaration following the `{`. fn parse_enum_def(&mut self, _generics: &ast::Generics) -> PResult<'a, EnumDef> { let mut variants = Vec::new(); - let mut all_nullary = true; let mut any_disr = vec![]; while self.token != token::CloseDelim(token::Brace) { let variant_attrs = self.parse_outer_attributes()?; @@ -7478,11 +7477,9 @@ impl<'a> Parser<'a> { let ident = self.parse_ident()?; if self.check(&token::OpenDelim(token::Brace)) { // Parse a struct variant. - all_nullary = false; let (fields, recovered) = self.parse_record_struct_body()?; struct_def = VariantData::Struct(fields, recovered); } else if self.check(&token::OpenDelim(token::Paren)) { - all_nullary = false; struct_def = VariantData::Tuple( self.parse_tuple_struct_body()?, ast::DUMMY_NODE_ID, @@ -7526,16 +7523,7 @@ impl<'a> Parser<'a> { } } self.expect(&token::CloseDelim(token::Brace))?; - if !any_disr.is_empty() && !all_nullary { - let mut err = self.struct_span_err( - any_disr.clone(), - "discriminator values can only be used with a field-less enum", - ); - for sp in any_disr { - err.span_label(sp, "only valid in field-less enums"); - } - err.emit(); - } + self.maybe_report_invalid_custom_discriminants(any_disr, &variants); Ok(ast::EnumDef { variants }) } diff --git a/src/test/incremental/cyclic-trait-hierarchy.rs b/src/test/incremental/cyclic-trait-hierarchy.rs index 4102eb32580f0..27287d06d54b1 100644 --- a/src/test/incremental/cyclic-trait-hierarchy.rs +++ b/src/test/incremental/cyclic-trait-hierarchy.rs @@ -7,7 +7,6 @@ pub trait T2 { } #[cfg(cfail2)] pub trait T2: T1 { } //[cfail2]~^ ERROR cycle detected when computing the supertraits of `T2` -//[cfail2]~| ERROR cycle detected when computing the supertraits of `T2` pub trait T1: T2 { } diff --git a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs index 4e43aa96e1d85..1bab3f01aba04 100644 --- a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs +++ b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs @@ -47,8 +47,8 @@ impl CodegenBackend for TheBackend { fn provide(&self, providers: &mut Providers) { rustc_codegen_utils::symbol_names::provide(providers); - providers.target_features_whitelist = |_tcx, _cnum| { - Default::default() // Just a dummy + providers.target_features_whitelist = |tcx, _cnum| { + tcx.arena.alloc(Default::default()) // Just a dummy }; providers.is_reachable_non_generic = |_tcx, _defid| true; providers.exported_symbols = |_tcx, _crate| Arc::new(Vec::new()); diff --git a/src/test/ui/cycle-projection-based-on-where-clause.rs b/src/test/ui/cycle-projection-based-on-where-clause.rs index 336b67852cd01..d3609acfdff63 100644 --- a/src/test/ui/cycle-projection-based-on-where-clause.rs +++ b/src/test/ui/cycle-projection-based-on-where-clause.rs @@ -16,7 +16,6 @@ struct A where T : Trait, T : Add //~^ ERROR cycle detected - //~| ERROR associated type `Item` not found for `T` { data: T } diff --git a/src/test/ui/cycle-projection-based-on-where-clause.stderr b/src/test/ui/cycle-projection-based-on-where-clause.stderr index e5a5e2897cd0a..59815138e2e36 100644 --- a/src/test/ui/cycle-projection-based-on-where-clause.stderr +++ b/src/test/ui/cycle-projection-based-on-where-clause.stderr @@ -11,13 +11,6 @@ note: cycle used when processing `A` LL | T : Add | ^^^^^^^ -error[E0220]: associated type `Item` not found for `T` - --> $DIR/cycle-projection-based-on-where-clause.rs:17:19 - | -LL | T : Add - | ^^^^^^^ associated type `Item` not found - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0220, E0391. -For more information about an error, try `rustc --explain E0220`. +For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/issues/issue-20772.rs b/src/test/ui/issues/issue-20772.rs index 36551e7014f10..1500bc831528a 100644 --- a/src/test/ui/issues/issue-20772.rs +++ b/src/test/ui/issues/issue-20772.rs @@ -1,6 +1,5 @@ trait T : Iterator //~^ ERROR cycle detected -//~| ERROR associated type `Item` not found for `Self` {} fn main() {} diff --git a/src/test/ui/issues/issue-20772.stderr b/src/test/ui/issues/issue-20772.stderr index 3b5dd975ce9e9..d64636310a368 100644 --- a/src/test/ui/issues/issue-20772.stderr +++ b/src/test/ui/issues/issue-20772.stderr @@ -3,7 +3,6 @@ error[E0391]: cycle detected when computing the supertraits of `T` | LL | / trait T : Iterator LL | | -LL | | LL | | {} | |__^ | @@ -13,17 +12,9 @@ note: cycle used when collecting item types in top-level module | LL | / trait T : Iterator LL | | -LL | | LL | | {} | |__^ -error[E0220]: associated type `Item` not found for `Self` - --> $DIR/issue-20772.rs:1:25 - | -LL | trait T : Iterator - | ^^^^^^^^^^ associated type `Item` not found - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0220, E0391. -For more information about an error, try `rustc --explain E0220`. +For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/issues/issue-21177.rs b/src/test/ui/issues/issue-21177.rs index 9d153696b885e..258e362d1317c 100644 --- a/src/test/ui/issues/issue-21177.rs +++ b/src/test/ui/issues/issue-21177.rs @@ -5,6 +5,5 @@ trait Trait { fn foo>() { } //~^ ERROR cycle detected -//~| ERROR associated type `B` not found for `T` fn main() { } diff --git a/src/test/ui/issues/issue-21177.stderr b/src/test/ui/issues/issue-21177.stderr index 6841fe85dd792..00d9a3c46a723 100644 --- a/src/test/ui/issues/issue-21177.stderr +++ b/src/test/ui/issues/issue-21177.stderr @@ -11,13 +11,6 @@ note: cycle used when processing `foo` LL | fn foo>() { } | ^^^^ -error[E0220]: associated type `B` not found for `T` - --> $DIR/issue-21177.rs:6:21 - | -LL | fn foo>() { } - | ^^^^ associated type `B` not found - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0220, E0391. -For more information about an error, try `rustc --explain E0220`. +For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/issues/issue-23302-3.rs b/src/test/ui/issues/issue-23302-3.rs index e17c5eea2a445..da75f33079886 100644 --- a/src/test/ui/issues/issue-23302-3.rs +++ b/src/test/ui/issues/issue-23302-3.rs @@ -1,5 +1,4 @@ const A: i32 = B; //~ ERROR cycle detected -//~^ ERROR cycle detected const B: i32 = A; diff --git a/src/test/ui/issues/issue-23302-3.stderr b/src/test/ui/issues/issue-23302-3.stderr index 94624640809b7..a7d643987f710 100644 --- a/src/test/ui/issues/issue-23302-3.stderr +++ b/src/test/ui/issues/issue-23302-3.stderr @@ -10,36 +10,18 @@ note: ...which requires checking which parts of `A` are promotable to static... LL | const A: i32 = B; | ^ note: ...which requires const checking if rvalue is promotable to static `B`... - --> $DIR/issue-23302-3.rs:4:1 + --> $DIR/issue-23302-3.rs:3:1 | LL | const B: i32 = A; | ^^^^^^^^^^^^^^^^^ note: ...which requires checking which parts of `B` are promotable to static... - --> $DIR/issue-23302-3.rs:4:16 + --> $DIR/issue-23302-3.rs:3:16 | LL | const B: i32 = A; | ^ = note: ...which again requires const checking if rvalue is promotable to static `A`, completing the cycle = note: cycle used when running analysis passes on this crate -error[E0391]: cycle detected when processing `A` - --> $DIR/issue-23302-3.rs:1:16 - | -LL | const A: i32 = B; - | ^ - | -note: ...which requires processing `B`... - --> $DIR/issue-23302-3.rs:4:16 - | -LL | const B: i32 = A; - | ^ - = note: ...which again requires processing `A`, completing the cycle -note: cycle used when processing `A` - --> $DIR/issue-23302-3.rs:1:1 - | -LL | const A: i32 = B; - | ^^^^^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/lint/deny-overflowing-literals.rs b/src/test/ui/lint/deny-overflowing-literals.rs index b887f66e94bd6..21c8ba7d6ce4e 100644 --- a/src/test/ui/lint/deny-overflowing-literals.rs +++ b/src/test/ui/lint/deny-overflowing-literals.rs @@ -1,4 +1,7 @@ fn main() { let x: u8 = 256; //~^ error: literal out of range for `u8` + + for _ in 0..256u8 {} + //~^ error: range endpoint is out of range for `u8` } diff --git a/src/test/ui/lint/deny-overflowing-literals.stderr b/src/test/ui/lint/deny-overflowing-literals.stderr index 1263a7bb7fd1b..c97872b5222e8 100644 --- a/src/test/ui/lint/deny-overflowing-literals.stderr +++ b/src/test/ui/lint/deny-overflowing-literals.stderr @@ -6,5 +6,11 @@ LL | let x: u8 = 256; | = note: #[deny(overflowing_literals)] on by default -error: aborting due to previous error +error: range endpoint is out of range for `u8` + --> $DIR/deny-overflowing-literals.rs:5:14 + | +LL | for _ in 0..256u8 {} + | ^^^^^^^^ help: use an inclusive range instead: `0..=255u8` + +error: aborting due to 2 previous errors diff --git a/src/test/ui/parser/issue-17383.rs b/src/test/ui/parser/issue-17383.rs index 04cd43d0b1071..f95005cd91483 100644 --- a/src/test/ui/parser/issue-17383.rs +++ b/src/test/ui/parser/issue-17383.rs @@ -1,6 +1,6 @@ enum X { A = 3, - //~^ ERROR discriminator values can only be used with a field-less enum + //~^ ERROR custom discriminant values are not allowed in enums with fields B(usize) } diff --git a/src/test/ui/parser/issue-17383.stderr b/src/test/ui/parser/issue-17383.stderr index 57caa3372a629..37abd0ff5e1f4 100644 --- a/src/test/ui/parser/issue-17383.stderr +++ b/src/test/ui/parser/issue-17383.stderr @@ -1,8 +1,11 @@ -error: discriminator values can only be used with a field-less enum +error: custom discriminant values are not allowed in enums with fields --> $DIR/issue-17383.rs:2:9 | LL | A = 3, - | ^ only valid in field-less enums + | ^ invalid custom discriminant +LL | +LL | B(usize) + | -------- variant with a field defined here error: aborting due to previous error diff --git a/src/test/ui/parser/tag-variant-disr-non-nullary.rs b/src/test/ui/parser/tag-variant-disr-non-nullary.rs index 83a3b727982b5..305edc4ad5a04 100644 --- a/src/test/ui/parser/tag-variant-disr-non-nullary.rs +++ b/src/test/ui/parser/tag-variant-disr-non-nullary.rs @@ -1,11 +1,12 @@ enum Color { Red = 0xff0000, - //~^ ERROR discriminator values can only be used with a field-less enum + //~^ ERROR custom discriminant values are not allowed in enums with fields Green = 0x00ff00, Blue = 0x0000ff, Black = 0x000000, White = 0xffffff, Other(usize), + Other2(usize, usize), } fn main() {} diff --git a/src/test/ui/parser/tag-variant-disr-non-nullary.stderr b/src/test/ui/parser/tag-variant-disr-non-nullary.stderr index 884e9672cb12d..2d3b283953124 100644 --- a/src/test/ui/parser/tag-variant-disr-non-nullary.stderr +++ b/src/test/ui/parser/tag-variant-disr-non-nullary.stderr @@ -1,17 +1,21 @@ -error: discriminator values can only be used with a field-less enum +error: custom discriminant values are not allowed in enums with fields --> $DIR/tag-variant-disr-non-nullary.rs:2:11 | LL | Red = 0xff0000, - | ^^^^^^^^ only valid in field-less enums + | ^^^^^^^^ invalid custom discriminant LL | LL | Green = 0x00ff00, - | ^^^^^^^^ only valid in field-less enums + | ^^^^^^^^ invalid custom discriminant LL | Blue = 0x0000ff, - | ^^^^^^^^ only valid in field-less enums + | ^^^^^^^^ invalid custom discriminant LL | Black = 0x000000, - | ^^^^^^^^ only valid in field-less enums + | ^^^^^^^^ invalid custom discriminant LL | White = 0xffffff, - | ^^^^^^^^ only valid in field-less enums + | ^^^^^^^^ invalid custom discriminant +LL | Other(usize), + | ------------ variant with a field defined here +LL | Other2(usize, usize), + | -------------------- variant with fields defined here error: aborting due to previous error diff --git a/src/test/ui/suggestions/mut-ref-reassignment.rs b/src/test/ui/suggestions/mut-ref-reassignment.rs new file mode 100644 index 0000000000000..1428324934de2 --- /dev/null +++ b/src/test/ui/suggestions/mut-ref-reassignment.rs @@ -0,0 +1,17 @@ +fn suggestion(opt: &mut Option) { + opt = None; //~ ERROR mismatched types +} + +fn no_suggestion(opt: &mut Result) { + opt = None //~ ERROR mismatched types +} + +fn suggestion2(opt: &mut Option) { + opt = Some(String::new())//~ ERROR mismatched types +} + +fn no_suggestion2(opt: &mut Option) { + opt = Some(42)//~ ERROR mismatched types +} + +fn main() {} diff --git a/src/test/ui/suggestions/mut-ref-reassignment.stderr b/src/test/ui/suggestions/mut-ref-reassignment.stderr new file mode 100644 index 0000000000000..66b78a1b14015 --- /dev/null +++ b/src/test/ui/suggestions/mut-ref-reassignment.stderr @@ -0,0 +1,47 @@ +error[E0308]: mismatched types + --> $DIR/mut-ref-reassignment.rs:2:11 + | +LL | opt = None; + | ^^^^ expected mutable reference, found enum `std::option::Option` + | + = note: expected type `&mut std::option::Option` + found type `std::option::Option<_>` +help: consider dereferencing here to assign to the mutable borrowed piece of memory + | +LL | *opt = None; + | ^^^^ + +error[E0308]: mismatched types + --> $DIR/mut-ref-reassignment.rs:6:11 + | +LL | opt = None + | ^^^^ expected mutable reference, found enum `std::option::Option` + | + = note: expected type `&mut std::result::Result` + found type `std::option::Option<_>` + +error[E0308]: mismatched types + --> $DIR/mut-ref-reassignment.rs:10:11 + | +LL | opt = Some(String::new()) + | ^^^^^^^^^^^^^^^^^^^ expected mutable reference, found enum `std::option::Option` + | + = note: expected type `&mut std::option::Option` + found type `std::option::Option` +help: consider dereferencing here to assign to the mutable borrowed piece of memory + | +LL | *opt = Some(String::new()) + | ^^^^ + +error[E0308]: mismatched types + --> $DIR/mut-ref-reassignment.rs:14:11 + | +LL | opt = Some(42) + | ^^^^^^^^ expected mutable reference, found enum `std::option::Option` + | + = note: expected type `&mut std::option::Option` + found type `std::option::Option<{integer}>` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/unreachable/unreachable-loop-patterns.rs b/src/test/ui/unreachable/unreachable-loop-patterns.rs index 3c878410f7710..56ab1a270a75d 100644 --- a/src/test/ui/unreachable/unreachable-loop-patterns.rs +++ b/src/test/ui/unreachable/unreachable-loop-patterns.rs @@ -19,4 +19,5 @@ impl Iterator for Void { fn main() { for _ in unimplemented!() as Void {} //~^ ERROR unreachable pattern + //~^^ ERROR unreachable pattern } diff --git a/src/test/ui/unreachable/unreachable-loop-patterns.stderr b/src/test/ui/unreachable/unreachable-loop-patterns.stderr index d2f255c3e104d..254d1178d142e 100644 --- a/src/test/ui/unreachable/unreachable-loop-patterns.stderr +++ b/src/test/ui/unreachable/unreachable-loop-patterns.stderr @@ -10,5 +10,11 @@ note: lint level defined here LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ -error: aborting due to previous error +error: unreachable pattern + --> $DIR/unreachable-loop-patterns.rs:20:14 + | +LL | for _ in unimplemented!() as Void {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors