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) ========================== 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"))) { 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() { 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..fb3e2ac7bf52c 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 7f7a597b47ed6c35c2a0f0ee6a69050fe2d5e013 +Subproject commit fb3e2ac7bf52c127a06ea02fd7673d2617c4272a 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 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/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/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/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/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index b6621e0962cf6..8576df976be1c 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 @@ -3020,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, @@ -3066,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, @@ -3110,8 +3134,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, } @@ -3134,17 +3159,48 @@ 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. + // 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)); - *vis = respan(prefix.span.shrink_to_lo(), hir::VisibilityKind::Inherited); hir::ItemKind::Use(path, hir::UseKind::ListStem) } } } + /// 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); @@ -4538,6 +4594,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 { 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) }; diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 6485acf4ed2cc..f3fe53444bfe9 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1484,15 +1484,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// done with either: `-Ztwo-phase-borrows`, `#![feature(nll)]`, /// or by opting into an edition after 2015. pub fn two_phase_borrows(self) -> bool { - if self.features().nll || self.sess.opts.debugging_opts.two_phase_borrows { - return true; - } - - match self.sess.edition() { - Edition::Edition2015 => false, - Edition::Edition2018 => true, - _ => true, - } + self.sess.rust_2018() || self.features().nll || + self.sess.opts.debugging_opts.two_phase_borrows } /// What mode(s) of borrowck should we run? AST? MIR? both? diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index 7153c729d1542..6d92890fc08ad 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -14,7 +14,6 @@ use ty::{self, DefIdTree, Ty, TyCtxt}; use middle::cstore::{ExternCrate, ExternCrateSource}; use syntax::ast; use syntax::symbol::{keywords, LocalInternedString, Symbol}; -use syntax_pos::edition::Edition; use std::cell::Cell; use std::fmt::Debug; @@ -140,7 +139,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { debug!("push_krate_path: name={:?}", name); buffer.push(&name); } - } else if self.sess.edition() == Edition::Edition2018 && !pushed_prelude_crate { + } else if self.sess.rust_2018() && !pushed_prelude_crate { SHOULD_PREFIX_WITH_CRATE.with(|flag| { // We only add the `crate::` keyword where appropriate. In particular, // when we've not previously pushed a prelude crate to this path. 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/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index b3a70c79df144..715b788ea8a9d 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -132,17 +132,21 @@ impl<'a, 'cl> Resolver<'a, 'cl> { // so prefixes are prepended with crate root segment if necessary. // The root is prepended lazily, when the first non-empty prefix or terminating glob // appears, so imports in braced groups can have roots prepended independently. + // 2015 identifiers used on global 2018 edition enter special "virtual 2015 mode", don't + // get crate root prepended, but get special treatment during in-scope resolution instead. let is_glob = if let ast::UseTreeKind::Glob = use_tree.kind { true } else { false }; - let crate_root = if !self.session.rust_2018() && - prefix_iter.peek().map_or(is_glob, |seg| !seg.ident.is_path_segment_keyword()) - { - Some(Segment::from_ident(Ident::new( - keywords::CrateRoot.name(), - use_tree.prefix.span.shrink_to_lo(), - ))) - } else { - None - }; + let crate_root = match prefix_iter.peek() { + Some(seg) if !seg.ident.is_path_segment_keyword() && + seg.ident.span.rust_2015() && self.session.rust_2015() => { + Some(seg.ident.span.ctxt()) + } + None if is_glob && use_tree.span.rust_2015() => { + Some(use_tree.span.ctxt()) + } + _ => None, + }.map(|ctxt| Segment::from_ident(Ident::new( + keywords::CrateRoot.name(), use_tree.prefix.span.shrink_to_lo().with_ctxt(ctxt) + ))); let prefix = crate_root.into_iter().chain(prefix_iter).collect::>(); debug!("build_reduced_graph_for_use_tree: prefix={:?}", prefix); diff --git a/src/librustc_resolve/error_reporting.rs b/src/librustc_resolve/error_reporting.rs index 263d23d133e1c..e2a6303f57944 100644 --- a/src/librustc_resolve/error_reporting.rs +++ b/src/librustc_resolve/error_reporting.rs @@ -33,7 +33,8 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { (Some(fst), Some(snd)) if fst.ident.name == keywords::CrateRoot.name() && !snd.ident.is_path_segment_keyword() => {} // `ident::...` on 2018 - (Some(fst), _) if self.session.rust_2018() && !fst.ident.is_path_segment_keyword() => { + (Some(fst), _) if fst.ident.span.rust_2018() && + !fst.ident.is_path_segment_keyword() => { // Insert a placeholder that's later replaced by `self`/`super`/etc. path.insert(0, Segment::from_ident(keywords::Invalid.ident())); } @@ -141,7 +142,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { mut path: Vec, parent_scope: &ParentScope<'b>, ) -> Option<(Vec, Option)> { - if !self.session.rust_2018() { + if path[1].ident.span.rust_2015() { return None; } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 4eb8a285aeccb..70324f6a1498b 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -13,6 +13,7 @@ html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(crate_visibility_modifier)] +#![feature(label_break_value)] #![feature(nll)] #![feature(rustc_diagnostic_macros)] #![feature(slice_sort_by_cached_key)] @@ -101,6 +102,13 @@ enum Weak { No, } +enum ScopeSet { + Import(Namespace), + AbsolutePath(Namespace), + Macro(MacroKind), + Module, +} + /// A free importable items suggested in case of resolution failure. struct ImportSuggestion { path: Path, @@ -996,31 +1004,33 @@ impl<'a> LexicalScopeBinding<'a> { } } - -#[derive(Clone, Copy, PartialEq, Debug)] -enum UniformRootKind { - CurrentScope, - ExternPrelude, -} - #[derive(Copy, Clone, Debug)] enum ModuleOrUniformRoot<'a> { /// Regular module. Module(Module<'a>), - /// This "virtual module" denotes either resolution in extern prelude - /// for paths starting with `::` on 2018 edition or `extern::`, - /// or resolution in current scope for single-segment imports. - UniformRoot(UniformRootKind), + /// Virtual module that denotes resolution in crate root with fallback to extern prelude. + CrateRootAndExternPrelude, + + /// Virtual module that denotes resolution in extern prelude. + /// Used for paths starting with `::` on 2018 edition or `extern::`. + ExternPrelude, + + /// Virtual module that denotes resolution in current scope. + /// Used only for resolving single-segment imports. The reason it exists is that import paths + /// are always split into two parts, the first of which should be some kind of module. + CurrentScope, } impl<'a> PartialEq for ModuleOrUniformRoot<'a> { fn eq(&self, other: &Self) -> bool { match (*self, *other) { - (ModuleOrUniformRoot::Module(lhs), ModuleOrUniformRoot::Module(rhs)) => - ptr::eq(lhs, rhs), - (ModuleOrUniformRoot::UniformRoot(lhs), ModuleOrUniformRoot::UniformRoot(rhs)) => - lhs == rhs, + (ModuleOrUniformRoot::Module(lhs), + ModuleOrUniformRoot::Module(rhs)) => ptr::eq(lhs, rhs), + (ModuleOrUniformRoot::CrateRootAndExternPrelude, + ModuleOrUniformRoot::CrateRootAndExternPrelude) | + (ModuleOrUniformRoot::ExternPrelude, ModuleOrUniformRoot::ExternPrelude) | + (ModuleOrUniformRoot::CurrentScope, ModuleOrUniformRoot::CurrentScope) => true, _ => false, } } @@ -1239,6 +1249,7 @@ struct UseError<'a> { #[derive(Clone, Copy, PartialEq, Debug)] enum AmbiguityKind { Import, + AbsolutePath, BuiltinAttr, DeriveHelper, LegacyHelperVsPrelude, @@ -1254,6 +1265,8 @@ impl AmbiguityKind { match self { AmbiguityKind::Import => "name vs any other name during import resolution", + AmbiguityKind::AbsolutePath => + "name in the crate root vs extern crate during absolute path resolution", AmbiguityKind::BuiltinAttr => "built-in attribute vs any other name", AmbiguityKind::DeriveHelper => @@ -1279,6 +1292,7 @@ impl AmbiguityKind { /// Miscellaneous bits of metadata for better ambiguity error reporting. #[derive(Clone, Copy, PartialEq)] enum AmbiguityErrorMisc { + SuggestCrate, SuggestSelf, FromPrelude, None, @@ -1762,8 +1776,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { error_callback(self, span, ResolutionError::FailedToResolve(msg)); Def::Err } - PathResult::Module(ModuleOrUniformRoot::UniformRoot(_)) | - PathResult::Indeterminate => unreachable!(), + PathResult::Module(..) | PathResult::Indeterminate => unreachable!(), PathResult::Failed(span, msg, _) => { error_callback(self, span, ResolutionError::FailedToResolve(&msg)); Def::Err @@ -2196,28 +2209,46 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { fn resolve_ident_in_module( &mut self, module: ModuleOrUniformRoot<'a>, - mut ident: Ident, + ident: Ident, ns: Namespace, parent_scope: Option<&ParentScope<'a>>, record_used: bool, path_span: Span ) -> Result<&'a NameBinding<'a>, Determinacy> { - ident.span = ident.span.modern(); + self.resolve_ident_in_module_ext( + module, ident, ns, parent_scope, record_used, path_span + ).map_err(|(determinacy, _)| determinacy) + } + + fn resolve_ident_in_module_ext( + &mut self, + module: ModuleOrUniformRoot<'a>, + mut ident: Ident, + ns: Namespace, + parent_scope: Option<&ParentScope<'a>>, + record_used: bool, + path_span: Span + ) -> Result<&'a NameBinding<'a>, (Determinacy, Weak)> { let orig_current_module = self.current_module; match module { ModuleOrUniformRoot::Module(module) => { + ident.span = ident.span.modern(); if let Some(def) = ident.span.adjust(module.expansion) { self.current_module = self.macro_def_scope(def); } } - ModuleOrUniformRoot::UniformRoot(UniformRootKind::ExternPrelude) => { + ModuleOrUniformRoot::ExternPrelude => { + ident.span = ident.span.modern(); ident.span.adjust(Mark::root()); } - _ => {} + ModuleOrUniformRoot::CrateRootAndExternPrelude | + ModuleOrUniformRoot::CurrentScope => { + // No adjustments + } } let result = self.resolve_ident_in_module_unadjusted_ext( module, ident, ns, parent_scope, false, record_used, path_span, - ).map_err(|(determinacy, _)| determinacy); + ); self.current_module = orig_current_module; result } @@ -2359,14 +2390,10 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } fn future_proof_import(&mut self, use_tree: &ast::UseTree) { - if !self.session.rust_2018() { - return; - } - let segments = &use_tree.prefix.segments; if !segments.is_empty() { let ident = segments[0].ident; - if ident.is_path_segment_keyword() { + if ident.is_path_segment_keyword() || ident.span.rust_2015() { return; } @@ -3186,10 +3213,10 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { // Try to lookup the name in more relaxed fashion for better error reporting. let ident = path.last().unwrap().ident; - let candidates = this.lookup_import_candidates(ident.name, ns, is_expected); + let candidates = this.lookup_import_candidates(ident, ns, is_expected); if candidates.is_empty() && is_expected(Def::Enum(DefId::local(CRATE_DEF_INDEX))) { let enum_candidates = - this.lookup_import_candidates(ident.name, ns, is_enum_variant); + this.lookup_import_candidates(ident, ns, is_enum_variant); let mut enum_candidates = enum_candidates.iter() .map(|suggestion| import_candidate_to_paths(&suggestion)).collect::>(); enum_candidates.sort(); @@ -3655,8 +3682,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { resolve_error(self, span, ResolutionError::FailedToResolve(&msg)); err_path_resolution() } - PathResult::Module(ModuleOrUniformRoot::UniformRoot(_)) | - PathResult::Failed(..) => return None, + PathResult::Module(..) | PathResult::Failed(..) => return None, PathResult::Indeterminate => bug!("indetermined path result in resolve_qpath"), }; @@ -3774,9 +3800,14 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { continue; } if name == keywords::Extern.name() || - name == keywords::CrateRoot.name() && self.session.rust_2018() { - module = - Some(ModuleOrUniformRoot::UniformRoot(UniformRootKind::ExternPrelude)); + name == keywords::CrateRoot.name() && ident.span.rust_2018() { + module = Some(ModuleOrUniformRoot::ExternPrelude); + continue; + } + if name == keywords::CrateRoot.name() && + ident.span.rust_2015() && self.session.rust_2018() { + // `::a::b` from 2015 macro on 2018 global edition + module = Some(ModuleOrUniformRoot::CrateRootAndExternPrelude); continue; } if name == keywords::CrateRoot.name() || @@ -3809,9 +3840,9 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { self.resolve_ident_in_module(module, ident, ns, None, record_used, path_span) } else if opt_ns.is_none() || opt_ns == Some(MacroNS) { assert!(ns == TypeNS); - self.early_resolve_ident_in_lexical_scope(ident, ns, None, opt_ns.is_none(), - parent_scope, record_used, record_used, - path_span) + let scopes = if opt_ns.is_none() { ScopeSet::Import(ns) } else { ScopeSet::Module }; + self.early_resolve_ident_in_lexical_scope(ident, scopes, parent_scope, record_used, + record_used, path_span) } else { let record_used_id = if record_used { crate_lint.node_id().or(Some(CRATE_NODE_ID)) } else { None }; @@ -3877,7 +3908,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { let msg = if module_def == self.graph_root.def() { let is_mod = |def| match def { Def::Mod(..) => true, _ => false }; let mut candidates = - self.lookup_import_candidates(name, TypeNS, is_mod); + self.lookup_import_candidates(ident, TypeNS, is_mod); candidates.sort_by_cached_key(|c| { (c.path.segments.len(), c.path.to_string()) }); @@ -3900,8 +3931,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { PathResult::Module(match module { Some(module) => module, - None if path.is_empty() => - ModuleOrUniformRoot::UniformRoot(UniformRootKind::CurrentScope), + None if path.is_empty() => ModuleOrUniformRoot::CurrentScope, _ => span_bug!(path_span, "resolve_path: non-empty path `{:?}` has no module", path), }) } @@ -3913,11 +3943,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { path_span: Span, second_binding: Option<&NameBinding>, ) { - // In the 2018 edition this lint is a hard error, so nothing to do - if self.session.rust_2018() { - return - } - let (diag_id, diag_span) = match crate_lint { CrateLint::No => return, CrateLint::SimplePath(id) => (id, path_span), @@ -3926,8 +3951,9 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { }; let first_name = match path.get(0) { - Some(ident) => ident.ident.name, - None => return, + // In the 2018 edition this lint is a hard error, so nothing to do + Some(seg) if seg.ident.span.rust_2015() => seg.ident.name, + _ => return, }; // We're only interested in `use` paths which should start with @@ -4509,7 +4535,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } fn lookup_import_candidates_from_module(&mut self, - lookup_name: Name, + lookup_ident: Ident, namespace: Namespace, start_module: &'a ModuleData<'a>, crate_name: Ident, @@ -4536,11 +4562,11 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { if !name_binding.is_importable() { return; } // collect results based on the filter function - if ident.name == lookup_name && ns == namespace { + if ident.name == lookup_ident.name && ns == namespace { if filter_fn(name_binding.def()) { // create the path let mut segms = path_segments.clone(); - if self.session.rust_2018() { + if lookup_ident.span.rust_2018() { // crate-local absolute paths start with `crate::` in edition 2018 // FIXME: may also be stabilized for Rust 2015 (Issues #45477, #44660) segms.insert( @@ -4574,7 +4600,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { let is_extern_crate_that_also_appears_in_prelude = name_binding.is_extern_crate() && - self.session.rust_2018(); + lookup_ident.span.rust_2018(); let is_visible_to_user = !in_module_is_extern || name_binding.vis == ty::Visibility::Public; @@ -4601,16 +4627,16 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { /// NOTE: The method does not look into imports, but this is not a problem, /// since we report the definitions (thus, the de-aliased imports). fn lookup_import_candidates(&mut self, - lookup_name: Name, + lookup_ident: Ident, namespace: Namespace, filter_fn: FilterFn) -> Vec where FilterFn: Fn(Def) -> bool { let mut suggestions = self.lookup_import_candidates_from_module( - lookup_name, namespace, self.graph_root, keywords::Crate.ident(), &filter_fn); + lookup_ident, namespace, self.graph_root, keywords::Crate.ident(), &filter_fn); - if self.session.rust_2018() { + if lookup_ident.span.rust_2018() { let extern_prelude_names = self.extern_prelude.clone(); for (ident, _) in extern_prelude_names.into_iter() { if let Some(crate_id) = self.crate_loader.maybe_process_path_extern(ident.name, @@ -4622,7 +4648,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { self.populate_module_if_necessary(&crate_root); suggestions.extend(self.lookup_import_candidates_from_module( - lookup_name, namespace, crate_root, ident, &filter_fn)); + lookup_ident, namespace, crate_root, ident, &filter_fn)); } } } @@ -4714,19 +4740,26 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { ast::VisibilityKind::Restricted { ref path, id, .. } => { // For visibilities we are not ready to provide correct implementation of "uniform // paths" right now, so on 2018 edition we only allow module-relative paths for now. - let first_ident = path.segments[0].ident; - if self.session.rust_2018() && !first_ident.is_path_segment_keyword() { + // On 2015 edition visibilities are resolved as crate-relative by default, + // so we are prepending a root segment if necessary. + let ident = path.segments.get(0).expect("empty path in visibility").ident; + let crate_root = if ident.is_path_segment_keyword() { + None + } else if ident.span.rust_2018() { let msg = "relative paths are not supported in visibilities on 2018 edition"; - self.session.struct_span_err(first_ident.span, msg) + self.session.struct_span_err(ident.span, msg) .span_suggestion(path.span, "try", format!("crate::{}", path)) .emit(); return ty::Visibility::Public; - } - // On 2015 visibilities are resolved as crate-relative by default, - // add starting root segment if necessary. - let segments = path.make_root().iter().chain(path.segments.iter()) - .map(|seg| Segment { ident: seg.ident, id: Some(seg.id) }) - .collect::>(); + } else { + let ctxt = ident.span.ctxt(); + Some(Segment::from_ident(Ident::new( + keywords::CrateRoot.name(), path.span.shrink_to_lo().with_ctxt(ctxt) + ))) + }; + + let segments = crate_root.into_iter() + .chain(path.segments.iter().map(|seg| seg.into())).collect::>(); let def = self.smart_resolve_path_fragment( id, None, @@ -4839,13 +4872,22 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { help_msgs.push(format!("consider adding an explicit import of \ `{ident}` to disambiguate", ident = ident)) } - if b.is_extern_crate() && self.session.rust_2018() { - help_msgs.push(format!("use `::{ident}` to refer to this {thing} unambiguously", - ident = ident, thing = b.descr())) + if b.is_extern_crate() && ident.span.rust_2018() { + help_msgs.push(format!( + "use `::{ident}` to refer to this {thing} unambiguously", + ident = ident, thing = b.descr(), + )) } - if misc == AmbiguityErrorMisc::SuggestSelf { - help_msgs.push(format!("use `self::{ident}` to refer to this {thing} unambiguously", - ident = ident, thing = b.descr())) + if misc == AmbiguityErrorMisc::SuggestCrate { + help_msgs.push(format!( + "use `crate::{ident}` to refer to this {thing} unambiguously", + ident = ident, thing = b.descr(), + )) + } else if misc == AmbiguityErrorMisc::SuggestSelf { + help_msgs.push(format!( + "use `self::{ident}` to refer to this {thing} unambiguously", + ident = ident, thing = b.descr(), + )) } if b.span.is_dummy() { @@ -5001,10 +5043,10 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { err.span_suggestion_with_applicability( binding.span, &rename_msg, - match (&directive.subclass, snippet.as_ref()) { - (ImportDirectiveSubclass::SingleImport { .. }, "self") => + match directive.subclass { + ImportDirectiveSubclass::SingleImport { type_ns_only: true, .. } => format!("self as {}", suggested_name), - (ImportDirectiveSubclass::SingleImport { source, .. }, _) => + ImportDirectiveSubclass::SingleImport { source, .. } => format!( "{} as {}{}", &snippet[..((source.span.hi().0 - binding.span.lo().0) as usize)], @@ -5015,13 +5057,13 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { "" } ), - (ImportDirectiveSubclass::ExternCrate { source, target, .. }, _) => + ImportDirectiveSubclass::ExternCrate { source, target, .. } => format!( "extern crate {} as {};", source.unwrap_or(target.name), suggested_name, ), - (_, _) => unreachable!(), + _ => unreachable!(), }, Applicability::MaybeIncorrect, ); diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index df73befa324f0..5db3efee9f6a1 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -9,11 +9,11 @@ // except according to those terms. use {AmbiguityError, AmbiguityKind, AmbiguityErrorMisc}; -use {CrateLint, Resolver, ResolutionError, Weak}; +use {CrateLint, Resolver, ResolutionError, ScopeSet, Weak}; use {Module, ModuleKind, NameBinding, NameBindingKind, PathResult, Segment, ToNameBinding}; use {is_known_tool, resolve_error}; use ModuleOrUniformRoot; -use Namespace::{self, *}; +use Namespace::*; use build_reduced_graph::{BuildReducedGraphVisitor, IsMacroExport}; use resolve_imports::ImportResolver; use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX, DefIndex, @@ -42,7 +42,7 @@ use syntax_pos::{Span, DUMMY_SP}; use errors::Applicability; use std::cell::Cell; -use std::mem; +use std::{mem, ptr}; use rustc_data_structures::sync::Lrc; #[derive(Clone, Debug)] @@ -502,7 +502,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { def } else { let binding = self.early_resolve_ident_in_lexical_scope( - path[0].ident, MacroNS, Some(kind), false, parent_scope, false, force, path_span + path[0].ident, ScopeSet::Macro(kind), parent_scope, false, force, path_span ); match binding { Ok(..) => {} @@ -526,10 +526,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> { // `foo::bar!(); or `foo!();`) and also for import paths on 2018 edition. crate fn early_resolve_ident_in_lexical_scope( &mut self, - mut ident: Ident, - ns: Namespace, - macro_kind: Option, - is_import: bool, + orig_ident: Ident, + scope_set: ScopeSet, parent_scope: &ParentScope<'a>, record_used: bool, force: bool, @@ -582,6 +580,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { enum WhereToResolve<'a> { DeriveHelpers, MacroRules(LegacyScope<'a>), + CrateRoot, Module(Module<'a>), MacroUsePrelude, BuiltinMacros, @@ -595,17 +594,17 @@ impl<'a, 'cl> Resolver<'a, 'cl> { bitflags! { struct Flags: u8 { - const MACRO_RULES = 1 << 0; - const MODULE = 1 << 1; - const PRELUDE = 1 << 2; - const MISC_SUGGEST_SELF = 1 << 3; - const MISC_FROM_PRELUDE = 1 << 4; + const MACRO_RULES = 1 << 0; + const MODULE = 1 << 1; + const PRELUDE = 1 << 2; + const MISC_SUGGEST_CRATE = 1 << 3; + const MISC_SUGGEST_SELF = 1 << 4; + const MISC_FROM_PRELUDE = 1 << 5; } } assert!(force || !record_used); // `record_used` implies `force` - assert!(macro_kind.is_none() || !is_import); // `is_import` implies no macro kind - ident = ident.modern(); + let mut ident = orig_ident.modern(); // Make sure `self`, `super` etc produce an error when passed to here. if ident.is_path_segment_keyword() { @@ -626,10 +625,17 @@ impl<'a, 'cl> Resolver<'a, 'cl> { let mut innermost_result: Option<(&NameBinding, Flags)> = None; // Go through all the scopes and try to resolve the name. - let mut where_to_resolve = if ns == MacroNS { - WhereToResolve::DeriveHelpers - } else { - WhereToResolve::Module(parent_scope.module) + let rust_2015 = orig_ident.span.rust_2015(); + let (ns, macro_kind, is_import, is_absolute_path) = match scope_set { + ScopeSet::Import(ns) => (ns, None, true, false), + ScopeSet::AbsolutePath(ns) => (ns, None, false, true), + ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind), false, false), + ScopeSet::Module => (TypeNS, None, false, false), + }; + let mut where_to_resolve = match ns { + _ if is_absolute_path || is_import && rust_2015 => WhereToResolve::CrateRoot, + TypeNS | ValueNS => WhereToResolve::Module(parent_scope.module), + MacroNS => WhereToResolve::DeriveHelpers, }; let mut use_prelude = !parent_scope.module.no_implicit_prelude; let mut determinacy = Determinacy::Determined; @@ -667,6 +673,26 @@ impl<'a, 'cl> Resolver<'a, 'cl> { Err(Determinacy::Undetermined), _ => Err(Determinacy::Determined), } + WhereToResolve::CrateRoot => { + let root_ident = Ident::new(keywords::CrateRoot.name(), orig_ident.span); + let root_module = self.resolve_crate_root(root_ident); + let binding = self.resolve_ident_in_module_ext( + ModuleOrUniformRoot::Module(root_module), + orig_ident, + ns, + None, + record_used, + path_span, + ); + match binding { + Ok(binding) => Ok((binding, Flags::MODULE | Flags::MISC_SUGGEST_CRATE)), + Err((Determinacy::Undetermined, Weak::No)) => + return Err(Determinacy::determined(force)), + Err((Determinacy::Undetermined, Weak::Yes)) => + Err(Determinacy::Undetermined), + Err((Determinacy::Determined, _)) => Err(Determinacy::Determined), + } + } WhereToResolve::Module(module) => { let orig_current_module = mem::replace(&mut self.current_module, module); let binding = self.resolve_ident_in_module_unadjusted_ext( @@ -681,7 +707,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> { self.current_module = orig_current_module; match binding { Ok(binding) => { - let misc_flags = if module.is_normal() { + let misc_flags = if ptr::eq(module, self.graph_root) { + Flags::MISC_SUGGEST_CRATE + } else if module.is_normal() { Flags::MISC_SUGGEST_SELF } else { Flags::empty() @@ -696,7 +724,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } } WhereToResolve::MacroUsePrelude => { - if use_prelude || self.session.rust_2015() { + if use_prelude || rust_2015 { match self.macro_use_prelude.get(&ident.name).cloned() { Some(binding) => Ok((binding, Flags::PRELUDE | Flags::MISC_FROM_PRELUDE)), @@ -725,7 +753,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } } WhereToResolve::LegacyPluginHelpers => { - if (use_prelude || self.session.rust_2015()) && + if (use_prelude || rust_2015) && self.session.plugin_attributes.borrow().iter() .any(|(name, _)| ident.name == &**name) { let binding = (Def::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper), @@ -737,7 +765,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } } WhereToResolve::ExternPrelude => { - if use_prelude { + if use_prelude || is_absolute_path { match self.extern_prelude_get(ident, !record_used) { Some(binding) => Ok((binding, Flags::PRELUDE)), None => Err(Determinacy::determined( @@ -803,6 +831,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> { let ambiguity_error_kind = if is_import { Some(AmbiguityKind::Import) + } else if is_absolute_path { + Some(AmbiguityKind::AbsolutePath) } else if innermost_def == builtin || def == builtin { Some(AmbiguityKind::BuiltinAttr) } else if innermost_def == derive_helper || def == derive_helper { @@ -815,7 +845,11 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } else if innermost_flags.contains(Flags::MACRO_RULES) && flags.contains(Flags::MODULE) && !self.disambiguate_legacy_vs_modern(innermost_binding, - binding) { + binding) || + flags.contains(Flags::MACRO_RULES) && + innermost_flags.contains(Flags::MODULE) && + !self.disambiguate_legacy_vs_modern(binding, + innermost_binding) { Some(AmbiguityKind::LegacyVsModern) } else if innermost_binding.is_glob_import() { Some(AmbiguityKind::GlobVsOuter) @@ -826,7 +860,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> { None }; if let Some(kind) = ambiguity_error_kind { - let misc = |f: Flags| if f.contains(Flags::MISC_SUGGEST_SELF) { + let misc = |f: Flags| if f.contains(Flags::MISC_SUGGEST_CRATE) { + AmbiguityErrorMisc::SuggestCrate + } else if f.contains(Flags::MISC_SUGGEST_SELF) { AmbiguityErrorMisc::SuggestSelf } else if f.contains(Flags::MISC_FROM_PRELUDE) { AmbiguityErrorMisc::FromPrelude @@ -835,7 +871,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { }; self.ambiguity_errors.push(AmbiguityError { kind, - ident, + ident: orig_ident, b1: innermost_binding, b2: binding, misc1: misc(innermost_flags), @@ -866,6 +902,18 @@ impl<'a, 'cl> Resolver<'a, 'cl> { LegacyScope::Empty => WhereToResolve::Module(parent_scope.module), LegacyScope::Uninitialized => unreachable!(), } + WhereToResolve::CrateRoot if is_import => match ns { + TypeNS | ValueNS => WhereToResolve::Module(parent_scope.module), + MacroNS => WhereToResolve::DeriveHelpers, + } + WhereToResolve::CrateRoot if is_absolute_path => match ns { + TypeNS => { + ident.span.adjust(Mark::root()); + WhereToResolve::ExternPrelude + } + ValueNS | MacroNS => break, + } + WhereToResolve::CrateRoot => unreachable!(), WhereToResolve::Module(module) => { match self.hygienic_lexical_parent(module, &mut ident.span) { Some(parent_module) => WhereToResolve::Module(parent_module), @@ -883,6 +931,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { WhereToResolve::BuiltinMacros => WhereToResolve::BuiltinAttrs, WhereToResolve::BuiltinAttrs => WhereToResolve::LegacyPluginHelpers, WhereToResolve::LegacyPluginHelpers => break, // nowhere else to search + WhereToResolve::ExternPrelude if is_absolute_path => break, WhereToResolve::ExternPrelude => WhereToResolve::ToolPrelude, WhereToResolve::ToolPrelude => WhereToResolve::StdLibPrelude, WhereToResolve::StdLibPrelude => match ns { @@ -898,30 +947,43 @@ impl<'a, 'cl> Resolver<'a, 'cl> { // The first found solution was the only one, return it. if let Some((binding, flags)) = innermost_result { - if is_import && !self.session.features_untracked().uniform_paths { - // We get to here only if there's no ambiguity, in ambiguous cases an error will - // be reported anyway, so there's no reason to report an additional feature error. - // The `binding` can actually be introduced by something other than `--extern`, - // but its `Def` should coincide with a crate passed with `--extern` - // (otherwise there would be ambiguity) and we can skip feature error in this case. - if ns != TypeNS || !use_prelude || - self.extern_prelude_get(ident, true).is_none() { - let msg = "imports can only refer to extern crate names \ - passed with `--extern` on stable channel"; - let mut err = feature_err(&self.session.parse_sess, "uniform_paths", - ident.span, GateIssue::Language, msg); - - let what = self.binding_description(binding, ident, - flags.contains(Flags::MISC_FROM_PRELUDE)); - let note_msg = format!("this import refers to {what}", what = what); - if binding.span.is_dummy() { - err.note(¬e_msg); - } else { - err.span_note(binding.span, ¬e_msg); - err.span_label(binding.span, "not an extern crate passed with `--extern`"); + // We get to here only if there's no ambiguity, in ambiguous cases an error will + // be reported anyway, so there's no reason to report an additional feature error. + // The `binding` can actually be introduced by something other than `--extern`, + // but its `Def` should coincide with a crate passed with `--extern` + // (otherwise there would be ambiguity) and we can skip feature error in this case. + 'ok: { + if !is_import || self.session.features_untracked().uniform_paths { + break 'ok; + } + if ns == TypeNS && use_prelude && self.extern_prelude_get(ident, true).is_some() { + break 'ok; + } + if rust_2015 { + let root_ident = Ident::new(keywords::CrateRoot.name(), orig_ident.span); + let root_module = self.resolve_crate_root(root_ident); + if self.resolve_ident_in_module_ext(ModuleOrUniformRoot::Module(root_module), + orig_ident, ns, None, false, path_span) + .is_ok() { + break 'ok; } - err.emit(); } + + let msg = "imports can only refer to extern crate names \ + passed with `--extern` on stable channel"; + let mut err = feature_err(&self.session.parse_sess, "uniform_paths", + ident.span, GateIssue::Language, msg); + + let what = self.binding_description(binding, ident, + flags.contains(Flags::MISC_FROM_PRELUDE)); + let note_msg = format!("this import refers to {what}", what = what); + if binding.span.is_dummy() { + err.note(¬e_msg); + } else { + err.span_note(binding.span, ¬e_msg); + err.span_label(binding.span, "not an extern crate passed with `--extern`"); + } + err.emit(); } return Ok(binding); @@ -998,7 +1060,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { let macro_resolutions = mem::replace(&mut *module.single_segment_macro_resolutions.borrow_mut(), Vec::new()); for (ident, kind, parent_scope, initial_binding) in macro_resolutions { - match self.early_resolve_ident_in_lexical_scope(ident, MacroNS, Some(kind), false, + match self.early_resolve_ident_in_lexical_scope(ident, ScopeSet::Macro(kind), &parent_scope, true, true, ident.span) { Ok(binding) => { let initial_def = initial_binding.map(|initial_binding| { @@ -1024,7 +1086,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { let builtin_attrs = mem::replace(&mut *module.builtin_attrs.borrow_mut(), Vec::new()); for (ident, parent_scope) in builtin_attrs { let _ = self.early_resolve_ident_in_lexical_scope( - ident, MacroNS, Some(MacroKind::Attr), false, &parent_scope, true, true, ident.span + ident, ScopeSet::Macro(MacroKind::Attr), &parent_scope, true, true, ident.span ); } } diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index b4490ea05f5a4..88551f6566a25 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -11,7 +11,7 @@ use self::ImportDirectiveSubclass::*; use {AmbiguityError, AmbiguityKind, AmbiguityErrorMisc}; -use {CrateLint, Module, ModuleOrUniformRoot, PerNS, UniformRootKind, Weak}; +use {CrateLint, Module, ModuleOrUniformRoot, PerNS, ScopeSet, Weak}; use Namespace::{self, TypeNS, MacroNS}; use {NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError}; use {Resolver, Segment}; @@ -162,46 +162,51 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { ) -> Result<&'a NameBinding<'a>, (Determinacy, Weak)> { let module = match module { ModuleOrUniformRoot::Module(module) => module, - ModuleOrUniformRoot::UniformRoot(uniform_root_kind) => { + ModuleOrUniformRoot::CrateRootAndExternPrelude => { assert!(!restricted_shadowing); - match uniform_root_kind { - UniformRootKind::ExternPrelude => { - return if let Some(binding) = - self.extern_prelude_get(ident, !record_used) { - Ok(binding) - } else if !self.graph_root.unresolved_invocations.borrow().is_empty() { - // Macro-expanded `extern crate` items can add names to extern prelude. - Err((Undetermined, Weak::No)) - } else { - Err((Determined, Weak::No)) - } - } - UniformRootKind::CurrentScope => { - let parent_scope = - parent_scope.expect("no parent scope for a single-segment import"); - - if ns == TypeNS { - if ident.name == keywords::Crate.name() || - ident.name == keywords::DollarCrate.name() { - let module = self.resolve_crate_root(ident); - let binding = (module, ty::Visibility::Public, - module.span, Mark::root()) - .to_name_binding(self.arenas); - return Ok(binding); - } else if ident.name == keywords::Super.name() || - ident.name == keywords::SelfValue.name() { - // FIXME: Implement these with renaming requirements so that e.g. - // `use super;` doesn't work, but `use super as name;` does. - // Fall through here to get an error from `early_resolve_...`. - } - } - - let binding = self.early_resolve_ident_in_lexical_scope( - ident, ns, None, true, parent_scope, record_used, record_used, path_span - ); - return binding.map_err(|determinacy| (determinacy, Weak::No)); + let parent_scope = self.dummy_parent_scope(); + let binding = self.early_resolve_ident_in_lexical_scope( + ident, ScopeSet::AbsolutePath(ns), &parent_scope, + record_used, record_used, path_span, + ); + return binding.map_err(|determinacy| (determinacy, Weak::No)); + } + ModuleOrUniformRoot::ExternPrelude => { + assert!(!restricted_shadowing); + return if let Some(binding) = self.extern_prelude_get(ident, !record_used) { + Ok(binding) + } else if !self.graph_root.unresolved_invocations.borrow().is_empty() { + // Macro-expanded `extern crate` items can add names to extern prelude. + Err((Undetermined, Weak::No)) + } else { + Err((Determined, Weak::No)) + } + } + ModuleOrUniformRoot::CurrentScope => { + assert!(!restricted_shadowing); + let parent_scope = + parent_scope.expect("no parent scope for a single-segment import"); + + if ns == TypeNS { + if ident.name == keywords::Crate.name() || + ident.name == keywords::DollarCrate.name() { + let module = self.resolve_crate_root(ident); + let binding = (module, ty::Visibility::Public, + module.span, Mark::root()) + .to_name_binding(self.arenas); + return Ok(binding); + } else if ident.name == keywords::Super.name() || + ident.name == keywords::SelfValue.name() { + // FIXME: Implement these with renaming requirements so that e.g. + // `use super;` doesn't work, but `use super as name;` does. + // Fall through here to get an error from `early_resolve_...`. } } + + let binding = self.early_resolve_ident_in_lexical_scope( + ident, ScopeSet::Import(ns), parent_scope, record_used, record_used, path_span + ); + return binding.map_err(|determinacy| (determinacy, Weak::No)); } }; @@ -334,7 +339,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { } let module = match glob_import.imported_module.get() { Some(ModuleOrUniformRoot::Module(module)) => module, - Some(ModuleOrUniformRoot::UniformRoot(_)) => continue, + Some(_) => continue, None => return Err((Undetermined, Weak::Yes)), }; let (orig_current_module, mut ident) = (self.current_module, ident.modern()); @@ -843,12 +848,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 ) { @@ -863,7 +870,8 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { } PathResult::NonModule(path_res) if path_res.base_def() == Def::Err => { // The error was already reported earlier. - assert!(directive.imported_module.get().is_none()); + assert!(!self.ambiguity_errors.is_empty() || + directive.imported_module.get().is_none()); return None; } PathResult::Indeterminate | PathResult::NonModule(..) => unreachable!(), @@ -964,9 +972,8 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { return if all_ns_failed { let resolutions = match module { - ModuleOrUniformRoot::Module(module) => - Some(module.resolutions.borrow()), - ModuleOrUniformRoot::UniformRoot(_) => None, + ModuleOrUniformRoot::Module(module) => Some(module.resolutions.borrow()), + _ => None, }; let resolutions = resolutions.as_ref().into_iter().flat_map(|r| r.iter()); let names = resolutions.filter_map(|(&(ref i, _), resolution)| { @@ -1004,7 +1011,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { format!("no `{}` in the root{}", ident, lev_suggestion) } } - ModuleOrUniformRoot::UniformRoot(_) => { + _ => { if !ident.is_path_segment_keyword() { format!("no `{}` external crate{}", ident, lev_suggestion) } else { @@ -1105,9 +1112,8 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { fn resolve_glob_import(&mut self, directive: &'b ImportDirective<'b>) { let module = match directive.imported_module.get().unwrap() { ModuleOrUniformRoot::Module(module) => module, - ModuleOrUniformRoot::UniformRoot(_) => { - self.session.span_err(directive.span, - "cannot glob-import all possible crates"); + _ => { + self.session.span_err(directive.span, "cannot glob-import all possible crates"); return; } }; @@ -1164,7 +1170,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/libstd/lib.rs b/src/libstd/lib.rs index a4db879680566..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/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#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/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", 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 /// diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index be448f960df3f..184f4bdc25606 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -43,7 +43,7 @@ use ast::{BinOpKind, UnOp}; use ast::{RangeEnd, RangeSyntax}; use {ast, attr}; use source_map::{self, SourceMap, Spanned, respan}; -use syntax_pos::{self, Span, MultiSpan, BytePos, FileName, edition::Edition}; +use syntax_pos::{self, Span, MultiSpan, BytePos, FileName}; use errors::{self, Applicability, DiagnosticBuilder, DiagnosticId}; use parse::{self, SeqSep, classify, token}; use parse::lexer::TokenAndSpan; @@ -1403,11 +1403,7 @@ impl<'a> Parser<'a> { // definition... // We don't allow argument names to be left off in edition 2018. - if p.span.edition() >= Edition::Edition2018 { - p.parse_arg_general(true) - } else { - p.parse_arg_general(false) - } + p.parse_arg_general(p.span.rust_2018()) })?; generics.where_clause = self.parse_where_clause()?; @@ -1600,9 +1596,9 @@ impl<'a> Parser<'a> { impl_dyn_multi = bounds.len() > 1 || self.prev_token_kind == PrevTokenKind::Plus; TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds) } else if self.check_keyword(keywords::Dyn) && - (self.span.edition() == Edition::Edition2018 || + (self.span.rust_2018() || self.look_ahead(1, |t| t.can_begin_bound() && - !can_continue_type_after_non_fn_ident(t))) { + !can_continue_type_after_non_fn_ident(t))) { self.bump(); // `dyn` // Always parse bounds greedily for better error recovery. let bounds = self.parse_generic_bounds()?; @@ -2043,8 +2039,9 @@ impl<'a> Parser<'a> { let lo = self.meta_var_span.unwrap_or(self.span); let mut segments = Vec::new(); + let mod_sep_ctxt = self.span.ctxt(); if self.eat(&token::ModSep) { - segments.push(PathSegment::crate_root(lo.shrink_to_lo())); + segments.push(PathSegment::crate_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt))); } self.parse_path_segments(&mut segments, style, enable_warning)?; @@ -2382,8 +2379,7 @@ impl<'a> Parser<'a> { hi = path.span; return Ok(self.mk_expr(lo.to(hi), ExprKind::Path(Some(qself), path), attrs)); } - if self.span.edition() >= Edition::Edition2018 && - self.check_keyword(keywords::Async) + if self.span.rust_2018() && self.check_keyword(keywords::Async) { if self.is_async_block() { // check for `async {` and `async move {` return self.parse_async_block(attrs); @@ -3395,7 +3391,7 @@ impl<'a> Parser<'a> { } else { Movability::Movable }; - let asyncness = if self.span.edition() >= Edition::Edition2018 { + let asyncness = if self.span.rust_2018() { self.parse_asyncness() } else { IsAsync::NotAsync @@ -4508,9 +4504,7 @@ impl<'a> Parser<'a> { fn is_try_block(&mut self) -> bool { self.token.is_keyword(keywords::Try) && self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace)) && - - self.span.edition() >= Edition::Edition2018 && - + self.span.rust_2018() && // prevent `while try {} {}`, `if try {} {} else {}`, etc. !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL) } @@ -7599,8 +7593,11 @@ impl<'a> Parser<'a> { self.check(&token::BinOp(token::Star)) || self.is_import_coupler() { // `use *;` or `use ::*;` or `use {...};` or `use ::{...};` + let mod_sep_ctxt = self.span.ctxt(); if self.eat(&token::ModSep) { - prefix.segments.push(PathSegment::crate_root(lo.shrink_to_lo())); + prefix.segments.push( + PathSegment::crate_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt)) + ); } if self.eat(&token::BinOp(token::Star)) { diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 45eaf1d3190f2..62c8f2a78e129 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -325,6 +325,16 @@ impl Span { |einfo| einfo.edition) } + #[inline] + pub fn rust_2015(&self) -> bool { + self.edition() == edition::Edition::Edition2015 + } + + #[inline] + pub fn rust_2018(&self) -> bool { + self.edition() >= edition::Edition::Edition2018 + } + /// Return the source callee. /// /// Returns `None` if the supplied span has no expansion trace, diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 361353c82e25c..e333a4f2176f5 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -12,7 +12,6 @@ //! allows bidirectional lookup; i.e. given a value, one can easily find the //! type, and vice versa. -use edition::Edition; use hygiene::SyntaxContext; use {Span, DUMMY_SP, GLOBALS}; @@ -444,7 +443,7 @@ impl Ident { pub fn is_unused_keyword(self) -> bool { // Note: `span.edition()` is relatively expensive, don't call it unless necessary. self.name >= keywords::Abstract.name() && self.name <= keywords::Yield.name() || - self.name.is_unused_keyword_2018() && self.span.edition() == Edition::Edition2018 + self.name.is_unused_keyword_2018() && self.span.rust_2018() } /// Returns `true` if the token is either a special identifier or a keyword. diff --git a/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.stderr b/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.stderr index ee98873064fc4..d288d7295120c 100644 --- a/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.stderr +++ b/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.stderr @@ -14,7 +14,7 @@ note: `helper` could also refer to the attribute macro imported here | LL | use plugin::helper; | ^^^^^^^^^^^^^^ - = help: use `self::helper` to refer to this attribute macro unambiguously + = help: use `crate::helper` to refer to this attribute macro unambiguously error: aborting due to previous error diff --git a/src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs.stderr b/src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs.stderr index 34b21ea26830c..79dc922b9db2c 100644 --- a/src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs.stderr +++ b/src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs.stderr @@ -16,7 +16,7 @@ note: `repr` could also refer to the attribute macro imported here | LL | use builtin_attrs::*; | ^^^^^^^^^^^^^^^^ - = help: use `self::repr` to refer to this attribute macro unambiguously + = help: use `crate::repr` to refer to this attribute macro unambiguously error[E0659]: `repr` is ambiguous (built-in attribute vs any other name) --> $DIR/ambiguous-builtin-attrs.rs:11:19 @@ -30,7 +30,7 @@ note: `repr` could also refer to the attribute macro imported here | LL | use builtin_attrs::*; | ^^^^^^^^^^^^^^^^ - = help: use `self::repr` to refer to this attribute macro unambiguously + = help: use `crate::repr` to refer to this attribute macro unambiguously error[E0659]: `repr` is ambiguous (built-in attribute vs any other name) --> $DIR/ambiguous-builtin-attrs.rs:20:34 @@ -44,7 +44,7 @@ note: `repr` could also refer to the attribute macro imported here | LL | use builtin_attrs::*; | ^^^^^^^^^^^^^^^^ - = help: use `self::repr` to refer to this attribute macro unambiguously + = help: use `crate::repr` to refer to this attribute macro unambiguously error[E0659]: `repr` is ambiguous (built-in attribute vs any other name) --> $DIR/ambiguous-builtin-attrs.rs:22:11 @@ -58,7 +58,7 @@ note: `repr` could also refer to the attribute macro imported here | LL | use builtin_attrs::*; | ^^^^^^^^^^^^^^^^ - = help: use `self::repr` to refer to this attribute macro unambiguously + = help: use `crate::repr` to refer to this attribute macro unambiguously error[E0659]: `feature` is ambiguous (built-in attribute vs any other name) --> $DIR/ambiguous-builtin-attrs.rs:3:4 @@ -72,7 +72,7 @@ note: `feature` could also refer to the attribute macro imported here | LL | use builtin_attrs::*; | ^^^^^^^^^^^^^^^^ - = help: use `self::feature` to refer to this attribute macro unambiguously + = help: use `crate::feature` to refer to this attribute macro unambiguously error: aborting due to 6 previous errors diff --git a/src/test/ui-fulldeps/proc-macro/auxiliary/edition-imports-2015.rs b/src/test/ui-fulldeps/proc-macro/auxiliary/edition-imports-2015.rs new file mode 100644 index 0000000000000..5bb818f7d23ba --- /dev/null +++ b/src/test/ui-fulldeps/proc-macro/auxiliary/edition-imports-2015.rs @@ -0,0 +1,19 @@ +// edition:2015 +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(Derive2015)] +pub fn derive_2015(_: TokenStream) -> TokenStream { + " + use import::Path; + + fn check_absolute() { + let x = ::absolute::Path; + } + ".parse().unwrap() +} diff --git a/src/test/ui-fulldeps/proc-macro/derive-helper-shadowing.stderr b/src/test/ui-fulldeps/proc-macro/derive-helper-shadowing.stderr index f04782fac4d2d..cc50fefc46453 100644 --- a/src/test/ui-fulldeps/proc-macro/derive-helper-shadowing.stderr +++ b/src/test/ui-fulldeps/proc-macro/derive-helper-shadowing.stderr @@ -14,7 +14,7 @@ note: `my_attr` could also refer to the attribute macro imported here | LL | use derive_helper_shadowing::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: use `self::my_attr` to refer to this attribute macro unambiguously + = help: use `crate::my_attr` to refer to this attribute macro unambiguously error: aborting due to previous error diff --git a/src/test/ui-fulldeps/proc-macro/edition-imports-2018.rs b/src/test/ui-fulldeps/proc-macro/edition-imports-2018.rs new file mode 100644 index 0000000000000..f8d6bc5e0785d --- /dev/null +++ b/src/test/ui-fulldeps/proc-macro/edition-imports-2018.rs @@ -0,0 +1,24 @@ +// compile-pass +// edition:2018 +// aux-build:edition-imports-2015.rs + +#[macro_use] +extern crate edition_imports_2015; + +mod import { + pub struct Path; +} +mod absolute { + pub struct Path; +} + +mod check { + #[derive(Derive2015)] // OK + struct S; + + fn check() { + Path; + } +} + +fn main() {} 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 + diff --git a/src/test/ui/editions/auxiliary/absolute.rs b/src/test/ui/editions/auxiliary/absolute.rs new file mode 100644 index 0000000000000..d596f97355f4c --- /dev/null +++ b/src/test/ui/editions/auxiliary/absolute.rs @@ -0,0 +1 @@ +pub struct Path; diff --git a/src/test/ui/editions/auxiliary/edition-imports-2015.rs b/src/test/ui/editions/auxiliary/edition-imports-2015.rs new file mode 100644 index 0000000000000..c72331ca2e119 --- /dev/null +++ b/src/test/ui/editions/auxiliary/edition-imports-2015.rs @@ -0,0 +1,31 @@ +// edition:2015 + +#[macro_export] +macro_rules! gen_imports { () => { + use import::Path; + use std::collections::LinkedList; + + fn check_absolute() { + ::absolute::Path; + ::std::collections::LinkedList::::new(); + } +}} + +#[macro_export] +macro_rules! gen_glob { () => { + use *; +}} + +#[macro_export] +macro_rules! gen_gated { () => { + fn check_gated() { + enum E { A } + use E::*; + } +}} + +#[macro_export] +macro_rules! gen_ambiguous { () => { + use Ambiguous; + type A = ::edition_imports_2015::Path; +}} diff --git a/src/test/ui/editions/auxiliary/edition-imports-2018.rs b/src/test/ui/editions/auxiliary/edition-imports-2018.rs new file mode 100644 index 0000000000000..b08dc499a0ddd --- /dev/null +++ b/src/test/ui/editions/auxiliary/edition-imports-2018.rs @@ -0,0 +1,17 @@ +// edition:2018 + +#[macro_export] +macro_rules! gen_imports { () => { + use import::Path; + use std::collections::LinkedList; + + fn check_absolute() { + ::absolute::Path; + ::std::collections::LinkedList::::new(); + } +}} + +#[macro_export] +macro_rules! gen_glob { () => { + use *; +}} diff --git a/src/test/ui/editions/edition-imports-2015.rs b/src/test/ui/editions/edition-imports-2015.rs new file mode 100644 index 0000000000000..b89ca28e279db --- /dev/null +++ b/src/test/ui/editions/edition-imports-2015.rs @@ -0,0 +1,28 @@ +// edition:2015 +// compile-flags:--extern absolute +// aux-build:edition-imports-2018.rs +// aux-build:absolute.rs + +#![feature(uniform_paths)] + +#[macro_use] +extern crate edition_imports_2018; + +mod check { + mod import { + pub struct Path; + } + + gen_imports!(); // OK + + fn check() { + Path; + LinkedList::::new(); + } +} + +mod check_glob { + gen_glob!(); //~ ERROR cannot glob-import all possible crates +} + +fn main() {} diff --git a/src/test/ui/editions/edition-imports-2015.stderr b/src/test/ui/editions/edition-imports-2015.stderr new file mode 100644 index 0000000000000..fb6b2e64ef5b8 --- /dev/null +++ b/src/test/ui/editions/edition-imports-2015.stderr @@ -0,0 +1,10 @@ +error: cannot glob-import all possible crates + --> $DIR/edition-imports-2015.rs:25:5 + | +LL | gen_glob!(); //~ ERROR cannot glob-import all possible crates + | ^^^^^^^^^^^^ + | + = 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: aborting due to previous error + diff --git a/src/test/ui/editions/edition-imports-2018.rs b/src/test/ui/editions/edition-imports-2018.rs new file mode 100644 index 0000000000000..dcdbf0d050be1 --- /dev/null +++ b/src/test/ui/editions/edition-imports-2018.rs @@ -0,0 +1,27 @@ +// edition:2018 +// aux-build:edition-imports-2015.rs + +#[macro_use] +extern crate edition_imports_2015; + +mod import { + pub struct Path; +} +mod absolute { + pub struct Path; +} + +mod check { + gen_imports!(); // OK + + fn check() { + Path; + LinkedList::::new(); + } +} + +mod check_glob { + gen_glob!(); //~ ERROR cannot glob-import all possible crates +} + +fn main() {} diff --git a/src/test/ui/editions/edition-imports-2018.stderr b/src/test/ui/editions/edition-imports-2018.stderr new file mode 100644 index 0000000000000..944f42ee0451b --- /dev/null +++ b/src/test/ui/editions/edition-imports-2018.stderr @@ -0,0 +1,10 @@ +error: cannot glob-import all possible crates + --> $DIR/edition-imports-2018.rs:24:5 + | +LL | gen_glob!(); //~ ERROR cannot glob-import all possible crates + | ^^^^^^^^^^^^ + | + = 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: aborting due to previous error + diff --git a/src/test/ui/editions/edition-imports-virtual-2015-ambiguity.rs b/src/test/ui/editions/edition-imports-virtual-2015-ambiguity.rs new file mode 100644 index 0000000000000..53ec3867f0110 --- /dev/null +++ b/src/test/ui/editions/edition-imports-virtual-2015-ambiguity.rs @@ -0,0 +1,20 @@ +// edition:2018 +// compile-flags:--extern edition_imports_2015 +// aux-build:edition-imports-2015.rs + +mod edition_imports_2015 { + pub struct Path; +} + +pub struct Ambiguous {} + +mod check { + pub struct Ambiguous {} + + fn check() { + edition_imports_2015::gen_ambiguous!(); //~ ERROR `Ambiguous` is ambiguous + //~| ERROR `edition_imports_2015` is ambiguous + } +} + +fn main() {} diff --git a/src/test/ui/editions/edition-imports-virtual-2015-ambiguity.stderr b/src/test/ui/editions/edition-imports-virtual-2015-ambiguity.stderr new file mode 100644 index 0000000000000..ac2bf21c5c0ba --- /dev/null +++ b/src/test/ui/editions/edition-imports-virtual-2015-ambiguity.stderr @@ -0,0 +1,40 @@ +error[E0659]: `Ambiguous` is ambiguous (name vs any other name during import resolution) + --> $DIR/edition-imports-virtual-2015-ambiguity.rs:15:9 + | +LL | edition_imports_2015::gen_ambiguous!(); //~ ERROR `Ambiguous` is ambiguous + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ambiguous name + | +note: `Ambiguous` could refer to the struct defined here + --> $DIR/edition-imports-virtual-2015-ambiguity.rs:9:1 + | +LL | pub struct Ambiguous {} + | ^^^^^^^^^^^^^^^^^^^^^^^ + = help: use `crate::Ambiguous` to refer to this struct unambiguously +note: `Ambiguous` could also refer to the struct defined here + --> $DIR/edition-imports-virtual-2015-ambiguity.rs:12:5 + | +LL | pub struct Ambiguous {} + | ^^^^^^^^^^^^^^^^^^^^^^^ + = help: use `self::Ambiguous` to refer to this struct unambiguously + = 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[E0659]: `edition_imports_2015` is ambiguous (name in the crate root vs extern crate during absolute path resolution) + --> $DIR/edition-imports-virtual-2015-ambiguity.rs:15:9 + | +LL | edition_imports_2015::gen_ambiguous!(); //~ ERROR `Ambiguous` is ambiguous + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ambiguous name + | + = note: `edition_imports_2015` could refer to an extern crate passed with `--extern` +note: `edition_imports_2015` could also refer to the module defined here + --> $DIR/edition-imports-virtual-2015-ambiguity.rs:5:1 + | +LL | / mod edition_imports_2015 { +LL | | pub struct Path; +LL | | } + | |_^ + = help: use `crate::edition_imports_2015` to refer to this module unambiguously + = 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: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0659`. diff --git a/src/test/ui/editions/edition-imports-virtual-2015-gated.rs b/src/test/ui/editions/edition-imports-virtual-2015-gated.rs new file mode 100644 index 0000000000000..a1bf4f5eb51dc --- /dev/null +++ b/src/test/ui/editions/edition-imports-virtual-2015-gated.rs @@ -0,0 +1,12 @@ +// edition:2018 +// aux-build:edition-imports-2015.rs +// error-pattern: imports can only refer to extern crate names passed with `--extern` + +#[macro_use] +extern crate edition_imports_2015; + +mod check { + gen_gated!(); +} + +fn main() {} diff --git a/src/test/ui/editions/edition-imports-virtual-2015-gated.stderr b/src/test/ui/editions/edition-imports-virtual-2015-gated.stderr new file mode 100644 index 0000000000000..7c1837e3f56e3 --- /dev/null +++ b/src/test/ui/editions/edition-imports-virtual-2015-gated.stderr @@ -0,0 +1,22 @@ +error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130) + --> <::edition_imports_2015::gen_gated macros>:1:50 + | +LL | ( ) => { fn check_gated ( ) { enum E { A } use E :: * ; } } + | ^ + | + ::: $DIR/edition-imports-virtual-2015-gated.rs:9:5 + | +LL | gen_gated!(); + | ------------- not an extern crate passed with `--extern` + | + = help: add #![feature(uniform_paths)] to the crate attributes to enable +note: this import refers to the enum defined here + --> $DIR/edition-imports-virtual-2015-gated.rs:9:5 + | +LL | gen_gated!(); + | ^^^^^^^^^^^^^ + = 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: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. 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/auxiliary/issue-56125.rs b/src/test/ui/imports/auxiliary/issue-56125.rs new file mode 100644 index 0000000000000..8e0797582970d --- /dev/null +++ b/src/test/ui/imports/auxiliary/issue-56125.rs @@ -0,0 +1,11 @@ +pub mod issue_56125 {} + +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-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() {} diff --git a/src/test/ui/imports/issue-56125.rs b/src/test/ui/imports/issue-56125.rs new file mode 100644 index 0000000000000..843b52f18435e --- /dev/null +++ b/src/test/ui/imports/issue-56125.rs @@ -0,0 +1,25 @@ +// edition:2018 +// compile-flags:--extern issue_56125 +// aux-build:issue-56125.rs + +#![feature(uniform_paths)] + +mod m1 { + use issue_56125::last_segment::*; + //~^ ERROR `issue_56125` is ambiguous + //~| ERROR unresolved import `issue_56125::last_segment` +} + +mod m2 { + 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` +} + +mod m3 { + mod empty {} + use empty::issue_56125; //~ ERROR unresolved import `empty::issue_56125` + use issue_56125::*; //~ ERROR `issue_56125` is ambiguous +} + +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..b1292ef8f783e --- /dev/null +++ b/src/test/ui/imports/issue-56125.stderr @@ -0,0 +1,67 @@ +error[E0433]: failed to resolve: could not find `non_last_segment` in `issue_56125` + --> $DIR/issue-56125.rs:14:22 + | +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:8:22 + | +LL | use issue_56125::last_segment::*; + | ^^^^^^^^^^^^ could not find `last_segment` in `issue_56125` + +error[E0432]: unresolved import `empty::issue_56125` + --> $DIR/issue-56125.rs:21:9 + | +LL | use empty::issue_56125; //~ ERROR unresolved import `empty::issue_56125` + | ^^^^^^^^^^^^^^^^^^ no `issue_56125` in `m3::empty` + +error[E0659]: `issue_56125` is ambiguous (name vs any other name during import resolution) + --> $DIR/issue-56125.rs:8:9 + | +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:8:9 + | +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:14:9 + | +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:14:9 + | +LL | use issue_56125::non_last_segment::non_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:22:9 + | +LL | use issue_56125::*; //~ ERROR `issue_56125` is ambiguous + | ^^^^^^^^^^^ 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 unresolved item imported here + --> $DIR/issue-56125.rs:21:9 + | +LL | use empty::issue_56125; //~ ERROR unresolved import `empty::issue_56125` + | ^^^^^^^^^^^^^^^^^^ + = help: use `self::issue_56125` to refer to this unresolved item unambiguously + +error: aborting due to 6 previous errors + +Some errors occurred: E0432, E0433, E0659. +For more information about an error, try `rustc --explain E0432`. diff --git a/src/test/ui/imports/local-modularized-tricky-fail-1.rs b/src/test/ui/imports/local-modularized-tricky-fail-1.rs index fb05b95a96dc6..37633c7a4415f 100644 --- a/src/test/ui/imports/local-modularized-tricky-fail-1.rs +++ b/src/test/ui/imports/local-modularized-tricky-fail-1.rs @@ -43,6 +43,7 @@ mod inner2 { fn main() { panic!(); //~ ERROR `panic` is ambiguous + //~| ERROR `panic` is ambiguous } mod inner3 { diff --git a/src/test/ui/imports/local-modularized-tricky-fail-1.stderr b/src/test/ui/imports/local-modularized-tricky-fail-1.stderr index 962294e48caef..1978648e206f1 100644 --- a/src/test/ui/imports/local-modularized-tricky-fail-1.stderr +++ b/src/test/ui/imports/local-modularized-tricky-fail-1.stderr @@ -22,7 +22,7 @@ LL | use inner1::*; = help: consider adding an explicit import of `exported` to disambiguate error[E0659]: `include` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) - --> $DIR/local-modularized-tricky-fail-1.rs:56:1 + --> $DIR/local-modularized-tricky-fail-1.rs:57:1 | LL | include!(); //~ ERROR `include` is ambiguous | ^^^^^^^ ambiguous name @@ -38,7 +38,7 @@ LL | | } ... LL | define_include!(); | ------------------ in this macro invocation - = help: use `self::include` to refer to this macro unambiguously + = help: use `crate::include` to refer to this macro unambiguously error[E0659]: `panic` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) --> $DIR/local-modularized-tricky-fail-1.rs:45:5 @@ -57,13 +57,13 @@ LL | | } ... LL | define_panic!(); | ---------------- in this macro invocation - = help: use `self::panic` to refer to this macro unambiguously + = help: use `crate::panic` to refer to this macro unambiguously error[E0659]: `panic` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) - --> <::std::macros::panic macros>:1:13 + --> $DIR/local-modularized-tricky-fail-1.rs:45:5 | -LL | ( ) => ( { panic ! ( "explicit panic" ) } ) ; ( $ msg : expr ) => ( - | ^^^^^ ambiguous name +LL | panic!(); //~ ERROR `panic` is ambiguous + | ^^^^^^^^^ ambiguous name | = note: `panic` could refer to a macro from prelude note: `panic` could also refer to the macro defined here @@ -76,7 +76,8 @@ LL | | } ... LL | define_panic!(); | ---------------- in this macro invocation - = help: use `self::panic` to refer to this macro unambiguously + = help: use `crate::panic` to refer to this macro unambiguously + = 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: aborting due to 4 previous errors diff --git a/src/test/ui/imports/macro-paths.stderr b/src/test/ui/imports/macro-paths.stderr index 8e8742f849bf0..3f481b0cfb0df 100644 --- a/src/test/ui/imports/macro-paths.stderr +++ b/src/test/ui/imports/macro-paths.stderr @@ -34,7 +34,7 @@ LL | / pub mod baz { LL | | pub use two_macros::m; LL | | } | |_^ - = help: use `self::baz` to refer to this module unambiguously + = help: use `crate::baz` to refer to this module unambiguously error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-45829/import-self.rs b/src/test/ui/issues/issue-45829/import-self.rs index 8b13ffd0076d5..eb5fb458d8279 100644 --- a/src/test/ui/issues/issue-45829/import-self.rs +++ b/src/test/ui/issues/issue-45829/import-self.rs @@ -19,4 +19,7 @@ use foo as self; use foo::self; +use foo::A; +use foo::{self as A}; + fn main() {} diff --git a/src/test/ui/issues/issue-45829/import-self.stderr b/src/test/ui/issues/issue-45829/import-self.stderr index 985dc4e7131cf..55e51952a8804 100644 --- a/src/test/ui/issues/issue-45829/import-self.stderr +++ b/src/test/ui/issues/issue-45829/import-self.stderr @@ -25,7 +25,21 @@ help: you can use `as` to change the binding name of the import LL | use foo::{self as other_foo}; | ^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error[E0252]: the name `A` is defined multiple times + --> $DIR/import-self.rs:23:11 + | +LL | use foo::A; + | ------ previous import of the type `A` here +LL | use foo::{self as A}; + | ^^^^^^^^^ `A` reimported here + | + = note: `A` must be defined only once in the type namespace of this module +help: you can use `as` to change the binding name of the import + | +LL | use foo::{self as OtherA}; + | ^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors -Some errors occurred: E0255, E0429. -For more information about an error, try `rustc --explain E0255`. +Some errors occurred: E0252, E0255, E0429. +For more information about an error, try `rustc --explain E0252`. diff --git a/src/test/ui/issues/issue-56128.rs b/src/test/ui/issues/issue-56128.rs new file mode 100644 index 0000000000000..3a3eccdc33ce8 --- /dev/null +++ b/src/test/ui/issues/issue-56128.rs @@ -0,0 +1,15 @@ +// 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}; + + mod baz { + pub fn x() { } + pub fn y() { } + } +} + +fn main() { } diff --git a/src/test/ui/macros/restricted-shadowing-legacy.stderr b/src/test/ui/macros/restricted-shadowing-legacy.stderr index 2135d63c80ec2..9d61799713b04 100644 --- a/src/test/ui/macros/restricted-shadowing-legacy.stderr +++ b/src/test/ui/macros/restricted-shadowing-legacy.stderr @@ -3,6 +3,9 @@ error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name | LL | m!(); //~ ERROR `m` is ambiguous | ^ ambiguous name +... +LL | include!(); + | ----------- in this macro invocation | note: `m` could refer to the macro defined here --> $DIR/restricted-shadowing-legacy.rs:88:9 @@ -26,6 +29,9 @@ error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name | LL | macro_rules! gen_invoc { () => { m!() } } //~ ERROR `m` is ambiguous | ^ ambiguous name +... +LL | include!(); + | ----------- in this macro invocation | note: `m` could refer to the macro defined here --> $DIR/restricted-shadowing-legacy.rs:88:9 @@ -49,6 +55,9 @@ error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name | LL | m!(); //~ ERROR `m` is ambiguous | ^ ambiguous name +... +LL | include!(); + | ----------- in this macro invocation | note: `m` could refer to the macro defined here --> $DIR/restricted-shadowing-legacy.rs:88:9 @@ -72,6 +81,9 @@ error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name | LL | m!(); //~ ERROR `m` is ambiguous | ^ ambiguous name +... +LL | include!(); + | ----------- in this macro invocation | note: `m` could refer to the macro defined here --> $DIR/restricted-shadowing-legacy.rs:88:9 @@ -95,6 +107,9 @@ error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name | LL | m!(); //~ ERROR `m` is ambiguous | ^ ambiguous name +... +LL | include!(); + | ----------- in this macro invocation | note: `m` could refer to the macro defined here --> $DIR/restricted-shadowing-legacy.rs:88:9 @@ -118,6 +133,9 @@ error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name | LL | macro_rules! gen_invoc { () => { m!() } } //~ ERROR `m` is ambiguous | ^ ambiguous name +... +LL | include!(); + | ----------- in this macro invocation | note: `m` could refer to the macro defined here --> $DIR/restricted-shadowing-legacy.rs:88:9 @@ -141,6 +159,9 @@ error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name | LL | m!(); //~ ERROR `m` is ambiguous | ^ ambiguous name +... +LL | include!(); + | ----------- in this macro invocation | note: `m` could refer to the macro defined here --> $DIR/restricted-shadowing-legacy.rs:88:9 @@ -164,6 +185,9 @@ error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name | LL | macro_rules! gen_invoc { () => { m!() } } //~ ERROR `m` is ambiguous | ^ ambiguous name +... +LL | include!(); + | ----------- in this macro invocation | note: `m` could refer to the macro defined here --> $DIR/restricted-shadowing-legacy.rs:88:9 diff --git a/src/test/ui/macros/restricted-shadowing-modern.stderr b/src/test/ui/macros/restricted-shadowing-modern.stderr index 2449e8512d3cd..398a7660d3093 100644 --- a/src/test/ui/macros/restricted-shadowing-modern.stderr +++ b/src/test/ui/macros/restricted-shadowing-modern.stderr @@ -3,6 +3,9 @@ error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name | LL | m!(); //~ ERROR `m` is ambiguous | ^ ambiguous name +... +LL | include!(); + | ----------- in this macro invocation | note: `m` could refer to the macro defined here --> $DIR/restricted-shadowing-modern.rs:91:9 @@ -26,6 +29,9 @@ error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name | LL | macro gen_invoc() { m!() } //~ ERROR `m` is ambiguous | ^ ambiguous name +... +LL | include!(); + | ----------- in this macro invocation | note: `m` could refer to the macro defined here --> $DIR/restricted-shadowing-modern.rs:91:9 @@ -49,6 +55,9 @@ error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name | LL | m!(); //~ ERROR `m` is ambiguous | ^ ambiguous name +... +LL | include!(); + | ----------- in this macro invocation | note: `m` could refer to the macro defined here --> $DIR/restricted-shadowing-modern.rs:91:9 @@ -72,6 +81,9 @@ error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name | LL | m!(); //~ ERROR `m` is ambiguous | ^ ambiguous name +... +LL | include!(); + | ----------- in this macro invocation | note: `m` could refer to the macro defined here --> $DIR/restricted-shadowing-modern.rs:91:9 @@ -95,6 +107,9 @@ error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name | LL | m!(); //~ ERROR `m` is ambiguous | ^ ambiguous name +... +LL | include!(); + | ----------- in this macro invocation | note: `m` could refer to the macro defined here --> $DIR/restricted-shadowing-modern.rs:91:9 @@ -118,6 +133,9 @@ error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name | LL | macro gen_invoc() { m!() } //~ ERROR `m` is ambiguous | ^ ambiguous name +... +LL | include!(); + | ----------- in this macro invocation | note: `m` could refer to the macro defined here --> $DIR/restricted-shadowing-modern.rs:91:9 diff --git a/src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity-macros-nested.rs b/src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity-macros-nested.rs deleted file mode 100644 index 4819711115c27..0000000000000 --- a/src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity-macros-nested.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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 - -// This test is similar to `ambiguity-macros.rs`, but nested in a module. - -mod foo { - pub use std::io; - //~^ ERROR `std` is ambiguous - - macro_rules! m { - () => { - mod std { - pub struct io; - } - } - } - m!(); -} - -fn main() {} diff --git a/src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity-macros-nested.stderr b/src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity-macros-nested.stderr deleted file mode 100644 index 204e0a7e1411e..0000000000000 --- a/src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity-macros-nested.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0659]: `std` is ambiguous (name vs any other name during import resolution) - --> $DIR/ambiguity-macros-nested.rs:16:13 - | -LL | pub use std::io; - | ^^^ ambiguous name - | - = note: `std` could refer to a built-in extern crate - = help: use `::std` to refer to this extern crate unambiguously -note: `std` could also refer to the module defined here - --> $DIR/ambiguity-macros-nested.rs:21:13 - | -LL | / mod std { -LL | | pub struct io; -LL | | } - | |_____________^ -... -LL | m!(); - | ----- in this macro invocation - = help: use `self::std` to refer to this module unambiguously - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0659`. diff --git a/src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity-macros.rs b/src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity-macros.rs deleted file mode 100644 index 148320de556d3..0000000000000 --- a/src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity-macros.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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 - -// This test is similar to `ambiguity.rs`, but with macros defining local items. - -use std::io; -//~^ ERROR `std` is ambiguous - -macro_rules! m { - () => { - mod std { - pub struct io; - } - } -} -m!(); - -fn main() {} diff --git a/src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity-macros.stderr b/src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity-macros.stderr deleted file mode 100644 index ac8d3b9d0cbe4..0000000000000 --- a/src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity-macros.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0659]: `std` is ambiguous (name vs any other name during import resolution) - --> $DIR/ambiguity-macros.rs:15:5 - | -LL | use std::io; - | ^^^ ambiguous name - | - = note: `std` could refer to a built-in extern crate - = help: use `::std` to refer to this extern crate unambiguously -note: `std` could also refer to the module defined here - --> $DIR/ambiguity-macros.rs:20:9 - | -LL | / mod std { -LL | | pub struct io; -LL | | } - | |_________^ -... -LL | m!(); - | ----- in this macro invocation - = help: use `self::std` to refer to this module unambiguously - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0659`. diff --git a/src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity-nested.rs b/src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity-nested.rs deleted file mode 100644 index 2791d4580daf1..0000000000000 --- a/src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity-nested.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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 - -// This test is similar to `ambiguity.rs`, but nested in a module. - -mod foo { - pub use std::io; - //~^ ERROR `std` is ambiguous - - mod std { - pub struct io; - } -} - -fn main() {} diff --git a/src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity-nested.stderr b/src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity-nested.stderr deleted file mode 100644 index 7bcfc563d39fc..0000000000000 --- a/src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity-nested.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0659]: `std` is ambiguous (name vs any other name during import resolution) - --> $DIR/ambiguity-nested.rs:16:13 - | -LL | pub use std::io; - | ^^^ ambiguous name - | - = note: `std` could refer to a built-in extern crate - = help: use `::std` to refer to this extern crate unambiguously -note: `std` could also refer to the module defined here - --> $DIR/ambiguity-nested.rs:19:5 - | -LL | / mod std { -LL | | pub struct io; -LL | | } - | |_____^ - = help: use `self::std` to refer to this module unambiguously - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0659`. diff --git a/src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity.rs b/src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity.rs deleted file mode 100644 index 2bfbb6b287153..0000000000000 --- a/src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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 - -use std::io; -//~^ ERROR `std` is ambiguous - -mod std { - pub struct io; -} - -fn main() {} diff --git a/src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity.stderr b/src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity.stderr deleted file mode 100644 index beeb74654e5b5..0000000000000 --- a/src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0659]: `std` is ambiguous (name vs any other name during import resolution) - --> $DIR/ambiguity.rs:13:5 - | -LL | use std::io; - | ^^^ ambiguous name - | - = note: `std` could refer to a built-in extern crate - = help: use `::std` to refer to this extern crate unambiguously -note: `std` could also refer to the module defined here - --> $DIR/ambiguity.rs:16:1 - | -LL | / mod std { -LL | | pub struct io; -LL | | } - | |_^ - = help: use `self::std` to refer to this module unambiguously - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0659`. diff --git a/src/test/ui/rust-2018/uniform-paths-forward-compat/block-scoped-shadow.rs b/src/test/ui/rust-2018/uniform-paths-forward-compat/block-scoped-shadow.rs deleted file mode 100644 index 2853b4b3a5b3f..0000000000000 --- a/src/test/ui/rust-2018/uniform-paths-forward-compat/block-scoped-shadow.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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 - -struct std; - -fn main() { - fn std() {} - enum std {} - use std as foo; - //~^ ERROR `std` is ambiguous - //~| ERROR `std` is ambiguous -} diff --git a/src/test/ui/rust-2018/uniform-paths-forward-compat/block-scoped-shadow.stderr b/src/test/ui/rust-2018/uniform-paths-forward-compat/block-scoped-shadow.stderr deleted file mode 100644 index 5d539e2d59f15..0000000000000 --- a/src/test/ui/rust-2018/uniform-paths-forward-compat/block-scoped-shadow.stderr +++ /dev/null @@ -1,39 +0,0 @@ -error[E0659]: `std` is ambiguous (name vs any other name during import resolution) - --> $DIR/block-scoped-shadow.rs:18:9 - | -LL | use std as foo; - | ^^^ ambiguous name - | -note: `std` could refer to the enum defined here - --> $DIR/block-scoped-shadow.rs:17:5 - | -LL | enum std {} - | ^^^^^^^^^^^ -note: `std` could also refer to the struct defined here - --> $DIR/block-scoped-shadow.rs:13:1 - | -LL | struct std; - | ^^^^^^^^^^^ - = help: use `self::std` to refer to this struct unambiguously - -error[E0659]: `std` is ambiguous (name vs any other name during import resolution) - --> $DIR/block-scoped-shadow.rs:18:9 - | -LL | use std as foo; - | ^^^ ambiguous name - | -note: `std` could refer to the function defined here - --> $DIR/block-scoped-shadow.rs:16:5 - | -LL | fn std() {} - | ^^^^^^^^^^^ -note: `std` could also refer to the unit struct defined here - --> $DIR/block-scoped-shadow.rs:13:1 - | -LL | struct std; - | ^^^^^^^^^^^ - = help: use `self::std` to refer to this unit struct unambiguously - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0659`. diff --git a/src/test/ui/rust-2018/uniform-paths-forward-compat/issue-54253.rs b/src/test/ui/rust-2018/uniform-paths-forward-compat/issue-54253.rs deleted file mode 100644 index ef2a1e3c70c6f..0000000000000 --- a/src/test/ui/rust-2018/uniform-paths-forward-compat/issue-54253.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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 - -// Dummy import that previously introduced uniform path canaries. -use std; - -// fn version() -> &'static str {""} - -mod foo { - // Error wasn't reported, despite `version` being commented out above. - use crate::version; //~ ERROR unresolved import `crate::version` - - fn bar() { - version(); - } -} - -fn main() {} diff --git a/src/test/ui/rust-2018/uniform-paths-forward-compat/issue-54253.stderr b/src/test/ui/rust-2018/uniform-paths-forward-compat/issue-54253.stderr deleted file mode 100644 index 6dcc451c60a61..0000000000000 --- a/src/test/ui/rust-2018/uniform-paths-forward-compat/issue-54253.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0432]: unresolved import `crate::version` - --> $DIR/issue-54253.rs:20:9 - | -LL | use crate::version; //~ ERROR unresolved import `crate::version` - | ^^^^^^^^^^^^^^ no `version` in the root - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0432`. diff --git a/src/test/ui/rust-2018/uniform-paths-forward-compat/redundant.rs b/src/test/ui/rust-2018/uniform-paths-forward-compat/redundant.rs deleted file mode 100644 index 05048cfd45105..0000000000000 --- a/src/test/ui/rust-2018/uniform-paths-forward-compat/redundant.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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. - -// run-pass -// edition:2018 - -use std; -use std::io; - -mod foo { - pub use std as my_std; -} - -mod bar { - pub use std::{self}; -} - -fn main() { - io::stdout(); - self::std::io::stdout(); - foo::my_std::io::stdout(); - bar::std::io::stdout(); -} diff --git a/src/test/ui/rust-2018/uniform-paths/ambiguity-macros.stderr b/src/test/ui/rust-2018/uniform-paths/ambiguity-macros.stderr index ac8d3b9d0cbe4..a9e6da8f211b3 100644 --- a/src/test/ui/rust-2018/uniform-paths/ambiguity-macros.stderr +++ b/src/test/ui/rust-2018/uniform-paths/ambiguity-macros.stderr @@ -16,7 +16,7 @@ LL | | } ... LL | m!(); | ----- in this macro invocation - = help: use `self::std` to refer to this module unambiguously + = help: use `crate::std` to refer to this module unambiguously error: aborting due to previous error diff --git a/src/test/ui/rust-2018/uniform-paths/ambiguity.stderr b/src/test/ui/rust-2018/uniform-paths/ambiguity.stderr index beeb74654e5b5..b1feb82fba90d 100644 --- a/src/test/ui/rust-2018/uniform-paths/ambiguity.stderr +++ b/src/test/ui/rust-2018/uniform-paths/ambiguity.stderr @@ -13,7 +13,7 @@ LL | / mod std { LL | | pub struct io; LL | | } | |_^ - = help: use `self::std` to refer to this module unambiguously + = help: use `crate::std` to refer to this module unambiguously error: aborting due to previous error diff --git a/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.stderr b/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.stderr index aa46947f93f4b..0088296b1a471 100644 --- a/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.stderr +++ b/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.stderr @@ -16,7 +16,7 @@ LL | / mod sub { LL | | pub fn bar() {} LL | | } | |_^ - = help: use `self::sub` to refer to this module unambiguously + = help: use `crate::sub` to refer to this module unambiguously error: aborting due to previous error diff --git a/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow.stderr b/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow.stderr index 010b9efad393b..213f723385b1c 100644 --- a/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow.stderr +++ b/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow.stderr @@ -14,7 +14,7 @@ note: `Foo` could also refer to the enum defined here | LL | enum Foo {} | ^^^^^^^^^^^ - = help: use `self::Foo` to refer to this enum unambiguously + = help: use `crate::Foo` to refer to this enum unambiguously error[E0659]: `std` is ambiguous (name vs any other name during import resolution) --> $DIR/block-scoped-shadow.rs:26:9 @@ -32,7 +32,7 @@ note: `std` could also refer to the struct defined here | LL | struct std; | ^^^^^^^^^^^ - = help: use `self::std` to refer to this struct unambiguously + = help: use `crate::std` to refer to this struct unambiguously error[E0659]: `std` is ambiguous (name vs any other name during import resolution) --> $DIR/block-scoped-shadow.rs:26:9 @@ -50,7 +50,7 @@ note: `std` could also refer to the unit struct defined here | LL | struct std; | ^^^^^^^^^^^ - = help: use `self::std` to refer to this unit struct unambiguously + = help: use `crate::std` to refer to this unit struct unambiguously error: aborting due to 3 previous errors 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