diff --git a/src/librustc/hir/map/hir_id_validator.rs b/src/librustc/hir/map/hir_id_validator.rs index 76e42b8af2874..f347a5373c08e 100644 --- a/src/librustc/hir/map/hir_id_validator.rs +++ b/src/librustc/hir/map/hir_id_validator.rs @@ -1,6 +1,6 @@ use crate::hir::map::Map; use rustc_data_structures::fx::FxHashSet; -use rustc_data_structures::sync::{par_iter, Lock, ParallelIterator}; +use rustc_data_structures::sync::{par_for_each, Lock}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX}; use rustc_hir::intravisit; @@ -12,7 +12,7 @@ pub fn check_crate(hir_map: &Map<'_>) { let errors = Lock::new(Vec::new()); - par_iter(&hir_map.krate().modules).for_each(|(module_id, _)| { + par_for_each(&hir_map.krate().modules, |(module_id, _)| { let local_def_id = hir_map.local_def_id(*module_id); hir_map.visit_item_likes_in_module( local_def_id, diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 46c5ee272d235..bf3a55e359890 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -8,10 +8,12 @@ use crate::middle::cstore::CrateStoreDyn; use crate::ty::query::Providers; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::svh::Svh; + +use rustc_data_structures::sync::{self, par_for_each}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX}; use rustc_hir::intravisit; -use rustc_hir::itemlikevisit::ItemLikeVisitor; +use rustc_hir::itemlikevisit::{ItemLikeVisitor, ParItemLikeVisitor}; use rustc_hir::print::Nested; use rustc_hir::*; use rustc_index::vec::IndexVec; @@ -582,6 +584,40 @@ impl<'hir> Map<'hir> { } } + /// A parallel version of `visit_item_likes_in_module`. + pub fn par_visit_item_likes_in_module(&self, module: DefId, visitor: &V) + where + V: ParItemLikeVisitor<'hir> + sync::Sync, + { + let hir_id = self.as_local_hir_id(module).unwrap(); + + // Read the module so we'll be re-executed if new items + // appear immediately under in the module. If some new item appears + // in some nested item in the module, we'll be re-executed due to reads + // in the expect_* calls the loops below + self.read(hir_id); + + let module = &self.forest.krate.modules[&hir_id]; + + parallel!( + { + par_for_each(&module.items, |id| { + visitor.visit_item(self.expect_item(*id)); + }); + }, + { + par_for_each(&module.trait_items, |id| { + visitor.visit_trait_item(self.expect_trait_item(id.hir_id)); + }); + }, + { + par_for_each(&module.impl_items, |id| { + visitor.visit_impl_item(self.expect_impl_item(id.hir_id)); + }); + } + ); + } + /// Retrieves the `Node` corresponding to `id`, panicking if it cannot be found. pub fn get(&self, id: HirId) -> Node<'hir> { // read recorded by `find` diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs index e7a4c5b592105..996d4b83132e3 100644 --- a/src/librustc/mir/mono.rs +++ b/src/librustc/mir/mono.rs @@ -234,7 +234,7 @@ pub struct CodegenUnit<'tcx> { /// as well as the crate name and disambiguator. name: Symbol, items: FxHashMap, (Linkage, Visibility)>, - size_estimate: Option, + size_estimate: usize, } #[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable, HashStable)] @@ -261,7 +261,7 @@ pub enum Visibility { impl<'tcx> CodegenUnit<'tcx> { pub fn new(name: Symbol) -> CodegenUnit<'tcx> { - CodegenUnit { name: name, items: Default::default(), size_estimate: None } + CodegenUnit { name: name, items: Default::default(), size_estimate: 0 } } pub fn name(&self) -> Symbol { @@ -293,19 +293,15 @@ impl<'tcx> CodegenUnit<'tcx> { pub fn estimate_size(&mut self, tcx: TyCtxt<'tcx>) { // Estimate the size of a codegen unit as (approximately) the number of MIR // statements it corresponds to. - self.size_estimate = Some(self.items.keys().map(|mi| mi.size_estimate(tcx)).sum()); + self.size_estimate = self.items.keys().map(|mi| mi.size_estimate(tcx)).sum(); } pub fn size_estimate(&self) -> usize { - // Should only be called if `estimate_size` has previously been called. - self.size_estimate.expect("estimate_size must be called before getting a size_estimate") + self.size_estimate } pub fn modify_size_estimate(&mut self, delta: usize) { - assert!(self.size_estimate.is_some()); - if let Some(size_estimate) = self.size_estimate { - self.size_estimate = Some(size_estimate + delta); - } + self.size_estimate += delta; } pub fn contains_item(&self, item: &MonoItem<'tcx>) -> bool { diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index a20e011b91a75..57132949503b2 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -393,6 +393,7 @@ rustc_queries! { TypeChecking { query typeck_item_bodies(_: CrateNum) -> () { + eval_always desc { "type-checking all item bodies" } } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index e6acb6b74dc63..772bfd0992008 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -30,7 +30,7 @@ use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_data_structures::sync::{self, par_iter, Lrc, ParallelIterator}; +use rustc_data_structures::sync::{self, balance_par_for_each, Lrc}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; @@ -2642,8 +2642,9 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn par_body_owners(self, f: F) { - par_iter(&self.hir().krate().body_ids) - .for_each(|&body_id| f(self.hir().body_owner_def_id(body_id))); + balance_par_for_each(&self.hir().krate().body_ids, |&body_id| { + f(self.hir().body_owner_def_id(body_id)) + }); } pub fn provided_trait_methods(self, id: DefId) -> Vec { diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 801bfdea70d6c..3356ddc7b90f3 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -21,7 +21,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::profiling::VerboseTimingGuard; use rustc_data_structures::svh::Svh; -use rustc_data_structures::sync::Lrc; +use rustc_data_structures::sync::{par_partition, Lrc}; use rustc_errors::emitter::Emitter; use rustc_errors::{DiagnosticId, FatalError, Handler, Level}; use rustc_fs_util::link_or_copy; @@ -239,7 +239,7 @@ pub struct CodegenContext { pub worker: usize, // The incremental compilation session directory, or None if we are not // compiling incrementally - pub incr_comp_session_dir: Option, + pub incr_comp_session_dir: Option>, // Used to update CGU re-use information during the thinlto phase. pub cgu_reuse_tracker: CguReuseTracker, // Channel back to the main control thread to send messages to @@ -473,32 +473,47 @@ fn copy_all_cgu_workproducts_to_incr_comp_cache_dir( sess: &Session, compiled_modules: &CompiledModules, ) -> FxHashMap { - let mut work_products = FxHashMap::default(); - if sess.opts.incremental.is_none() { - return work_products; + return FxHashMap::default(); } - let _timer = sess.timer("incr_comp_copy_cgu_workproducts"); + let _timer = sess.timer("incr_comp_copy_all_cgu_workproducts"); - for module in compiled_modules.modules.iter().filter(|m| m.kind == ModuleKind::Regular) { - let mut files = vec![]; + let session_dir = sess.incr_comp_session_dir(); - if let Some(ref path) = module.object { - files.push((WorkProductFileKind::Object, path.clone())); - } - if let Some(ref path) = module.bytecode { - files.push((WorkProductFileKind::Bytecode, path.clone())); - } - if let Some(ref path) = module.bytecode_compressed { - files.push((WorkProductFileKind::BytecodeCompressed, path.clone())); - } + // Split the modules into 3 parts, which limits usage to 3 threads. + // That seems to be all Windows' file system can handle. + let work_product_chunks = par_partition(&compiled_modules.modules, 3, |chunk| { + chunk + .iter() + .filter(|m| m.kind == ModuleKind::Regular) + .filter_map(|module| { + let mut files = vec![]; - if let Some((id, product)) = - copy_cgu_workproducts_to_incr_comp_cache_dir(sess, &module.name, &files) - { - work_products.insert(id, product); - } + if let Some(ref path) = module.object { + files.push((WorkProductFileKind::Object, path.clone())); + } + if let Some(ref path) = module.bytecode { + files.push((WorkProductFileKind::Bytecode, path.clone())); + } + if let Some(ref path) = module.bytecode_compressed { + files.push((WorkProductFileKind::BytecodeCompressed, path.clone())); + } + + copy_cgu_workproducts_to_incr_comp_cache_dir( + sess, + &session_dir, + &module.name, + &files, + ) + }) + .collect::>() + }); + + let mut work_products = FxHashMap::default(); + + for (id, product) in work_product_chunks.into_iter().flat_map(|chunk| chunk.into_iter()) { + work_products.insert(id, product); } work_products @@ -1029,7 +1044,7 @@ fn start_executing_work( exported_symbols, remark: sess.opts.cg.remark.clone(), worker: 0, - incr_comp_session_dir: sess.incr_comp_session_dir_opt().map(|r| r.clone()), + incr_comp_session_dir: sess.incr_comp_session_dir_opt(), cgu_reuse_tracker: sess.cgu_reuse_tracker.clone(), coordinator_send, diag_emitter: shared_emitter.clone(), diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index efd560071202c..d74c1d50e782f 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -40,7 +40,7 @@ use rustc::ty::{self, Instance, Ty, TyCtxt}; use rustc_codegen_utils::{check_for_rustc_errors_attr, symbol_names_test}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::profiling::print_time_passes_entry; -use rustc_data_structures::sync::{par_iter, Lock, ParallelIterator}; +use rustc_data_structures::sync::{par_map, Lock}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_index::vec::Idx; @@ -631,15 +631,13 @@ pub fn codegen_crate( .collect(); // Compile the found CGUs in parallel. - par_iter(cgus) - .map(|(i, _)| { - let start_time = Instant::now(); - let module = backend.compile_codegen_unit(tcx, codegen_units[i].name()); - let mut time = total_codegen_time.lock(); - *time += start_time.elapsed(); - (i, module) - }) - .collect() + par_map(cgus, |(i, _)| { + let start_time = Instant::now(); + let module = backend.compile_codegen_unit(tcx, codegen_units[i].name()); + let mut time = total_codegen_time.lock(); + *time += start_time.elapsed(); + (i, module) + }) }) } else { FxHashMap::default() diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index fa98b4d72dda2..69d03f2668e5c 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -18,14 +18,34 @@ //! depending on the value of cfg!(parallel_compiler). use crate::owning_ref::{Erased, OwningRef}; +use std::any::Any; +use std::cmp; use std::collections::HashMap; use std::hash::{BuildHasher, Hash}; use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; +use std::panic::{catch_unwind, resume_unwind, AssertUnwindSafe}; pub use std::sync::atomic::Ordering; pub use std::sync::atomic::Ordering::SeqCst; +pub fn catch( + store: &Lock>>, + f: impl FnOnce() -> R, +) -> Option { + catch_unwind(AssertUnwindSafe(f)) + .map_err(|err| { + *store.lock() = Some(err); + }) + .ok() +} + +pub fn resume(store: Lock>>) { + if let Some(panic) = store.into_inner() { + resume_unwind(panic); + } +} + cfg_if! { if #[cfg(not(parallel_compiler))] { pub auto trait Send {} @@ -42,7 +62,6 @@ cfg_if! { } use std::ops::Add; - use std::panic::{resume_unwind, catch_unwind, AssertUnwindSafe}; /// This is a single threaded variant of AtomicCell provided by crossbeam. /// Unlike `Atomic` this is intended for all `Copy` types, @@ -157,7 +176,11 @@ cfg_if! { where A: FnOnce() -> RA, B: FnOnce() -> RB { - (oper_a(), oper_b()) + let panic = Lock::new(None); + let a = catch(&panic, oper_a); + let b = catch(&panic, oper_b); + resume(panic); + (a.unwrap(), b.unwrap()) } pub struct SerialScope; @@ -181,46 +204,47 @@ cfg_if! { ($($blocks:tt),*) => { // We catch panics here ensuring that all the blocks execute. // This makes behavior consistent with the parallel compiler. - let mut panic = None; + let panic = $crate::sync::Lock::new(None); $( - if let Err(p) = ::std::panic::catch_unwind( - ::std::panic::AssertUnwindSafe(|| $blocks) - ) { - if panic.is_none() { - panic = Some(p); - } - } + $crate::sync::catch(&panic, || $blocks); )* - if let Some(panic) = panic { - ::std::panic::resume_unwind(panic); + $crate::sync::resume(panic); } } - } - - pub use std::iter::Iterator as ParallelIterator; - pub fn par_iter(t: T) -> T::IntoIter { - t.into_iter() - } + use std::iter::{Iterator, IntoIterator, FromIterator}; - pub fn par_for_each_in( + pub fn par_for_each( t: T, - for_each: - impl Fn(<::IntoIter as Iterator>::Item) + Sync + Send + mut for_each: impl FnMut(<::IntoIter as Iterator>::Item), ) { // We catch panics here ensuring that all the loop iterations execute. // This makes behavior consistent with the parallel compiler. - let mut panic = None; + let panic = Lock::new(None); t.into_iter().for_each(|i| { - if let Err(p) = catch_unwind(AssertUnwindSafe(|| for_each(i))) { - if panic.is_none() { - panic = Some(p); - } - } + catch(&panic, || for_each(i)); }); - if let Some(panic) = panic { - resume_unwind(panic); + resume(panic); } + + pub fn balance_par_for_each( + t: T, + for_each: impl FnMut(<::IntoIter as Iterator>::Item), + ) { + par_for_each(t, for_each) + } + + pub fn par_map>( + t: T, + mut map: impl FnMut(<::IntoIter as Iterator>::Item) -> R, + ) -> C { + // We catch panics here ensuring that all the loop iterations execute. + let panic = Lock::new(None); + let r = t.into_iter().filter_map(|i| { + catch(&panic, || map(i)) + }).collect(); + resume(panic); + r } pub type MetadataRef = OwningRef, [u8]>; @@ -371,7 +395,7 @@ cfg_if! { parallel!(impl $fblock [$block, $($c,)*] [$($rest),*]) }; (impl $fblock:tt [$($blocks:tt,)*] []) => { - ::rustc_data_structures::sync::scope(|s| { + $crate::sync::scope(|s| { $( s.spawn(|_| $blocks); )* @@ -388,20 +412,60 @@ cfg_if! { pub use rayon_core::WorkerLocal; - pub use rayon::iter::ParallelIterator; - use rayon::iter::IntoParallelIterator; + use rayon::iter::{ + ParallelIterator, IndexedParallelIterator, FromParallelIterator, IntoParallelIterator + }; - pub fn par_iter(t: T) -> T::Iter { - t.into_par_iter() + pub fn par_for_each( + t: T, + for_each: impl Fn( + <::Iter as ParallelIterator>::Item + ) + Sync + Send + ) { + // We catch panics here ensuring that all the loop iterations execute. + let panic = Lock::new(None); + t.into_par_iter().for_each(|i| { + catch(&panic, || for_each(i)); + }); + resume(panic); } - pub fn par_for_each_in( + /// This does the same as `par_for_each`, + /// but each loop iteration is stealable by other threads. + pub fn balance_par_for_each( t: T, for_each: impl Fn( <::Iter as ParallelIterator>::Item ) + Sync + Send - ) { - t.into_par_iter().for_each(for_each) + ) + where + ::Iter: IndexedParallelIterator + { + // We catch panics here ensuring that all the loop iterations execute. + let panic = Lock::new(None); + t.into_par_iter().with_max_len(1).for_each(|i| { + catch(&panic, || for_each(i)); + }); + resume(panic); + } + + pub fn par_map< + T: IntoParallelIterator, + R: Send, + C: FromParallelIterator + >( + t: T, + map: impl Fn( + <::Iter as ParallelIterator>::Item + ) -> R + Sync + Send + ) -> C { + // We catch panics here ensuring that all the loop iterations execute. + let panic = Lock::new(None); + let r = t.into_par_iter().filter_map(|i| { + catch(&panic, || map(i)) + }).collect(); + resume(panic); + r } pub type MetadataRef = OwningRef, [u8]>; @@ -414,7 +478,7 @@ cfg_if! { macro_rules! rustc_erase_owner { ($v:expr) => {{ let v = $v; - ::rustc_data_structures::sync::assert_send_val(&v); + $crate::sync::assert_send_val(&v); v.erase_send_sync_owner() }} } @@ -788,3 +852,13 @@ impl DerefMut for OneThread { &mut self.inner } } + +/// Splits the slice into parts and runs `f` on them in parallel. +pub fn par_partition<'a, T: Sync, R: Send>( + slice: &'a [T], + parts: usize, + f: impl Fn(&'a [T]) -> R + Sync, +) -> Vec { + let chunks: Vec<_> = slice.chunks(cmp::max((slice.len() + parts - 1) / parts, 1)).collect(); + par_map(chunks, |chunk| f(chunk)) +} diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index 550e3654d0800..fc016f579e2da 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -9,7 +9,7 @@ crate use FunctionRetTy::*; crate use UnsafeSource::*; use rustc_data_structures::fx::FxHashSet; -use rustc_data_structures::sync::{par_for_each_in, Send, Sync}; +use rustc_data_structures::sync::{par_for_each, Send, Sync}; use rustc_errors::FatalError; use rustc_macros::HashStable_Generic; use rustc_session::node_id::NodeMap; @@ -669,17 +669,17 @@ impl Crate<'_> { { parallel!( { - par_for_each_in(&self.items, |(_, item)| { + par_for_each(&self.items, |(_, item)| { visitor.visit_item(item); }); }, { - par_for_each_in(&self.trait_items, |(_, trait_item)| { + par_for_each(&self.trait_items, |(_, trait_item)| { visitor.visit_trait_item(trait_item); }); }, { - par_for_each_in(&self.impl_items, |(_, impl_item)| { + par_for_each(&self.impl_items, |(_, impl_item)| { visitor.visit_impl_item(impl_item); }); } diff --git a/src/librustc_hir/intravisit.rs b/src/librustc_hir/intravisit.rs index 3dbc5253a9abf..e952845b22cf3 100644 --- a/src/librustc_hir/intravisit.rs +++ b/src/librustc_hir/intravisit.rs @@ -70,6 +70,13 @@ pub trait IntoVisitor<'hir> { fn into_visitor(&self) -> Self::Visitor; } +impl<'hir, T: Clone + Visitor<'hir>> IntoVisitor<'hir> for T { + type Visitor = Self; + fn into_visitor(&self) -> Self::Visitor { + self.clone() + } +} + pub struct ParDeepVisitor(pub V); impl<'hir, V> ParItemLikeVisitor<'hir> for ParDeepVisitor diff --git a/src/librustc_incremental/persist/fs.rs b/src/librustc_incremental/persist/fs.rs index ba20006d73ccc..3b9d290f8e572 100644 --- a/src/librustc_incremental/persist/fs.rs +++ b/src/librustc_incremental/persist/fs.rs @@ -310,7 +310,7 @@ pub fn finalize_session_directory(sess: &Session, svh: Svh) { let _timer = sess.timer("incr_comp_finalize_session_directory"); - let incr_comp_session_dir: PathBuf = sess.incr_comp_session_dir().clone(); + let incr_comp_session_dir = sess.incr_comp_session_dir(); if sess.has_errors_or_delayed_span_bugs() { // If there have been any errors during compilation, we don't want to diff --git a/src/librustc_incremental/persist/work_product.rs b/src/librustc_incremental/persist/work_product.rs index 65a742a202ddd..448602c42d535 100644 --- a/src/librustc_incremental/persist/work_product.rs +++ b/src/librustc_incremental/persist/work_product.rs @@ -5,10 +5,11 @@ use rustc::dep_graph::{WorkProduct, WorkProductFileKind, WorkProductId}; use rustc::session::Session; use rustc_fs_util::link_or_copy; use std::fs as std_fs; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; pub fn copy_cgu_workproducts_to_incr_comp_cache_dir( sess: &Session, + session_dir: &Path, cgu_name: &str, files: &[(WorkProductFileKind, PathBuf)], ) -> Option<(WorkProductId, WorkProduct)> { @@ -17,6 +18,8 @@ pub fn copy_cgu_workproducts_to_incr_comp_cache_dir( return None; } + let _timer = sess.prof.generic_activity("incr_comp_copy_cgu_workproducts"); + let saved_files = files .iter() .map(|&(kind, ref path)| { @@ -26,7 +29,7 @@ pub fn copy_cgu_workproducts_to_incr_comp_cache_dir( WorkProductFileKind::BytecodeCompressed => "bc.z", }; let file_name = format!("{}.{}", cgu_name, extension); - let path_in_incr_dir = in_incr_comp_dir_sess(sess, &file_name); + let path_in_incr_dir = session_dir.join(&file_name); match link_or_copy(path, &path_in_incr_dir) { Ok(_) => Some((kind, file_name)), Err(err) => { diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index c4444fbaa2fc7..ba90729a7b5bd 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -21,7 +21,7 @@ use rustc_builtin_macros; use rustc_codegen_ssa::back::link::emit_metadata; use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc_codegen_utils::link::filename_for_metadata; -use rustc_data_structures::sync::{par_iter, Lrc, Once, ParallelIterator, WorkerLocal}; +use rustc_data_structures::sync::{join, par_for_each, Lrc, Once, WorkerLocal}; use rustc_data_structures::{box_region_allow_access, declare_box_region_type, parallel}; use rustc_errors::PResult; use rustc_expand::base::ExtCtxt; @@ -721,10 +721,13 @@ pub fn create_global_ctxt<'tcx>( let sess = &compiler.session(); let defs = mem::take(&mut resolver_outputs.definitions); - // Construct the HIR map. - let hir_map = map::map_crate(sess, &*resolver_outputs.cstore, &hir_forest, defs); - - let query_result_on_disk_cache = rustc_incremental::load_query_result_cache(sess); + let (query_result_on_disk_cache, hir_map) = join( + || rustc_incremental::load_query_result_cache(sess), + || { + // Construct the HIR map. + map::map_crate(sess, &*resolver_outputs.cstore, &hir_forest, defs) + }, + ); let codegen_backend = compiler.codegen_backend(); let mut local_providers = ty::query::Providers::default(); @@ -786,12 +789,51 @@ fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> { sess.time("looking_for_derive_registrar", || proc_macro_decls::find(tcx)); }, { - par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| { + let _timer = tcx.sess.timer("check_const_bodies"); + par_for_each(&tcx.hir().krate().modules, |(&module, _)| { + let local_def_id = tcx.hir().local_def_id(module); + tcx.ensure().check_mod_const_bodies(local_def_id); + }); + }, + { + let _timer = tcx.sess.timer("check_loops"); + par_for_each(&tcx.hir().krate().modules, |(&module, _)| { let local_def_id = tcx.hir().local_def_id(module); tcx.ensure().check_mod_loops(local_def_id); + }); + }, + { + // This is used by the loop below. + // Make sure it is complete before we fan out. + tcx.get_lang_items(LOCAL_CRATE); + + let _timer = tcx.sess.timer("check_attrs"); + par_for_each(&tcx.hir().krate().modules, |(&module, _)| { + let local_def_id = tcx.hir().local_def_id(module); tcx.ensure().check_mod_attrs(local_def_id); + }); + }, + { + // Prefetch in case lints are emitted. + tcx.lint_levels(LOCAL_CRATE); + }, + { + // Prefetch in case something needs printing. + tcx.visible_parent_map(LOCAL_CRATE); + }, + { + // Prefetch mir_keys + tcx.mir_keys(LOCAL_CRATE); + }, + { + // This is used by `check_mod_unstable_api_usage`. + // Make sure it is complete before we fan out. + tcx.stability_index(LOCAL_CRATE); + + let _timer = tcx.sess.timer("check_unstable_api_usage"); + par_for_each(&tcx.hir().krate().modules, |(&module, _)| { + let local_def_id = tcx.hir().local_def_id(module); tcx.ensure().check_mod_unstable_api_usage(local_def_id); - tcx.ensure().check_mod_const_bodies(local_def_id); }); } ); @@ -802,6 +844,19 @@ fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> { sess.time("misc_checking_2", || { parallel!( + { + sess.time("liveness_checking", || { + par_for_each(&tcx.hir().krate().modules, |(&module, _)| { + // this must run before MIR dump, because + // "not all control paths return a value" is reported here. + // + // maybe move the check to a MIR pass? + let local_def_id = tcx.hir().local_def_id(module); + + tcx.ensure().check_mod_liveness(local_def_id); + }); + }); + }, { sess.time("match_checking", || { tcx.par_body_owners(|def_id| { @@ -810,38 +865,48 @@ fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> { }); }, { - sess.time("liveness_and_intrinsic_checking", || { - par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| { - // this must run before MIR dump, because - // "not all control paths return a value" is reported here. - // - // maybe move the check to a MIR pass? + sess.time("intrinsic_checking", || { + par_for_each(&tcx.hir().krate().modules, |(&module, _)| { let local_def_id = tcx.hir().local_def_id(module); - - tcx.ensure().check_mod_liveness(local_def_id); tcx.ensure().check_mod_intrinsics(local_def_id); }); }); + }, + { + typeck::check_crate_late(tcx); } ); }); - sess.time("MIR_borrow_checking", || { - tcx.par_body_owners(|def_id| tcx.ensure().mir_borrowck(def_id)); - }); - - sess.time("dumping_chalk_like_clauses", || { - rustc_traits::lowering::dump_program_clauses(tcx); - }); - - sess.time("MIR_effect_checking", || { - for def_id in tcx.body_owners() { - mir::transform::check_unsafety::check_unsafety(tcx, def_id) - } + sess.time("misc_checking_3", || { + parallel!( + { + // Prefetch this as it is used later by lint checking and privacy checking. + tcx.privacy_access_levels(LOCAL_CRATE); + }, + { + sess.time("MIR_borrow_checking", || { + tcx.par_body_owners(|def_id| tcx.ensure().mir_borrowck(def_id)); + }); + }, + { + sess.time("dumping_chalk_like_clauses", || { + rustc_traits::lowering::dump_program_clauses(tcx); + }); + }, + { + sess.time("MIR_effect_checking", || { + for def_id in tcx.body_owners() { + mir::transform::check_unsafety::check_unsafety(tcx, def_id) + } + }); + }, + { + sess.time("layout_testing", || layout_test::test_layout(tcx)); + } + ); }); - sess.time("layout_testing", || layout_test::test_layout(tcx)); - // Avoid overwhelming user with errors if borrow checking failed. // I'm not sure how helpful this is, to be honest, but it avoids a // lot of annoying errors in the compile-fail tests (basically, @@ -851,35 +916,27 @@ fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> { return Err(ErrorReported); } - sess.time("misc_checking_3", || { + sess.time("misc_checking_4", || { parallel!( { - tcx.ensure().privacy_access_levels(LOCAL_CRATE); - - parallel!( - { - tcx.ensure().check_private_in_public(LOCAL_CRATE); - }, - { - sess.time("death_checking", || rustc_passes::dead::check_crate(tcx)); - }, - { - sess.time("unused_lib_feature_checking", || { - rustc_passes::stability::check_unused_or_stable_features(tcx) - }); - }, - { - sess.time("lint_checking", || { - rustc_lint::check_crate(tcx, || { - rustc_lint::BuiltinCombinedLateLintPass::new() - }); - }); - } - ); + tcx.ensure().check_private_in_public(LOCAL_CRATE); + }, + { + sess.time("death_checking", || rustc_passes::dead::check_crate(tcx)); + }, + { + sess.time("unused_lib_feature_checking", || { + rustc_passes::stability::check_unused_or_stable_features(tcx) + }); + }, + { + sess.time("lint_checking", || { + rustc_lint::check_crate(tcx, || rustc_lint::BuiltinCombinedLateLintPass::new()); + }); }, { sess.time("privacy_checking_modules", || { - par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| { + par_for_each(&tcx.hir().krate().modules, |(&module, _)| { tcx.ensure().check_mod_privacy(tcx.hir().local_def_id(module)); }); }); diff --git a/src/librustc_lint/late.rs b/src/librustc_lint/late.rs index 30a3788377508..b1467da1bf5e5 100644 --- a/src/librustc_lint/late.rs +++ b/src/librustc_lint/late.rs @@ -17,7 +17,7 @@ use crate::{passes::LateLintPassObject, LateContext, LateLintPass, LintStore}; use rustc::hir::map::Map; use rustc::ty::{self, TyCtxt}; -use rustc_data_structures::sync::{join, par_iter, ParallelIterator}; +use rustc_data_structures::sync::{join, par_for_each}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::intravisit as hir_visit; @@ -481,7 +481,7 @@ pub fn check_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>( || { tcx.sess.time("module_lints", || { // Run per-module lints - par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| { + par_for_each(&tcx.hir().krate().modules, |(&module, _)| { tcx.ensure().lint_mod(tcx.hir().local_def_id(module)); }); }); diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index f5f00c9343561..7bab9ffa8fc82 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -189,7 +189,7 @@ use rustc::ty::print::obsolete::DefPathBasedNames; use rustc::ty::subst::{InternalSubsts, SubstsRef}; use rustc::ty::{self, GenericParamDefKind, Instance, Ty, TyCtxt, TypeFoldable}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::sync::{par_iter, MTLock, MTRef, ParallelIterator}; +use rustc_data_structures::sync::{join, par_for_each, MTLock, MTRef}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, DefIdMap, LOCAL_CRATE}; use rustc_hir::itemlikevisit::ItemLikeVisitor; @@ -278,8 +278,16 @@ pub fn collect_crate_mono_items( ) -> (FxHashSet>, InliningMap<'_>) { let _prof_timer = tcx.prof.generic_activity("monomorphization_collector"); - let roots = - tcx.sess.time("monomorphization_collector_root_collections", || collect_roots(tcx, mode)); + let (roots, _) = join( + || { + tcx.sess + .time("monomorphization_collector_root_collections", || collect_roots(tcx, mode)) + }, + || { + // Prefetch upstream_monomorphizations + tcx.upstream_monomorphizations(LOCAL_CRATE); + }, + ); debug!("building mono item graph, beginning at roots"); @@ -291,7 +299,7 @@ pub fn collect_crate_mono_items( let inlining_map: MTRef<'_, _> = &mut inlining_map; tcx.sess.time("monomorphization_collector_graph_walk", || { - par_iter(roots).for_each(|root| { + par_for_each(roots, |root| { let mut recursion_depths = DefIdMap::default(); collect_items_rec(tcx, root, visited, &mut recursion_depths, inlining_map); }); diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index 0def51a6a33e5..185b54c19f733 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -102,9 +102,9 @@ use rustc::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, Linkage, Visibility} use rustc::mir::mono::{InstantiationMode, MonoItem}; use rustc::ty::print::characteristic_def_id_of_type; use rustc::ty::query::Providers; -use rustc::ty::{self, DefIdTree, InstanceDef, TyCtxt}; +use rustc::ty::{self, DefIdTree, InstanceDef, SymbolName, TyCtxt}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::sync; +use rustc_data_structures::sync::{self, join}; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, DefIdSet, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_span::symbol::Symbol; @@ -125,26 +125,24 @@ fn fallback_cgu_name(name_builder: &mut CodegenUnitNameBuilder<'_>) -> Symbol { name_builder.build_cgu_name(LOCAL_CRATE, &["fallback"], Some("cgu")) } -pub fn partition<'tcx, I>( +pub fn partition<'tcx>( tcx: TyCtxt<'tcx>, - mono_items: I, + mono_items: &[MonoItem<'tcx>], strategy: PartitioningStrategy, inlining_map: &InliningMap<'tcx>, -) -> Vec> -where - I: Iterator>, -{ +) -> Vec> { let _prof_timer = tcx.prof.generic_activity("cgu_partitioning"); // In the first step, we place all regular monomorphizations into their // respective 'home' codegen unit. Regular monomorphizations are all // functions and statics defined in the local crate. - let mut initial_partitioning = { - let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_place_roots"); - place_root_mono_items(tcx, mono_items) - }; - - initial_partitioning.codegen_units.iter_mut().for_each(|cgu| cgu.estimate_size(tcx)); + let (mut initial_partitioning, accessor_map) = join( + || { + let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_place_roots"); + place_root_mono_items(tcx, mono_items) + }, + || accessor_map(tcx, inlining_map), + ); debug_dump(tcx, "INITIAL PARTITIONING:", initial_partitioning.codegen_units.iter()); @@ -173,7 +171,7 @@ where // more freedom to optimize. if !tcx.sess.opts.cg.link_dead_code { let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_internalize_symbols"); - internalize_symbols(tcx, &mut post_inlining, inlining_map); + internalize_symbols(tcx, &mut post_inlining, &accessor_map); } // Finally, sort by codegen unit name, so that we get deterministic results. @@ -209,14 +207,11 @@ struct PostInliningPartitioning<'tcx> { internalization_candidates: FxHashSet>, } -fn place_root_mono_items<'tcx, I>(tcx: TyCtxt<'tcx>, mono_items: I) -> PreInliningPartitioning<'tcx> -where - I: Iterator>, -{ - let mut roots = FxHashSet::default(); - let mut codegen_units = FxHashMap::default(); +fn place_root_mono_items<'tcx>( + tcx: TyCtxt<'tcx>, + mono_items: &[MonoItem<'tcx>], +) -> PreInliningPartitioning<'tcx> { let is_incremental_build = tcx.sess.opts.incremental.is_some(); - let mut internalization_candidates = FxHashSet::default(); // Determine if monomorphizations instantiated in this crate will be made // available to downstream crates. This depends on whether we are in @@ -224,52 +219,79 @@ where // downstream crates. let export_generics = tcx.sess.opts.share_generics() && tcx.local_crate_exports_generics(); - let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx); - let cgu_name_cache = &mut FxHashMap::default(); + let chunks = tcx.prof.generic_activity("place_root_mono_items_par").run(|| { + sync::par_partition(&mono_items, 2, |chunk| { + let mut roots = Vec::new(); + let mut codegen_units = FxHashMap::default(); + let mut internalization_candidates = Vec::new(); - for mono_item in mono_items { - match mono_item.instantiation_mode(tcx) { - InstantiationMode::GloballyShared { .. } => {} - InstantiationMode::LocalCopy => continue, - } + let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx); + let cgu_name_cache = &mut FxHashMap::default(); - let characteristic_def_id = characteristic_def_id_of_mono_item(tcx, mono_item); - let is_volatile = is_incremental_build && mono_item.is_generic_fn(); - - let codegen_unit_name = match characteristic_def_id { - Some(def_id) => compute_codegen_unit_name( - tcx, - cgu_name_builder, - def_id, - is_volatile, - cgu_name_cache, - ), - None => fallback_cgu_name(cgu_name_builder), - }; + for &mono_item in chunk { + match mono_item.instantiation_mode(tcx) { + InstantiationMode::GloballyShared { .. } => {} + InstantiationMode::LocalCopy => continue, + } + + let characteristic_def_id = characteristic_def_id_of_mono_item(tcx, mono_item); + let is_volatile = is_incremental_build && mono_item.is_generic_fn(); + + let codegen_unit_name = match characteristic_def_id { + Some(def_id) => compute_codegen_unit_name( + tcx, + cgu_name_builder, + def_id, + is_volatile, + cgu_name_cache, + ), + None => fallback_cgu_name(cgu_name_builder), + }; - let codegen_unit = codegen_units - .entry(codegen_unit_name) - .or_insert_with(|| CodegenUnit::new(codegen_unit_name)); + let codegen_unit = + codegen_units.entry(codegen_unit_name).or_insert_with(|| (Vec::new(), 0)); - let mut can_be_internalized = true; - let (linkage, visibility) = mono_item_linkage_and_visibility( - tcx, - &mono_item, - &mut can_be_internalized, - export_generics, - ); - if visibility == Visibility::Hidden && can_be_internalized { - internalization_candidates.insert(mono_item); - } + let mut can_be_internalized = true; + let (linkage, visibility) = mono_item_linkage_and_visibility( + tcx, + &mono_item, + &mut can_be_internalized, + export_generics, + ); + if visibility == Visibility::Hidden && can_be_internalized { + internalization_candidates.push(mono_item); + } + + codegen_unit.0.push((mono_item, (linkage, visibility))); + codegen_unit.1 += mono_item.size_estimate(tcx); + + roots.push(mono_item); + } + + (roots, codegen_units, internalization_candidates) + }) + }); - codegen_unit.items_mut().insert(mono_item, (linkage, visibility)); - roots.insert(mono_item); + let _prof_timer = tcx.prof.generic_activity("place_root_mono_items_merge"); + + let mut roots = FxHashSet::default(); + let mut codegen_units: FxHashMap> = FxHashMap::default(); + let mut internalization_candidates = FxHashSet::default(); + + for (chunk_roots, chunk_codegen_units, chunk_internalization_candidates) in chunks { + roots.extend(chunk_roots); + internalization_candidates.extend(chunk_internalization_candidates); + for (name, (items, cost)) in chunk_codegen_units { + let codegen_unit = codegen_units.entry(name).or_insert_with(|| CodegenUnit::new(name)); + codegen_unit.modify_size_estimate(cost); + codegen_unit.items_mut().extend(items); + } } // Always ensure we have at least one CGU; otherwise, if we have a // crate with just types (for example), we could wind up with no CGU. if codegen_units.is_empty() { - let codegen_unit_name = fallback_cgu_name(cgu_name_builder); + let codegen_unit_name = fallback_cgu_name(&mut CodegenUnitNameBuilder::new(tcx)); codegen_units.insert(codegen_unit_name, CodegenUnit::new(codegen_unit_name)); } @@ -592,10 +614,27 @@ fn place_inlined_mono_items<'tcx>( } } +// Build a map from every monomorphization to all the monomorphizations that +// reference it. +fn accessor_map<'tcx>( + tcx: TyCtxt<'tcx>, + inlining_map: &InliningMap<'tcx>, +) -> FxHashMap, Vec>> { + let _prof_timer = tcx.prof.generic_activity("build_accessor_map"); + + let mut accessor_map: FxHashMap, Vec>> = Default::default(); + inlining_map.iter_accesses(|accessor, accessees| { + for accessee in accessees { + accessor_map.entry(*accessee).or_default().push(accessor); + } + }); + accessor_map +} + fn internalize_symbols<'tcx>( _tcx: TyCtxt<'tcx>, partitioning: &mut PostInliningPartitioning<'tcx>, - inlining_map: &InliningMap<'tcx>, + accessor_map: &FxHashMap, Vec>>, ) { if partitioning.codegen_units.len() == 1 { // Fast path for when there is only one codegen unit. In this case we @@ -610,15 +649,6 @@ fn internalize_symbols<'tcx>( return; } - // Build a map from every monomorphization to all the monomorphizations that - // reference it. - let mut accessor_map: FxHashMap, Vec>> = Default::default(); - inlining_map.iter_accesses(|accessor, accessees| { - for accessee in accessees { - accessor_map.entry(*accessee).or_default().push(accessor); - } - }); - let mono_item_placements = &partitioning.mono_item_placements; // For each internalization candidates in each codegen unit, check if it is @@ -792,17 +822,23 @@ where } #[inline(never)] // give this a place in the profiler -fn assert_symbols_are_distinct<'a, 'tcx, I>(tcx: TyCtxt<'tcx>, mono_items: I) -where - I: Iterator>, - 'tcx: 'a, -{ +fn assert_symbols_are_distinct<'tcx>(tcx: TyCtxt<'tcx>, mono_items: &[MonoItem<'tcx>]) { let _prof_timer = tcx.prof.generic_activity("assert_symbols_are_distinct"); - let mut symbols: Vec<_> = - mono_items.map(|mono_item| (mono_item, mono_item.symbol_name(tcx))).collect(); + let mut symbols: Vec<(&MonoItem<'tcx>, SymbolName)> = + sync::par_partition(mono_items, 2, |chunk| { + chunk + .iter() + .map(|mono_item| (mono_item, mono_item.symbol_name(tcx))) + .collect::>() + }) + .into_iter() + .flatten() + .collect(); - symbols.sort_by_key(|sym| sym.1); + tcx.prof + .generic_activity("assert_symbols_are_distinct_sort") + .run(|| symbols.sort_by_key(|sym| sym.1)); for pair in symbols.windows(2) { let sym1 = &pair[0].1; @@ -872,6 +908,8 @@ fn collect_and_partition_mono_items( tcx.sess.abort_if_errors(); + let items: Vec<_> = items.iter().copied().collect(); + let (codegen_units, _) = tcx.sess.time("partition_and_assert_distinct_symbols", || { sync::join( || { @@ -881,12 +919,12 @@ fn collect_and_partition_mono_items( PartitioningStrategy::FixedUnitCount(tcx.sess.codegen_units()) }; - partition(tcx, items.iter().cloned(), strategy, &inlining_map) + partition(tcx, &items, strategy, &inlining_map) .into_iter() .map(Arc::new) .collect::>() }, - || assert_symbols_are_distinct(tcx, items.iter()), + || assert_symbols_are_distinct(tcx, &items), ) }); diff --git a/src/librustc_passes/liveness.rs b/src/librustc_passes/liveness.rs index 7718139f6e924..da344712ab2f4 100644 --- a/src/librustc_passes/liveness.rs +++ b/src/librustc_passes/liveness.rs @@ -106,6 +106,7 @@ use rustc_hir as hir; use rustc_hir::def::*; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{self, FnKind, NestedVisitorMap, Visitor}; +use rustc_hir::itemlikevisit::ParItemLikeVisitor; use rustc_hir::{Expr, HirId, HirIdMap, HirIdSet, Node}; use rustc_span::symbol::sym; use rustc_span::Span; @@ -182,11 +183,28 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> { } } +struct LivenessVisitor<'tcx> { + tcx: TyCtxt<'tcx>, + module_def_id: DefId, +} + +impl<'tcx> ParItemLikeVisitor<'tcx> for LivenessVisitor<'tcx> { + fn visit_item(&self, item: &'tcx hir::Item<'tcx>) { + IrMaps::new(self.tcx, self.module_def_id).visit_item(item); + } + + fn visit_trait_item(&self, trait_item: &'tcx hir::TraitItem<'tcx>) { + IrMaps::new(self.tcx, self.module_def_id).visit_trait_item(trait_item); + } + + fn visit_impl_item(&self, impl_item: &'tcx hir::ImplItem<'tcx>) { + IrMaps::new(self.tcx, self.module_def_id).visit_impl_item(impl_item); + } +} + fn check_mod_liveness(tcx: TyCtxt<'_>, module_def_id: DefId) { - tcx.hir().visit_item_likes_in_module( - module_def_id, - &mut IrMaps::new(tcx, module_def_id).as_deep_visitor(), - ); + tcx.hir() + .par_visit_item_likes_in_module(module_def_id, &LivenessVisitor { tcx, module_def_id }); } pub fn provide(providers: &mut Providers<'_>) { diff --git a/src/librustc_session/session.rs b/src/librustc_session/session.rs index d979247b46d3a..29cbe77588d58 100644 --- a/src/librustc_session/session.rs +++ b/src/librustc_session/session.rs @@ -34,7 +34,7 @@ use rustc_data_structures::profiling::{SelfProfiler, SelfProfilerRef}; use rustc_target::spec::{PanicStrategy, RelroLevel, Target, TargetTriple}; use std; -use std::cell::{self, RefCell}; +use std::cell::RefCell; use std::env; use std::fmt; use std::io::Write; @@ -94,7 +94,7 @@ pub struct Session { /// macro name and definition span in the source crate. pub imported_macro_spans: OneThread>>, - incr_comp_session: OneThread>, + incr_comp_session: Lock, /// Used for incremental compilation tests. Will only be populated if /// `-Zquery-dep-graph` is specified. pub cgu_reuse_tracker: CguReuseTracker, @@ -599,41 +599,28 @@ impl Session { ) } - pub fn set_incr_session_load_dep_graph(&self, load: bool) { - let mut incr_comp_session = self.incr_comp_session.borrow_mut(); - - if let IncrCompSession::Active { ref mut load_dep_graph, .. } = *incr_comp_session { - *load_dep_graph = load; - } - } - - pub fn incr_session_load_dep_graph(&self) -> bool { - let incr_comp_session = self.incr_comp_session.borrow(); - match *incr_comp_session { - IncrCompSession::Active { load_dep_graph, .. } => load_dep_graph, - _ => false, - } - } - pub fn init_incr_comp_session( &self, session_dir: PathBuf, lock_file: flock::Lock, load_dep_graph: bool, ) { - let mut incr_comp_session = self.incr_comp_session.borrow_mut(); + let mut incr_comp_session = self.incr_comp_session.lock(); if let IncrCompSession::NotInitialized = *incr_comp_session { } else { panic!("Trying to initialize IncrCompSession `{:?}`", *incr_comp_session) } - *incr_comp_session = - IncrCompSession::Active { session_directory: session_dir, lock_file, load_dep_graph }; + *incr_comp_session = IncrCompSession::Active { + session_directory: Arc::new(session_dir), + lock_file, + load_dep_graph, + }; } pub fn finalize_incr_comp_session(&self, new_directory_path: PathBuf) { - let mut incr_comp_session = self.incr_comp_session.borrow_mut(); + let mut incr_comp_session = self.incr_comp_session.lock(); if let IncrCompSession::Active { .. } = *incr_comp_session { } else { @@ -641,11 +628,12 @@ impl Session { } // Note: this will also drop the lock file, thus unlocking the directory. - *incr_comp_session = IncrCompSession::Finalized { session_directory: new_directory_path }; + *incr_comp_session = + IncrCompSession::Finalized { session_directory: Arc::new(new_directory_path) }; } pub fn mark_incr_comp_session_as_invalid(&self) { - let mut incr_comp_session = self.incr_comp_session.borrow_mut(); + let mut incr_comp_session = self.incr_comp_session.lock(); let session_directory = match *incr_comp_session { IncrCompSession::Active { ref session_directory, .. } => session_directory.clone(), @@ -657,22 +645,21 @@ impl Session { *incr_comp_session = IncrCompSession::InvalidBecauseOfErrors { session_directory }; } - pub fn incr_comp_session_dir(&self) -> cell::Ref<'_, PathBuf> { - let incr_comp_session = self.incr_comp_session.borrow(); - cell::Ref::map(incr_comp_session, |incr_comp_session| match *incr_comp_session { - IncrCompSession::NotInitialized => panic!( - "trying to get session directory from `IncrCompSession`: {:?}", - *incr_comp_session, - ), + pub fn incr_comp_session_dir(&self) -> Arc { + let session = self.incr_comp_session.lock(); + match *session { + IncrCompSession::NotInitialized => { + panic!("trying to get session directory from `IncrCompSession`: {:?}", *session) + } IncrCompSession::Active { ref session_directory, .. } | IncrCompSession::Finalized { ref session_directory } | IncrCompSession::InvalidBecauseOfErrors { ref session_directory } => { - session_directory + session_directory.clone() } - }) + } } - pub fn incr_comp_session_dir_opt(&self) -> Option> { + pub fn incr_comp_session_dir_opt(&self) -> Option> { self.opts.incremental.as_ref().map(|_| self.incr_comp_session_dir()) } @@ -1050,7 +1037,7 @@ fn build_session_( recursion_limit: Once::new(), type_length_limit: Once::new(), imported_macro_spans: OneThread::new(RefCell::new(FxHashMap::default())), - incr_comp_session: OneThread::new(RefCell::new(IncrCompSession::NotInitialized)), + incr_comp_session: Lock::new(IncrCompSession::NotInitialized), cgu_reuse_tracker, prof, perf_stats: PerfStats { @@ -1188,14 +1175,14 @@ pub enum IncrCompSession { NotInitialized, /// This is the state during which the session directory is private and can /// be modified. - Active { session_directory: PathBuf, lock_file: flock::Lock, load_dep_graph: bool }, + Active { session_directory: Arc, lock_file: flock::Lock, load_dep_graph: bool }, /// This is the state after the session directory has been finalized. In this /// state, the contents of the directory must not be modified any more. - Finalized { session_directory: PathBuf }, + Finalized { session_directory: Arc }, /// This is an error state that is reached when some compilation error has /// occurred. It indicates that the contents of the session directory must /// not be used, since they might be invalid. - InvalidBecauseOfErrors { session_directory: PathBuf }, + InvalidBecauseOfErrors { session_directory: Arc }, } pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index baf9ae1ac2911..0da6035b96a07 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -121,7 +121,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LOCAL_CRATE}; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; -use rustc_hir::itemlikevisit::ItemLikeVisitor; +use rustc_hir::itemlikevisit::ParItemLikeVisitor; use rustc_hir::{ExprKind, GenericArg, HirIdMap, ItemKind, Node, PatKind, QPath}; use rustc_index::vec::Idx; use rustc_span::hygiene::DesugaringKind; @@ -730,12 +730,12 @@ struct CheckItemTypesVisitor<'tcx> { tcx: TyCtxt<'tcx>, } -impl ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> { - fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) { +impl ParItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> { + fn visit_item(&self, i: &'tcx hir::Item<'tcx>) { check_item_type(self.tcx, i); } - fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem<'tcx>) {} - fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem<'tcx>) {} + fn visit_trait_item(&self, _: &'tcx hir::TraitItem<'tcx>) {} + fn visit_impl_item(&self, _: &'tcx hir::ImplItem<'tcx>) {} } pub fn check_wf_new(tcx: TyCtxt<'_>) { @@ -744,7 +744,7 @@ pub fn check_wf_new(tcx: TyCtxt<'_>) { } fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: DefId) { - tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckItemTypesVisitor { tcx }); + tcx.hir().par_visit_item_likes_in_module(module_def_id, &CheckItemTypesVisitor { tcx }); } fn typeck_item_bodies(tcx: TyCtxt<'_>, crate_num: CrateNum) { diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs index ec098c1d89679..ec466173a5b46 100644 --- a/src/librustc_typeck/check_unused.rs +++ b/src/librustc_typeck/check_unused.rs @@ -10,6 +10,8 @@ use rustc_span::Span; use syntax::ast; pub fn check_crate(tcx: TyCtxt<'_>) { + let _timer = tcx.sess.timer("check_unused_imports"); + let mut used_trait_imports = DefIdSet::default(); for &body_id in tcx.hir().krate().bodies.keys() { let item_def_id = tcx.hir().body_owner_def_id(body_id); diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index 8b3db15c02b4e..af90afd948947 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -12,6 +12,7 @@ use rustc::traits::{self, ObligationCause, TraitEngine}; use rustc::ty::adjustment::CoerceUnsizedInfo; use rustc::ty::TypeFoldable; use rustc::ty::{self, Ty, TyCtxt}; +use rustc_data_structures::sync::par_for_each; use rustc_error_codes::*; use rustc_errors::struct_span_err; use rustc_hir as hir; @@ -19,9 +20,16 @@ use rustc_hir::def_id::DefId; use rustc_hir::ItemKind; pub fn check_trait(tcx: TyCtxt<'_>, trait_def_id: DefId) { + if Some(trait_def_id) == tcx.lang_items().copy_trait() { + // Checking `Copy` impls can be expensive. Do it in parallel. + let _timer = tcx.prof.generic_activity("check_implementations_of_copy"); + par_for_each(tcx.hir().trait_impls(trait_def_id), |&impl_id| { + visit_implementation_of_copy(tcx, tcx.hir().local_def_id(impl_id)); + }); + } + Checker { tcx, trait_def_id } .check(tcx.lang_items().drop_trait(), visit_implementation_of_drop) - .check(tcx.lang_items().copy_trait(), visit_implementation_of_copy) .check(tcx.lang_items().coerce_unsized_trait(), visit_implementation_of_coerce_unsized) .check( tcx.lang_items().dispatch_from_dyn_trait(), diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index fd685e77b418c..a91bd83160cef 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -8,6 +8,7 @@ use rustc::traits; use rustc::ty::query::Providers; use rustc::ty::{self, TyCtxt, TypeFoldable}; +use rustc_data_structures::sync::par_for_each; use rustc_error_codes::*; use rustc_errors::struct_span_err; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; @@ -141,16 +142,27 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) { } pub fn check_coherence(tcx: TyCtxt<'_>) { - for &trait_def_id in tcx.hir().krate().trait_impls.keys() { - tcx.ensure().coherent_trait(trait_def_id); - } - - tcx.sess.time("unsafety_checking", || unsafety::check(tcx)); - tcx.sess.time("orphan_checking", || orphan::check(tcx)); - - // these queries are executed for side-effects (error reporting): - tcx.ensure().crate_inherent_impls(LOCAL_CRATE); - tcx.ensure().crate_inherent_impls_overlap_check(LOCAL_CRATE); + parallel!( + { + par_for_each(&tcx.hir().krate().trait_impls, |(&trait_def_id, _)| { + tcx.ensure().coherent_trait(trait_def_id); + }); + }, + { + tcx.sess.time("unsafety_checking", || unsafety::check(tcx)); + }, + { + tcx.sess.time("orphan_checking", || orphan::check(tcx)); + }, + { + // This query is executed for side-effects (error reporting) + tcx.ensure().crate_inherent_impls(LOCAL_CRATE); + }, + { + // This query is executed for side-effects (error reporting) + tcx.ensure().crate_inherent_impls_overlap_check(LOCAL_CRATE); + } + ); } /// Overlap: no two impls for the same trait are implemented for the diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index dca3289747e4c..9454a62c4ba92 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -38,7 +38,7 @@ use rustc_errors::{struct_span_err, Applicability, StashKey}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; -use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; +use rustc_hir::intravisit::{self, NestedVisitorMap, ParDeepVisitor, Visitor}; use rustc_hir::{GenericParamKind, Node, Unsafety}; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; @@ -55,9 +55,9 @@ struct OnlySelfBounds(bool); // Main entry point fn collect_mod_item_types(tcx: TyCtxt<'_>, module_def_id: DefId) { - tcx.hir().visit_item_likes_in_module( + tcx.hir().par_visit_item_likes_in_module( module_def_id, - &mut CollectItemTypesVisitor { tcx }.as_deep_visitor(), + &ParDeepVisitor(CollectItemTypesVisitor { tcx }), ); } @@ -118,6 +118,7 @@ impl<'v> Visitor<'v> for PlaceholderHirTyCollector { } } +#[derive(Clone)] struct CollectItemTypesVisitor<'tcx> { tcx: TyCtxt<'tcx>, } diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index fb87b285fa29f..6274c41c36bc9 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -12,10 +12,11 @@ use crate::constrained_generic_params as cgp; use rustc::ty::query::Providers; use rustc::ty::{self, TyCtxt, TypeFoldable}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::sync::par_for_each; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def_id::DefId; -use rustc_hir::itemlikevisit::ItemLikeVisitor; +use rustc_hir::itemlikevisit::ParItemLikeVisitor; use std::collections::hash_map::Entry::{Occupied, Vacant}; use rustc_span::Span; @@ -56,13 +57,13 @@ pub fn impl_wf_check(tcx: TyCtxt<'_>) { // We will tag this as part of the WF check -- logically, it is, // but it's one that we must perform earlier than the rest of // WfCheck. - for &module in tcx.hir().krate().modules.keys() { + par_for_each(&tcx.hir().krate().modules, |(&module, _)| { tcx.ensure().check_mod_impl_wf(tcx.hir().local_def_id(module)); - } + }); } fn check_mod_impl_wf(tcx: TyCtxt<'_>, module_def_id: DefId) { - tcx.hir().visit_item_likes_in_module(module_def_id, &mut ImplWfCheck { tcx }); + tcx.hir().par_visit_item_likes_in_module(module_def_id, &mut ImplWfCheck { tcx }); } pub fn provide(providers: &mut Providers<'_>) { @@ -73,8 +74,8 @@ struct ImplWfCheck<'tcx> { tcx: TyCtxt<'tcx>, } -impl ItemLikeVisitor<'tcx> for ImplWfCheck<'tcx> { - fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { +impl ParItemLikeVisitor<'tcx> for ImplWfCheck<'tcx> { + fn visit_item(&self, item: &'tcx hir::Item<'tcx>) { if let hir::ItemKind::Impl(.., ref impl_item_refs) = item.kind { let impl_def_id = self.tcx.hir().local_def_id(item.hir_id); enforce_impl_params_are_constrained(self.tcx, impl_def_id, impl_item_refs); @@ -82,9 +83,9 @@ impl ItemLikeVisitor<'tcx> for ImplWfCheck<'tcx> { } } - fn visit_trait_item(&mut self, _trait_item: &'tcx hir::TraitItem<'tcx>) {} + fn visit_trait_item(&self, _trait_item: &'tcx hir::TraitItem<'tcx>) {} - fn visit_impl_item(&mut self, _impl_item: &'tcx hir::ImplItem<'tcx>) {} + fn visit_impl_item(&self, _impl_item: &'tcx hir::ImplItem<'tcx>) {} } fn enforce_impl_params_are_constrained( diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index b951883ac195a..7f650bf515317 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -75,6 +75,9 @@ extern crate log; #[macro_use] extern crate rustc; +#[macro_use] +extern crate rustc_data_structures; + // This is used by Clippy. pub mod expr_use_visitor; @@ -102,6 +105,7 @@ use rustc::ty::subst::SubstsRef; use rustc::ty::{self, Ty, TyCtxt}; use rustc::util; use rustc::util::common::ErrorReported; +use rustc_data_structures::sync::{join, par_for_each}; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; @@ -286,6 +290,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) { } fn check_for_entry_fn(tcx: TyCtxt<'_>) { + let _timer = tcx.sess.prof.generic_activity("check_entry_fn"); match tcx.entry_fn(LOCAL_CRATE) { Some((def_id, EntryFnType::Main)) => check_main_fn_ty(tcx, def_id), Some((def_id, EntryFnType::Start)) => check_start_fn_ty(tcx, def_id), @@ -310,9 +315,13 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorReported> { // FIXME(matthewjasper) We shouldn't need to do this. tcx.sess.track_errors(|| { tcx.sess.time("type_collecting", || { - for &module in tcx.hir().krate().modules.keys() { + // Run dependencies of type collecting before entering the loop + tcx.inferred_outlives_crate(LOCAL_CRATE); + + let _prof_timer = tcx.sess.timer("type_collecting_loop"); + par_for_each(&tcx.hir().krate().modules, |(&module, _)| { tcx.ensure().collect_mod_item_types(tcx.hir().local_def_id(module)); - } + }); }); })?; @@ -340,20 +349,26 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorReported> { tcx.sess.time("wf_checking", || check::check_wf_new(tcx)); })?; - tcx.sess.time("item_types_checking", || { - for &module in tcx.hir().krate().modules.keys() { - tcx.ensure().check_mod_item_types(tcx.hir().local_def_id(module)); - } + tcx.sess.time("item_types_and_item_bodies_checking", || { + join( + || { + tcx.sess.time("item_types_checking", || { + par_for_each(&tcx.hir().krate().modules, |(&module, _)| { + tcx.ensure().check_mod_item_types(tcx.hir().local_def_id(module)); + }); + }) + }, + || tcx.sess.time("item_bodies_checking", || tcx.typeck_item_bodies(LOCAL_CRATE)), + ) }); - tcx.sess.time("item_bodies_checking", || tcx.typeck_item_bodies(LOCAL_CRATE)); - - check_unused::check_crate(tcx); - check_for_entry_fn(tcx); - if tcx.sess.err_count() == 0 { Ok(()) } else { Err(ErrorReported) } } +pub fn check_crate_late(tcx: TyCtxt<'_>) { + join(|| check_unused::check_crate(tcx), || check_for_entry_fn(tcx)); +} + /// A quasi-deprecated helper used in rustdoc and clippy to get /// the type from a HIR node. pub fn hir_ty_to_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'_>) -> Ty<'tcx> { diff --git a/src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs b/src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs index 35ddab95831db..353fe7205d4fe 100644 --- a/src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs +++ b/src/test/ui-fulldeps/lint-plugin-forbid-attrs.rs @@ -12,6 +12,7 @@ fn lintme() { } //~ ERROR item is named 'lintme' //~^ ERROR allow(test_lint) overruled by outer forbid(test_lint) //~| ERROR allow(test_lint) overruled by outer forbid(test_lint) //~| ERROR allow(test_lint) overruled by outer forbid(test_lint) +//~| ERROR allow(test_lint) overruled by outer forbid(test_lint) pub fn main() { lintme(); } diff --git a/src/test/ui-fulldeps/lint-plugin-forbid-attrs.stderr b/src/test/ui-fulldeps/lint-plugin-forbid-attrs.stderr index f93a0a0de5377..b638c0978a64e 100644 --- a/src/test/ui-fulldeps/lint-plugin-forbid-attrs.stderr +++ b/src/test/ui-fulldeps/lint-plugin-forbid-attrs.stderr @@ -45,6 +45,15 @@ LL | #![forbid(test_lint)] LL | #[allow(test_lint)] | ^^^^^^^^^ overruled by previous forbid -error: aborting due to 4 previous errors +error[E0453]: allow(test_lint) overruled by outer forbid(test_lint) + --> $DIR/lint-plugin-forbid-attrs.rs:11:9 + | +LL | #![forbid(test_lint)] + | --------- `forbid` level set here +... +LL | #[allow(test_lint)] + | ^^^^^^^^^ overruled by previous forbid + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0453`. diff --git a/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs b/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs index 695d3aef16905..daa7eedf0f23f 100644 --- a/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs +++ b/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.rs @@ -10,6 +10,7 @@ fn lintme() { } //~ ERROR item is named 'lintme' #[allow(test_lint)] //~ ERROR allow(test_lint) overruled by outer forbid(test_lint) //~| ERROR allow(test_lint) overruled by outer forbid(test_lint) //~| ERROR allow(test_lint) overruled by outer forbid(test_lint) + //~| ERROR allow(test_lint) overruled by outer forbid(test_lint) pub fn main() { lintme(); } diff --git a/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.stderr b/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.stderr index 0302ec84d5620..7a8dbd5976b30 100644 --- a/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.stderr +++ b/src/test/ui-fulldeps/lint-plugin-forbid-cmdline.stderr @@ -38,6 +38,14 @@ LL | #[allow(test_lint)] | = note: `forbid` lint level was set on command line -error: aborting due to 4 previous errors +error[E0453]: allow(test_lint) overruled by outer forbid(test_lint) + --> $DIR/lint-plugin-forbid-cmdline.rs:10:9 + | +LL | #[allow(test_lint)] + | ^^^^^^^^^ overruled by previous forbid + | + = note: `forbid` lint level was set on command line + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0453`. diff --git a/src/test/ui-fulldeps/lint-tool-test.rs b/src/test/ui-fulldeps/lint-tool-test.rs index f92bcd213b844..0d04eb6fcfa96 100644 --- a/src/test/ui-fulldeps/lint-tool-test.rs +++ b/src/test/ui-fulldeps/lint-tool-test.rs @@ -10,10 +10,12 @@ //~^ WARNING lint name `test_lint` is deprecated and may not have an effect in the future //~| WARNING lint name `test_lint` is deprecated and may not have an effect in the future //~| WARNING lint name `test_lint` is deprecated and may not have an effect in the future +//~| WARNING lint name `test_lint` is deprecated and may not have an effect in the future #![deny(clippy_group)] //~^ WARNING lint name `clippy_group` is deprecated and may not have an effect in the future //~| WARNING lint name `clippy_group` is deprecated and may not have an effect in the future //~| WARNING lint name `clippy_group` is deprecated and may not have an effect in the future +//~| WARNING lint name `clippy_group` is deprecated and may not have an effect in the future fn lintme() { } //~ ERROR item is named 'lintme' @@ -30,6 +32,7 @@ pub fn main() { //~^ WARNING lint name `test_group` is deprecated and may not have an effect in the future //~| WARNING lint name `test_group` is deprecated and may not have an effect in the future //~| WARNING lint name `test_group` is deprecated and may not have an effect in the future +//~| WARNING lint name `test_group` is deprecated and may not have an effect in the future #[deny(this_lint_does_not_exist)] //~ WARNING unknown lint: `this_lint_does_not_exist` fn hello() { fn lintmetoo() { } diff --git a/src/test/ui-fulldeps/lint-tool-test.stderr b/src/test/ui-fulldeps/lint-tool-test.stderr index 809b9ac16205d..713548b1fd32a 100644 --- a/src/test/ui-fulldeps/lint-tool-test.stderr +++ b/src/test/ui-fulldeps/lint-tool-test.stderr @@ -7,19 +7,19 @@ LL | #![cfg_attr(foo, warn(test_lint))] = note: `#[warn(renamed_and_removed_lints)]` on by default warning: lint name `clippy_group` is deprecated and may not have an effect in the future. Also `cfg_attr(cargo-clippy)` won't be necessary anymore - --> $DIR/lint-tool-test.rs:13:9 + --> $DIR/lint-tool-test.rs:14:9 | LL | #![deny(clippy_group)] | ^^^^^^^^^^^^ help: change it to: `clippy::group` warning: lint name `test_group` is deprecated and may not have an effect in the future. Also `cfg_attr(cargo-clippy)` won't be necessary anymore - --> $DIR/lint-tool-test.rs:29:9 + --> $DIR/lint-tool-test.rs:31:9 | LL | #[allow(test_group)] | ^^^^^^^^^^ help: change it to: `clippy::test_group` warning: unknown lint: `this_lint_does_not_exist` - --> $DIR/lint-tool-test.rs:33:8 + --> $DIR/lint-tool-test.rs:36:8 | LL | #[deny(this_lint_does_not_exist)] | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,13 +33,13 @@ LL | #![cfg_attr(foo, warn(test_lint))] | ^^^^^^^^^ help: change it to: `clippy::test_lint` warning: lint name `clippy_group` is deprecated and may not have an effect in the future. Also `cfg_attr(cargo-clippy)` won't be necessary anymore - --> $DIR/lint-tool-test.rs:13:9 + --> $DIR/lint-tool-test.rs:14:9 | LL | #![deny(clippy_group)] | ^^^^^^^^^^^^ help: change it to: `clippy::group` warning: lint name `test_group` is deprecated and may not have an effect in the future. Also `cfg_attr(cargo-clippy)` won't be necessary anymore - --> $DIR/lint-tool-test.rs:29:9 + --> $DIR/lint-tool-test.rs:31:9 | LL | #[allow(test_group)] | ^^^^^^^^^^ help: change it to: `clippy::test_group` @@ -59,39 +59,57 @@ LL | #![cfg_attr(foo, warn(test_lint))] | ^^^^^^^^^ help: change it to: `clippy::test_lint` warning: lint name `clippy_group` is deprecated and may not have an effect in the future. Also `cfg_attr(cargo-clippy)` won't be necessary anymore - --> $DIR/lint-tool-test.rs:13:9 + --> $DIR/lint-tool-test.rs:14:9 | LL | #![deny(clippy_group)] | ^^^^^^^^^^^^ help: change it to: `clippy::group` error: item is named 'lintme' - --> $DIR/lint-tool-test.rs:18:1 + --> $DIR/lint-tool-test.rs:20:1 | LL | fn lintme() { } | ^^^^^^^^^^^^^^^ | note: lint level defined here - --> $DIR/lint-tool-test.rs:13:9 + --> $DIR/lint-tool-test.rs:14:9 | LL | #![deny(clippy_group)] | ^^^^^^^^^^^^ = note: `#[deny(clippy::test_lint)]` implied by `#[deny(clippy::group)]` error: item is named 'lintmetoo' - --> $DIR/lint-tool-test.rs:26:5 + --> $DIR/lint-tool-test.rs:28:5 | LL | fn lintmetoo() { } | ^^^^^^^^^^^^^^^^^^ | note: lint level defined here - --> $DIR/lint-tool-test.rs:13:9 + --> $DIR/lint-tool-test.rs:14:9 | LL | #![deny(clippy_group)] | ^^^^^^^^^^^^ = note: `#[deny(clippy::test_group)]` implied by `#[deny(clippy::group)]` warning: lint name `test_group` is deprecated and may not have an effect in the future. Also `cfg_attr(cargo-clippy)` won't be necessary anymore - --> $DIR/lint-tool-test.rs:29:9 + --> $DIR/lint-tool-test.rs:31:9 + | +LL | #[allow(test_group)] + | ^^^^^^^^^^ help: change it to: `clippy::test_group` + +warning: lint name `test_lint` is deprecated and may not have an effect in the future. Also `cfg_attr(cargo-clippy)` won't be necessary anymore + --> $DIR/lint-tool-test.rs:9:23 + | +LL | #![cfg_attr(foo, warn(test_lint))] + | ^^^^^^^^^ help: change it to: `clippy::test_lint` + +warning: lint name `clippy_group` is deprecated and may not have an effect in the future. Also `cfg_attr(cargo-clippy)` won't be necessary anymore + --> $DIR/lint-tool-test.rs:14:9 + | +LL | #![deny(clippy_group)] + | ^^^^^^^^^^^^ help: change it to: `clippy::group` + +warning: lint name `test_group` is deprecated and may not have an effect in the future. Also `cfg_attr(cargo-clippy)` won't be necessary anymore + --> $DIR/lint-tool-test.rs:31:9 | LL | #[allow(test_group)] | ^^^^^^^^^^ help: change it to: `clippy::test_group` diff --git a/src/test/ui/bad/bad-expr-path.rs b/src/test/ui/bad/bad-expr-path.rs index 31fc9cf2cb575..93df6287b6bae 100644 --- a/src/test/ui/bad/bad-expr-path.rs +++ b/src/test/ui/bad/bad-expr-path.rs @@ -1,6 +1,6 @@ mod m1 {} -fn main(arguments: Vec) { //~ ERROR `main` function has wrong type +fn main(arguments: Vec) { log(debug, m1::arguments); //~^ ERROR cannot find function `log` in this scope //~| ERROR cannot find value `debug` in this scope diff --git a/src/test/ui/bad/bad-expr-path.stderr b/src/test/ui/bad/bad-expr-path.stderr index 56bb6e2be88c4..5dfa921aa061d 100644 --- a/src/test/ui/bad/bad-expr-path.stderr +++ b/src/test/ui/bad/bad-expr-path.stderr @@ -16,16 +16,6 @@ error[E0425]: cannot find value `arguments` in module `m1` LL | log(debug, m1::arguments); | ^^^^^^^^^ not found in `m1` -error[E0580]: `main` function has wrong type - --> $DIR/bad-expr-path.rs:3:1 - | -LL | fn main(arguments: Vec) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters - | - = note: expected fn pointer `fn()` - found fn pointer `fn(std::vec::Vec)` - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0425, E0580. -For more information about an error, try `rustc --explain E0425`. +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/bad/bad-expr-path2.rs b/src/test/ui/bad/bad-expr-path2.rs index eb88edb9071ef..737d3c42934e4 100644 --- a/src/test/ui/bad/bad-expr-path2.rs +++ b/src/test/ui/bad/bad-expr-path2.rs @@ -2,7 +2,7 @@ mod m1 { pub mod arguments {} } -fn main(arguments: Vec) { //~ ERROR `main` function has wrong type +fn main(arguments: Vec) { log(debug, m1::arguments); //~^ ERROR cannot find function `log` in this scope //~| ERROR cannot find value `debug` in this scope diff --git a/src/test/ui/bad/bad-expr-path2.stderr b/src/test/ui/bad/bad-expr-path2.stderr index e217c45b267af..98bbadd268163 100644 --- a/src/test/ui/bad/bad-expr-path2.stderr +++ b/src/test/ui/bad/bad-expr-path2.stderr @@ -16,16 +16,7 @@ error[E0423]: expected value, found module `m1::arguments` LL | log(debug, m1::arguments); | ^^^^^^^^^^^^^ not a value -error[E0580]: `main` function has wrong type - --> $DIR/bad-expr-path2.rs:5:1 - | -LL | fn main(arguments: Vec) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters - | - = note: expected fn pointer `fn()` - found fn pointer `fn(std::vec::Vec)` - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0423, E0425, E0580. +Some errors have detailed explanations: E0423, E0425. For more information about an error, try `rustc --explain E0423`. diff --git a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.rs b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.rs index 0f9d37292958a..86c3b8477ade4 100644 --- a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.rs +++ b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.rs @@ -7,5 +7,6 @@ const fn error(_: fn()) {} #[rustc_allow_const_fn_ptr] //~^ ERROR internal implementation detail const fn compiles(_: fn()) {} +//~^ ERROR rustc_promotable and rustc_allow_const_fn_ptr attributes must be paired fn main() {} diff --git a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.stderr b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.stderr index 70a10d9a0c12a..4f93102f49fc6 100644 --- a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.stderr +++ b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.stderr @@ -7,6 +7,12 @@ LL | #[rustc_allow_const_fn_ptr] = note: for more information, see https://github.com/rust-lang/rust/issues/29642 = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable -error: aborting due to previous error +error[E0717]: rustc_promotable and rustc_allow_const_fn_ptr attributes must be paired with either a rustc_const_unstable or a rustc_const_stable attribute + --> $DIR/allow_const_fn_ptr_feature_gate.rs:9:1 + | +LL | const fn compiles(_: fn()) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/deduplicate-diagnostics.duplicate.stderr b/src/test/ui/deduplicate-diagnostics.duplicate.stderr index 3b100b59995f0..49dd15f6a5e01 100644 --- a/src/test/ui/deduplicate-diagnostics.duplicate.stderr +++ b/src/test/ui/deduplicate-diagnostics.duplicate.stderr @@ -28,6 +28,12 @@ error[E0452]: malformed lint attribute input LL | #[deny("literal")] | ^^^^^^^^^ bad attribute argument -error: aborting due to 5 previous errors +error[E0452]: malformed lint attribute input + --> $DIR/deduplicate-diagnostics.rs:8:8 + | +LL | #[deny("literal")] + | ^^^^^^^^^ bad attribute argument + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0452`. diff --git a/src/test/ui/deduplicate-diagnostics.rs b/src/test/ui/deduplicate-diagnostics.rs index c5d41ff2fdac3..2f72c6e61b4b7 100644 --- a/src/test/ui/deduplicate-diagnostics.rs +++ b/src/test/ui/deduplicate-diagnostics.rs @@ -8,4 +8,5 @@ struct S; #[deny("literal")] //~ ERROR malformed lint attribute input //[duplicate]~| ERROR malformed lint attribute input //[duplicate]~| ERROR malformed lint attribute input + //[duplicate]~| ERROR malformed lint attribute input fn main() {} diff --git a/src/test/ui/error-codes/E0452.rs b/src/test/ui/error-codes/E0452.rs index 4e5a6c9301467..9355f9a41a0e6 100644 --- a/src/test/ui/error-codes/E0452.rs +++ b/src/test/ui/error-codes/E0452.rs @@ -4,5 +4,7 @@ //~| ERROR E0452 //~| ERROR E0452 //~| ERROR E0452 + //~| ERROR E0452 + //~| ERROR E0452 fn main() { } diff --git a/src/test/ui/error-codes/E0452.stderr b/src/test/ui/error-codes/E0452.stderr index 30c11e3274e1c..e37602f29f765 100644 --- a/src/test/ui/error-codes/E0452.stderr +++ b/src/test/ui/error-codes/E0452.stderr @@ -34,6 +34,18 @@ error[E0452]: malformed lint attribute input LL | #![allow(foo = "")] | ^^^^^^^^ bad attribute argument -error: aborting due to 6 previous errors +error[E0452]: malformed lint attribute input + --> $DIR/E0452.rs:1:10 + | +LL | #![allow(foo = "")] + | ^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/E0452.rs:1:10 + | +LL | #![allow(foo = "")] + | ^^^^^^^^ bad attribute argument + +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0452`. diff --git a/src/test/ui/error-codes/E0453.rs b/src/test/ui/error-codes/E0453.rs index 69155b0688bc0..f4bc3e049a7da 100644 --- a/src/test/ui/error-codes/E0453.rs +++ b/src/test/ui/error-codes/E0453.rs @@ -4,5 +4,6 @@ //~^ ERROR allow(non_snake_case) overruled by outer forbid(non_snake_case) //~| ERROR allow(non_snake_case) overruled by outer forbid(non_snake_case) //~| ERROR allow(non_snake_case) overruled by outer forbid(non_snake_case) +//~| ERROR allow(non_snake_case) overruled by outer forbid(non_snake_case) fn main() { } diff --git a/src/test/ui/error-codes/E0453.stderr b/src/test/ui/error-codes/E0453.stderr index 138e8483461c9..3ff4f4aef57a7 100644 --- a/src/test/ui/error-codes/E0453.stderr +++ b/src/test/ui/error-codes/E0453.stderr @@ -25,6 +25,15 @@ LL | LL | #[allow(non_snake_case)] | ^^^^^^^^^^^^^^ overruled by previous forbid -error: aborting due to 3 previous errors +error[E0453]: allow(non_snake_case) overruled by outer forbid(non_snake_case) + --> $DIR/E0453.rs:3:9 + | +LL | #![forbid(non_snake_case)] + | -------------- `forbid` level set here +LL | +LL | #[allow(non_snake_case)] + | ^^^^^^^^^^^^^^ overruled by previous forbid + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0453`. diff --git a/src/test/ui/error-codes/E0602.stderr b/src/test/ui/error-codes/E0602.stderr index 70137cb166206..32138e63a4bfb 100644 --- a/src/test/ui/error-codes/E0602.stderr +++ b/src/test/ui/error-codes/E0602.stderr @@ -10,6 +10,10 @@ error[E0602]: unknown lint: `bogus` | = note: requested on the command line with `-D bogus` -error: aborting due to 3 previous errors +error[E0602]: unknown lint: `bogus` + | + = note: requested on the command line with `-D bogus` + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0602`. diff --git a/src/test/ui/feature-gates/feature-gate-lint-reasons.rs b/src/test/ui/feature-gates/feature-gate-lint-reasons.rs index b124e9b2f4d71..2d15bf99613d8 100644 --- a/src/test/ui/feature-gates/feature-gate-lint-reasons.rs +++ b/src/test/ui/feature-gates/feature-gate-lint-reasons.rs @@ -2,5 +2,6 @@ //~^ ERROR lint reasons are experimental //~| ERROR lint reasons are experimental //~| ERROR lint reasons are experimental +//~| ERROR lint reasons are experimental fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-lint-reasons.stderr b/src/test/ui/feature-gates/feature-gate-lint-reasons.stderr index 08ba9d0d3a313..4843f7385042e 100644 --- a/src/test/ui/feature-gates/feature-gate-lint-reasons.stderr +++ b/src/test/ui/feature-gates/feature-gate-lint-reasons.stderr @@ -25,6 +25,15 @@ LL | #![warn(nonstandard_style, reason = "the standard should be respected")] = note: for more information, see https://github.com/rust-lang/rust/issues/54503 = help: add `#![feature(lint_reasons)]` to the crate attributes to enable -error: aborting due to 3 previous errors +error[E0658]: lint reasons are experimental + --> $DIR/feature-gate-lint-reasons.rs:1:28 + | +LL | #![warn(nonstandard_style, reason = "the standard should be respected")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/54503 + = help: add `#![feature(lint_reasons)]` to the crate attributes to enable + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/lint/lint-forbid-attr.rs b/src/test/ui/lint/lint-forbid-attr.rs index 13b28e8830b62..6d12215e99d6a 100644 --- a/src/test/ui/lint/lint-forbid-attr.rs +++ b/src/test/ui/lint/lint-forbid-attr.rs @@ -4,5 +4,6 @@ //~^ ERROR allow(deprecated) overruled by outer forbid(deprecated) //~| ERROR allow(deprecated) overruled by outer forbid(deprecated) //~| ERROR allow(deprecated) overruled by outer forbid(deprecated) +//~| ERROR allow(deprecated) overruled by outer forbid(deprecated) fn main() { } diff --git a/src/test/ui/lint/lint-forbid-attr.stderr b/src/test/ui/lint/lint-forbid-attr.stderr index bf138c317e93d..3b00a0144aa03 100644 --- a/src/test/ui/lint/lint-forbid-attr.stderr +++ b/src/test/ui/lint/lint-forbid-attr.stderr @@ -25,6 +25,15 @@ LL | LL | #[allow(deprecated)] | ^^^^^^^^^^ overruled by previous forbid -error: aborting due to 3 previous errors +error[E0453]: allow(deprecated) overruled by outer forbid(deprecated) + --> $DIR/lint-forbid-attr.rs:3:9 + | +LL | #![forbid(deprecated)] + | ---------- `forbid` level set here +LL | +LL | #[allow(deprecated)] + | ^^^^^^^^^^ overruled by previous forbid + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0453`. diff --git a/src/test/ui/lint/lint-forbid-cmdline.rs b/src/test/ui/lint/lint-forbid-cmdline.rs index 821470c86860a..69528c6f85135 100644 --- a/src/test/ui/lint/lint-forbid-cmdline.rs +++ b/src/test/ui/lint/lint-forbid-cmdline.rs @@ -3,5 +3,6 @@ #[allow(deprecated)] //~ ERROR allow(deprecated) overruled by outer forbid(deprecated) //~| ERROR allow(deprecated) overruled by outer forbid(deprecated) //~| ERROR allow(deprecated) overruled by outer forbid(deprecated) + //~| ERROR allow(deprecated) overruled by outer forbid(deprecated) fn main() { } diff --git a/src/test/ui/lint/lint-forbid-cmdline.stderr b/src/test/ui/lint/lint-forbid-cmdline.stderr index 89a4445d80068..1d2eda5db0780 100644 --- a/src/test/ui/lint/lint-forbid-cmdline.stderr +++ b/src/test/ui/lint/lint-forbid-cmdline.stderr @@ -22,6 +22,14 @@ LL | #[allow(deprecated)] | = note: `forbid` lint level was set on command line -error: aborting due to 3 previous errors +error[E0453]: allow(deprecated) overruled by outer forbid(deprecated) + --> $DIR/lint-forbid-cmdline.rs:3:9 + | +LL | #[allow(deprecated)] + | ^^^^^^^^^^ overruled by previous forbid + | + = note: `forbid` lint level was set on command line + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0453`. diff --git a/src/test/ui/lint/lint-malformed.rs b/src/test/ui/lint/lint-malformed.rs index cf5570753d85d..57ec290cdfb34 100644 --- a/src/test/ui/lint/lint-malformed.rs +++ b/src/test/ui/lint/lint-malformed.rs @@ -5,4 +5,6 @@ //~| ERROR malformed lint attribute //~| ERROR malformed lint attribute //~| ERROR malformed lint attribute + //~| ERROR malformed lint attribute + //~| ERROR malformed lint attribute fn main() { } diff --git a/src/test/ui/lint/lint-malformed.stderr b/src/test/ui/lint/lint-malformed.stderr index 6dc8d4984445e..777197a4f4267 100644 --- a/src/test/ui/lint/lint-malformed.stderr +++ b/src/test/ui/lint/lint-malformed.stderr @@ -40,6 +40,18 @@ error[E0452]: malformed lint attribute input LL | #![allow(bar = "baz")] | ^^^^^^^^^^^ bad attribute argument -error: aborting due to 7 previous errors +error[E0452]: malformed lint attribute input + --> $DIR/lint-malformed.rs:2:10 + | +LL | #![allow(bar = "baz")] + | ^^^^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/lint-malformed.rs:2:10 + | +LL | #![allow(bar = "baz")] + | ^^^^^^^^^^^ bad attribute argument + +error: aborting due to 9 previous errors For more information about this error, try `rustc --explain E0452`. diff --git a/src/test/ui/lint/lint-unknown-lint-cmdline.stderr b/src/test/ui/lint/lint-unknown-lint-cmdline.stderr index 27e7ee7fc03bd..6bd98fa8f51ba 100644 --- a/src/test/ui/lint/lint-unknown-lint-cmdline.stderr +++ b/src/test/ui/lint/lint-unknown-lint-cmdline.stderr @@ -25,6 +25,15 @@ error[E0602]: unknown lint: `dead_cod` = help: did you mean: `dead_code` = note: requested on the command line with `-D dead_cod` -error: aborting due to 6 previous errors +error[E0602]: unknown lint: `bogus` + | + = note: requested on the command line with `-D bogus` + +error[E0602]: unknown lint: `dead_cod` + | + = help: did you mean: `dead_code` + = note: requested on the command line with `-D dead_cod` + +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0602`. diff --git a/src/test/ui/lint/lint-unused-imports-2.rs b/src/test/ui/lint/lint-unused-imports-2.rs new file mode 100644 index 0000000000000..fcc08c3bc725c --- /dev/null +++ b/src/test/ui/lint/lint-unused-imports-2.rs @@ -0,0 +1,23 @@ +#![deny(unused_imports)] +#![allow(dead_code)] + +// Be sure that if we just bring some methods into scope that they're also +// counted as being used. +use test::B; +// But only when actually used: do not get confused by the method with the same name. +use test::B2; //~ ERROR unused import: `test::B2` + +mod test { + pub trait B { + fn b(&self) {} + } + pub trait B2 { + fn b(&self) {} + } + pub struct C; + impl B for C {} +} + +fn main() { + test::C.b(); +} diff --git a/src/test/ui/lint/lint-unused-imports-2.stderr b/src/test/ui/lint/lint-unused-imports-2.stderr new file mode 100644 index 0000000000000..e7e6888c2a278 --- /dev/null +++ b/src/test/ui/lint/lint-unused-imports-2.stderr @@ -0,0 +1,14 @@ +error: unused import: `test::B2` + --> $DIR/lint-unused-imports-2.rs:8:5 + | +LL | use test::B2; + | ^^^^^^^^ + | +note: lint level defined here + --> $DIR/lint-unused-imports-2.rs:1:9 + | +LL | #![deny(unused_imports)] + | ^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/lint/lint-unused-imports.rs b/src/test/ui/lint/lint-unused-imports.rs index 4754d8880763a..73548f1da36e8 100644 --- a/src/test/ui/lint/lint-unused-imports.rs +++ b/src/test/ui/lint/lint-unused-imports.rs @@ -13,11 +13,6 @@ use std::option::Option::{Some, None}; //~^ ERROR unused imports: `None`, `Some` use test::A; //~ ERROR unused import: `test::A` -// Be sure that if we just bring some methods into scope that they're also -// counted as being used. -use test::B; -// But only when actually used: do not get confused by the method with the same name. -use test::B2; //~ ERROR unused import: `test::B2` // Make sure this import is warned about when at least one of its imported names // is unused @@ -30,11 +25,6 @@ mod test2 { mod test { pub trait A { fn a(&self) {} } - pub trait B { fn b(&self) {} } - pub trait B2 { fn b(&self) {} } - pub struct C; - impl A for C {} - impl B for C {} } mod foo { @@ -85,6 +75,5 @@ fn main() { let mut a = 3; let mut b = 4; swap(&mut a, &mut b); - test::C.b(); let _a = foo(); } diff --git a/src/test/ui/lint/lint-unused-imports.stderr b/src/test/ui/lint/lint-unused-imports.stderr index 96d71a228a5f2..b6bf823bcd4c8 100644 --- a/src/test/ui/lint/lint-unused-imports.stderr +++ b/src/test/ui/lint/lint-unused-imports.stderr @@ -23,19 +23,19 @@ LL | use test::A; | ^^^^^^^ error: unused import: `bar` - --> $DIR/lint-unused-imports.rs:24:18 + --> $DIR/lint-unused-imports.rs:19:18 | LL | use test2::{foo, bar}; | ^^^ error: unused import: `foo::Square` - --> $DIR/lint-unused-imports.rs:52:13 + --> $DIR/lint-unused-imports.rs:42:13 | LL | use foo::Square; | ^^^^^^^^^^^ error: the item `g` is imported redundantly - --> $DIR/lint-unused-imports.rs:68:9 + --> $DIR/lint-unused-imports.rs:58:9 | LL | / fn g() { LL | | use self::g; @@ -48,13 +48,13 @@ LL | | } | |_- the item `g` is already defined here error: unused import: `self::g` - --> $DIR/lint-unused-imports.rs:68:9 + --> $DIR/lint-unused-imports.rs:58:9 | LL | use self::g; | ^^^^^^^ error: the item `foo` is imported redundantly - --> $DIR/lint-unused-imports.rs:78:9 + --> $DIR/lint-unused-imports.rs:68:9 | LL | use test2::{foo, bar}; | --- the item `foo` is already imported here @@ -63,16 +63,10 @@ LL | use test2::foo; | ^^^^^^^^^^ error: unused import: `test2::foo` - --> $DIR/lint-unused-imports.rs:78:9 + --> $DIR/lint-unused-imports.rs:68:9 | LL | use test2::foo; | ^^^^^^^^^^ -error: unused import: `test::B2` - --> $DIR/lint-unused-imports.rs:20:5 - | -LL | use test::B2; - | ^^^^^^^^ - -error: aborting due to 10 previous errors +error: aborting due to 9 previous errors diff --git a/src/test/ui/lint/lint-uppercase-variables.stderr b/src/test/ui/lint/lint-uppercase-variables.stderr index b937832ac622d..3f44a64dbbc41 100644 --- a/src/test/ui/lint/lint-uppercase-variables.stderr +++ b/src/test/ui/lint/lint-uppercase-variables.stderr @@ -1,11 +1,3 @@ -warning[E0170]: pattern binding `Foo` is named the same as one of the variants of the type `foo::Foo` - --> $DIR/lint-uppercase-variables.rs:22:9 - | -LL | Foo => {} - | ^^^ help: to match on the variant, qualify the path: `foo::Foo::Foo` - | - = note: `#[warn(bindings_with_variant_name)]` on by default - warning: unused variable: `Foo` --> $DIR/lint-uppercase-variables.rs:22:9 | @@ -19,6 +11,14 @@ LL | #![warn(unused)] | ^^^^^^ = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` +warning[E0170]: pattern binding `Foo` is named the same as one of the variants of the type `foo::Foo` + --> $DIR/lint-uppercase-variables.rs:22:9 + | +LL | Foo => {} + | ^^^ help: to match on the variant, qualify the path: `foo::Foo::Foo` + | + = note: `#[warn(bindings_with_variant_name)]` on by default + error: structure field `X` should have a snake case name --> $DIR/lint-uppercase-variables.rs:10:5 | diff --git a/src/test/ui/lint/outer-forbid.rs b/src/test/ui/lint/outer-forbid.rs index 2a38565f60364..c2e1f0cb4ba7a 100644 --- a/src/test/ui/lint/outer-forbid.rs +++ b/src/test/ui/lint/outer-forbid.rs @@ -9,16 +9,19 @@ #[allow(unused_variables)] //~ ERROR overruled //~| ERROR overruled //~| ERROR overruled + //~| ERROR overruled fn foo() {} #[allow(unused)] //~ ERROR overruled //~| ERROR overruled //~| ERROR overruled + //~| ERROR overruled fn bar() {} #[allow(nonstandard_style)] //~ ERROR overruled //~| ERROR overruled //~| ERROR overruled + //~| ERROR overruled fn main() { println!("hello forbidden world") } diff --git a/src/test/ui/lint/outer-forbid.stderr b/src/test/ui/lint/outer-forbid.stderr index b2e638e7af978..b8c3171ab3a4e 100644 --- a/src/test/ui/lint/outer-forbid.stderr +++ b/src/test/ui/lint/outer-forbid.stderr @@ -8,7 +8,7 @@ LL | #[allow(unused_variables)] | ^^^^^^^^^^^^^^^^ overruled by previous forbid error[E0453]: allow(unused) overruled by outer forbid(unused) - --> $DIR/outer-forbid.rs:14:9 + --> $DIR/outer-forbid.rs:15:9 | LL | #![forbid(unused, non_snake_case)] | ------ `forbid` level set here @@ -17,7 +17,7 @@ LL | #[allow(unused)] | ^^^^^^ overruled by previous forbid error[E0453]: allow(nonstandard_style) overruled by outer forbid(non_snake_case) - --> $DIR/outer-forbid.rs:19:9 + --> $DIR/outer-forbid.rs:21:9 | LL | #![forbid(unused, non_snake_case)] | -------------- `forbid` level set here @@ -35,7 +35,7 @@ LL | #[allow(unused_variables)] | ^^^^^^^^^^^^^^^^ overruled by previous forbid error[E0453]: allow(unused) overruled by outer forbid(unused) - --> $DIR/outer-forbid.rs:14:9 + --> $DIR/outer-forbid.rs:15:9 | LL | #![forbid(unused, non_snake_case)] | ------ `forbid` level set here @@ -44,7 +44,7 @@ LL | #[allow(unused)] | ^^^^^^ overruled by previous forbid error[E0453]: allow(nonstandard_style) overruled by outer forbid(non_snake_case) - --> $DIR/outer-forbid.rs:19:9 + --> $DIR/outer-forbid.rs:21:9 | LL | #![forbid(unused, non_snake_case)] | -------------- `forbid` level set here @@ -62,7 +62,7 @@ LL | #[allow(unused_variables)] | ^^^^^^^^^^^^^^^^ overruled by previous forbid error[E0453]: allow(unused) overruled by outer forbid(unused) - --> $DIR/outer-forbid.rs:14:9 + --> $DIR/outer-forbid.rs:15:9 | LL | #![forbid(unused, non_snake_case)] | ------ `forbid` level set here @@ -71,7 +71,7 @@ LL | #[allow(unused)] | ^^^^^^ overruled by previous forbid error[E0453]: allow(nonstandard_style) overruled by outer forbid(non_snake_case) - --> $DIR/outer-forbid.rs:19:9 + --> $DIR/outer-forbid.rs:21:9 | LL | #![forbid(unused, non_snake_case)] | -------------- `forbid` level set here @@ -79,6 +79,33 @@ LL | #![forbid(unused, non_snake_case)] LL | #[allow(nonstandard_style)] | ^^^^^^^^^^^^^^^^^ overruled by previous forbid -error: aborting due to 9 previous errors +error[E0453]: allow(unused_variables) overruled by outer forbid(unused) + --> $DIR/outer-forbid.rs:9:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +LL | +LL | #[allow(unused_variables)] + | ^^^^^^^^^^^^^^^^ overruled by previous forbid + +error[E0453]: allow(unused) overruled by outer forbid(unused) + --> $DIR/outer-forbid.rs:15:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + +error[E0453]: allow(nonstandard_style) overruled by outer forbid(non_snake_case) + --> $DIR/outer-forbid.rs:21:9 + | +LL | #![forbid(unused, non_snake_case)] + | -------------- `forbid` level set here +... +LL | #[allow(nonstandard_style)] + | ^^^^^^^^^^^^^^^^^ overruled by previous forbid + +error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0453`. diff --git a/src/test/ui/lint/reasons-erroneous.rs b/src/test/ui/lint/reasons-erroneous.rs index 03cf0679fce94..d9cebdc406c52 100644 --- a/src/test/ui/lint/reasons-erroneous.rs +++ b/src/test/ui/lint/reasons-erroneous.rs @@ -4,6 +4,8 @@ //~^ ERROR malformed lint attribute //~| ERROR malformed lint attribute //~| ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| NOTE reason must be a string literal //~| NOTE reason must be a string literal //~| NOTE reason must be a string literal //~| NOTE reason must be a string literal @@ -11,6 +13,8 @@ //~^ ERROR malformed lint attribute //~| ERROR malformed lint attribute //~| ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| NOTE reason must be a string literal //~| NOTE reason must be a string literal //~| NOTE reason must be a string literal //~| NOTE reason must be a string literal @@ -21,6 +25,10 @@ //~| ERROR malformed lint attribute //~| ERROR malformed lint attribute //~| ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| NOTE bad attribute argument +//~| NOTE bad attribute argument //~| NOTE bad attribute argument //~| NOTE bad attribute argument //~| NOTE bad attribute argument @@ -34,6 +42,10 @@ //~| ERROR malformed lint attribute //~| ERROR malformed lint attribute //~| ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| NOTE bad attribute argument +//~| NOTE bad attribute argument //~| NOTE bad attribute argument //~| NOTE bad attribute argument //~| NOTE bad attribute argument @@ -47,6 +59,10 @@ //~| ERROR malformed lint attribute //~| ERROR malformed lint attribute //~| ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| NOTE bad attribute argument +//~| NOTE bad attribute argument //~| NOTE bad attribute argument //~| NOTE bad attribute argument //~| NOTE bad attribute argument @@ -57,6 +73,8 @@ //~^ ERROR malformed lint attribute //~| ERROR malformed lint attribute //~| ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| NOTE reason in lint attribute must come last //~| NOTE reason in lint attribute must come last //~| NOTE reason in lint attribute must come last //~| NOTE reason in lint attribute must come last @@ -64,6 +82,8 @@ //~^ ERROR malformed lint attribute //~| ERROR malformed lint attribute //~| ERROR malformed lint attribute +//~| ERROR malformed lint attribute +//~| NOTE reason in lint attribute must come last //~| NOTE reason in lint attribute must come last //~| NOTE reason in lint attribute must come last //~| NOTE reason in lint attribute must come last diff --git a/src/test/ui/lint/reasons-erroneous.stderr b/src/test/ui/lint/reasons-erroneous.stderr index a84167fed12d0..3a32c2ecfce5f 100644 --- a/src/test/ui/lint/reasons-erroneous.stderr +++ b/src/test/ui/lint/reasons-erroneous.stderr @@ -5,61 +5,61 @@ LL | #![warn(absolute_paths_not_starting_with_crate, reason = 0)] | ^ reason must be a string literal error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:10:40 + --> $DIR/reasons-erroneous.rs:12:40 | LL | #![warn(anonymous_parameters, reason = b"consider these, for we have condemned them")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reason must be a string literal error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:17:29 + --> $DIR/reasons-erroneous.rs:21:29 | LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:17:29 + --> $DIR/reasons-erroneous.rs:21:29 | LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:30:23 + --> $DIR/reasons-erroneous.rs:38:23 | LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:30:23 + --> $DIR/reasons-erroneous.rs:38:23 | LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:43:36 + --> $DIR/reasons-erroneous.rs:55:36 | LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:43:36 + --> $DIR/reasons-erroneous.rs:55:36 | LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:56:44 + --> $DIR/reasons-erroneous.rs:72:44 | LL | #![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")] | ^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:63:25 + --> $DIR/reasons-erroneous.rs:81:25 | LL | #![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last warning: unknown lint: `reason` - --> $DIR/reasons-erroneous.rs:70:39 + --> $DIR/reasons-erroneous.rs:90:39 | LL | #![warn(missing_copy_implementations, reason)] | ^^^^^^ @@ -73,55 +73,55 @@ LL | #![warn(absolute_paths_not_starting_with_crate, reason = 0)] | ^ reason must be a string literal error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:10:40 + --> $DIR/reasons-erroneous.rs:12:40 | LL | #![warn(anonymous_parameters, reason = b"consider these, for we have condemned them")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reason must be a string literal error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:17:29 + --> $DIR/reasons-erroneous.rs:21:29 | LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:17:29 + --> $DIR/reasons-erroneous.rs:21:29 | LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:30:23 + --> $DIR/reasons-erroneous.rs:38:23 | LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:30:23 + --> $DIR/reasons-erroneous.rs:38:23 | LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:43:36 + --> $DIR/reasons-erroneous.rs:55:36 | LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:43:36 + --> $DIR/reasons-erroneous.rs:55:36 | LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:56:44 + --> $DIR/reasons-erroneous.rs:72:44 | LL | #![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")] | ^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:63:25 + --> $DIR/reasons-erroneous.rs:81:25 | LL | #![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last @@ -133,59 +133,119 @@ LL | #![warn(absolute_paths_not_starting_with_crate, reason = 0)] | ^ reason must be a string literal error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:10:40 + --> $DIR/reasons-erroneous.rs:12:40 | LL | #![warn(anonymous_parameters, reason = b"consider these, for we have condemned them")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reason must be a string literal error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:17:29 + --> $DIR/reasons-erroneous.rs:21:29 | LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:17:29 + --> $DIR/reasons-erroneous.rs:21:29 | LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:30:23 + --> $DIR/reasons-erroneous.rs:38:23 | LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:30:23 + --> $DIR/reasons-erroneous.rs:38:23 | LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:43:36 + --> $DIR/reasons-erroneous.rs:55:36 | LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:43:36 + --> $DIR/reasons-erroneous.rs:55:36 | LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:56:44 + --> $DIR/reasons-erroneous.rs:72:44 | LL | #![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")] | ^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last error[E0452]: malformed lint attribute input - --> $DIR/reasons-erroneous.rs:63:25 + --> $DIR/reasons-erroneous.rs:81:25 | LL | #![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last -error: aborting due to 30 previous errors +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:3:58 + | +LL | #![warn(absolute_paths_not_starting_with_crate, reason = 0)] + | ^ reason must be a string literal + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:12:40 + | +LL | #![warn(anonymous_parameters, reason = b"consider these, for we have condemned them")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reason must be a string literal + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:21:29 + | +LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:21:29 + | +LL | #![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:38:23 + | +LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:38:23 + | +LL | #![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:55:36 + | +LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:55:36 + | +LL | #![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bad attribute argument + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:72:44 + | +LL | #![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")] + | ^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last + +error[E0452]: malformed lint attribute input + --> $DIR/reasons-erroneous.rs:81:25 + | +LL | #![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ reason in lint attribute must come last + +error: aborting due to 40 previous errors For more information about this error, try `rustc --explain E0452`. diff --git a/src/test/ui/lint/reasons-forbidden.rs b/src/test/ui/lint/reasons-forbidden.rs index 6a71176aabb15..7a4a739565a36 100644 --- a/src/test/ui/lint/reasons-forbidden.rs +++ b/src/test/ui/lint/reasons-forbidden.rs @@ -5,6 +5,7 @@ //~^ NOTE `forbid` level set here //~| NOTE `forbid` level set here //~| NOTE `forbid` level set here + //~| NOTE `forbid` level set here reason = "our errors & omissions insurance policy doesn't cover unsafe Rust" )] @@ -17,9 +18,12 @@ fn main() { //~^ ERROR allow(unsafe_code) overruled by outer forbid(unsafe_code) //~| ERROR allow(unsafe_code) overruled by outer forbid(unsafe_code) //~| ERROR allow(unsafe_code) overruled by outer forbid(unsafe_code) + //~| ERROR allow(unsafe_code) overruled by outer forbid(unsafe_code) //~| NOTE overruled by previous forbid //~| NOTE overruled by previous forbid //~| NOTE overruled by previous forbid + //~| NOTE overruled by previous forbid + //~| NOTE our errors & omissions insurance policy doesn't cover unsafe Rust //~| NOTE our errors & omissions insurance policy doesn't cover unsafe Rust //~| NOTE our errors & omissions insurance policy doesn't cover unsafe Rust //~| NOTE our errors & omissions insurance policy doesn't cover unsafe Rust diff --git a/src/test/ui/lint/reasons-forbidden.stderr b/src/test/ui/lint/reasons-forbidden.stderr index 0954edea7378c..3ce1b332c369a 100644 --- a/src/test/ui/lint/reasons-forbidden.stderr +++ b/src/test/ui/lint/reasons-forbidden.stderr @@ -1,5 +1,5 @@ error[E0453]: allow(unsafe_code) overruled by outer forbid(unsafe_code) - --> $DIR/reasons-forbidden.rs:16:13 + --> $DIR/reasons-forbidden.rs:17:13 | LL | unsafe_code, | ----------- `forbid` level set here @@ -10,7 +10,7 @@ LL | #[allow(unsafe_code)] = note: our errors & omissions insurance policy doesn't cover unsafe Rust error[E0453]: allow(unsafe_code) overruled by outer forbid(unsafe_code) - --> $DIR/reasons-forbidden.rs:16:13 + --> $DIR/reasons-forbidden.rs:17:13 | LL | unsafe_code, | ----------- `forbid` level set here @@ -21,7 +21,7 @@ LL | #[allow(unsafe_code)] = note: our errors & omissions insurance policy doesn't cover unsafe Rust error[E0453]: allow(unsafe_code) overruled by outer forbid(unsafe_code) - --> $DIR/reasons-forbidden.rs:16:13 + --> $DIR/reasons-forbidden.rs:17:13 | LL | unsafe_code, | ----------- `forbid` level set here @@ -31,6 +31,17 @@ LL | #[allow(unsafe_code)] | = note: our errors & omissions insurance policy doesn't cover unsafe Rust -error: aborting due to 3 previous errors +error[E0453]: allow(unsafe_code) overruled by outer forbid(unsafe_code) + --> $DIR/reasons-forbidden.rs:17:13 + | +LL | unsafe_code, + | ----------- `forbid` level set here +... +LL | #[allow(unsafe_code)] + | ^^^^^^^^^^^ overruled by previous forbid + | + = note: our errors & omissions insurance policy doesn't cover unsafe Rust + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0453`. diff --git a/src/test/ui/privacy/privacy2.stderr b/src/test/ui/privacy/privacy2.stderr index 9f2359657bd7c..f55adc8c70110 100644 --- a/src/test/ui/privacy/privacy2.stderr +++ b/src/test/ui/privacy/privacy2.stderr @@ -12,7 +12,13 @@ LL | use bar::glob::foo; error: requires `sized` lang_item -error: aborting due to 3 previous errors +error: requires `sized` lang_item + +error: requires `sized` lang_item + +error: requires `sized` lang_item + +error: aborting due to 6 previous errors Some errors have detailed explanations: E0432, E0603. For more information about an error, try `rustc --explain E0432`. diff --git a/src/test/ui/privacy/privacy3.stderr b/src/test/ui/privacy/privacy3.stderr index 22c1e48b07d94..42ce456d962a1 100644 --- a/src/test/ui/privacy/privacy3.stderr +++ b/src/test/ui/privacy/privacy3.stderr @@ -6,6 +6,12 @@ LL | use bar::gpriv; error: requires `sized` lang_item -error: aborting due to 2 previous errors +error: requires `sized` lang_item + +error: requires `sized` lang_item + +error: requires `sized` lang_item + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0432`. diff --git a/src/test/ui/span/issue-35987.rs b/src/test/ui/span/issue-35987.rs index 3a6e6ffe24910..7fa1a33ac84c1 100644 --- a/src/test/ui/span/issue-35987.rs +++ b/src/test/ui/span/issue-35987.rs @@ -3,10 +3,11 @@ struct Foo(T); use std::ops::Add; impl Add for Foo { -//~^ ERROR expected trait, found type parameter + //~^ ERROR expected trait, found type parameter type Output = usize; fn add(self, rhs: Self) -> Self::Output { + //~^ ERROR ambiguous associated type unimplemented!(); } } diff --git a/src/test/ui/span/issue-35987.stderr b/src/test/ui/span/issue-35987.stderr index 3245d8655e87d..2ab2400fc7c00 100644 --- a/src/test/ui/span/issue-35987.stderr +++ b/src/test/ui/span/issue-35987.stderr @@ -9,6 +9,13 @@ help: possible better candidate is found in another module, you can import it in LL | use std::ops::Add; | -error: aborting due to previous error +error[E0223]: ambiguous associated type + --> $DIR/issue-35987.rs:9:32 + | +LL | fn add(self, rhs: Self) -> Self::Output { + | ^^^^^^^^^^^^ help: use fully-qualified syntax: ` as Trait>::Output` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0404`. +Some errors have detailed explanations: E0223, E0404. +For more information about an error, try `rustc --explain E0223`. diff --git a/src/test/ui/tool_lints.rs b/src/test/ui/tool_lints.rs index 9c8540eede792..3f79f8c7b08ab 100644 --- a/src/test/ui/tool_lints.rs +++ b/src/test/ui/tool_lints.rs @@ -2,4 +2,5 @@ //~^ ERROR an unknown tool name found in scoped lint: `foo::bar` //~| ERROR an unknown tool name found in scoped lint: `foo::bar` //~| ERROR an unknown tool name found in scoped lint: `foo::bar` +//~| ERROR an unknown tool name found in scoped lint: `foo::bar` fn main() {} diff --git a/src/test/ui/tool_lints.stderr b/src/test/ui/tool_lints.stderr index 86f87784eaf86..90f15d0ad7ee0 100644 --- a/src/test/ui/tool_lints.stderr +++ b/src/test/ui/tool_lints.stderr @@ -16,5 +16,11 @@ error[E0710]: an unknown tool name found in scoped lint: `foo::bar` LL | #[warn(foo::bar)] | ^^^ -error: aborting due to 3 previous errors +error[E0710]: an unknown tool name found in scoped lint: `foo::bar` + --> $DIR/tool_lints.rs:1:8 + | +LL | #[warn(foo::bar)] + | ^^^ + +error: aborting due to 4 previous errors diff --git a/src/test/ui/unknown-lint-tool-name.rs b/src/test/ui/unknown-lint-tool-name.rs index 182aec34b4781..fe67df6c4cc29 100644 --- a/src/test/ui/unknown-lint-tool-name.rs +++ b/src/test/ui/unknown-lint-tool-name.rs @@ -1,8 +1,10 @@ #![deny(foo::bar)] //~ ERROR an unknown tool name found in scoped lint: `foo::bar` //~| ERROR an unknown tool name found in scoped lint: `foo::bar` //~| ERROR an unknown tool name found in scoped lint: `foo::bar` + //~| ERROR an unknown tool name found in scoped lint: `foo::bar` #[allow(foo::bar)] //~ ERROR an unknown tool name found in scoped lint: `foo::bar` //~| ERROR an unknown tool name found in scoped lint: `foo::bar` //~| ERROR an unknown tool name found in scoped lint: `foo::bar` + //~| ERROR an unknown tool name found in scoped lint: `foo::bar` fn main() {} diff --git a/src/test/ui/unknown-lint-tool-name.stderr b/src/test/ui/unknown-lint-tool-name.stderr index 1940f61a47b68..1f5f9b014a80f 100644 --- a/src/test/ui/unknown-lint-tool-name.stderr +++ b/src/test/ui/unknown-lint-tool-name.stderr @@ -5,7 +5,7 @@ LL | #![deny(foo::bar)] | ^^^ error[E0710]: an unknown tool name found in scoped lint: `foo::bar` - --> $DIR/unknown-lint-tool-name.rs:5:9 + --> $DIR/unknown-lint-tool-name.rs:6:9 | LL | #[allow(foo::bar)] | ^^^ @@ -17,7 +17,7 @@ LL | #![deny(foo::bar)] | ^^^ error[E0710]: an unknown tool name found in scoped lint: `foo::bar` - --> $DIR/unknown-lint-tool-name.rs:5:9 + --> $DIR/unknown-lint-tool-name.rs:6:9 | LL | #[allow(foo::bar)] | ^^^ @@ -29,10 +29,22 @@ LL | #![deny(foo::bar)] | ^^^ error[E0710]: an unknown tool name found in scoped lint: `foo::bar` - --> $DIR/unknown-lint-tool-name.rs:5:9 + --> $DIR/unknown-lint-tool-name.rs:6:9 | LL | #[allow(foo::bar)] | ^^^ -error: aborting due to 6 previous errors +error[E0710]: an unknown tool name found in scoped lint: `foo::bar` + --> $DIR/unknown-lint-tool-name.rs:1:9 + | +LL | #![deny(foo::bar)] + | ^^^ + +error[E0710]: an unknown tool name found in scoped lint: `foo::bar` + --> $DIR/unknown-lint-tool-name.rs:6:9 + | +LL | #[allow(foo::bar)] + | ^^^ + +error: aborting due to 8 previous errors