diff --git a/config.toml.example b/config.toml.example index 35f69cd05b607..087dc418e2dce 100644 --- a/config.toml.example +++ b/config.toml.example @@ -82,6 +82,10 @@ # passed to prefer linking to shared libraries. #link-shared = false +# When building llvm, this configures what is being appended to the version. +# If absent, we let the version as-is. +#version-suffix = "-rust" + # On MSVC you can compile LLVM with clang-cl, but the test suite doesn't pass # with clang-cl, so this is special in that it only compiles LLVM with clang-cl #clang-cl = '/path/to/clang-cl.exe' diff --git a/src/Cargo.lock b/src/Cargo.lock index fc2dfcfd8604c..77618a32e2c5f 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -138,7 +138,7 @@ dependencies = [ "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "petgraph 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1471,7 +1471,7 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2433,6 +2433,7 @@ name = "rustdoc" version = "0.0.0" dependencies = [ "minifier 0.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3243,7 +3244,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0fce5d8b5cc33983fc74f78ad552b5522ab41442c4ca91606e4236eb4b5ceefc" "checksum pest_derive 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ab94faafeb93f4c5e3ce81ca0e5a779529a602ad5d09ae6d21996bfb8b6a52bf" -"checksum petgraph 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "8b30dc85588cd02b9b76f5e386535db546d21dc68506cff2abebee0b6445e8e4" +"checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" "checksum phf 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "7d37a244c75a9748e049225155f56dbcb98fe71b192fd25fd23cb914b5ad62f2" "checksum phf_codegen 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "4e4048fe7dd7a06b8127ecd6d3803149126e9b33c7558879846da3a63f734f2b" "checksum phf_generator 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "05a079dd052e7b674d21cb31cbb6c05efd56a2cd2827db7692e2f1a507ebd998" diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 57a526038041e..3e91c2b3e86c8 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -47,7 +47,7 @@ serde_json = "1.0.2" toml = "0.4" lazy_static = "0.2" time = "0.1" -petgraph = "0.4.12" +petgraph = "0.4.13" [dev-dependencies] pretty_assertions = "0.5" diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index bf4d39c4947e5..70b21a1567b0f 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -86,6 +86,7 @@ pub struct Config { pub llvm_targets: Option, pub llvm_experimental_targets: String, pub llvm_link_jobs: Option, + pub llvm_version_suffix: Option, pub lld_enabled: bool, pub lldb_enabled: bool, @@ -256,6 +257,7 @@ struct Llvm { experimental_targets: Option, link_jobs: Option, link_shared: Option, + version_suffix: Option, clang_cl: Option } @@ -516,6 +518,7 @@ impl Config { config.llvm_experimental_targets = llvm.experimental_targets.clone() .unwrap_or("WebAssembly;RISCV".to_string()); config.llvm_link_jobs = llvm.link_jobs; + config.llvm_version_suffix = llvm.version_suffix.clone(); config.llvm_clang_cl = llvm.clang_cl.clone(); } diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 167e4a78edaf8..2d94704fda7d6 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -2056,7 +2056,8 @@ impl Step for Lldb { drop(fs::remove_dir_all(&image)); // Prepare the image directory - let dst = image.join("bin"); + let root = image.join("lib/rustlib").join(&*target); + let dst = root.join("bin"); t!(fs::create_dir_all(&dst)); for program in &["lldb", "lldb-argdumper", "lldb-mi", "lldb-server"] { let exe = bindir.join(exe(program, &target)); @@ -2065,7 +2066,7 @@ impl Step for Lldb { // The libraries. let libdir = builder.llvm_out(target).join("lib"); - let dst = image.join("lib"); + let dst = root.join("lib"); t!(fs::create_dir_all(&dst)); for entry in t!(fs::read_dir(&libdir)) { let entry = entry.unwrap(); @@ -2093,7 +2094,7 @@ impl Step for Lldb { let entry = t!(entry); if let Ok(name) = entry.file_name().into_string() { if name.starts_with("python") { - let dst = image.join(libdir_name) + let dst = root.join(libdir_name) .join(entry.file_name()); t!(fs::create_dir_all(&dst)); builder.cp_r(&entry.path(), &dst); diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index caf38d766f54e..828a7d14c0437 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -239,6 +239,10 @@ impl Step for Llvm { cfg.define("LLVM_NATIVE_BUILD", builder.llvm_out(builder.config.build).join("build")); } + if let Some(ref suffix) = builder.config.llvm_version_suffix { + cfg.define("LLVM_VERSION_SUFFIX", suffix); + } + if let Some(ref python) = builder.config.python { cfg.define("PYTHON_EXECUTABLE", python); } diff --git a/src/doc/book b/src/doc/book index 16c9dee7666c2..cff0930664b68 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit 16c9dee7666c2b2766fd98d89003e028679d1207 +Subproject commit cff0930664b688f1dd22aefb3d16944eb4cdbfd5 diff --git a/src/doc/nomicon b/src/doc/nomicon index ae42ad7aa4d79..7fd493465b7dd 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit ae42ad7aa4d7907cca941371c9eee8de8c2ee40d +Subproject commit 7fd493465b7dd6cf3476f0b834884059bbdd1d93 diff --git a/src/doc/reference b/src/doc/reference index 219e261ddb833..821355a6fd642 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 219e261ddb833a5683627b0a9be87a0f4486abb9 +Subproject commit 821355a6fd642b71988a2f88a3162fb358732012 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index e3719fc78ff4a..e459fb3f07f2b 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit e3719fc78ff4a21dfd13cfcc9e2ca42cb5de29f4 +Subproject commit e459fb3f07f2b930ccd25d348671b8eae233fd64 diff --git a/src/etc/rust-lldb b/src/etc/rust-lldb index 6a2849b55485e..6ed8210349e17 100755 --- a/src/etc/rust-lldb +++ b/src/etc/rust-lldb @@ -12,27 +12,35 @@ # Exit if anything fails set -e -LLDB_VERSION=`lldb --version 2>/dev/null | head -1 | cut -d. -f1` +# Find out where to look for the pretty printer Python module +RUSTC_SYSROOT=`rustc --print sysroot` + +# Find the host triple so we can find lldb in rustlib. +host=`rustc -vV | sed -n -e 's/^host: //p'` + +lldb=lldb +if [ -f "$RUSTC_SYSROOT/lib/rustlib/$host/bin/lldb" ]; then + lldb="$RUSTC_SYSROOT/lib/rustlib/$host/bin/lldb" +else + LLDB_VERSION=`"$lldb" --version 2>/dev/null | head -1 | cut -d. -f1` -if [ "$LLDB_VERSION" = "lldb-350" ] -then - echo "***" + if [ "$LLDB_VERSION" = "lldb-350" ] + then + echo "***" echo \ "WARNING: This version of LLDB has known issues with Rust and cannot \ display the contents of local variables!" - echo "***" + echo "***" + fi fi -# Find out where to look for the pretty printer Python module -RUSTC_SYSROOT=`rustc --print sysroot` - # Prepare commands that will be loaded before any file on the command line has been loaded script_import="command script import \"$RUSTC_SYSROOT/lib/rustlib/etc/lldb_rust_formatters.py\"" category_definition="type summary add --no-value --python-function lldb_rust_formatters.print_val -x \".*\" --category Rust" category_enable="type category enable Rust" # Call LLDB with the commands added to the argument list -exec lldb --one-line-before-file="$script_import" \ +exec "$lldb" --one-line-before-file="$script_import" \ --one-line-before-file="$category_definition" \ --one-line-before-file="$category_enable" \ "$@" diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index dfe0a395ca140..d15568af6aebe 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -574,6 +574,7 @@ define_dep_nodes!( <'tcx> [] IsPanicRuntime(CrateNum), [] IsCompilerBuiltins(CrateNum), [] HasGlobalAllocator(CrateNum), + [] HasPanicHandler(CrateNum), [input] ExternCrate(DefId), [eval_always] LintLevels, [] Specializes { impl1: DefId, impl2: DefId }, diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 778c388c7dec7..272967282e03b 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -159,6 +159,9 @@ pub struct Session { /// Metadata about the allocators for the current crate being compiled pub has_global_allocator: Once, + /// Metadata about the panic handlers for the current crate being compiled + pub has_panic_handler: Once, + /// Cap lint level specified by a driver specifically. pub driver_lint_caps: FxHashMap, } @@ -1160,6 +1163,7 @@ pub fn build_session_( (*GLOBAL_JOBSERVER).clone() }, has_global_allocator: Once::new(), + has_panic_handler: Once::new(), driver_lint_caps: FxHashMap(), }; diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index 837354bfcaf36..2bbf5aacc1aca 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -464,6 +464,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::has_global_allocator<'tcx> { } } +impl<'tcx> QueryDescription<'tcx> for queries::has_panic_handler<'tcx> { + fn describe(_: TyCtxt, _: CrateNum) -> String { + "checking if the crate has_panic_handler".to_string() + } +} + impl<'tcx> QueryDescription<'tcx> for queries::extern_crate<'tcx> { fn describe(_: TyCtxt, _: DefId) -> String { "getting crate's ExternCrateData".to_string() diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 993ba2fd13d0d..f0ca168e9e467 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -381,6 +381,7 @@ define_queries! { <'tcx> [fatal_cycle] fn is_panic_runtime: IsPanicRuntime(CrateNum) -> bool, [fatal_cycle] fn is_compiler_builtins: IsCompilerBuiltins(CrateNum) -> bool, [fatal_cycle] fn has_global_allocator: HasGlobalAllocator(CrateNum) -> bool, + [fatal_cycle] fn has_panic_handler: HasPanicHandler(CrateNum) -> bool, [fatal_cycle] fn is_sanitizer_runtime: IsSanitizerRuntime(CrateNum) -> bool, [fatal_cycle] fn is_profiler_runtime: IsProfilerRuntime(CrateNum) -> bool, [fatal_cycle] fn panic_strategy: GetPanicStrategy(CrateNum) -> PanicStrategy, diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 215fba54499b7..3c26732fbac67 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -1168,6 +1168,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::IsPanicRuntime => { force!(is_panic_runtime, krate!()); } DepKind::IsCompilerBuiltins => { force!(is_compiler_builtins, krate!()); } DepKind::HasGlobalAllocator => { force!(has_global_allocator, krate!()); } + DepKind::HasPanicHandler => { force!(has_panic_handler, krate!()); } DepKind::ExternCrate => { force!(extern_crate, def_id!()); } DepKind::LintLevels => { force!(lint_levels, LOCAL_CRATE); } DepKind::InScopeTraits => { force!(in_scope_traits_map, def_id!().index); } diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 5aa05270a2a0b..87a32b5a53e7a 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -173,6 +173,7 @@ provide! { <'tcx> tcx, def_id, other, cdata, is_panic_runtime => { cdata.root.panic_runtime } is_compiler_builtins => { cdata.root.compiler_builtins } has_global_allocator => { cdata.root.has_global_allocator } + has_panic_handler => { cdata.root.has_panic_handler } is_sanitizer_runtime => { cdata.root.sanitizer_runtime } is_profiler_runtime => { cdata.root.profiler_runtime } panic_strategy => { cdata.root.panic_strategy } diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 0fd43c592c853..aae45c17c6771 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -484,6 +484,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let is_proc_macro = tcx.sess.crate_types.borrow().contains(&CrateType::ProcMacro); let has_default_lib_allocator = attr::contains_name(&attrs, "default_lib_allocator"); let has_global_allocator = *tcx.sess.has_global_allocator.get(); + let has_panic_handler = *tcx.sess.has_panic_handler.try_get().unwrap_or(&false); let root = self.lazy(&CrateRoot { name: tcx.crate_name(LOCAL_CRATE), @@ -494,6 +495,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { panic_strategy: tcx.sess.panic_strategy(), edition: hygiene::default_edition(), has_global_allocator: has_global_allocator, + has_panic_handler: has_panic_handler, has_default_lib_allocator: has_default_lib_allocator, plugin_registrar_fn: tcx.sess .plugin_registrar_fn diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index 8e454ddc0adc4..ab22a8e4db919 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -193,6 +193,7 @@ pub struct CrateRoot { pub panic_strategy: PanicStrategy, pub edition: Edition, pub has_global_allocator: bool, + pub has_panic_handler: bool, pub has_default_lib_allocator: bool, pub plugin_registrar_fn: Option, pub macro_derive_registrar: Option, diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 272f5024f9f1a..5050b5ab2b414 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -1605,10 +1605,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { place_span: (&Place<'tcx>, Span), flow_state: &Flows<'cx, 'gcx, 'tcx>, ) { - // FIXME: analogous code in check_loans first maps `place` to - // its base_path ... but is that what we want here? - let place = self.base_path(place_span.0); - let maybe_uninits = &flow_state.uninits; // Bad scenarios: @@ -1646,8 +1642,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { // // This code covers scenarios 1, 2, and 3. - debug!("check_if_full_path_is_moved place: {:?}", place); - match self.move_path_closest_to(place) { + debug!("check_if_full_path_is_moved place: {:?}", place_span.0); + match self.move_path_closest_to(place_span.0) { Ok(mpi) => { if maybe_uninits.contains(&mpi) { self.report_use_of_moved_or_uninitialized( @@ -1677,10 +1673,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { place_span: (&Place<'tcx>, Span), flow_state: &Flows<'cx, 'gcx, 'tcx>, ) { - // FIXME: analogous code in check_loans first maps `place` to - // its base_path ... but is that what we want here? - let place = self.base_path(place_span.0); - let maybe_uninits = &flow_state.uninits; // Bad scenarios: @@ -1709,8 +1701,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { // // This code covers scenario 1. - debug!("check_if_path_or_subpath_is_moved place: {:?}", place); - if let Some(mpi) = self.move_path_for_place(place) { + debug!("check_if_path_or_subpath_is_moved place: {:?}", place_span.0); + if let Some(mpi) = self.move_path_for_place(place_span.0) { if let Some(child_mpi) = maybe_uninits.has_any_child_of(mpi) { self.report_use_of_moved_or_uninitialized( context, @@ -1813,11 +1805,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { let tcx = self.tcx; match base.ty(self.mir, tcx).to_ty(tcx).sty { ty::Adt(def, _) if def.has_dtor(tcx) => { - - // FIXME: analogous code in - // check_loans.rs first maps - // `base` to its base_path. - self.check_if_path_or_subpath_is_moved( context, InitializationRequiringAction::Assignment, (base, span), flow_state); @@ -2190,35 +2177,6 @@ enum Overlap { Disjoint, } -impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { - // FIXME (#16118): function intended to allow the borrow checker - // to be less precise in its handling of Box while still allowing - // moves out of a Box. They should be removed when/if we stop - // treating Box specially (e.g. when/if DerefMove is added...) - - fn base_path<'d>(&self, place: &'d Place<'tcx>) -> &'d Place<'tcx> { - //! Returns the base of the leftmost (deepest) dereference of an - //! Box in `place`. If there is no dereference of an Box - //! in `place`, then it just returns `place` itself. - - let mut cursor = place; - let mut deepest = place; - loop { - let proj = match *cursor { - Place::Promoted(_) | - Place::Local(..) | Place::Static(..) => return deepest, - Place::Projection(ref proj) => proj, - }; - if proj.elem == ProjectionElem::Deref - && place.ty(self.mir, self.tcx).to_ty(self.tcx).is_box() - { - deepest = &proj.base; - } - cursor = &proj.base; - } - } -} - #[derive(Copy, Clone, PartialEq, Eq, Debug)] struct Context { kind: ContextKind, diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index cb551df910627..995e70fb382fc 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -21,7 +21,7 @@ use rustc::ty::{RegionKind, RegionVid}; use rustc::ty::RegionKind::ReScope; use rustc_data_structures::bitslice::{BitwiseOperator, Word}; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexed_set::IdxSet; use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::sync::Lrc; @@ -53,6 +53,13 @@ pub struct Borrows<'a, 'gcx: 'tcx, 'tcx: 'a> { _nonlexical_regioncx: Rc>, } +struct StackEntry { + bb: mir::BasicBlock, + lo: usize, + hi: usize, + first_part_only: bool +} + fn precompute_borrows_out_of_scope<'tcx>( mir: &Mir<'tcx>, regioncx: &Rc>, @@ -61,48 +68,79 @@ fn precompute_borrows_out_of_scope<'tcx>( borrow_region: RegionVid, location: Location, ) { - // Keep track of places we've locations to check and locations that we have checked. - let mut stack = vec![ location ]; - let mut visited = FxHashSet(); - visited.insert(location); - - debug!( - "borrow {:?} has region {:?} with value {:?}", - borrow_index, - borrow_region, - regioncx.region_value_str(borrow_region), - ); - debug!("borrow {:?} starts at {:?}", borrow_index, location); - while let Some(location) = stack.pop() { - // If region does not contain a point at the location, then add to list and skip - // successor locations. - if !regioncx.region_contains(borrow_region, location) { - debug!("borrow {:?} gets killed at {:?}", borrow_index, location); - borrows_out_of_scope_at_location - .entry(location) - .or_default() - .push(borrow_index); - continue; + // We visit one BB at a time. The complication is that we may start in the + // middle of the first BB visited (the one containing `location`), in which + // case we may have to later on process the first part of that BB if there + // is a path back to its start. + + // For visited BBs, we record the index of the first statement processed. + // (In fully processed BBs this index is 0.) Note also that we add BBs to + // `visited` once they are added to `stack`, before they are actually + // processed, because this avoids the need to look them up again on + // completion. + let mut visited = FxHashMap(); + visited.insert(location.block, location.statement_index); + + let mut stack = vec![]; + stack.push(StackEntry { + bb: location.block, + lo: location.statement_index, + hi: mir[location.block].statements.len(), + first_part_only: false, + }); + + while let Some(StackEntry { bb, lo, hi, first_part_only }) = stack.pop() { + let mut finished_early = first_part_only; + for i in lo ..= hi { + let location = Location { block: bb, statement_index: i }; + // If region does not contain a point at the location, then add to list and skip + // successor locations. + if !regioncx.region_contains(borrow_region, location) { + debug!("borrow {:?} gets killed at {:?}", borrow_index, location); + borrows_out_of_scope_at_location + .entry(location) + .or_default() + .push(borrow_index); + finished_early = true; + break; + } } - let bb_data = &mir[location.block]; - // If this is the last statement in the block, then add the - // terminator successors next. - if location.statement_index == bb_data.statements.len() { - // Add successors to locations to visit, if not visited before. - if let Some(ref terminator) = bb_data.terminator { - for block in terminator.successors() { - let loc = block.start_location(); - if visited.insert(loc) { - stack.push(loc); - } - } - } - } else { - // Visit next statement in block. - let loc = location.successor_within_block(); - if visited.insert(loc) { - stack.push(loc); + if !finished_early { + // Add successor BBs to the work list, if necessary. + let bb_data = &mir[bb]; + assert!(hi == bb_data.statements.len()); + for &succ_bb in bb_data.terminator.as_ref().unwrap().successors() { + visited.entry(succ_bb) + .and_modify(|lo| { + // `succ_bb` has been seen before. If it wasn't + // fully processed, add its first part to `stack` + // for processing. + if *lo > 0 { + stack.push(StackEntry { + bb: succ_bb, + lo: 0, + hi: *lo - 1, + first_part_only: true, + }); + } + // And update this entry with 0, to represent the + // whole BB being processed. + *lo = 0; + }) + .or_insert_with(|| { + // succ_bb hasn't been seen before. Add it to + // `stack` for processing. + stack.push(StackEntry { + bb: succ_bb, + lo: 0, + hi: mir[succ_bb].statements.len(), + first_part_only: false, + }); + // Insert 0 for this BB, to represent the whole BB + // being processed. + 0 + }); } } } diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 73c9af0d11c47..a72ee7ae3794c 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -1147,7 +1147,15 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { None => continue, }; - if binding.is_import() || binding.is_macro_def() { + // Don't reexport `uniform_path` canaries. + let non_canary_import = match binding.kind { + NameBindingKind::Import { directive, .. } => { + !directive.is_uniform_paths_canary + } + _ => false, + }; + + if non_canary_import || binding.is_macro_def() { let def = binding.def(); if def != Def::Err { if !def.def_id().is_local() { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index a45e5c8ec2a45..a1e4c85f82141 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1138,6 +1138,11 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, if let Some(panic_impl_did) = fcx.tcx.lang_items().panic_impl() { if panic_impl_did == fcx.tcx.hir.local_def_id(fn_id) { if let Some(panic_info_did) = fcx.tcx.lang_items().panic_info() { + // at this point we don't care if there are duplicate handlers or if the handler has + // the wrong signature as this value we'll be used when writing metadata and that + // only happens if compilation succeeded + fcx.tcx.sess.has_panic_handler.try_set_same(true); + if declared_ret_ty.sty != ty::Never { fcx.tcx.sess.span_err( decl.output.span(), diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs index fa152b386a825..5967bd1ba3eea 100644 --- a/src/librustc_typeck/check_unused.rs +++ b/src/librustc_typeck/check_unused.rs @@ -117,6 +117,7 @@ fn unused_crates_lint<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) { !tcx.is_compiler_builtins(cnum) && !tcx.is_panic_runtime(cnum) && !tcx.has_global_allocator(cnum) + && !tcx.has_panic_handler(cnum) }) .cloned() .collect(); diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index e163fc68cbda7..845bfad7807d3 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -11,3 +11,4 @@ path = "lib.rs" pulldown-cmark = { version = "0.1.2", default-features = false } minifier = "0.0.19" tempfile = "3" +parking_lot = "0.6.4" diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index e7e371cd56785..34c4c70159f3a 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -69,7 +69,7 @@ impl<'a, 'tcx, 'rcx, 'cstore> BlanketImplFinder <'a, 'tcx, 'rcx, 'cstore> { let real_name = name.clone().map(|name| Ident::from_str(&name)); let param_env = self.cx.tcx.param_env(def_id); for &trait_def_id in self.cx.all_traits.iter() { - if !self.cx.access_levels.borrow().is_doc_reachable(trait_def_id) || + if !self.cx.renderinfo.borrow().access_levels.is_doc_reachable(trait_def_id) || self.cx.generated_synthetics .borrow_mut() .get(&(def_id, trait_def_id)) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 75d7488d26a75..6e1c1d17d6e15 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -29,8 +29,6 @@ use clean::{ self, GetDefId, ToSource, - get_auto_traits_with_def_id, - get_blanket_impls_with_def_id, }; use super::Clean; @@ -56,7 +54,7 @@ pub fn try_inline(cx: &DocContext, def: Def, name: ast::Name, visited: &mut FxHa let inner = match def { Def::Trait(did) => { record_extern_fqn(cx, did, clean::TypeKind::Trait); - ret.extend(build_impls(cx, did, false)); + ret.extend(build_impls(cx, did)); clean::TraitItem(build_external_trait(cx, did)) } Def::Fn(did) => { @@ -65,27 +63,27 @@ pub fn try_inline(cx: &DocContext, def: Def, name: ast::Name, visited: &mut FxHa } Def::Struct(did) => { record_extern_fqn(cx, did, clean::TypeKind::Struct); - ret.extend(build_impls(cx, did, true)); + ret.extend(build_impls(cx, did)); clean::StructItem(build_struct(cx, did)) } Def::Union(did) => { record_extern_fqn(cx, did, clean::TypeKind::Union); - ret.extend(build_impls(cx, did, true)); + ret.extend(build_impls(cx, did)); clean::UnionItem(build_union(cx, did)) } Def::TyAlias(did) => { record_extern_fqn(cx, did, clean::TypeKind::Typedef); - ret.extend(build_impls(cx, did, false)); + ret.extend(build_impls(cx, did)); clean::TypedefItem(build_type_alias(cx, did), false) } Def::Enum(did) => { record_extern_fqn(cx, did, clean::TypeKind::Enum); - ret.extend(build_impls(cx, did, true)); + ret.extend(build_impls(cx, did)); clean::EnumItem(build_enum(cx, did)) } Def::ForeignTy(did) => { record_extern_fqn(cx, did, clean::TypeKind::Foreign); - ret.extend(build_impls(cx, did, false)); + ret.extend(build_impls(cx, did)); clean::ForeignTypeItem } // Never inline enum variants but leave them shown as re-exports. @@ -158,12 +156,11 @@ pub fn load_attrs(cx: &DocContext, did: DefId) -> clean::Attributes { /// These names are used later on by HTML rendering to generate things like /// source links back to the original item. pub fn record_extern_fqn(cx: &DocContext, did: DefId, kind: clean::TypeKind) { + let mut crate_name = cx.tcx.crate_name(did.krate).to_string(); if did.is_local() { - debug!("record_extern_fqn(did={:?}, kind+{:?}): def_id is local, aborting", did, kind); - return; + crate_name = cx.crate_name.clone().unwrap_or(crate_name); } - let crate_name = cx.tcx.crate_name(did.krate).to_string(); let relative = cx.tcx.def_path(did).data.into_iter().filter_map(|elem| { // extern blocks have an empty name let s = elem.data.to_string(); @@ -178,7 +175,12 @@ pub fn record_extern_fqn(cx: &DocContext, did: DefId, kind: clean::TypeKind) { } else { once(crate_name).chain(relative).collect() }; - cx.renderinfo.borrow_mut().external_paths.insert(did, (fqn, kind)); + + if did.is_local() { + cx.renderinfo.borrow_mut().exact_paths.insert(did, fqn); + } else { + cx.renderinfo.borrow_mut().external_paths.insert(did, (fqn, kind)); + } } pub fn build_external_trait(cx: &DocContext, did: DefId) -> clean::Trait { @@ -270,7 +272,7 @@ fn build_type_alias(cx: &DocContext, did: DefId) -> clean::Typedef { } } -pub fn build_impls(cx: &DocContext, did: DefId, auto_traits: bool) -> Vec { +pub fn build_impls(cx: &DocContext, did: DefId) -> Vec { let tcx = cx.tcx; let mut impls = Vec::new(); @@ -278,85 +280,6 @@ pub fn build_impls(cx: &DocContext, did: DefId, auto_traits: bool) -> Vec = auto_impls.into_iter() - .filter(|i| renderinfo.inlined.insert(i.def_id)).collect(); - - impls.extend(new_impls); - } - impls.extend(get_blanket_impls_with_def_id(cx, did)); - } - - // If this is the first time we've inlined something from another crate, then - // we inline *all* impls from all the crates into this crate. Note that there's - // currently no way for us to filter this based on type, and we likely need - // many impls for a variety of reasons. - // - // Primarily, the impls will be used to populate the documentation for this - // type being inlined, but impls can also be used when generating - // documentation for primitives (no way to find those specifically). - if cx.populated_all_crate_impls.get() { - return impls; - } - - cx.populated_all_crate_impls.set(true); - - for &cnum in tcx.crates().iter() { - for did in tcx.all_trait_implementations(cnum).iter() { - build_impl(cx, *did, &mut impls); - } - } - - // Also try to inline primitive impls from other crates. - let lang_items = tcx.lang_items(); - let primitive_impls = [ - lang_items.isize_impl(), - lang_items.i8_impl(), - lang_items.i16_impl(), - lang_items.i32_impl(), - lang_items.i64_impl(), - lang_items.i128_impl(), - lang_items.usize_impl(), - lang_items.u8_impl(), - lang_items.u16_impl(), - lang_items.u32_impl(), - lang_items.u64_impl(), - lang_items.u128_impl(), - lang_items.f32_impl(), - lang_items.f64_impl(), - lang_items.f32_runtime_impl(), - lang_items.f64_runtime_impl(), - lang_items.char_impl(), - lang_items.str_impl(), - lang_items.slice_impl(), - lang_items.slice_u8_impl(), - lang_items.str_alloc_impl(), - lang_items.slice_alloc_impl(), - lang_items.slice_u8_alloc_impl(), - lang_items.const_ptr_impl(), - lang_items.mut_ptr_impl(), - ]; - - for def_id in primitive_impls.iter().filter_map(|&def_id| def_id) { - if !def_id.is_local() { - build_impl(cx, def_id, &mut impls); - - let auto_impls = get_auto_traits_with_def_id(cx, def_id); - let blanket_impls = get_blanket_impls_with_def_id(cx, def_id); - let mut renderinfo = cx.renderinfo.borrow_mut(); - - let new_impls: Vec = auto_impls.into_iter() - .chain(blanket_impls.into_iter()) - .filter(|i| renderinfo.inlined.insert(i.def_id)) - .collect(); - - impls.extend(new_impls); - } - } - impls } @@ -371,30 +294,60 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec) { // Only inline impl if the implemented trait is // reachable in rustdoc generated documentation - if let Some(traitref) = associated_trait { - if !cx.access_levels.borrow().is_doc_reachable(traitref.def_id) { - return + if !did.is_local() { + if let Some(traitref) = associated_trait { + if !cx.renderinfo.borrow().access_levels.is_doc_reachable(traitref.def_id) { + return + } } } - let for_ = tcx.type_of(did).clean(cx); + let for_ = if let Some(nodeid) = tcx.hir.as_local_node_id(did) { + match tcx.hir.expect_item(nodeid).node { + hir::ItemKind::Impl(.., ref t, _) => { + t.clean(cx) + } + _ => panic!("did given to build_impl was not an impl"), + } + } else { + tcx.type_of(did).clean(cx) + }; // Only inline impl if the implementing type is // reachable in rustdoc generated documentation - if let Some(did) = for_.def_id() { - if !cx.access_levels.borrow().is_doc_reachable(did) { - return + if !did.is_local() { + if let Some(did) = for_.def_id() { + if !cx.renderinfo.borrow().access_levels.is_doc_reachable(did) { + return + } } } let predicates = tcx.predicates_of(did); - let trait_items = tcx.associated_items(did).filter_map(|item| { - if associated_trait.is_some() || item.vis == ty::Visibility::Public { - Some(item.clean(cx)) - } else { - None + let (trait_items, generics) = if let Some(nodeid) = tcx.hir.as_local_node_id(did) { + match tcx.hir.expect_item(nodeid).node { + hir::ItemKind::Impl(.., ref gen, _, _, ref item_ids) => { + ( + item_ids.iter() + .map(|ii| tcx.hir.impl_item(ii.id).clean(cx)) + .collect::>(), + gen.clean(cx), + ) + } + _ => panic!("did given to build_impl was not an impl"), } - }).collect::>(); + } else { + ( + tcx.associated_items(did).filter_map(|item| { + if associated_trait.is_some() || item.vis == ty::Visibility::Public { + Some(item.clean(cx)) + } else { + None + } + }).collect::>(), + (tcx.generics_of(did), &predicates).clean(cx), + ) + }; let polarity = tcx.impl_polarity(did); let trait_ = associated_trait.clean(cx).map(|bound| { match bound { @@ -416,10 +369,12 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec) { .collect() }).unwrap_or(FxHashSet()); + debug!("build_impl: impl {:?} for {:?}", trait_.def_id(), for_.def_id()); + ret.push(clean::Item { inner: clean::ImplItem(clean::Impl { unsafety: hir::Unsafety::Normal, - generics: (tcx.generics_of(did), &predicates).clean(cx), + generics, provided_trait_methods: provided, trait_, for_, @@ -464,7 +419,11 @@ fn build_module(cx: &DocContext, did: DefId, visited: &mut FxHashSet) -> } pub fn print_inlined_const(cx: &DocContext, did: DefId) -> String { - cx.tcx.rendered_const(did) + if let Some(node_id) = cx.tcx.hir.as_local_node_id(did) { + cx.tcx.hir.node_to_pretty_string(node_id) + } else { + cx.tcx.rendered_const(did) + } } fn build_const(cx: &DocContext, did: DefId) -> clean::Constant { @@ -575,16 +534,27 @@ fn separate_supertrait_bounds(mut g: clean::Generics) } pub fn record_extern_trait(cx: &DocContext, did: DefId) { - if cx.external_traits.borrow().contains_key(&did) || - cx.active_extern_traits.borrow().contains(&did) - { + if did.is_local() { return; } + { + let external_traits = cx.external_traits.lock(); + if external_traits.borrow().contains_key(&did) || + cx.active_extern_traits.borrow().contains(&did) + { + return; + } + } + cx.active_extern_traits.borrow_mut().push(did); + debug!("record_extern_trait: {:?}", did); let trait_ = build_external_trait(cx, did); - cx.external_traits.borrow_mut().insert(did, trait_); + { + let external_traits = cx.external_traits.lock(); + external_traits.borrow_mut().insert(did, trait_); + } cx.active_extern_traits.borrow_mut().remove_item(&did); } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index da18e3e6b91b3..943bd2526c9c2 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -28,7 +28,6 @@ use syntax::symbol::InternedString; use syntax_pos::{self, DUMMY_SP, Pos, FileName}; use rustc::mir::interpret::ConstValue; -use rustc::middle::privacy::AccessLevels; use rustc::middle::resolve_lifetime as rl; use rustc::ty::fold::TypeFolder; use rustc::middle::lang_items; @@ -56,6 +55,8 @@ use std::cell::RefCell; use std::sync::Arc; use std::u32; +use parking_lot::ReentrantMutex; + use core::{self, DocContext}; use doctree; use visit_ast; @@ -135,10 +136,9 @@ pub struct Crate { pub module: Option, pub externs: Vec<(CrateNum, ExternalCrate)>, pub primitives: Vec<(DefId, PrimitiveType, Attributes)>, - pub access_levels: Arc>, // These are later on moved into `CACHEKEY`, leaving the map empty. // Only here so that they can be filtered through the rustdoc passes. - pub external_traits: FxHashMap, + pub external_traits: Arc>>>, pub masked_crates: FxHashSet, } @@ -209,9 +209,6 @@ impl<'a, 'tcx, 'rcx, 'cstore> Clean for visit_ast::RustdocVisitor<'a, 'tc })); } - let mut access_levels = cx.access_levels.borrow_mut(); - let mut external_traits = cx.external_traits.borrow_mut(); - Crate { name, version: None, @@ -219,8 +216,7 @@ impl<'a, 'tcx, 'rcx, 'cstore> Clean for visit_ast::RustdocVisitor<'a, 'tc module: Some(module), externs, primitives, - access_levels: Arc::new(mem::replace(&mut access_levels, Default::default())), - external_traits: mem::replace(&mut external_traits, Default::default()), + external_traits: cx.external_traits.clone(), masked_crates, } } @@ -579,9 +575,9 @@ impl Clean for doctree::Module { let mut items: Vec = vec![]; items.extend(self.extern_crates.iter().map(|x| x.clean(cx))); items.extend(self.imports.iter().flat_map(|x| x.clean(cx))); - items.extend(self.structs.iter().flat_map(|x| x.clean(cx))); - items.extend(self.unions.iter().flat_map(|x| x.clean(cx))); - items.extend(self.enums.iter().flat_map(|x| x.clean(cx))); + items.extend(self.structs.iter().map(|x| x.clean(cx))); + items.extend(self.unions.iter().map(|x| x.clean(cx))); + items.extend(self.enums.iter().map(|x| x.clean(cx))); items.extend(self.fns.iter().map(|x| x.clean(cx))); items.extend(self.foreigns.iter().flat_map(|x| x.clean(cx))); items.extend(self.mods.iter().map(|x| x.clean(cx))); @@ -2436,7 +2432,7 @@ impl Clean for hir::Ty { if let Def::TyAlias(def_id) = path.def { // Substitute private type aliases if let Some(node_id) = cx.tcx.hir.as_local_node_id(def_id) { - if !cx.access_levels.borrow().is_exported(def_id) { + if !cx.renderinfo.borrow().access_levels.is_exported(def_id) { alias = Some(&cx.tcx.hir.expect_item(node_id).node); } } @@ -2816,14 +2812,10 @@ pub struct Union { pub fields_stripped: bool, } -impl Clean> for doctree::Struct { - fn clean(&self, cx: &DocContext) -> Vec { - let name = self.name.clean(cx); - let mut ret = get_auto_traits_with_node_id(cx, self.id, name.clone()); - ret.extend(get_blanket_impls_with_node_id(cx, self.id, name.clone())); - - ret.push(Item { - name: Some(name), +impl Clean for doctree::Struct { + fn clean(&self, cx: &DocContext) -> Item { + Item { + name: Some(self.name.clean(cx)), attrs: self.attrs.clean(cx), source: self.whence.clean(cx), def_id: cx.tcx.hir.local_def_id(self.id), @@ -2836,20 +2828,14 @@ impl Clean> for doctree::Struct { fields: self.fields.clean(cx), fields_stripped: false, }), - }); - - ret + } } } -impl Clean> for doctree::Union { - fn clean(&self, cx: &DocContext) -> Vec { - let name = self.name.clean(cx); - let mut ret = get_auto_traits_with_node_id(cx, self.id, name.clone()); - ret.extend(get_blanket_impls_with_node_id(cx, self.id, name.clone())); - - ret.push(Item { - name: Some(name), +impl Clean for doctree::Union { + fn clean(&self, cx: &DocContext) -> Item { + Item { + name: Some(self.name.clean(cx)), attrs: self.attrs.clean(cx), source: self.whence.clean(cx), def_id: cx.tcx.hir.local_def_id(self.id), @@ -2862,9 +2848,7 @@ impl Clean> for doctree::Union { fields: self.fields.clean(cx), fields_stripped: false, }), - }); - - ret + } } } @@ -2895,14 +2879,10 @@ pub struct Enum { pub variants_stripped: bool, } -impl Clean> for doctree::Enum { - fn clean(&self, cx: &DocContext) -> Vec { - let name = self.name.clean(cx); - let mut ret = get_auto_traits_with_node_id(cx, self.id, name.clone()); - ret.extend(get_blanket_impls_with_node_id(cx, self.id, name.clone())); - - ret.push(Item { - name: Some(name), +impl Clean for doctree::Enum { + fn clean(&self, cx: &DocContext) -> Item { + Item { + name: Some(self.name.clean(cx)), attrs: self.attrs.clean(cx), source: self.whence.clean(cx), def_id: cx.tcx.hir.local_def_id(self.id), @@ -2914,9 +2894,7 @@ impl Clean> for doctree::Enum { generics: self.generics.clean(cx), variants_stripped: false, }), - }); - - ret + } } } @@ -3445,11 +3423,7 @@ fn build_deref_target_impls(cx: &DocContext, let primitive = match *target { ResolvedPath { did, .. } if did.is_local() => continue, ResolvedPath { did, .. } => { - // We set the last parameter to false to avoid looking for auto-impls for traits - // and therefore avoid an ICE. - // The reason behind this is that auto-traits don't propagate through Deref so - // we're not supposed to synthesise impls for them. - ret.extend(inline::build_impls(cx, did, false)); + ret.extend(inline::build_impls(cx, did)); continue } _ => match target.primitive_type() { diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index a312913a69c17..253d8b93c667b 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -36,11 +36,13 @@ use syntax::symbol::keywords; use syntax_pos::DUMMY_SP; use errors; use errors::emitter::{Emitter, EmitterWriter}; +use parking_lot::ReentrantMutex; -use std::cell::{RefCell, Cell}; +use std::cell::RefCell; use std::mem; use rustc_data_structures::sync::{self, Lrc}; use std::rc::Rc; +use std::sync::Arc; use std::path::PathBuf; use visit_ast::RustdocVisitor; @@ -60,16 +62,13 @@ pub struct DocContext<'a, 'tcx: 'a, 'rcx: 'a, 'cstore: 'rcx> { /// The stack of module NodeIds up till this point pub crate_name: Option, pub cstore: Rc, - pub populated_all_crate_impls: Cell, // Note that external items for which `doc(hidden)` applies to are shown as // non-reachable while local items aren't. This is because we're reusing // the access levels from crateanalysis. - /// Later on moved into `clean::Crate` - pub access_levels: RefCell>, /// Later on moved into `html::render::CACHE_KEY` pub renderinfo: RefCell, /// Later on moved through `clean::Crate` into `html::render::CACHE_KEY` - pub external_traits: RefCell>, + pub external_traits: Arc>>>, /// Used while populating `external_traits` to ensure we don't process the same trait twice at /// the same time. pub active_extern_traits: RefCell>, @@ -506,16 +505,17 @@ pub fn run_core(search_paths: SearchPaths, clean::path_to_def(&tcx, &["core", "marker", "Send"]) }; + let mut renderinfo = RenderInfo::default(); + renderinfo.access_levels = access_levels; + let ctxt = DocContext { tcx, resolver: &resolver, crate_name, cstore: cstore.clone(), - populated_all_crate_impls: Cell::new(false), - access_levels: RefCell::new(access_levels), external_traits: Default::default(), active_extern_traits: Default::default(), - renderinfo: Default::default(), + renderinfo: RefCell::new(renderinfo), ty_substs: Default::default(), lt_substs: Default::default(), impl_trait_bounds: Default::default(), diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs index 6d96bc8e36038..b8e27c5317083 100644 --- a/src/librustdoc/fold.rs +++ b/src/librustdoc/fold.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::mem; - use clean::*; pub struct StripItem(pub Item); @@ -116,11 +114,14 @@ pub trait DocFolder : Sized { fn fold_crate(&mut self, mut c: Crate) -> Crate { c.module = c.module.take().and_then(|module| self.fold_item(module)); - let traits = mem::replace(&mut c.external_traits, Default::default()); - c.external_traits.extend(traits.into_iter().map(|(k, mut v)| { - v.items = v.items.into_iter().filter_map(|i| self.fold_item(i)).collect(); - (k, v) - })); + { + let guard = c.external_traits.lock(); + let traits = guard.replace(Default::default()); + guard.borrow_mut().extend(traits.into_iter().map(|(k, mut v)| { + v.items = v.items.into_iter().filter_map(|i| self.fold_item(i)).collect(); + (k, v) + })); + } c } } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 972c2f0e15c5e..e6ef9e97da8eb 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -313,7 +313,7 @@ pub struct Cache { // Note that external items for which `doc(hidden)` applies to are shown as // non-reachable while local items aren't. This is because we're reusing // the access levels from crateanalysis. - pub access_levels: Arc>, + pub access_levels: AccessLevels, /// The version of the crate being documented, if given from the `--crate-version` flag. pub crate_version: Option, @@ -337,6 +337,15 @@ pub struct Cache { // and their parent id here and indexes them at the end of crate parsing. orphan_impl_items: Vec<(DefId, clean::Item)>, + // Similarly to `orphan_impl_items`, sometimes trait impls are picked up + // even though the trait itself is not exported. This can happen if a trait + // was defined in function/expression scope, since the impl will be picked + // up by `collect-trait-impls` but the trait won't be scraped out in the HIR + // crawl. In order to prevent crashes when looking for spotlight traits or + // when gathering trait documentation on a type, hold impls here while + // folding and add them to the cache later on if we find the trait. + orphan_trait_impls: Vec<(DefId, FxHashSet, Impl)>, + /// Aliases added through `#[doc(alias = "...")]`. Since a few items can have the same alias, /// we need the alias element to have an array of items. aliases: FxHashMap>, @@ -350,6 +359,7 @@ pub struct RenderInfo { pub external_paths: ::core::ExternalPaths, pub external_typarams: FxHashMap, pub exact_paths: FxHashMap>, + pub access_levels: AccessLevels, pub deref_trait_did: Option, pub deref_mut_trait_did: Option, pub owned_box_did: Option, @@ -569,6 +579,7 @@ pub fn run(mut krate: clean::Crate, external_paths, external_typarams, exact_paths, + access_levels, deref_trait_did, deref_mut_trait_did, owned_box_did, @@ -591,10 +602,11 @@ pub fn run(mut krate: clean::Crate, extern_locations: FxHashMap(), primitive_locations: FxHashMap(), stripped_mod: false, - access_levels: krate.access_levels.clone(), + access_levels, crate_version: krate.version.take(), orphan_impl_items: Vec::new(), - traits: mem::replace(&mut krate.external_traits, FxHashMap()), + orphan_trait_impls: Vec::new(), + traits: krate.external_traits.lock().replace(FxHashMap()), deref_trait_did, deref_mut_trait_did, owned_box_did, @@ -636,6 +648,14 @@ pub fn run(mut krate: clean::Crate, cache.stack.push(krate.name.clone()); krate = cache.fold_crate(krate); + for (trait_did, dids, impl_) in cache.orphan_trait_impls.drain(..) { + if cache.traits.contains_key(&trait_did) { + for did in dids { + cache.impls.entry(did).or_insert(vec![]).push(impl_.clone()); + } + } + } + // Build our search index let index = build_index(&krate, &mut cache); @@ -1223,6 +1243,10 @@ impl<'a> SourceCollector<'a> { impl DocFolder for Cache { fn fold_item(&mut self, item: clean::Item) -> Option { + if item.def_id.is_local() { + debug!("folding {} \"{:?}\", id {:?}", item.type_(), item.name, item.def_id); + } + // If this is a stripped module, // we don't want it or its children in the search index. let orig_stripped_mod = match item.inner { @@ -1451,10 +1475,16 @@ impl DocFolder for Cache { } else { unreachable!() }; - for did in dids { - self.impls.entry(did).or_default().push(Impl { - impl_item: item.clone(), - }); + let impl_item = Impl { + impl_item: item, + }; + if impl_item.trait_did().map_or(true, |d| self.traits.contains_key(&d)) { + for did in dids { + self.impls.entry(did).or_insert(vec![]).push(impl_item.clone()); + } + } else { + let trait_did = impl_item.trait_did().unwrap(); + self.orphan_trait_impls.push((trait_did, dids, impl_item)); } None } else { diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 1acae86f0068f..d0b00fd52ee77 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -25,6 +25,7 @@ #![feature(ptr_offset_from)] #![feature(crate_visibility_modifier)] #![feature(const_fn)] +#![feature(drain_filter)] #![recursion_limit="256"] @@ -49,6 +50,7 @@ extern crate rustc_errors as errors; extern crate pulldown_cmark; extern crate tempfile; extern crate minifier; +extern crate parking_lot; extern crate serialize as rustc_serialize; // used by deriving diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs new file mode 100644 index 0000000000000..56940483d7be2 --- /dev/null +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -0,0 +1,130 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use clean::*; + +use super::Pass; +use core::DocContext; +use fold::DocFolder; + +pub const COLLECT_TRAIT_IMPLS: Pass = + Pass::early("collect-trait-impls", collect_trait_impls, + "retrieves trait impls for items in the crate"); + +pub fn collect_trait_impls(krate: Crate, cx: &DocContext) -> Crate { + let mut synth = SyntheticImplCollector::new(cx); + let mut krate = synth.fold_crate(krate); + + if let Some(ref mut it) = krate.module { + if let ModuleItem(Module { ref mut items, .. }) = it.inner { + items.extend(synth.impls); + + for &cnum in cx.tcx.crates().iter() { + for &did in cx.tcx.all_trait_implementations(cnum).iter() { + inline::build_impl(cx, did, items); + } + } + + // `tcx.crates()` doesn't include the local crate, and `tcx.all_trait_implementations` + // doesn't work with it anyway, so pull them from the HIR map instead + for &trait_did in cx.all_traits.iter() { + for &impl_node in cx.tcx.hir.trait_impls(trait_did) { + let impl_did = cx.tcx.hir.local_def_id(impl_node); + inline::build_impl(cx, impl_did, items); + } + } + + // Also try to inline primitive impls from other crates. + let lang_items = cx.tcx.lang_items(); + let primitive_impls = [ + lang_items.isize_impl(), + lang_items.i8_impl(), + lang_items.i16_impl(), + lang_items.i32_impl(), + lang_items.i64_impl(), + lang_items.i128_impl(), + lang_items.usize_impl(), + lang_items.u8_impl(), + lang_items.u16_impl(), + lang_items.u32_impl(), + lang_items.u64_impl(), + lang_items.u128_impl(), + lang_items.f32_impl(), + lang_items.f64_impl(), + lang_items.f32_runtime_impl(), + lang_items.f64_runtime_impl(), + lang_items.char_impl(), + lang_items.str_impl(), + lang_items.slice_impl(), + lang_items.slice_u8_impl(), + lang_items.str_alloc_impl(), + lang_items.slice_alloc_impl(), + lang_items.slice_u8_alloc_impl(), + lang_items.const_ptr_impl(), + lang_items.mut_ptr_impl(), + ]; + + for def_id in primitive_impls.iter().filter_map(|&def_id| def_id) { + if !def_id.is_local() { + inline::build_impl(cx, def_id, items); + + let auto_impls = get_auto_traits_with_def_id(cx, def_id); + let blanket_impls = get_blanket_impls_with_def_id(cx, def_id); + let mut renderinfo = cx.renderinfo.borrow_mut(); + + let new_impls: Vec = auto_impls.into_iter() + .chain(blanket_impls.into_iter()) + .filter(|i| renderinfo.inlined.insert(i.def_id)) + .collect(); + + items.extend(new_impls); + } + } + } else { + panic!("collect-trait-impls can't run"); + } + } else { + panic!("collect-trait-impls can't run"); + } + + krate +} + +struct SyntheticImplCollector<'a, 'tcx: 'a, 'rcx: 'a, 'cstore: 'rcx> { + cx: &'a DocContext<'a, 'tcx, 'rcx, 'cstore>, + impls: Vec, +} + +impl<'a, 'tcx, 'rcx, 'cstore> SyntheticImplCollector<'a, 'tcx, 'rcx, 'cstore> { + fn new(cx: &'a DocContext<'a, 'tcx, 'rcx, 'cstore>) -> Self { + SyntheticImplCollector { + cx, + impls: Vec::new(), + } + } +} + +impl<'a, 'tcx, 'rcx, 'cstore> DocFolder for SyntheticImplCollector<'a, 'tcx, 'rcx, 'cstore> { + fn fold_item(&mut self, i: Item) -> Option { + if i.is_struct() || i.is_enum() || i.is_union() { + if let (Some(node_id), Some(name)) = + (self.cx.tcx.hir.as_local_node_id(i.def_id), i.name.clone()) + { + self.impls.extend(get_auto_traits_with_node_id(self.cx, node_id, name.clone())); + self.impls.extend(get_blanket_impls_with_node_id(self.cx, node_id, name)); + } else { + self.impls.extend(get_auto_traits_with_def_id(self.cx, i.def_id)); + self.impls.extend(get_blanket_impls_with_def_id(self.cx, i.def_id)); + } + } + + self.fold_item_recur(i) + } +} diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index 16251877bb106..24fec62dd573a 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -43,6 +43,9 @@ pub use self::propagate_doc_cfg::PROPAGATE_DOC_CFG; mod collect_intra_doc_links; pub use self::collect_intra_doc_links::COLLECT_INTRA_DOC_LINKS; +mod collect_trait_impls; +pub use self::collect_trait_impls::COLLECT_TRAIT_IMPLS; + /// Represents a single pass. #[derive(Copy, Clone)] pub enum Pass { @@ -132,10 +135,12 @@ pub const PASSES: &'static [Pass] = &[ STRIP_PRIV_IMPORTS, PROPAGATE_DOC_CFG, COLLECT_INTRA_DOC_LINKS, + COLLECT_TRAIT_IMPLS, ]; /// The list of passes run by default. pub const DEFAULT_PASSES: &'static [&'static str] = &[ + "collect-trait-impls", "strip-hidden", "strip-private", "collect-intra-doc-links", @@ -146,6 +151,7 @@ pub const DEFAULT_PASSES: &'static [&'static str] = &[ /// The list of default passes run with `--document-private-items` is passed to rustdoc. pub const DEFAULT_PRIVATE_PASSES: &'static [&'static str] = &[ + "collect-trait-impls", "strip-priv-imports", "collect-intra-doc-links", "collapse-docs", @@ -189,6 +195,7 @@ impl<'a> fold::DocFolder for Stripper<'a> { // We need to recurse into stripped modules to strip things // like impl methods but when doing so we must not add any // items to the `retained` set. + debug!("Stripper: recursing into stripped {} {:?}", i.type_(), i.name); let old = mem::replace(&mut self.update_retained, false); let ret = self.fold_item_recur(i); self.update_retained = old; @@ -212,6 +219,7 @@ impl<'a> fold::DocFolder for Stripper<'a> { | clean::ForeignTypeItem => { if i.def_id.is_local() { if !self.access_levels.is_exported(i.def_id) { + debug!("Stripper: stripping {} {:?}", i.type_(), i.name); return None; } } @@ -225,6 +233,7 @@ impl<'a> fold::DocFolder for Stripper<'a> { clean::ModuleItem(..) => { if i.def_id.is_local() && i.visibility != Some(clean::Public) { + debug!("Stripper: stripping module {:?}", i.name); let old = mem::replace(&mut self.update_retained, false); let ret = StripItem(self.fold_item_recur(i).unwrap()).strip(); self.update_retained = old; @@ -296,11 +305,13 @@ impl<'a> fold::DocFolder for ImplStripper<'a> { } if let Some(did) = imp.for_.def_id() { if did.is_local() && !imp.for_.is_generic() && !self.retained.contains(&did) { + debug!("ImplStripper: impl item for stripped type; removing"); return None; } } if let Some(did) = imp.trait_.def_id() { if did.is_local() && !self.retained.contains(&did) { + debug!("ImplStripper: impl item for stripped trait; removing"); return None; } } @@ -308,6 +319,8 @@ impl<'a> fold::DocFolder for ImplStripper<'a> { for typaram in generics { if let Some(did) = typaram.def_id() { if did.is_local() && !self.retained.contains(&did) { + debug!("ImplStripper: stripped item in trait's generics; \ + removing impl"); return None; } } diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs index cc0b6fb6d6705..24dd4cc13bfe8 100644 --- a/src/librustdoc/passes/strip_hidden.rs +++ b/src/librustdoc/passes/strip_hidden.rs @@ -35,7 +35,9 @@ pub fn strip_hidden(krate: clean::Crate, _: &DocContext) -> clean::Crate { // strip all impls referencing stripped items let mut stripper = ImplStripper { retained: &retained }; - stripper.fold_crate(krate) + let krate = stripper.fold_crate(krate); + + krate } struct Stripper<'a> { @@ -46,7 +48,7 @@ struct Stripper<'a> { impl<'a> fold::DocFolder for Stripper<'a> { fn fold_item(&mut self, i: Item) -> Option { if i.attrs.lists("doc").has_word("hidden") { - debug!("found one in strip_hidden; removing"); + debug!("strip_hidden: stripping {} {:?}", i.type_(), i.name); // use a dedicated hidden item for given item type if any match i.inner { clean::StructFieldItem(..) | clean::ModuleItem(..) => { diff --git a/src/librustdoc/passes/strip_private.rs b/src/librustdoc/passes/strip_private.rs index 3b17a768ffdee..46d0034497e28 100644 --- a/src/librustdoc/passes/strip_private.rs +++ b/src/librustdoc/passes/strip_private.rs @@ -22,10 +22,10 @@ pub const STRIP_PRIVATE: Pass = /// Strip private items from the point of view of a crate or externally from a /// crate, specified by the `xcrate` flag. -pub fn strip_private(mut krate: clean::Crate, _: &DocContext) -> clean::Crate { +pub fn strip_private(mut krate: clean::Crate, cx: &DocContext) -> clean::Crate { // This stripper collects all *retained* nodes. let mut retained = DefIdSet(); - let access_levels = krate.access_levels.clone(); + let access_levels = cx.renderinfo.borrow().access_levels.clone(); // strip all private items { diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 451e24d6c0dc9..3f8b13d145856 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -269,7 +269,10 @@ impl<'a, 'tcx, 'rcx, 'cstore> RustdocVisitor<'a, 'tcx, 'rcx, 'cstore> { Def::Enum(did) | Def::ForeignTy(did) | Def::TyAlias(did) if !self_is_hidden => { - self.cx.access_levels.borrow_mut().map.insert(did, AccessLevel::Public); + self.cx.renderinfo + .borrow_mut() + .access_levels.map + .insert(did, AccessLevel::Public); }, Def::Mod(did) => if !self_is_hidden { ::visit_lib::LibEmbargoVisitor::new(self.cx).visit_mod(did); @@ -284,7 +287,7 @@ impl<'a, 'tcx, 'rcx, 'cstore> RustdocVisitor<'a, 'tcx, 'rcx, 'cstore> { Some(n) => n, None => return false }; - let is_private = !self.cx.access_levels.borrow().is_public(def_did); + let is_private = !self.cx.renderinfo.borrow().access_levels.is_public(def_did); let is_hidden = inherits_doc_hidden(self.cx, def_node_id); // Only inline if requested or if the item would otherwise be stripped @@ -510,9 +513,9 @@ impl<'a, 'tcx, 'rcx, 'cstore> RustdocVisitor<'a, 'tcx, 'rcx, 'cstore> { ref tr, ref ty, ref item_ids) => { - // Don't duplicate impls when inlining, we'll pick them up - // regardless of where they're located. - if !self.inlining { + // Don't duplicate impls when inlining or if it's implementing a trait, we'll pick + // them up regardless of where they're located. + if !self.inlining && tr.is_none() { let items = item_ids.iter() .map(|ii| self.cx.tcx.hir.impl_item(ii.id).clone()) .collect(); diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs index 10a4e69dcc6cd..fd81f937f30c7 100644 --- a/src/librustdoc/visit_lib.rs +++ b/src/librustdoc/visit_lib.rs @@ -38,7 +38,7 @@ impl<'a, 'tcx, 'rcx, 'cstore> LibEmbargoVisitor<'a, 'tcx, 'rcx, 'cstore> { ) -> LibEmbargoVisitor<'a, 'tcx, 'rcx, 'cstore> { LibEmbargoVisitor { cx, - access_levels: cx.access_levels.borrow_mut(), + access_levels: RefMut::map(cx.renderinfo.borrow_mut(), |ri| &mut ri.access_levels), prev_level: Some(AccessLevel::Public), visited_mods: FxHashSet() } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index e7195b3e21ee3..4278926b042f3 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -312,7 +312,6 @@ #![feature(doc_keyword)] #![feature(panic_info_message)] #![cfg_attr(stage0, feature(panic_implementation))] -#![cfg_attr(not(stage0), feature(panic_handler))] #![feature(non_exhaustive)] #![default_lib_allocator] diff --git a/src/libstd/sys/unix/fd.rs b/src/libstd/sys/unix/fd.rs index 12e14734ff515..db2ea6b660a7a 100644 --- a/src/libstd/sys/unix/fd.rs +++ b/src/libstd/sys/unix/fd.rs @@ -11,7 +11,7 @@ #![unstable(reason = "not public", issue = "0", feature = "fd")] use cmp; -use io::{self, Read}; +use io::{self, Read, Initializer}; use libc::{self, c_int, c_void, ssize_t}; use mem; use sync::atomic::{AtomicBool, Ordering}; @@ -270,6 +270,11 @@ impl<'a> Read for &'a FileDesc { fn read(&mut self, buf: &mut [u8]) -> io::Result { (**self).read(buf) } + + #[inline] + unsafe fn initializer(&self) -> Initializer { + Initializer::nop() + } } impl AsInner for FileDesc { diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index e3ea3563d853b..0270e36db1177 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -487,7 +487,6 @@ declare_features! ( // RFC 2070: #[panic_implementation] / #[panic_handler] (active, panic_implementation, "1.28.0", Some(44489), None), - (active, panic_handler, "1.30.0", Some(44489), None), // #[doc(keyword = "...")] (active, doc_keyword, "1.28.0", Some(51315), None), @@ -674,6 +673,7 @@ declare_features! ( (accepted, proc_macro_path_invoc, "1.30.0", Some(38356), None), // Allows all literals in attribute lists and values of key-value pairs. (accepted, attr_literals, "1.30.0", Some(34981), None), + (accepted, panic_handler, "1.30.0", Some(44489), None), ); // If you change this, please modify src/doc/unstable-book as well. You must @@ -1143,10 +1143,7 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG cfg_fn!(panic_implementation))), // RFC 2070 - ("panic_handler", Normal, Gated(Stability::Unstable, - "panic_handler", - "#[panic_handler] is an unstable feature", - cfg_fn!(panic_handler))), + ("panic_handler", Normal, Ungated), ("alloc_error_handler", Normal, Gated(Stability::Unstable, "alloc_error_handler", diff --git a/src/test/compile-fail/auxiliary/some-panic-impl.rs b/src/test/compile-fail/auxiliary/some-panic-impl.rs index e3b4fba176e3c..090123198d175 100644 --- a/src/test/compile-fail/auxiliary/some-panic-impl.rs +++ b/src/test/compile-fail/auxiliary/some-panic-impl.rs @@ -11,7 +11,6 @@ // no-prefer-dynamic #![crate_type = "rlib"] -#![feature(panic_handler)] #![no_std] use core::panic::PanicInfo; diff --git a/src/test/compile-fail/panic-handler-twice.rs b/src/test/compile-fail/panic-handler-twice.rs index 6c9515ca90994..10e0453cf5ed4 100644 --- a/src/test/compile-fail/panic-handler-twice.rs +++ b/src/test/compile-fail/panic-handler-twice.rs @@ -10,7 +10,6 @@ // aux-build:some-panic-impl.rs -#![feature(panic_handler)] #![feature(lang_items)] #![no_std] #![no_main] diff --git a/src/test/run-make-fulldeps/issue-51671/app.rs b/src/test/run-make-fulldeps/issue-51671/app.rs index e980b12039e96..4066214f4b47e 100644 --- a/src/test/run-make-fulldeps/issue-51671/app.rs +++ b/src/test/run-make-fulldeps/issue-51671/app.rs @@ -10,7 +10,6 @@ #![crate_type = "bin"] #![feature(lang_items)] -#![feature(panic_handler)] #![no_main] #![no_std] diff --git a/src/test/run-make-fulldeps/issue-53964/Makefile b/src/test/run-make-fulldeps/issue-53964/Makefile new file mode 100644 index 0000000000000..c56beb52fdd61 --- /dev/null +++ b/src/test/run-make-fulldeps/issue-53964/Makefile @@ -0,0 +1,5 @@ +-include ../tools.mk + +all: + $(RUSTC) panic.rs + $(RUSTC) -C panic=abort --emit=obj app.rs -L $(TMPDIR) diff --git a/src/test/run-make-fulldeps/issue-53964/app.rs b/src/test/run-make-fulldeps/issue-53964/app.rs new file mode 100644 index 0000000000000..8127b9578bfee --- /dev/null +++ b/src/test/run-make-fulldeps/issue-53964/app.rs @@ -0,0 +1,8 @@ +#![crate_type = "bin"] +#![no_main] +#![no_std] + +#![deny(unused_extern_crates)] + +// `panic` provides a `panic_handler` so it shouldn't trip the `unused_extern_crates` lint +extern crate panic; diff --git a/src/test/ui/feature-gates/feature-gate-panic-handler.rs b/src/test/run-make-fulldeps/issue-53964/panic.rs similarity index 75% rename from src/test/ui/feature-gates/feature-gate-panic-handler.rs rename to src/test/run-make-fulldeps/issue-53964/panic.rs index fd16268ef8b4e..87c7b218822a0 100644 --- a/src/test/ui/feature-gates/feature-gate-panic-handler.rs +++ b/src/test/run-make-fulldeps/issue-53964/panic.rs @@ -8,14 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags:-C panic=abort - +#![crate_type = "lib"] +#![feature(panic_handler)] #![no_std] -#![no_main] use core::panic::PanicInfo; -#[panic_handler] //~ ERROR #[panic_handler] is an unstable feature (see issue #44489) -fn panic(info: &PanicInfo) -> ! { +#[panic_handler] +fn panic(_: &PanicInfo) -> ! { loop {} } diff --git a/src/test/run-make-fulldeps/panic-impl-transitive/panic-impl-provider.rs b/src/test/run-make-fulldeps/panic-impl-transitive/panic-impl-provider.rs index 065b2b6bf18fa..77aae7ee2c06b 100644 --- a/src/test/run-make-fulldeps/panic-impl-transitive/panic-impl-provider.rs +++ b/src/test/run-make-fulldeps/panic-impl-transitive/panic-impl-provider.rs @@ -9,7 +9,6 @@ // except according to those terms. #![crate_type = "rlib"] -#![feature(panic_handler)] #![no_std] use core::panic::PanicInfo; diff --git a/src/test/run-pass/uniform-paths/auxiliary/issue-53691.rs b/src/test/run-pass/uniform-paths/auxiliary/issue-53691.rs new file mode 100644 index 0000000000000..5845afd72fbe7 --- /dev/null +++ b/src/test/run-pass/uniform-paths/auxiliary/issue-53691.rs @@ -0,0 +1,19 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// edition:2018 + +#![feature(uniform_paths)] + +mod m { pub fn f() {} } +mod n { pub fn g() {} } + +pub use m::f; +pub use n::g; diff --git a/src/test/run-pass/uniform-paths/issue-53691.rs b/src/test/run-pass/uniform-paths/issue-53691.rs new file mode 100644 index 0000000000000..62be31d6b85fe --- /dev/null +++ b/src/test/run-pass/uniform-paths/issue-53691.rs @@ -0,0 +1,18 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:issue-53691.rs + +extern crate issue_53691; + +fn main() { + issue_53691::f(); + issue_53691::g(); +} diff --git a/src/test/rustdoc/doc-proc-macro.rs b/src/test/rustdoc/doc-proc-macro.rs index b3b403a7b86aa..01a4a410b03fb 100644 --- a/src/test/rustdoc/doc-proc-macro.rs +++ b/src/test/rustdoc/doc-proc-macro.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-stage1 + // Issue #52129: ICE when trying to document the `quote` proc-macro from proc_macro // As of this writing, we don't currently attempt to document proc-macros. However, we shouldn't diff --git a/src/test/rustdoc/inline_cross/auxiliary/trait-vis.rs b/src/test/rustdoc/inline_cross/auxiliary/trait-vis.rs new file mode 100644 index 0000000000000..7457a5d4899fe --- /dev/null +++ b/src/test/rustdoc/inline_cross/auxiliary/trait-vis.rs @@ -0,0 +1,23 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_name = "inner"] + +pub struct SomeStruct; + +fn asdf() { + const _FOO: () = { + impl Clone for SomeStruct { + fn clone(&self) -> Self { + SomeStruct + } + } + }; +} diff --git a/src/test/rustdoc/inline_cross/trait-vis.rs b/src/test/rustdoc/inline_cross/trait-vis.rs new file mode 100644 index 0000000000000..5b5410b1da44d --- /dev/null +++ b/src/test/rustdoc/inline_cross/trait-vis.rs @@ -0,0 +1,17 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:trait-vis.rs + +extern crate inner; + +// @has trait_vis/struct.SomeStruct.html +// @has - '//code' 'impl Clone for SomeStruct' +pub use inner::SomeStruct; diff --git a/src/test/rustdoc/inline_local/trait-vis.rs b/src/test/rustdoc/inline_local/trait-vis.rs new file mode 100644 index 0000000000000..73b1cc2ce8f2d --- /dev/null +++ b/src/test/rustdoc/inline_local/trait-vis.rs @@ -0,0 +1,28 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub trait ThisTrait {} + +mod asdf { + use ThisTrait; + + pub struct SomeStruct; + + impl ThisTrait for SomeStruct {} + + trait PrivateTrait {} + + impl PrivateTrait for SomeStruct {} +} + +// @has trait_vis/struct.SomeStruct.html +// @has - '//code' 'impl ThisTrait for SomeStruct' +// !@has - '//code' 'impl PrivateTrait for SomeStruct' +pub use asdf::SomeStruct; diff --git a/src/test/rustdoc/primitive-generic-impl.rs b/src/test/rustdoc/primitive-generic-impl.rs index b4351b8268c8b..a771b1b15ce4d 100644 --- a/src/test/rustdoc/primitive-generic-impl.rs +++ b/src/test/rustdoc/primitive-generic-impl.rs @@ -10,9 +10,6 @@ #![crate_name = "foo"] -// we need to reexport something from libstd so that `all_trait_implementations` is called. -pub use std::string::String; - include!("primitive/primitive-generic-impl.rs"); // @has foo/primitive.i32.html '//h3[@id="impl-ToString"]//code' 'impl ToString for T' diff --git a/src/test/rustdoc/traits-in-bodies-private.rs b/src/test/rustdoc/traits-in-bodies-private.rs new file mode 100644 index 0000000000000..ac3be7e61e9a0 --- /dev/null +++ b/src/test/rustdoc/traits-in-bodies-private.rs @@ -0,0 +1,23 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// when implementing the fix for traits-in-bodies, there was an ICE when documenting private items +// and a trait was defined in non-module scope + +// compile-flags:--document-private-items + +// @has traits_in_bodies_private/struct.SomeStruct.html +// @!has - '//code' 'impl HiddenTrait for SomeStruct' +pub struct SomeStruct; + +fn __implementation_details() { + trait HiddenTrait {} + impl HiddenTrait for SomeStruct {} +} diff --git a/src/test/rustdoc/traits-in-bodies.rs b/src/test/rustdoc/traits-in-bodies.rs index 3acf4af5fd247..a1d4019bba2bf 100644 --- a/src/test/rustdoc/traits-in-bodies.rs +++ b/src/test/rustdoc/traits-in-bodies.rs @@ -11,11 +11,10 @@ //prior to fixing `everybody_loops` to preserve items, rustdoc would crash on this file, as it //didn't see that `SomeStruct` implemented `Clone` -//FIXME(misdreavus): whenever rustdoc shows traits impl'd inside bodies, make sure this test -//reflects that - pub struct Bounded(T); +// @has traits_in_bodies/struct.SomeStruct.html +// @has - '//code' 'impl Clone for SomeStruct' pub struct SomeStruct; fn asdf() -> Bounded { @@ -27,3 +26,37 @@ fn asdf() -> Bounded { Bounded(SomeStruct) } + +// @has traits_in_bodies/struct.Point.html +// @has - '//code' 'impl Copy for Point' +#[derive(Clone)] +pub struct Point { + x: i32, + y: i32, +} + +const _FOO: () = { + impl Copy for Point {} + () +}; + +// @has traits_in_bodies/struct.Inception.html +// @has - '//code' 'impl Clone for Inception' +pub struct Inception; + +static _BAR: usize = { + trait HiddenTrait { + fn hidden_fn(&self) { + for _ in 0..5 { + impl Clone for Inception { + fn clone(&self) -> Self { + // we need to go deeper + Inception + } + } + } + } + } + + 5 +}; diff --git a/src/test/ui/borrowck/borrowck-box-insensitivity.nll.stderr b/src/test/ui/borrowck/borrowck-box-insensitivity.nll.stderr index 601f05b499c75..0e380e90e7591 100644 --- a/src/test/ui/borrowck/borrowck-box-insensitivity.nll.stderr +++ b/src/test/ui/borrowck/borrowck-box-insensitivity.nll.stderr @@ -1,25 +1,14 @@ -error[E0382]: use of moved value: `a.y` - --> $DIR/borrowck-box-insensitivity.rs:46:14 - | -LL | let _x = a.x; - | --- value moved here -LL | //~^ value moved here -LL | let _y = a.y; //~ ERROR use of moved - | ^^^ value used here after move - | - = note: move occurs because `a.x` has type `std::boxed::Box`, which does not implement the `Copy` trait - -error[E0382]: use of moved value: `a.y` - --> $DIR/borrowck-box-insensitivity.rs:108:14 - | -LL | let _x = a.x.x; - | ----- value moved here -LL | //~^ value moved here -LL | let _y = a.y; //~ ERROR use of collaterally moved - | ^^^ value used here after move - | - = note: move occurs because `a.x.x` has type `std::boxed::Box`, which does not implement the `Copy` trait +error: compilation successful + --> $DIR/borrowck-box-insensitivity.rs:160:1 + | +LL | / fn main() { +LL | | copy_after_move(); +LL | | move_after_move(); +LL | | borrow_after_move(); +... | +LL | | mut_borrow_after_borrow_nested(); +LL | | } + | |_^ -error: aborting due to 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/borrowck/borrowck-box-insensitivity.rs b/src/test/ui/borrowck/borrowck-box-insensitivity.rs index 75bf6bce04b39..eabb8d7bca3fa 100644 --- a/src/test/ui/borrowck/borrowck-box-insensitivity.rs +++ b/src/test/ui/borrowck/borrowck-box-insensitivity.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(box_syntax)] +#![feature(box_syntax, rustc_attrs)] struct A { x: Box, @@ -156,6 +156,7 @@ fn mut_borrow_after_borrow_nested() { //~^ mutable borrow occurs here } +#[rustc_error] fn main() { copy_after_move(); move_after_move(); diff --git a/src/test/ui/consts/const-eval/const_panic_libcore_main.rs b/src/test/ui/consts/const-eval/const_panic_libcore_main.rs index f5e5f9778faed..0364123994dff 100644 --- a/src/test/ui/consts/const-eval/const_panic_libcore_main.rs +++ b/src/test/ui/consts/const-eval/const_panic_libcore_main.rs @@ -10,7 +10,6 @@ #![crate_type = "bin"] #![feature(lang_items)] -#![feature(panic_handler)] #![feature(const_panic)] #![no_main] #![no_std] diff --git a/src/test/ui/consts/const-eval/const_panic_libcore_main.stderr b/src/test/ui/consts/const-eval/const_panic_libcore_main.stderr index 7cb9f51c427a7..44b30c08cdea2 100644 --- a/src/test/ui/consts/const-eval/const_panic_libcore_main.stderr +++ b/src/test/ui/consts/const-eval/const_panic_libcore_main.stderr @@ -1,31 +1,31 @@ error: this constant cannot be used - --> $DIR/const_panic_libcore_main.rs:20:1 + --> $DIR/const_panic_libcore_main.rs:19:1 | LL | const Z: () = panic!("cheese"); | ^^^^^^^^^^^^^^----------------^ | | - | the evaluated program panicked at 'cheese', $DIR/const_panic_libcore_main.rs:20:15 + | the evaluated program panicked at 'cheese', $DIR/const_panic_libcore_main.rs:19:15 | = note: #[deny(const_err)] on by default = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: this constant cannot be used - --> $DIR/const_panic_libcore_main.rs:23:1 + --> $DIR/const_panic_libcore_main.rs:22:1 | LL | const Y: () = unreachable!(); | ^^^^^^^^^^^^^^--------------^ | | - | the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_libcore_main.rs:23:15 + | the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_libcore_main.rs:22:15 | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: this constant cannot be used - --> $DIR/const_panic_libcore_main.rs:26:1 + --> $DIR/const_panic_libcore_main.rs:25:1 | LL | const X: () = unimplemented!(); | ^^^^^^^^^^^^^^----------------^ | | - | the evaluated program panicked at 'not yet implemented', $DIR/const_panic_libcore_main.rs:26:15 + | the evaluated program panicked at 'not yet implemented', $DIR/const_panic_libcore_main.rs:25:15 | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) diff --git a/src/test/ui/feature-gates/feature-gate-panic-handler.stderr b/src/test/ui/feature-gates/feature-gate-panic-handler.stderr deleted file mode 100644 index 9680a240a9925..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-panic-handler.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0658]: #[panic_handler] is an unstable feature (see issue #44489) - --> $DIR/feature-gate-panic-handler.rs:18:1 - | -LL | #[panic_handler] //~ ERROR #[panic_handler] is an unstable feature (see issue #44489) - | ^^^^^^^^^^^^^^^^ - | - = help: add #![feature(panic_handler)] to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/panic-handler/auxiliary/some-panic-impl.rs b/src/test/ui/panic-handler/auxiliary/some-panic-impl.rs index e3b4fba176e3c..090123198d175 100644 --- a/src/test/ui/panic-handler/auxiliary/some-panic-impl.rs +++ b/src/test/ui/panic-handler/auxiliary/some-panic-impl.rs @@ -11,7 +11,6 @@ // no-prefer-dynamic #![crate_type = "rlib"] -#![feature(panic_handler)] #![no_std] use core::panic::PanicInfo; diff --git a/src/test/ui/panic-handler/panic-handler-bad-signature-1.rs b/src/test/ui/panic-handler/panic-handler-bad-signature-1.rs index cc7e337fc9e65..8d53c66adbd93 100644 --- a/src/test/ui/panic-handler/panic-handler-bad-signature-1.rs +++ b/src/test/ui/panic-handler/panic-handler-bad-signature-1.rs @@ -10,7 +10,6 @@ // compile-flags:-C panic=abort -#![feature(panic_handler)] #![no_std] #![no_main] diff --git a/src/test/ui/panic-handler/panic-handler-bad-signature-1.stderr b/src/test/ui/panic-handler/panic-handler-bad-signature-1.stderr index 5771f4277b46d..72b85da028f1f 100644 --- a/src/test/ui/panic-handler/panic-handler-bad-signature-1.stderr +++ b/src/test/ui/panic-handler/panic-handler-bad-signature-1.stderr @@ -1,11 +1,11 @@ error: return type should be `!` - --> $DIR/panic-handler-bad-signature-1.rs:22:6 + --> $DIR/panic-handler-bad-signature-1.rs:21:6 | LL | ) -> () //~ ERROR return type should be `!` | ^^ error: argument should be `&PanicInfo` - --> $DIR/panic-handler-bad-signature-1.rs:21:11 + --> $DIR/panic-handler-bad-signature-1.rs:20:11 | LL | info: PanicInfo, //~ ERROR argument should be `&PanicInfo` | ^^^^^^^^^ diff --git a/src/test/ui/panic-handler/panic-handler-bad-signature-2.rs b/src/test/ui/panic-handler/panic-handler-bad-signature-2.rs index ec698903c846e..0e8b3d5e855cb 100644 --- a/src/test/ui/panic-handler/panic-handler-bad-signature-2.rs +++ b/src/test/ui/panic-handler/panic-handler-bad-signature-2.rs @@ -10,7 +10,6 @@ // compile-flags:-C panic=abort -#![feature(panic_handler)] #![no_std] #![no_main] diff --git a/src/test/ui/panic-handler/panic-handler-bad-signature-2.stderr b/src/test/ui/panic-handler/panic-handler-bad-signature-2.stderr index 4823f8a2781b0..f2bcb6b680952 100644 --- a/src/test/ui/panic-handler/panic-handler-bad-signature-2.stderr +++ b/src/test/ui/panic-handler/panic-handler-bad-signature-2.stderr @@ -1,5 +1,5 @@ error: argument should be `&PanicInfo` - --> $DIR/panic-handler-bad-signature-2.rs:21:11 + --> $DIR/panic-handler-bad-signature-2.rs:20:11 | LL | info: &'static PanicInfo, //~ ERROR argument should be `&PanicInfo` | ^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/panic-handler/panic-handler-bad-signature-3.rs b/src/test/ui/panic-handler/panic-handler-bad-signature-3.rs index 585716c7c7569..ac1b19105b62e 100644 --- a/src/test/ui/panic-handler/panic-handler-bad-signature-3.rs +++ b/src/test/ui/panic-handler/panic-handler-bad-signature-3.rs @@ -10,7 +10,6 @@ // compile-flags:-C panic=abort -#![feature(panic_handler)] #![no_std] #![no_main] diff --git a/src/test/ui/panic-handler/panic-handler-bad-signature-3.stderr b/src/test/ui/panic-handler/panic-handler-bad-signature-3.stderr index 5d0395e17f54d..77227e0d5a61c 100644 --- a/src/test/ui/panic-handler/panic-handler-bad-signature-3.stderr +++ b/src/test/ui/panic-handler/panic-handler-bad-signature-3.stderr @@ -1,5 +1,5 @@ error: function should have one argument - --> $DIR/panic-handler-bad-signature-3.rs:20:1 + --> $DIR/panic-handler-bad-signature-3.rs:19:1 | LL | fn panic() -> ! { //~ ERROR function should have one argument | ^^^^^^^^^^^^^^^ diff --git a/src/test/ui/panic-handler/panic-handler-bad-signature-4.rs b/src/test/ui/panic-handler/panic-handler-bad-signature-4.rs index 9cda37f27b332..f4728408a1afa 100644 --- a/src/test/ui/panic-handler/panic-handler-bad-signature-4.rs +++ b/src/test/ui/panic-handler/panic-handler-bad-signature-4.rs @@ -10,7 +10,6 @@ // compile-flags:-C panic=abort -#![feature(panic_handler)] #![no_std] #![no_main] diff --git a/src/test/ui/panic-handler/panic-handler-bad-signature-4.stderr b/src/test/ui/panic-handler/panic-handler-bad-signature-4.stderr index a61b9b3743c7d..0dd47cafd7553 100644 --- a/src/test/ui/panic-handler/panic-handler-bad-signature-4.stderr +++ b/src/test/ui/panic-handler/panic-handler-bad-signature-4.stderr @@ -1,5 +1,5 @@ error: should have no type parameters - --> $DIR/panic-handler-bad-signature-4.rs:20:1 + --> $DIR/panic-handler-bad-signature-4.rs:19:1 | LL | / fn panic(pi: &PanicInfo) -> ! { LL | | //~^ ERROR should have no type parameters diff --git a/src/test/ui/panic-handler/panic-handler-duplicate.rs b/src/test/ui/panic-handler/panic-handler-duplicate.rs index 7d7fe251869f1..c4fb4903e0031 100644 --- a/src/test/ui/panic-handler/panic-handler-duplicate.rs +++ b/src/test/ui/panic-handler/panic-handler-duplicate.rs @@ -11,7 +11,6 @@ // compile-flags:-C panic=abort #![feature(lang_items)] -#![feature(panic_handler)] #![no_std] #![no_main] diff --git a/src/test/ui/panic-handler/panic-handler-duplicate.stderr b/src/test/ui/panic-handler/panic-handler-duplicate.stderr index d8afaa27e2662..e243d9079d851 100644 --- a/src/test/ui/panic-handler/panic-handler-duplicate.stderr +++ b/src/test/ui/panic-handler/panic-handler-duplicate.stderr @@ -1,5 +1,5 @@ error[E0152]: duplicate lang item found: `panic_impl`. - --> $DIR/panic-handler-duplicate.rs:26:1 + --> $DIR/panic-handler-duplicate.rs:25:1 | LL | / fn panic2(info: &PanicInfo) -> ! { //~ ERROR duplicate lang item found: `panic_impl`. LL | | loop {} @@ -7,7 +7,7 @@ LL | | } | |_^ | note: first defined here. - --> $DIR/panic-handler-duplicate.rs:21:1 + --> $DIR/panic-handler-duplicate.rs:20:1 | LL | / fn panic(info: &PanicInfo) -> ! { LL | | loop {} diff --git a/src/test/ui/panic-handler/panic-handler-requires-panic-info.rs b/src/test/ui/panic-handler/panic-handler-requires-panic-info.rs index ec68a414f54d5..133d6c0557ab6 100644 --- a/src/test/ui/panic-handler/panic-handler-requires-panic-info.rs +++ b/src/test/ui/panic-handler/panic-handler-requires-panic-info.rs @@ -13,7 +13,6 @@ #![feature(lang_items)] #![feature(no_core)] -#![feature(panic_handler)] #![no_core] #![no_main] diff --git a/src/test/ui/panic-handler/panic-handler-std.rs b/src/test/ui/panic-handler/panic-handler-std.rs index 7cbe0a35baed8..ff5995237cf21 100644 --- a/src/test/ui/panic-handler/panic-handler-std.rs +++ b/src/test/ui/panic-handler/panic-handler-std.rs @@ -10,7 +10,6 @@ // error-pattern: duplicate lang item found: `panic_impl`. -#![feature(panic_handler)] use std::panic::PanicInfo; diff --git a/src/test/ui/panic-handler/panic-handler-std.stderr b/src/test/ui/panic-handler/panic-handler-std.stderr index b141a2171646c..4ec1c6df35522 100644 --- a/src/test/ui/panic-handler/panic-handler-std.stderr +++ b/src/test/ui/panic-handler/panic-handler-std.stderr @@ -1,5 +1,5 @@ error[E0152]: duplicate lang item found: `panic_impl`. - --> $DIR/panic-handler-std.rs:18:1 + --> $DIR/panic-handler-std.rs:17:1 | LL | / fn panic(info: PanicInfo) -> ! { LL | | loop {} @@ -9,7 +9,7 @@ LL | | } = note: first defined in crate `std`. error: argument should be `&PanicInfo` - --> $DIR/panic-handler-std.rs:18:16 + --> $DIR/panic-handler-std.rs:17:16 | LL | fn panic(info: PanicInfo) -> ! { | ^^^^^^^^^ diff --git a/src/test/ui/panic_implementation-closures.rs b/src/test/ui/panic_implementation-closures.rs index 6642db6ee76bf..5902a1ae1b023 100644 --- a/src/test/ui/panic_implementation-closures.rs +++ b/src/test/ui/panic_implementation-closures.rs @@ -12,7 +12,6 @@ #![crate_type = "rlib"] #![no_std] -#![feature(panic_handler)] #[panic_handler] pub fn panic_fmt(_: &::core::panic::PanicInfo) -> ! { diff --git a/src/test/ui/removing-extern-crate.rs b/src/test/ui/removing-extern-crate.rs index 3905d285becb5..9762db38a1ca6 100644 --- a/src/test/ui/removing-extern-crate.rs +++ b/src/test/ui/removing-extern-crate.rs @@ -16,12 +16,12 @@ #![warn(rust_2018_idioms)] #![allow(unused_imports)] -extern crate std as foo; +extern crate removing_extern_crate as foo; extern crate core; mod another { - extern crate std as foo; - extern crate std; + extern crate removing_extern_crate as foo; + extern crate core; } fn main() {} diff --git a/src/test/ui/removing-extern-crate.stderr b/src/test/ui/removing-extern-crate.stderr index f2eed27a26693..758ec67d17823 100644 --- a/src/test/ui/removing-extern-crate.stderr +++ b/src/test/ui/removing-extern-crate.stderr @@ -1,8 +1,8 @@ warning: unused extern crate --> $DIR/removing-extern-crate.rs:19:1 | -LL | extern crate std as foo; - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it +LL | extern crate removing_extern_crate as foo; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it | note: lint level defined here --> $DIR/removing-extern-crate.rs:16:9 @@ -20,12 +20,12 @@ LL | extern crate core; warning: unused extern crate --> $DIR/removing-extern-crate.rs:23:5 | -LL | extern crate std as foo; - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it +LL | extern crate removing_extern_crate as foo; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it warning: unused extern crate --> $DIR/removing-extern-crate.rs:24:5 | -LL | extern crate std; - | ^^^^^^^^^^^^^^^^^ help: remove it +LL | extern crate core; + | ^^^^^^^^^^^^^^^^^^ help: remove it