From 5b6eb25157cd0ad69abb886ae01794da33e4de3f Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 6 Nov 2018 19:44:35 -0700 Subject: [PATCH 01/21] Include changes from 1.30.1 in release notes --- RELEASES.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index fc76fbc95bd3b..db4f6aaa778bc 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -74,6 +74,14 @@ Cargo [cargo-rename-reference]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#renaming-dependencies-in-cargotoml [const-reference]: https://doc.rust-lang.org/reference/items/functions.html#const-functions +Version 1.30.1 (2018-11-08) +=========================== + +- [Fixed overflow ICE in rustdoc][54199] +- [Cap Cargo progress bar width at 60 in MSYS terminals][cargo/6122] + +[54199]: https://github.com/rust-lang/rust/pull/54199 +[cargo/6122]: https://github.com/rust-lang/cargo/pull/6122 Version 1.30.0 (2018-10-25) ========================== From 9e887df940cc921b4f478dfa49d051ce9ceb9a1b Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 22 Nov 2018 01:13:09 +0300 Subject: [PATCH 02/21] resolve: Fix some asserts in import validation --- src/librustc_resolve/resolve_imports.rs | 6 ++- src/test/ui/imports/auxiliary/issue-56125.rs | 9 ++++ src/test/ui/imports/issue-56125.rs | 12 +++++ src/test/ui/imports/issue-56125.stderr | 46 ++++++++++++++++++++ 4 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/imports/auxiliary/issue-56125.rs create mode 100644 src/test/ui/imports/issue-56125.rs create mode 100644 src/test/ui/imports/issue-56125.stderr diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index b4490ea05f5a4..7c1ff3d29faa6 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -843,12 +843,14 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { module } PathResult::Failed(span, msg, false) => { - assert!(directive.imported_module.get().is_none()); + assert!(!self.ambiguity_errors.is_empty() || + directive.imported_module.get().is_none()); resolve_error(self, span, ResolutionError::FailedToResolve(&msg)); return None; } PathResult::Failed(span, msg, true) => { - assert!(directive.imported_module.get().is_none()); + assert!(!self.ambiguity_errors.is_empty() || + directive.imported_module.get().is_none()); return if let Some((suggested_path, note)) = self.make_path_suggestion( span, directive.module_path.clone(), &directive.parent_scope ) { diff --git a/src/test/ui/imports/auxiliary/issue-56125.rs b/src/test/ui/imports/auxiliary/issue-56125.rs new file mode 100644 index 0000000000000..0ff407756b3ae --- /dev/null +++ b/src/test/ui/imports/auxiliary/issue-56125.rs @@ -0,0 +1,9 @@ +pub mod last_segment { + pub mod issue_56125 {} +} + +pub mod non_last_segment { + pub mod non_last_segment { + pub mod issue_56125 {} + } +} diff --git a/src/test/ui/imports/issue-56125.rs b/src/test/ui/imports/issue-56125.rs new file mode 100644 index 0000000000000..4baeb8a34dd76 --- /dev/null +++ b/src/test/ui/imports/issue-56125.rs @@ -0,0 +1,12 @@ +// edition:2018 +// compile-flags:--extern issue_56125 +// aux-build:issue-56125.rs + +use issue_56125::last_segment::*; +//~^ ERROR `issue_56125` is ambiguous +//~| ERROR unresolved import `issue_56125::last_segment` +use issue_56125::non_last_segment::non_last_segment::*; +//~^ ERROR `issue_56125` is ambiguous +//~| ERROR failed to resolve: could not find `non_last_segment` in `issue_56125` + +fn main() {} diff --git a/src/test/ui/imports/issue-56125.stderr b/src/test/ui/imports/issue-56125.stderr new file mode 100644 index 0000000000000..096d5be97f0e0 --- /dev/null +++ b/src/test/ui/imports/issue-56125.stderr @@ -0,0 +1,46 @@ +error[E0433]: failed to resolve: could not find `non_last_segment` in `issue_56125` + --> $DIR/issue-56125.rs:8:18 + | +LL | use issue_56125::non_last_segment::non_last_segment::*; + | ^^^^^^^^^^^^^^^^ could not find `non_last_segment` in `issue_56125` + +error[E0432]: unresolved import `issue_56125::last_segment` + --> $DIR/issue-56125.rs:5:18 + | +LL | use issue_56125::last_segment::*; + | ^^^^^^^^^^^^ could not find `last_segment` in `issue_56125` + +error[E0659]: `issue_56125` is ambiguous (name vs any other name during import resolution) + --> $DIR/issue-56125.rs:5:5 + | +LL | use issue_56125::last_segment::*; + | ^^^^^^^^^^^ ambiguous name + | + = note: `issue_56125` could refer to an extern crate passed with `--extern` + = help: use `::issue_56125` to refer to this extern crate unambiguously +note: `issue_56125` could also refer to the module imported here + --> $DIR/issue-56125.rs:5:5 + | +LL | use issue_56125::last_segment::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: use `self::issue_56125` to refer to this module unambiguously + +error[E0659]: `issue_56125` is ambiguous (name vs any other name during import resolution) + --> $DIR/issue-56125.rs:8:5 + | +LL | use issue_56125::non_last_segment::non_last_segment::*; + | ^^^^^^^^^^^ ambiguous name + | + = note: `issue_56125` could refer to an extern crate passed with `--extern` + = help: use `::issue_56125` to refer to this extern crate unambiguously +note: `issue_56125` could also refer to the module imported here + --> $DIR/issue-56125.rs:5:5 + | +LL | use issue_56125::last_segment::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: use `self::issue_56125` to refer to this module unambiguously + +error: aborting due to 4 previous errors + +Some errors occurred: E0432, E0433, E0659. +For more information about an error, try `rustc --explain E0432`. From f89c3a271dfb4d3dc559d91875c2220c4f8c65a8 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 20 Nov 2018 07:40:31 -0500 Subject: [PATCH 03/21] update books --- src/doc/book | 2 +- src/doc/nomicon | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/book b/src/doc/book index e871c45989255..616fe4172b688 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit e871c4598925594421d63e929fee292e6e071f97 +Subproject commit 616fe4172b688393aeee5f34935cc25733c9c062 diff --git a/src/doc/nomicon b/src/doc/nomicon index 7f7a597b47ed6..f8a4e96feb2e5 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 7f7a597b47ed6c35c2a0f0ee6a69050fe2d5e013 +Subproject commit f8a4e96feb2e5a6ed1ef170ad40e3509a7755cb4 diff --git a/src/doc/reference b/src/doc/reference index b9fb838054b84..60077efda319c 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit b9fb838054b8441223c22eeae5b6d8e498071cd0 +Subproject commit 60077efda319c95a89fe39609803c5433567adbf diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index bc342a475c09b..2ce92beabb912 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit bc342a475c09b6df8004d518382e6d5b6bcb49f7 +Subproject commit 2ce92beabb912d417a7314d6da83ac9b50dc2afb From 0402d26027df30fa4c97e8646ad123498a6bd06b Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 20 Nov 2018 14:57:56 -0500 Subject: [PATCH 04/21] fix rustbuild to build all the books --- src/bootstrap/doc.rs | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index ed4805b8ea330..cb3b61792bf87 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -260,22 +260,31 @@ impl Step for TheBook { let compiler = self.compiler; let target = self.target; let name = self.name; - // build book first edition + + // build book builder.ensure(Rustbook { target, - name: INTERNER.intern_string(format!("{}/first-edition", name)), + name: INTERNER.intern_string(name.to_string()), }); - // build book second edition + // building older edition redirects + + let source_name = format!("{}/first-edition", name); builder.ensure(Rustbook { target, - name: INTERNER.intern_string(format!("{}/second-edition", name)), + name: INTERNER.intern_string(source_name), }); - // build book 2018 edition + let source_name = format!("{}/second-edition", name); builder.ensure(Rustbook { target, - name: INTERNER.intern_string(format!("{}/2018-edition", name)), + name: INTERNER.intern_string(source_name), + }); + + let source_name = format!("{}/2018-edition", name); + builder.ensure(Rustbook { + target, + name: INTERNER.intern_string(source_name), }); // build the version info page and CSS @@ -284,11 +293,6 @@ impl Step for TheBook { target, }); - // build the index page - let index = format!("{}/index.md", name); - builder.info(&format!("Documenting book index ({})", target)); - invoke_rustdoc(builder, compiler, target, &index); - // build the redirect pages builder.info(&format!("Documenting book redirect pages ({})", target)); for file in t!(fs::read_dir(builder.src.join("src/doc/book/redirects"))) { From bbe0c827510a97ab81fc62a9844c8e5cce605e10 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 20 Nov 2018 18:42:49 -0500 Subject: [PATCH 05/21] fix more links --- .../src/language-features/macro-literal-matcher.md | 4 ++-- src/doc/unstable-book/src/language-features/plugin.md | 2 -- src/libcore/iter/iterator.rs | 6 +++--- src/libstd/lib.rs | 10 +++++----- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/macro-literal-matcher.md b/src/doc/unstable-book/src/language-features/macro-literal-matcher.md index 7e3638fd1cf4c..870158200dee9 100644 --- a/src/doc/unstable-book/src/language-features/macro-literal-matcher.md +++ b/src/doc/unstable-book/src/language-features/macro-literal-matcher.md @@ -4,7 +4,7 @@ The tracking issue for this feature is: [#35625] The RFC is: [rfc#1576]. -With this feature gate enabled, the [list of fragment specifiers][frags] gains one more entry: +With this feature gate enabled, the [list of designators] gains one more entry: * `literal`: a literal. Examples: 2, "string", 'c' @@ -12,6 +12,6 @@ A `literal` may be followed by anything, similarly to the `ident` specifier. [rfc#1576]: http://rust-lang.github.io/rfcs/1576-macros-literal-matcher.html [#35625]: https://github.com/rust-lang/rust/issues/35625 -[frags]: ../book/first-edition/macros.html#syntactic-requirements +[list of designators]: ../reference/macros-by-example.html ------------------------ diff --git a/src/doc/unstable-book/src/language-features/plugin.md b/src/doc/unstable-book/src/language-features/plugin.md index b408d5d080515..74bdd4dc3b599 100644 --- a/src/doc/unstable-book/src/language-features/plugin.md +++ b/src/doc/unstable-book/src/language-features/plugin.md @@ -137,8 +137,6 @@ of extensions. See `Registry::register_syntax_extension` and the ## Tips and tricks -Some of the [macro debugging tips](../book/first-edition/macros.html#debugging-macro-code) are applicable. - You can use `syntax::parse` to turn token trees into higher-level syntax elements like expressions: diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 5b6d9e2033caa..1038a47d3f0fc 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -532,7 +532,7 @@ pub trait Iterator { /// If you're doing some sort of looping for a side effect, it's considered /// more idiomatic to use [`for`] than `map()`. /// - /// [`for`]: ../../book/first-edition/loops.html#for + /// [`for`]: ../../book/ch03-05-control-flow.html#looping-through-a-collection-with-for /// /// # Examples /// @@ -580,7 +580,7 @@ pub trait Iterator { /// cases `for_each` may also be faster than a loop, because it will use /// internal iteration on adaptors like `Chain`. /// - /// [`for`]: ../../book/first-edition/loops.html#for + /// [`for`]: ../../book/ch03-05-control-flow.html#looping-through-a-collection-with-for /// /// # Examples /// @@ -1669,7 +1669,7 @@ pub trait Iterator { /// use a `for` loop with a list of things to build up a result. Those /// can be turned into `fold()`s: /// - /// [`for`]: ../../book/first-edition/loops.html#for + /// [`for`]: ../../book/ch03-05-control-flow.html#looping-through-a-collection-with-for /// /// ``` /// let numbers = [1, 2, 3, 4, 5]; diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index a4db879680566..4499b97bf996a 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -185,7 +185,7 @@ //! [slice]: primitive.slice.html //! [`atomic`]: sync/atomic/index.html //! [`collections`]: collections/index.html -//! [`for`]: ../book/first-edition/loops.html#for +/// [`for`]: ../../book/ch03-05-control-flow.html#looping-through-a-collection-with-for //! [`format!`]: macro.format.html //! [`fs`]: fs/index.html //! [`io`]: io/index.html @@ -200,14 +200,14 @@ //! [`sync`]: sync/index.html //! [`thread`]: thread/index.html //! [`use std::env`]: env/index.html -//! [`use`]: ../book/first-edition/crates-and-modules.html#importing-modules-with-use -//! [crate root]: ../book/first-edition/crates-and-modules.html#basic-terminology-crates-and-modules +//! [`use`]: ../book/ch07-02-modules-and-use-to-control-scope-and-privacy.html#use-to-bring-paths-into-scope +//! [crate root]: ../book/ch07-01-packages-and-crates-for-making-libraries-and-executables.html //! [crates.io]: https://crates.io -//! [deref-coercions]: ../book/second-edition/ch15-02-deref.html#implicit-deref-coercions-with-functions-and-methods +//! [deref-coercions]: ../book/ch15-02-deref.html#implicit-deref-coercions-with-functions-and-methods //! [files]: fs/struct.File.html //! [multithreading]: thread/index.html //! [other]: #what-is-in-the-standard-library-documentation -//! [primitive types]: ../book/first-edition/primitive-types.html +//! [primitive types]: ../book/ch03-02-data-types.html #![stable(feature = "rust1", since = "1.0.0")] #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", From bf86cc5fc9923d7b22cac00a2570868fc037d027 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 20 Nov 2018 19:49:47 -0500 Subject: [PATCH 06/21] update various stdlib docs --- src/liballoc/rc.rs | 5 ++--- src/liballoc/sync.rs | 5 ++--- src/libcore/char/convert.rs | 6 ++---- src/libcore/mem.rs | 15 +++++---------- src/libcore/ptr.rs | 2 +- src/libcore/raw.rs | 6 +----- src/libstd/lib.rs | 4 ++-- src/libstd/macros.rs | 11 +++++------ src/libstd/primitive_docs.rs | 5 ++--- 9 files changed, 22 insertions(+), 37 deletions(-) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 40bb2faa3623b..39a261d3d5097 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -43,8 +43,8 @@ //! //! `Rc` automatically dereferences to `T` (via the [`Deref`] trait), //! so you can call `T`'s methods on a value of type [`Rc`][`Rc`]. To avoid name -//! clashes with `T`'s methods, the methods of [`Rc`][`Rc`] itself are [associated -//! functions][assoc], called using function-like syntax: +//! clashes with `T`'s methods, the methods of [`Rc`][`Rc`] itself are associated +//! functions, called using function-like syntax: //! //! ``` //! use std::rc::Rc; @@ -234,7 +234,6 @@ //! [downgrade]: struct.Rc.html#method.downgrade //! [upgrade]: struct.Weak.html#method.upgrade //! [`None`]: ../../std/option/enum.Option.html#variant.None -//! [assoc]: ../../book/first-edition/method-syntax.html#associated-functions //! [mutability]: ../../std/cell/index.html#introducing-mutability-inside-of-something-immutable #![stable(feature = "rust1", since = "1.0.0")] diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 35935861fb182..db3049b8fae16 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -120,8 +120,8 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// /// `Arc` automatically dereferences to `T` (via the [`Deref`][deref] trait), /// so you can call `T`'s methods on a value of type `Arc`. To avoid name -/// clashes with `T`'s methods, the methods of `Arc` itself are [associated -/// functions][assoc], called using function-like syntax: +/// clashes with `T`'s methods, the methods of `Arc` itself are associated +/// functions, called using function-like syntax: /// /// ``` /// use std::sync::Arc; @@ -146,7 +146,6 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// [downgrade]: struct.Arc.html#method.downgrade /// [upgrade]: struct.Weak.html#method.upgrade /// [`None`]: ../../std/option/enum.Option.html#variant.None -/// [assoc]: ../../book/first-edition/method-syntax.html#associated-functions /// [`RefCell`]: ../../std/cell/struct.RefCell.html /// [`std::sync`]: ../../std/sync/index.html /// [`Arc::clone(&from)`]: #method.clone diff --git a/src/libcore/char/convert.rs b/src/libcore/char/convert.rs index e9ccdd0ea3c57..160728f923dbc 100644 --- a/src/libcore/char/convert.rs +++ b/src/libcore/char/convert.rs @@ -19,7 +19,7 @@ use super::MAX; /// Converts a `u32` to a `char`. /// /// Note that all [`char`]s are valid [`u32`]s, and can be cast to one with -/// [`as`]: +/// `as`: /// /// ``` /// let c = '💯'; @@ -34,7 +34,6 @@ use super::MAX; /// /// [`char`]: ../../std/primitive.char.html /// [`u32`]: ../../std/primitive.u32.html -/// [`as`]: ../../book/first-edition/casting-between-types.html#as /// /// For an unsafe version of this function which ignores these checks, see /// [`from_u32_unchecked`]. @@ -71,7 +70,7 @@ pub fn from_u32(i: u32) -> Option { /// Converts a `u32` to a `char`, ignoring validity. /// /// Note that all [`char`]s are valid [`u32`]s, and can be cast to one with -/// [`as`]: +/// `as`: /// /// ``` /// let c = '💯'; @@ -86,7 +85,6 @@ pub fn from_u32(i: u32) -> Option { /// /// [`char`]: ../../std/primitive.char.html /// [`u32`]: ../../std/primitive.u32.html -/// [`as`]: ../../book/first-edition/casting-between-types.html#as /// /// # Safety /// diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 27ee9556bd089..6de27d1b3a864 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -132,7 +132,6 @@ pub use intrinsics::transmute; /// [uninit]: fn.uninitialized.html /// [clone]: ../clone/trait.Clone.html /// [swap]: fn.swap.html -/// [FFI]: ../../book/first-edition/ffi.html /// [box]: ../../std/boxed/struct.Box.html /// [leak]: ../../std/boxed/struct.Box.html#method.leak /// [into_raw]: ../../std/boxed/struct.Box.html#method.into_raw @@ -475,7 +474,7 @@ pub fn needs_drop() -> bool { /// /// This has the same effect as allocating space with /// [`mem::uninitialized`][uninit] and then zeroing it out. It is useful for -/// [FFI] sometimes, but should generally be avoided. +/// FFI sometimes, but should generally be avoided. /// /// There is no guarantee that an all-zero byte-pattern represents a valid value of /// some type `T`. If `T` has a destructor and the value is destroyed (due to @@ -486,7 +485,6 @@ pub fn needs_drop() -> bool { /// many of the same caveats. /// /// [uninit]: fn.uninitialized.html -/// [FFI]: ../../book/first-edition/ffi.html /// [ub]: ../../reference/behavior-considered-undefined.html /// /// # Examples @@ -510,11 +508,9 @@ pub unsafe fn zeroed() -> T { /// **This is incredibly dangerous and should not be done lightly. Deeply /// consider initializing your memory with a default value instead.** /// -/// This is useful for [FFI] functions and initializing arrays sometimes, +/// This is useful for FFI functions and initializing arrays sometimes, /// but should generally be avoided. /// -/// [FFI]: ../../book/first-edition/ffi.html -/// /// # Undefined behavior /// /// It is [undefined behavior][ub] to read uninitialized memory, even just an @@ -685,10 +681,9 @@ pub fn replace(dest: &mut T, mut src: T) -> T { /// While this does call the argument's implementation of [`Drop`][drop], /// it will not release any borrows, as borrows are based on lexical scope. /// -/// This effectively does nothing for -/// [types which implement `Copy`](../../book/first-edition/ownership.html#copy-types), -/// e.g. integers. Such values are copied and _then_ moved into the function, -/// so the value persists after this function call. +/// This effectively does nothing for types which implement `Copy`, e.g. +/// integers. Such values are copied and _then_ moved into the function, so the +/// value persists after this function call. /// /// This function is not magic; it is literally defined as /// diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index b699cb028842b..ede24348fdfc8 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -58,7 +58,7 @@ //! [`NonNull::dangling`] in such cases. //! //! [aliasing]: ../../nomicon/aliasing.html -//! [book]: ../../book/second-edition/ch19-01-unsafe-rust.html#dereferencing-a-raw-pointer +//! [book]: ../../book/ch19-01-unsafe-rust.html#dereferencing-a-raw-pointer //! [ub]: ../../reference/behavior-considered-undefined.html //! [null]: ./fn.null.html //! [zst]: ../../nomicon/exotic-sizes.html#zero-sized-types-zsts diff --git a/src/libcore/raw.rs b/src/libcore/raw.rs index a95f05227fb8b..495b9afe86023 100644 --- a/src/libcore/raw.rs +++ b/src/libcore/raw.rs @@ -21,11 +21,7 @@ /// The representation of a trait object like `&SomeTrait`. /// /// This struct has the same layout as types like `&SomeTrait` and -/// `Box`. The [Trait Objects chapter of the -/// Book][moreinfo] contains more details about the precise nature of -/// these internals. -/// -/// [moreinfo]: ../../book/first-edition/trait-objects.html#representation +/// `Box`. /// /// `TraitObject` is guaranteed to match layouts, but it is not the /// type of trait objects (e.g. the fields are not directly accessible diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 4499b97bf996a..30547289a05a4 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -185,7 +185,7 @@ //! [slice]: primitive.slice.html //! [`atomic`]: sync/atomic/index.html //! [`collections`]: collections/index.html -/// [`for`]: ../../book/ch03-05-control-flow.html#looping-through-a-collection-with-for +//! [`for`]: ../book/ch03-05-control-flow.html#looping-through-a-collection-with-for //! [`format!`]: macro.format.html //! [`fs`]: fs/index.html //! [`io`]: io/index.html @@ -200,7 +200,7 @@ //! [`sync`]: sync/index.html //! [`thread`]: thread/index.html //! [`use std::env`]: env/index.html -//! [`use`]: ../book/ch07-02-modules-and-use-to-control-scope-and-privacy.html#use-to-bring-paths-into-scope +//! [`use`]: ../book/ch07-02-modules-and-use-to-control-scope-and-privacy.html#the-use-keyword-to-bring-paths-into-a-scope //! [crate root]: ../book/ch07-01-packages-and-crates-for-making-libraries-and-executables.html //! [crates.io]: https://crates.io //! [deref-coercions]: ../book/ch15-02-deref.html#implicit-deref-coercions-with-functions-and-methods diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index 34bbbb53d5ff1..334367eed6289 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -32,7 +32,7 @@ /// /// [`Result`] enum is often a better solution for recovering from errors than /// using the `panic!` macro. This macro should be used to avoid proceeding using -/// incorrect values, such as from external sources. Detailed information about +/// incorrect values, such as from external sources. Detailed information about /// error handling is found in the [book]. /// /// The multi-argument form of this macro panics with a string and has the @@ -45,7 +45,7 @@ /// [`Result`]: ../std/result/enum.Result.html /// [`format!`]: ../std/macro.format.html /// [`compile_error!`]: ../std/macro.compile_error.html -/// [book]: ../book/second-edition/ch09-01-unrecoverable-errors-with-panic.html +/// [book]: ../book/ch09-00-error-handling.html /// /// # Current implementation /// @@ -837,8 +837,8 @@ mod builtin { /// boolean expression evaluation of configuration flags. This frequently /// leads to less duplicated code. /// - /// The syntax given to this macro is the same syntax as [the `cfg` - /// attribute](../book/first-edition/conditional-compilation.html). + /// The syntax given to this macro is the same syntax as the `cfg` + /// attribute. /// /// # Examples /// @@ -913,7 +913,7 @@ mod builtin { /// Unsafe code relies on `assert!` to enforce run-time invariants that, if /// violated could lead to unsafety. /// - /// Other use-cases of `assert!` include [testing] and enforcing run-time + /// Other use-cases of `assert!` include testing and enforcing run-time /// invariants in safe code (whose violation cannot result in unsafety). /// /// # Custom Messages @@ -924,7 +924,6 @@ mod builtin { /// /// [`panic!`]: macro.panic.html /// [`debug_assert!`]: macro.debug_assert.html - /// [testing]: ../book/second-edition/ch11-01-writing-tests.html#checking-results-with-the-assert-macro /// [`std::fmt`]: ../std/fmt/index.html /// /// # Examples diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index c2a16122a0dd1..48acc1096a681 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -22,7 +22,7 @@ /// `bool` implements various traits, such as [`BitAnd`], [`BitOr`], [`Not`], etc., /// which allow us to perform boolean operations using `&`, `|` and `!`. /// -/// [`if`] always demands a `bool` value. [`assert!`], being an important macro in testing, +/// `if` always demands a `bool` value. [`assert!`], being an important macro in testing, /// checks whether an expression returns `true`. /// /// ``` @@ -31,7 +31,6 @@ /// ``` /// /// [`assert!`]: macro.assert.html -/// [`if`]: ../book/first-edition/if.html /// [`BitAnd`]: ops/trait.BitAnd.html /// [`BitOr`]: ops/trait.BitOr.html /// [`Not`]: ops/trait.Not.html @@ -695,7 +694,7 @@ mod prim_str { } /// assert_eq!(tuple.2, 'c'); /// ``` /// -/// For more about tuples, see [the book](../book/first-edition/primitive-types.html#tuples). +/// For more about tuples, see [the book](../book/ch03-02-data-types.html#the-tuple-type). /// /// # Trait implementations /// From 155d1910a81302181dc4cc6c0d98e3fe4031066d Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 21 Nov 2018 03:39:41 +0300 Subject: [PATCH 07/21] resolve: Make "empty import canaries" invisible from other crates --- src/librustc_resolve/resolve_imports.rs | 5 ++++- src/test/ui/imports/auxiliary/issue-55811.rs | 5 +++++ src/test/ui/imports/issue-55811.rs | 6 ++++++ 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/imports/auxiliary/issue-55811.rs create mode 100644 src/test/ui/imports/issue-55811.rs diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 7c1ff3d29faa6..ca839433a5ad4 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -1166,7 +1166,10 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { None => continue, }; - if binding.is_import() || binding.is_macro_def() { + // Filter away "empty import canaries". + let is_non_canary_import = + binding.is_import() && binding.vis != ty::Visibility::Invisible; + if is_non_canary_import || binding.is_macro_def() { let def = binding.def(); if def != Def::Err { if let Some(def_id) = def.opt_def_id() { diff --git a/src/test/ui/imports/auxiliary/issue-55811.rs b/src/test/ui/imports/auxiliary/issue-55811.rs new file mode 100644 index 0000000000000..877e4cdb0bdfc --- /dev/null +++ b/src/test/ui/imports/auxiliary/issue-55811.rs @@ -0,0 +1,5 @@ +mod m {} + +// These two imports should not conflict when this crate is loaded from some other crate. +use m::{}; +use m::{}; diff --git a/src/test/ui/imports/issue-55811.rs b/src/test/ui/imports/issue-55811.rs new file mode 100644 index 0000000000000..95316777fabf6 --- /dev/null +++ b/src/test/ui/imports/issue-55811.rs @@ -0,0 +1,6 @@ +// compile-pass +// aux-build:issue-55811.rs + +extern crate issue_55811; + +fn main() {} From 5ad2bc7fe8a2c29e292320a7537f47b479f768a3 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 19 Nov 2018 10:40:09 +0100 Subject: [PATCH 08/21] Replace the ICEing on const fn loops with an error --- src/librustc_mir/transform/qualify_min_const_fn.rs | 8 +++----- src/test/ui/consts/min_const_fn/loop_ice.rs | 5 +++++ src/test/ui/consts/min_const_fn/loop_ice.stderr | 8 ++++++++ 3 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/consts/min_const_fn/loop_ice.rs create mode 100644 src/test/ui/consts/min_const_fn/loop_ice.stderr diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index 6ab68789c027b..b6f4f4b1de437 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -364,10 +364,8 @@ fn check_terminator( cleanup: _, } => check_operand(tcx, mir, cond, span), - | TerminatorKind::FalseUnwind { .. } => span_bug!( - terminator.source_info.span, - "min_const_fn encountered `{:#?}`", - terminator - ), + TerminatorKind::FalseUnwind { .. } => { + Err((span, "loops are not allowed in const fn".into())) + }, } } diff --git a/src/test/ui/consts/min_const_fn/loop_ice.rs b/src/test/ui/consts/min_const_fn/loop_ice.rs new file mode 100644 index 0000000000000..4278a8e2d0036 --- /dev/null +++ b/src/test/ui/consts/min_const_fn/loop_ice.rs @@ -0,0 +1,5 @@ +const fn foo() { + loop {} //~ ERROR loops are not allowed in const fn +} + +fn main() {} diff --git a/src/test/ui/consts/min_const_fn/loop_ice.stderr b/src/test/ui/consts/min_const_fn/loop_ice.stderr new file mode 100644 index 0000000000000..1424cea65afd5 --- /dev/null +++ b/src/test/ui/consts/min_const_fn/loop_ice.stderr @@ -0,0 +1,8 @@ +error: loops are not allowed in const fn + --> $DIR/loop_ice.rs:2:5 + | +LL | loop {} //~ ERROR loops are not allowed in const fn + | ^^^^^^^ + +error: aborting due to previous error + From 069ce5f4918cdaf7375663312b06c276c5f31f96 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Nov 2018 13:35:14 -0500 Subject: [PATCH 09/21] track the span for each id so that we can give a nice ICE --- src/librustc/hir/map/collector.rs | 64 ++++++++++++++++++------------- src/librustc/hir/map/mod.rs | 4 +- 2 files changed, 39 insertions(+), 29 deletions(-) diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 4fbcd83adb555..2917fd7457acf 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -28,6 +28,10 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHashe pub(super) struct NodeCollector<'a, 'hir> { /// The crate krate: &'hir Crate, + + /// Source map + source_map: &'a SourceMap, + /// The node map map: Vec>>, /// The parent of this node @@ -54,7 +58,8 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { pub(super) fn root(krate: &'hir Crate, dep_graph: &'a DepGraph, definitions: &'a definitions::Definitions, - hcx: StableHashingContext<'a>) + hcx: StableHashingContext<'a>, + source_map: &'a SourceMap) -> NodeCollector<'a, 'hir> { let root_mod_def_path_hash = definitions.def_path_hash(CRATE_DEF_INDEX); @@ -102,6 +107,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { let mut collector = NodeCollector { krate, + source_map, map: vec![], parent_node: CRATE_NODE_ID, current_signature_dep_index: root_mod_sig_dep_index, @@ -125,7 +131,6 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { pub(super) fn finalize_and_compute_crate_hash(mut self, crate_disambiguator: CrateDisambiguator, cstore: &dyn CrateStore, - source_map: &SourceMap, commandline_args_hash: u64) -> (Vec>>, Svh) { @@ -154,7 +159,8 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { // If we included the full mapping in the SVH, we could only have // reproducible builds by compiling from the same directory. So we just // hash the result of the mapping instead of the mapping itself. - let mut source_file_names: Vec<_> = source_map + let mut source_file_names: Vec<_> = self + .source_map .files() .iter() .filter(|source_file| CrateNum::from_u32(source_file.crate_of_origin) == LOCAL_CRATE) @@ -186,7 +192,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { self.map[id.as_usize()] = Some(entry); } - fn insert(&mut self, id: NodeId, node: Node<'hir>) { + fn insert(&mut self, span: Span, id: NodeId, node: Node<'hir>) { let entry = Entry { parent: self.parent_node, dep_node: if self.currently_in_body { @@ -216,8 +222,11 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { String::new() }; - bug!("inconsistent DepNode for `{}`: \ - current_dep_node_owner={} ({:?}), hir_id.owner={} ({:?}){}", + span_bug!( + span, + "inconsistent DepNode at `{:?}` for `{}`: \ + current_dep_node_owner={} ({:?}), hir_id.owner={} ({:?}){}", + self.source_map.span_to_string(span), node_str, self.definitions .def_path(self.current_dep_node_owner) @@ -225,7 +234,8 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { self.current_dep_node_owner, self.definitions.def_path(hir_id.owner).to_string_no_crate(), hir_id.owner, - forgot_str) + forgot_str, + ) } } @@ -309,12 +319,12 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { debug_assert_eq!(i.hir_id.owner, self.definitions.opt_def_index(i.id).unwrap()); self.with_dep_node_owner(i.hir_id.owner, i, |this| { - this.insert(i.id, Node::Item(i)); + this.insert(i.span, i.id, Node::Item(i)); this.with_parent(i.id, |this| { if let ItemKind::Struct(ref struct_def, _) = i.node { // If this is a tuple-like struct, register the constructor. if !struct_def.is_struct() { - this.insert(struct_def.id(), Node::StructCtor(struct_def)); + this.insert(i.span, struct_def.id(), Node::StructCtor(struct_def)); } } intravisit::walk_item(this, i); @@ -323,7 +333,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { } fn visit_foreign_item(&mut self, foreign_item: &'hir ForeignItem) { - self.insert(foreign_item.id, Node::ForeignItem(foreign_item)); + self.insert(foreign_item.span, foreign_item.id, Node::ForeignItem(foreign_item)); self.with_parent(foreign_item.id, |this| { intravisit::walk_foreign_item(this, foreign_item); @@ -331,7 +341,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { } fn visit_generic_param(&mut self, param: &'hir GenericParam) { - self.insert(param.id, Node::GenericParam(param)); + self.insert(param.span, param.id, Node::GenericParam(param)); intravisit::walk_generic_param(self, param); } @@ -339,7 +349,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { debug_assert_eq!(ti.hir_id.owner, self.definitions.opt_def_index(ti.id).unwrap()); self.with_dep_node_owner(ti.hir_id.owner, ti, |this| { - this.insert(ti.id, Node::TraitItem(ti)); + this.insert(ti.span, ti.id, Node::TraitItem(ti)); this.with_parent(ti.id, |this| { intravisit::walk_trait_item(this, ti); @@ -351,7 +361,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { debug_assert_eq!(ii.hir_id.owner, self.definitions.opt_def_index(ii.id).unwrap()); self.with_dep_node_owner(ii.hir_id.owner, ii, |this| { - this.insert(ii.id, Node::ImplItem(ii)); + this.insert(ii.span, ii.id, Node::ImplItem(ii)); this.with_parent(ii.id, |this| { intravisit::walk_impl_item(this, ii); @@ -365,7 +375,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { } else { Node::Pat(pat) }; - self.insert(pat.id, node); + self.insert(pat.span, pat.id, node); self.with_parent(pat.id, |this| { intravisit::walk_pat(this, pat); @@ -373,7 +383,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { } fn visit_anon_const(&mut self, constant: &'hir AnonConst) { - self.insert(constant.id, Node::AnonConst(constant)); + self.insert(DUMMY_SP, constant.id, Node::AnonConst(constant)); self.with_parent(constant.id, |this| { intravisit::walk_anon_const(this, constant); @@ -381,7 +391,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { } fn visit_expr(&mut self, expr: &'hir Expr) { - self.insert(expr.id, Node::Expr(expr)); + self.insert(expr.span, expr.id, Node::Expr(expr)); self.with_parent(expr.id, |this| { intravisit::walk_expr(this, expr); @@ -390,7 +400,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { fn visit_stmt(&mut self, stmt: &'hir Stmt) { let id = stmt.node.id(); - self.insert(id, Node::Stmt(stmt)); + self.insert(stmt.span, id, Node::Stmt(stmt)); self.with_parent(id, |this| { intravisit::walk_stmt(this, stmt); @@ -399,13 +409,13 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { fn visit_path_segment(&mut self, path_span: Span, path_segment: &'hir PathSegment) { if let Some(id) = path_segment.id { - self.insert(id, Node::PathSegment(path_segment)); + self.insert(path_span, id, Node::PathSegment(path_segment)); } intravisit::walk_path_segment(self, path_span, path_segment); } fn visit_ty(&mut self, ty: &'hir Ty) { - self.insert(ty.id, Node::Ty(ty)); + self.insert(ty.span, ty.id, Node::Ty(ty)); self.with_parent(ty.id, |this| { intravisit::walk_ty(this, ty); @@ -413,7 +423,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { } fn visit_trait_ref(&mut self, tr: &'hir TraitRef) { - self.insert(tr.ref_id, Node::TraitRef(tr)); + self.insert(tr.path.span, tr.ref_id, Node::TraitRef(tr)); self.with_parent(tr.ref_id, |this| { intravisit::walk_trait_ref(this, tr); @@ -427,21 +437,21 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { } fn visit_block(&mut self, block: &'hir Block) { - self.insert(block.id, Node::Block(block)); + self.insert(block.span, block.id, Node::Block(block)); self.with_parent(block.id, |this| { intravisit::walk_block(this, block); }); } fn visit_local(&mut self, l: &'hir Local) { - self.insert(l.id, Node::Local(l)); + self.insert(l.span, l.id, Node::Local(l)); self.with_parent(l.id, |this| { intravisit::walk_local(this, l) }) } fn visit_lifetime(&mut self, lifetime: &'hir Lifetime) { - self.insert(lifetime.id, Node::Lifetime(lifetime)); + self.insert(lifetime.span, lifetime.id, Node::Lifetime(lifetime)); } fn visit_vis(&mut self, visibility: &'hir Visibility) { @@ -450,7 +460,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { VisibilityKind::Crate(_) | VisibilityKind::Inherited => {} VisibilityKind::Restricted { id, .. } => { - self.insert(id, Node::Visibility(visibility)); + self.insert(visibility.span, id, Node::Visibility(visibility)); self.with_parent(id, |this| { intravisit::walk_vis(this, visibility); }); @@ -462,20 +472,20 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { let def_index = self.definitions.opt_def_index(macro_def.id).unwrap(); self.with_dep_node_owner(def_index, macro_def, |this| { - this.insert(macro_def.id, Node::MacroDef(macro_def)); + this.insert(macro_def.span, macro_def.id, Node::MacroDef(macro_def)); }); } fn visit_variant(&mut self, v: &'hir Variant, g: &'hir Generics, item_id: NodeId) { let id = v.node.data.id(); - self.insert(id, Node::Variant(v)); + self.insert(v.span, id, Node::Variant(v)); self.with_parent(id, |this| { intravisit::walk_variant(this, v, g, item_id); }); } fn visit_struct_field(&mut self, field: &'hir StructField) { - self.insert(field.id, Node::Field(field)); + self.insert(field.span, field.id, Node::Field(field)); self.with_parent(field.id, |this| { intravisit::walk_struct_field(this, field); }); diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 7a20146130d94..9e7b26baa1db8 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -1034,14 +1034,14 @@ pub fn map_crate<'hir>(sess: &::session::Session, let mut collector = NodeCollector::root(&forest.krate, &forest.dep_graph, &definitions, - hcx); + hcx, + sess.source_map()); intravisit::walk_crate(&mut collector, &forest.krate); let crate_disambiguator = sess.local_crate_disambiguator(); let cmdline_args = sess.opts.dep_tracking_hash(); collector.finalize_and_compute_crate_hash(crate_disambiguator, cstore, - sess.source_map(), cmdline_args) }; From f6720e2d58801007752a84c761eada6c7dfecf5d Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Nov 2018 13:35:54 -0500 Subject: [PATCH 10/21] add some `debug!` into lowering --- src/librustc/hir/lowering.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index b6621e0962cf6..6023bf88b157d 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1867,6 +1867,10 @@ impl<'a> LoweringContext<'a> { } else { self.lower_node_id(segment.id) }; + debug!( + "lower_path_segment: ident={:?} original-id={:?} new-id={:?}", + segment.ident, segment.id, id, + ); hir::PathSegment::new( segment.ident, @@ -2953,6 +2957,9 @@ impl<'a> LoweringContext<'a> { name: &mut Name, attrs: &hir::HirVec, ) -> hir::ItemKind { + debug!("lower_use_tree(tree={:?})", tree); + debug!("lower_use_tree: vis = {:?}", vis); + let path = &tree.prefix; let segments = prefix .segments @@ -4538,6 +4545,7 @@ impl<'a> LoweringContext<'a> { VisibilityKind::Public => hir::VisibilityKind::Public, VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar), VisibilityKind::Restricted { ref path, id } => { + debug!("lower_visibility: restricted path id = {:?}", id); let lowered_id = if let Some(owner) = explicit_owner { self.lower_node_id_with_owner(id, owner) } else { From ff003e1c1187a62c217776a21dd3becb0b9f05ea Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Nov 2018 13:36:11 -0500 Subject: [PATCH 11/21] renumber segment ids for visibilities whenever we clone them --- src/librustc/hir/lowering.rs | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 6023bf88b157d..d0a616076a701 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -3027,12 +3027,7 @@ impl<'a> LoweringContext<'a> { hir::VisibilityKind::Inherited => hir::VisibilityKind::Inherited, hir::VisibilityKind::Restricted { ref path, id: _, hir_id: _ } => { let id = this.next_id(); - let mut path = path.clone(); - for seg in path.segments.iter_mut() { - if seg.id.is_some() { - seg.id = Some(this.next_id().node_id); - } - } + let path = this.renumber_segment_ids(path); hir::VisibilityKind::Restricted { path, id: id.node_id, @@ -3117,8 +3112,9 @@ impl<'a> LoweringContext<'a> { hir::VisibilityKind::Inherited => hir::VisibilityKind::Inherited, hir::VisibilityKind::Restricted { ref path, id: _, hir_id: _ } => { let id = this.next_id(); + let path = this.renumber_segment_ids(path); hir::VisibilityKind::Restricted { - path: path.clone(), + path: path, id: id.node_id, hir_id: id.hir_id, } @@ -3152,6 +3148,20 @@ impl<'a> LoweringContext<'a> { } } + /// Paths like the visibility path in `pub(super) use foo::{bar, baz}` are repeated + /// many times in the HIR tree; for each occurrence, we need to assign distinct + /// node-ids. (See e.g. #56128.) + fn renumber_segment_ids(&mut self, path: &P) -> P { + debug!("renumber_segment_ids(path = {:?})", path); + let mut path = path.clone(); + for seg in path.segments.iter_mut() { + if seg.id.is_some() { + seg.id = Some(self.next_id().node_id); + } + } + path + } + fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem { let LoweredNodeId { node_id, hir_id } = self.lower_node_id(i.id); let trait_item_def_id = self.resolver.definitions().local_def_id(node_id); From 26f711a8c851b7fb38be59acabeb683cd2231a05 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Nov 2018 15:34:11 -0500 Subject: [PATCH 12/21] preserve the original visibility for the "list stem" node Without this, the `vis` does not wind up in the tree anywhere, and then we get ICEs because the node-ids it refers to are not present. The motivation seemed to be documentation, but `ListStem` HIR nodes are ignored in rustdoc, from what I can tell. --- src/librustc/hir/lowering.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index d0a616076a701..422df26b055ab 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -3137,12 +3137,8 @@ impl<'a> LoweringContext<'a> { }); } - // Privatize the degenerate import base, used only to check - // the stability of `use a::{};`, to avoid it showing up as - // a re-export by accident when `pub`, e.g. in documentation. let def = self.expect_full_def_from_use(id).next().unwrap_or(Def::Err); let path = P(self.lower_path_extra(def, &prefix, ParamMode::Explicit, None)); - *vis = respan(prefix.span.shrink_to_lo(), hir::VisibilityKind::Inherited); hir::ItemKind::Use(path, hir::UseKind::ListStem) } } From ed51070f17d949eaca7794ee026e33740d4f3a41 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Nov 2018 14:20:03 -0500 Subject: [PATCH 13/21] add regression test --- src/test/ui/issues/issue-56128.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/test/ui/issues/issue-56128.rs diff --git a/src/test/ui/issues/issue-56128.rs b/src/test/ui/issues/issue-56128.rs new file mode 100644 index 0000000000000..4d36fec9c04fa --- /dev/null +++ b/src/test/ui/issues/issue-56128.rs @@ -0,0 +1,13 @@ +// Regression test for #56128. When this `pub(super) use...` gets +// exploded in the HIR, we were not handling ids correctly. + +mod bar { + pub(super) use self::baz::{x, y}; + + mod baz { + pub fn x() { } + pub fn y() { } + } +} + +fn main() { } From 4179c40576ee8f6880ec692441b10361768d94cc Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Nov 2018 14:24:36 -0500 Subject: [PATCH 14/21] pass vis by shared reference We are not mutating it now. --- src/librustc/hir/lowering.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 422df26b055ab..466e898116548 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -2750,7 +2750,7 @@ impl<'a> LoweringContext<'a> { id: NodeId, name: &mut Name, attrs: &hir::HirVec, - vis: &mut hir::Visibility, + vis: &hir::Visibility, i: &ItemKind, ) -> hir::ItemKind { match *i { @@ -2953,7 +2953,7 @@ impl<'a> LoweringContext<'a> { tree: &UseTree, prefix: &Path, id: NodeId, - vis: &mut hir::Visibility, + vis: &hir::Visibility, name: &mut Name, attrs: &hir::HirVec, ) -> hir::ItemKind { @@ -3084,7 +3084,7 @@ impl<'a> LoweringContext<'a> { hir_id: new_hir_id, } = self.lower_node_id(id); - let mut vis = vis.clone(); + let vis = vis.clone(); let mut name = name.clone(); let mut prefix = prefix.clone(); @@ -3102,7 +3102,7 @@ impl<'a> LoweringContext<'a> { let item = this.lower_use_tree(use_tree, &prefix, new_id, - &mut vis, + &vis, &mut name, attrs); @@ -3382,7 +3382,7 @@ impl<'a> LoweringContext<'a> { pub fn lower_item(&mut self, i: &Item) -> Option { let mut name = i.ident.name; - let mut vis = self.lower_visibility(&i.vis, None); + let vis = self.lower_visibility(&i.vis, None); let attrs = self.lower_attrs(&i.attrs); if let ItemKind::MacroDef(ref def) = i.node { if !def.legacy || attr::contains_name(&i.attrs, "macro_export") || @@ -3401,7 +3401,7 @@ impl<'a> LoweringContext<'a> { return None; } - let node = self.lower_item_kind(i.id, &mut name, &attrs, &mut vis, &i.node); + let node = self.lower_item_kind(i.id, &mut name, &attrs, &vis, &i.node); let LoweredNodeId { node_id, hir_id } = self.lower_node_id(i.id); From 221c33adf1bed0772f8f59fdf3e5fcce506b2e07 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Nov 2018 16:09:17 -0500 Subject: [PATCH 15/21] hack: ignore list-stems for pub lint --- src/librustc_lint/builtin.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 7291e27048280..58ef67ec6204a 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1136,7 +1136,15 @@ impl UnreachablePub { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnreachablePub { fn check_item(&mut self, cx: &LateContext, item: &hir::Item) { - self.perform_lint(cx, "item", item.id, &item.vis, item.span, true); + match item.node { + hir::ItemKind::Use(_, hir::UseKind::ListStem) => { + // Hack: ignore these `use foo::{}` remnants which are just a figment + // our IR. + } + _ => { + self.perform_lint(cx, "item", item.id, &item.vis, item.span, true); + } + } } fn check_foreign_item(&mut self, cx: &LateContext, foreign_item: &hir::ForeignItem) { From 5fc113de609468962bbe115e1ea7765670aaf75a Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Nov 2018 18:50:10 -0500 Subject: [PATCH 16/21] add compile-pass annotation --- src/test/ui/issues/issue-56128.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/ui/issues/issue-56128.rs b/src/test/ui/issues/issue-56128.rs index 4d36fec9c04fa..3a3eccdc33ce8 100644 --- a/src/test/ui/issues/issue-56128.rs +++ b/src/test/ui/issues/issue-56128.rs @@ -1,5 +1,7 @@ // Regression test for #56128. When this `pub(super) use...` gets // exploded in the HIR, we were not handling ids correctly. +// +// compile-pass mod bar { pub(super) use self::baz::{x, y}; From 19ba1b66686edcb3cb477961abe6e1505ce1734a Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 22 Nov 2018 06:41:26 -0500 Subject: [PATCH 17/21] only reset non-restricted visibilities --- src/librustc/hir/lowering.rs | 33 +++++++++++++++++++++++++++------ src/librustc_lint/builtin.rs | 10 +--------- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 466e898116548..5340df0d6319b 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -2750,7 +2750,7 @@ impl<'a> LoweringContext<'a> { id: NodeId, name: &mut Name, attrs: &hir::HirVec, - vis: &hir::Visibility, + vis: &mut hir::Visibility, i: &ItemKind, ) -> hir::ItemKind { match *i { @@ -2953,7 +2953,7 @@ impl<'a> LoweringContext<'a> { tree: &UseTree, prefix: &Path, id: NodeId, - vis: &hir::Visibility, + vis: &mut hir::Visibility, name: &mut Name, attrs: &hir::HirVec, ) -> hir::ItemKind { @@ -3084,7 +3084,7 @@ impl<'a> LoweringContext<'a> { hir_id: new_hir_id, } = self.lower_node_id(id); - let vis = vis.clone(); + let mut vis = vis.clone(); let mut name = name.clone(); let mut prefix = prefix.clone(); @@ -3102,7 +3102,7 @@ impl<'a> LoweringContext<'a> { let item = this.lower_use_tree(use_tree, &prefix, new_id, - &vis, + &mut vis, &mut name, attrs); @@ -3137,6 +3137,27 @@ impl<'a> LoweringContext<'a> { }); } + // Subtle and a bit hacky: we lower the privacy level + // of the list stem to "private" most of the time, but + // not for "restricted" paths. The key thing is that + // we don't want it to stay as `pub` (with no caveats) + // because that affects rustdoc and also the lints + // about `pub` items. But we can't *always* make it + // private -- particularly not for restricted paths -- + // because it contains node-ids that would then be + // unused, failing the check that HirIds are "densely + // assigned". + match vis.node { + hir::VisibilityKind::Public | + hir::VisibilityKind::Crate(_) | + hir::VisibilityKind::Inherited => { + *vis = respan(prefix.span.shrink_to_lo(), hir::VisibilityKind::Inherited); + } + hir::VisibilityKind::Restricted { .. } => { + // do nothing here, as described in the comment on the match + } + } + let def = self.expect_full_def_from_use(id).next().unwrap_or(Def::Err); let path = P(self.lower_path_extra(def, &prefix, ParamMode::Explicit, None)); hir::ItemKind::Use(path, hir::UseKind::ListStem) @@ -3382,7 +3403,7 @@ impl<'a> LoweringContext<'a> { pub fn lower_item(&mut self, i: &Item) -> Option { let mut name = i.ident.name; - let vis = self.lower_visibility(&i.vis, None); + let mut vis = self.lower_visibility(&i.vis, None); let attrs = self.lower_attrs(&i.attrs); if let ItemKind::MacroDef(ref def) = i.node { if !def.legacy || attr::contains_name(&i.attrs, "macro_export") || @@ -3401,7 +3422,7 @@ impl<'a> LoweringContext<'a> { return None; } - let node = self.lower_item_kind(i.id, &mut name, &attrs, &vis, &i.node); + let node = self.lower_item_kind(i.id, &mut name, &attrs, &mut vis, &i.node); let LoweredNodeId { node_id, hir_id } = self.lower_node_id(i.id); diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 58ef67ec6204a..7291e27048280 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1136,15 +1136,7 @@ impl UnreachablePub { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnreachablePub { fn check_item(&mut self, cx: &LateContext, item: &hir::Item) { - match item.node { - hir::ItemKind::Use(_, hir::UseKind::ListStem) => { - // Hack: ignore these `use foo::{}` remnants which are just a figment - // our IR. - } - _ => { - self.perform_lint(cx, "item", item.id, &item.vis, item.span, true); - } - } + self.perform_lint(cx, "item", item.id, &item.vis, item.span, true); } fn check_foreign_item(&mut self, cx: &LateContext, foreign_item: &hir::ForeignItem) { From 647cb20a0b96b2020f98e5550819a6dffd3eadc5 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 22 Nov 2018 06:48:13 -0500 Subject: [PATCH 18/21] explain how this works --- src/librustc/hir/lowering.rs | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 5340df0d6319b..8576df976be1c 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -3068,7 +3068,29 @@ impl<'a> LoweringContext<'a> { hir::ItemKind::Use(path, hir::UseKind::Glob) } UseTreeKind::Nested(ref trees) => { - // Nested imports are desugared into simple imports. + // Nested imports are desugared into simple + // imports. So if we start with + // + // ``` + // pub(x) use foo::{a, b}; + // ``` + // + // we will create three items: + // + // ``` + // pub(x) use foo::a; + // pub(x) use foo::b; + // pub(x) use foo::{}; // <-- this is called the `ListStem` + // ``` + // + // The first two are produced by recursively invoking + // `lower_use_tree` (and indeed there may be things + // like `use foo::{a::{b, c}}` and so forth). They + // wind up being directly added to + // `self.items`. However, the structure of this + // function also requires us to return one item, and + // for that we return the `{}` import (called the + // "`ListStem`"). let prefix = Path { segments, From fffcde647a5fa4d46db4fb42cd5525bfe973b86e Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 22 Nov 2018 21:29:56 -0800 Subject: [PATCH 19/21] Fix minor nomicon breakage --- src/doc/nomicon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/nomicon b/src/doc/nomicon index f8a4e96feb2e5..fb3e2ac7bf52c 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit f8a4e96feb2e5a6ed1ef170ad40e3509a7755cb4 +Subproject commit fb3e2ac7bf52c127a06ea02fd7673d2617c4272a From ec39ea893b9ac2f4096491c2851a2fe65a4ee7fc Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 21 Nov 2018 14:27:30 +0100 Subject: [PATCH 20/21] Forward rust version number to tools Clippy uses it to identify the correct documentation to point to --- src/bootstrap/tool.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 15d27c613423a..6868a063ce58f 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -22,6 +22,7 @@ use util::{exe, add_lib_path}; use compile; use native; use channel::GitInfo; +use channel; use cache::Interned; use toolstate::ToolState; @@ -240,6 +241,7 @@ pub fn prepare_tool_cargo( cargo.env("CFG_RELEASE_CHANNEL", &builder.config.channel); cargo.env("CFG_VERSION", builder.rust_version()); + cargo.env("CFG_RELEASE_NUM", channel::CFG_RELEASE_NUM); let info = GitInfo::new(&builder.config, &dir); if let Some(sha) = info.sha() { From 659fcb94cb7a3f52fc1f5d19fcd6259dad0d455f Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 22 Nov 2018 10:47:19 +0100 Subject: [PATCH 21/21] Update clippy submodule --- src/tools/clippy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy b/src/tools/clippy index 246a77ebe8c9d..2e26fdc2a86f0 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit 246a77ebe8c9d640c76a82f3869c5272ba51346d +Subproject commit 2e26fdc2a86f03771a31b8a1e1a35cf8397cb69b