about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-11-19 02:59:29 +0000
committerbors <bors@rust-lang.org>2018-11-19 02:59:29 +0000
commit7e82eda000c8d4abbdaa76b3563cd77f938fc411 (patch)
treeb245a1f7b79958535f7d14d14039710e1d3b6991 /src
parenta9b791b3c0543120ed03e70600e6cf4f451b4124 (diff)
parent38025e0dca8c2f049884eedc58792c4e321ed27c (diff)
downloadrust-7e82eda000c8d4abbdaa76b3563cd77f938fc411.tar.gz
rust-7e82eda000c8d4abbdaa76b3563cd77f938fc411.zip
Auto merge of #56042 - petrochenkov:nuni, r=petrochenkov
[nightly] resolve: Implement uniform paths 2.0

Forward-port of https://github.com/rust-lang/rust/pull/55884 to nightly.

r? @ghost
Diffstat (limited to 'src')
-rw-r--r--src/doc/unstable-book/src/language-features/extern-in-paths.md4
-rw-r--r--src/librustc/hir/def.rs31
-rw-r--r--src/librustc/hir/def_id.rs4
-rw-r--r--src/librustc/middle/dead.rs2
-rw-r--r--src/librustc/middle/stability.rs6
-rw-r--r--src/librustc_mir/hair/pattern/check_match.rs3
-rw-r--r--src/librustc_privacy/lib.rs8
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs190
-rw-r--r--src/librustc_resolve/diagnostics.rs2
-rw-r--r--src/librustc_resolve/error_reporting.rs86
-rw-r--r--src/librustc_resolve/lib.rs408
-rw-r--r--src/librustc_resolve/macros.rs493
-rw-r--r--src/librustc_resolve/resolve_imports.rs644
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs2
-rw-r--r--src/libsyntax/ext/base.rs7
-rw-r--r--src/test/ui-fulldeps/custom-derive/derive-in-mod.rs13
-rw-r--r--src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.stderr7
-rw-r--r--src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs.stderr72
-rw-r--r--src/test/ui-fulldeps/proc-macro/derive-helper-shadowing.stderr7
-rw-r--r--src/test/ui/absolute-paths-in-nested-use-groups.stderr6
-rw-r--r--src/test/ui/bad/bad-module.rs4
-rw-r--r--src/test/ui/bad/bad-module.stderr8
-rw-r--r--src/test/ui/custom-attribute-multisegment.rs2
-rw-r--r--src/test/ui/custom-attribute-multisegment.stderr6
-rw-r--r--src/test/ui/derived-errors/issue-31997-1.stderr4
-rw-r--r--src/test/ui/dollar-crate/dollar-crate-is-keyword-2.stderr4
-rw-r--r--src/test/ui/dyn-trait-compatibility.rs4
-rw-r--r--src/test/ui/dyn-trait-compatibility.stderr8
-rw-r--r--src/test/ui/empty/empty-struct-tuple-pat.stderr4
-rw-r--r--src/test/ui/enum/enum-in-scope.stderr2
-rw-r--r--src/test/ui/error-codes/E0432.stderr2
-rw-r--r--src/test/ui/error-codes/E0433.stderr4
-rw-r--r--src/test/ui/error-codes/E0530.stderr2
-rw-r--r--src/test/ui/error-codes/E0659.stderr9
-rw-r--r--src/test/ui/export-fully-qualified.rs2
-rw-r--r--src/test/ui/export-fully-qualified.stderr6
-rw-r--r--src/test/ui/export2.rs2
-rw-r--r--src/test/ui/export2.stderr6
-rw-r--r--src/test/ui/extern/extern-macro.rs2
-rw-r--r--src/test/ui/extern/extern-macro.stderr7
-rw-r--r--src/test/ui/feature-gates/feature-gate-extern_absolute_paths.stderr6
-rw-r--r--src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.rs4
-rw-r--r--src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-uniform-paths.rs11
-rw-r--r--src/test/ui/feature-gates/feature-gate-uniform-paths.stderr65
-rw-r--r--src/test/ui/hygiene/no_implicit_prelude.stderr4
-rw-r--r--src/test/ui/import2.rs2
-rw-r--r--src/test/ui/import2.stderr2
-rw-r--r--src/test/ui/import3.stderr2
-rw-r--r--src/test/ui/imports/auxiliary/glob-conflict.rs9
-rw-r--r--src/test/ui/imports/duplicate.stderr36
-rw-r--r--src/test/ui/imports/extern-prelude-extern-crate-fail.rs2
-rw-r--r--src/test/ui/imports/extern-prelude-extern-crate-fail.stderr6
-rw-r--r--src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr7
-rw-r--r--src/test/ui/imports/glob-conflict-cross-crate.rs7
-rw-r--r--src/test/ui/imports/glob-conflict-cross-crate.stderr9
-rw-r--r--src/test/ui/imports/glob-shadowing.stderr26
-rw-r--r--src/test/ui/imports/issue-53269.stderr9
-rw-r--r--src/test/ui/imports/issue-55457.stderr2
-rw-r--r--src/test/ui/imports/issue-55884-1.rs21
-rw-r--r--src/test/ui/imports/issue-55884-1.stderr22
-rw-r--r--src/test/ui/imports/issue-55884-2.rs14
-rw-r--r--src/test/ui/imports/issue-55884-2.stderr9
-rw-r--r--src/test/ui/imports/local-modularized-tricky-fail-1.stderr32
-rw-r--r--src/test/ui/imports/macro-paths.stderr16
-rw-r--r--src/test/ui/imports/macros.stderr16
-rw-r--r--src/test/ui/imports/rfc-1560-warning-cycle.stderr9
-rw-r--r--src/test/ui/imports/shadow_builtin_macros.stderr33
-rw-r--r--src/test/ui/issues/issue-16149.stderr2
-rw-r--r--src/test/ui/issues/issue-1697.rs2
-rw-r--r--src/test/ui/issues/issue-1697.stderr2
-rw-r--r--src/test/ui/issues/issue-17718-patterns.stderr4
-rw-r--r--src/test/ui/issues/issue-23716.stderr4
-rw-r--r--src/test/ui/issues/issue-27033.stderr2
-rw-r--r--src/test/ui/issues/issue-30560.rs4
-rw-r--r--src/test/ui/issues/issue-30560.stderr4
-rw-r--r--src/test/ui/issues/issue-33293.rs2
-rw-r--r--src/test/ui/issues/issue-33293.stderr4
-rw-r--r--src/test/ui/issues/issue-33464.stderr6
-rw-r--r--src/test/ui/issues/issue-34047.stderr2
-rw-r--r--src/test/ui/issues/issue-36881.stderr2
-rw-r--r--src/test/ui/issues/issue-37887.stderr2
-rw-r--r--src/test/ui/issues/issue-38857.rs2
-rw-r--r--src/test/ui/issues/issue-38857.stderr4
-rw-r--r--src/test/ui/keyword/keyword-super-as-identifier.rs2
-rw-r--r--src/test/ui/keyword/keyword-super-as-identifier.stderr6
-rw-r--r--src/test/ui/keyword/keyword-super.rs2
-rw-r--r--src/test/ui/keyword/keyword-super.stderr6
-rw-r--r--src/test/ui/macros/ambiguity-legacy-vs-modern.stderr12
-rw-r--r--src/test/ui/macros/macro-inner-attributes.rs2
-rw-r--r--src/test/ui/macros/macro-inner-attributes.stderr4
-rw-r--r--src/test/ui/macros/macro-path-prelude-fail-1.rs4
-rw-r--r--src/test/ui/macros/macro-path-prelude-fail-1.stderr12
-rw-r--r--src/test/ui/macros/macro-path-prelude-fail-2.rs2
-rw-r--r--src/test/ui/macros/macro-path-prelude-fail-2.stderr7
-rw-r--r--src/test/ui/macros/macro-path-prelude-shadowing.stderr9
-rw-r--r--src/test/ui/macros/macro-shadowing.stderr7
-rw-r--r--src/test/ui/macros/macro_path_as_generic_bound.stderr4
-rw-r--r--src/test/ui/macros/restricted-shadowing-legacy.stderr56
-rw-r--r--src/test/ui/macros/restricted-shadowing-modern.stderr42
-rw-r--r--src/test/ui/out-of-order-shadowing.stderr7
-rw-r--r--src/test/ui/pattern/pat-shadow-in-nested-binding.stderr2
-rw-r--r--src/test/ui/pattern/pattern-binding-disambiguation.stderr16
-rw-r--r--src/test/ui/pattern/pattern-error-continue.rs2
-rw-r--r--src/test/ui/pattern/pattern-error-continue.stderr6
-rw-r--r--src/test/ui/privacy/decl-macro.rs9
-rw-r--r--src/test/ui/privacy/decl-macro.stderr9
-rw-r--r--src/test/ui/privacy/restricted/test.rs2
-rw-r--r--src/test/ui/privacy/restricted/test.stderr6
-rw-r--r--src/test/ui/resolve/resolve-variant-assoc-item.rs4
-rw-r--r--src/test/ui/resolve/resolve-variant-assoc-item.stderr12
-rw-r--r--src/test/ui/resolve_self_super_hint.rs8
-rw-r--r--src/test/ui/resolve_self_super_hint.stderr8
-rw-r--r--src/test/ui/rfc-2126-crate-paths/crate-path-non-absolute.stderr4
-rw-r--r--src/test/ui/rfc-2126-extern-absolute-paths/non-existent-1.stderr2
-rw-r--r--src/test/ui/rfc-2126-extern-absolute-paths/non-existent-2.rs2
-rw-r--r--src/test/ui/rfc-2126-extern-absolute-paths/non-existent-2.stderr4
-rw-r--r--src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.rs6
-rw-r--r--src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.stderr22
-rw-r--r--src/test/ui/rfc-2126-extern-in-paths/non-existent-1.stderr2
-rw-r--r--src/test/ui/rfc-2126-extern-in-paths/non-existent-2.rs2
-rw-r--r--src/test/ui/rfc-2126-extern-in-paths/non-existent-2.stderr4
-rw-r--r--src/test/ui/rust-2018/future-proofing-locals.rs49
-rw-r--r--src/test/ui/rust-2018/future-proofing-locals.stderr50
-rw-r--r--src/test/ui/rust-2018/issue-54006.stderr2
-rw-r--r--src/test/ui/rust-2018/local-path-suggestions-2015.stderr2
-rw-r--r--src/test/ui/rust-2018/local-path-suggestions-2018.rs8
-rw-r--r--src/test/ui/rust-2018/local-path-suggestions-2018.stderr20
-rw-r--r--src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity-macros-nested.rs2
-rw-r--r--src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity-macros-nested.stderr23
-rw-r--r--src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity-macros.rs2
-rw-r--r--src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity-macros.stderr23
-rw-r--r--src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity-nested.rs2
-rw-r--r--src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity-nested.stderr20
-rw-r--r--src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity.rs2
-rw-r--r--src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity.stderr20
-rw-r--r--src/test/ui/rust-2018/uniform-paths-forward-compat/block-scoped-shadow.rs4
-rw-r--r--src/test/ui/rust-2018/uniform-paths-forward-compat/block-scoped-shadow.stderr46
-rw-r--r--src/test/ui/rust-2018/uniform-paths-forward-compat/issue-54253.rs2
-rw-r--r--src/test/ui/rust-2018/uniform-paths/ambiguity-macros-nested.rs4
-rw-r--r--src/test/ui/rust-2018/uniform-paths/ambiguity-macros-nested.stderr25
-rw-r--r--src/test/ui/rust-2018/uniform-paths/ambiguity-macros.rs4
-rw-r--r--src/test/ui/rust-2018/uniform-paths/ambiguity-macros.stderr25
-rw-r--r--src/test/ui/rust-2018/uniform-paths/ambiguity-nested.rs4
-rw-r--r--src/test/ui/rust-2018/uniform-paths/ambiguity-nested.stderr22
-rw-r--r--src/test/ui/rust-2018/uniform-paths/ambiguity.rs4
-rw-r--r--src/test/ui/rust-2018/uniform-paths/ambiguity.stderr22
-rw-r--r--src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.rs22
-rw-r--r--src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.stderr23
-rw-r--r--src/test/ui/rust-2018/uniform-paths/block-scoped-shadow.rs12
-rw-r--r--src/test/ui/rust-2018/uniform-paths/block-scoped-shadow.stderr76
-rw-r--r--src/test/ui/rust-2018/uniform-paths/deadlock.rs7
-rw-r--r--src/test/ui/rust-2018/uniform-paths/deadlock.stderr9
-rw-r--r--src/test/ui/rust-2018/uniform-paths/fn-local-enum.rs15
-rw-r--r--src/test/ui/rust-2018/uniform-paths/from-decl-macro.rs12
-rw-r--r--src/test/ui/rust-2018/uniform-paths/issue-54253.rs4
-rw-r--r--src/test/ui/rust-2018/uniform-paths/issue-54253.stderr2
-rw-r--r--src/test/ui/rust-2018/uniform-paths/issue-54390.rs11
-rw-r--r--src/test/ui/rust-2018/uniform-paths/issue-54390.stderr32
-rw-r--r--src/test/ui/rust-2018/uniform-paths/macro-rules.rs44
-rw-r--r--src/test/ui/rust-2018/uniform-paths/macro-rules.stderr58
-rw-r--r--src/test/ui/rust-2018/uniform-paths/prelude-fail.rs13
-rw-r--r--src/test/ui/rust-2018/uniform-paths/prelude-fail.stderr15
-rw-r--r--src/test/ui/rust-2018/uniform-paths/prelude.rs28
-rw-r--r--src/test/ui/rust-2018/uniform-paths/redundant.rs2
-rw-r--r--src/test/ui/span/macro-ty-params.stderr12
-rw-r--r--src/test/ui/span/non-existing-module-import.stderr2
-rw-r--r--src/test/ui/static/static-mut-not-pat.stderr4
-rw-r--r--src/test/ui/super-at-top-level.rs2
-rw-r--r--src/test/ui/super-at-top-level.stderr6
-rw-r--r--src/test/ui/tool-attributes/tool-attributes-shadowing.rs2
-rw-r--r--src/test/ui/tool-attributes/tool-attributes-shadowing.stderr6
-rw-r--r--src/test/ui/type/type-path-err-node-types.stderr4
-rw-r--r--src/test/ui/ufcs/ufcs-partially-resolved.rs4
-rw-r--r--src/test/ui/ufcs/ufcs-partially-resolved.stderr12
-rw-r--r--src/test/ui/unknown-tool-name.rs2
-rw-r--r--src/test/ui/unknown-tool-name.stderr6
-rw-r--r--src/test/ui/unresolved/unresolved-import.rs6
-rw-r--r--src/test/ui/unresolved/unresolved-import.stderr6
-rw-r--r--src/test/ui/use/use-from-trait-xc.stderr6
-rw-r--r--src/test/ui/use/use-from-trait.rs4
-rw-r--r--src/test/ui/use/use-from-trait.stderr4
-rw-r--r--src/test/ui/use/use-mod/use-mod-4.stderr2
-rw-r--r--src/test/ui/use/use-self-type.rs2
-rw-r--r--src/test/ui/use/use-self-type.stderr8
-rw-r--r--src/test/ui/use/use-super-global-path.stderr4
186 files changed, 2186 insertions, 1520 deletions
diff --git a/src/doc/unstable-book/src/language-features/extern-in-paths.md b/src/doc/unstable-book/src/language-features/extern-in-paths.md
index 3ae6cc29df0..9979d774229 100644
--- a/src/doc/unstable-book/src/language-features/extern-in-paths.md
+++ b/src/doc/unstable-book/src/language-features/extern-in-paths.md
@@ -11,8 +11,8 @@ introducing `extern crate` items, using keyword `extern`.
 
 For example, `extern::my_crat::a::b` will resolve to path `a::b` in crate `my_crate`.
 
-`feature(extern_absolute_paths)` mode provides the same effect by resolving absolute paths like
-`::my_crate::a::b` to paths from extern crates by default.
+Absolute paths on 2018 edition (e.g. `::my_crate::a::b`) provide the same effect
+and resolve to extern crates (built-in or passed with `--extern`).
 
 ```rust,ignore
 #![feature(extern_in_paths)]
diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs
index e4c434b562d..50922ee601d 100644
--- a/src/librustc/hir/def.rs
+++ b/src/librustc/hir/def.rs
@@ -128,14 +128,6 @@ impl PathResolution {
     pub fn unresolved_segments(&self) -> usize {
         self.unresolved_segments
     }
-
-    pub fn kind_name(&self) -> &'static str {
-        if self.unresolved_segments != 0 {
-            "associated item"
-        } else {
-            self.base_def.kind_name()
-        }
-    }
 }
 
 /// Different kinds of symbols don't influence each other.
@@ -269,6 +261,12 @@ impl NonMacroAttrKind {
 
 impl Def {
     pub fn def_id(&self) -> DefId {
+        self.opt_def_id().unwrap_or_else(|| {
+            bug!("attempted .def_id() on invalid def: {:?}", self)
+        })
+    }
+
+    pub fn opt_def_id(&self) -> Option<DefId> {
         match *self {
             Def::Fn(id) | Def::Mod(id) | Def::Static(id, _) |
             Def::Variant(id) | Def::VariantCtor(id, ..) | Def::Enum(id) |
@@ -276,9 +274,8 @@ impl Def {
             Def::AssociatedTy(id) | Def::TyParam(id) | Def::Struct(id) | Def::StructCtor(id, ..) |
             Def::Union(id) | Def::Trait(id) | Def::Method(id) | Def::Const(id) |
             Def::AssociatedConst(id) | Def::Macro(id, ..) |
-            Def::Existential(id) | Def::AssociatedExistential(id) | Def::ForeignTy(id) |
-            Def::SelfCtor(id) => {
-                id
+            Def::Existential(id) | Def::AssociatedExistential(id) | Def::ForeignTy(id) => {
+                Some(id)
             }
 
             Def::Local(..) |
@@ -286,10 +283,11 @@ impl Def {
             Def::Label(..)  |
             Def::PrimTy(..) |
             Def::SelfTy(..) |
+            Def::SelfCtor(..) |
             Def::ToolMod |
             Def::NonMacroAttr(..) |
             Def::Err => {
-                bug!("attempted .def_id() on invalid def: {:?}", self)
+                None
             }
         }
     }
@@ -333,4 +331,13 @@ impl Def {
             Def::Err => "unresolved item",
         }
     }
+
+    pub fn article(&self) -> &'static str {
+        match *self {
+            Def::AssociatedTy(..) | Def::AssociatedConst(..) | Def::AssociatedExistential(..) |
+            Def::Enum(..) | Def::Existential(..) | Def::Err => "an",
+            Def::Macro(.., macro_kind) => macro_kind.article(),
+            _ => "a",
+        }
+    }
 }
diff --git a/src/librustc/hir/def_id.rs b/src/librustc/hir/def_id.rs
index e378e1b8be0..319d63f66c4 100644
--- a/src/librustc/hir/def_id.rs
+++ b/src/librustc/hir/def_id.rs
@@ -225,8 +225,8 @@ pub struct DefId {
 
 impl fmt::Debug for DefId {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "DefId({:?}/{}:{}",
-               self.krate.index(),
+        write!(f, "DefId({}/{}:{}",
+               self.krate,
                self.index.address_space().index(),
                self.index.as_array_index())?;
 
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index c5bcfd48cf3..282b5d13e2c 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -80,7 +80,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
                 self.check_def_id(def.def_id());
             }
             _ if self.in_pat => (),
-            Def::PrimTy(..) | Def::SelfTy(..) |
+            Def::PrimTy(..) | Def::SelfTy(..) | Def::SelfCtor(..) |
             Def::Local(..) | Def::Upvar(..) => {}
             Def::Variant(variant_id) | Def::VariantCtor(variant_id, ..) => {
                 if let Some(enum_id) = self.tcx.parent_def_id(variant_id) {
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index 5d456481896..543d1053b55 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -781,10 +781,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
 
     fn visit_path(&mut self, path: &'tcx hir::Path, id: hir::HirId) {
         let id = self.tcx.hir.hir_to_node_id(id);
-        match path.def {
-            Def::Local(..) | Def::Upvar(..) | Def::SelfCtor(..) |
-            Def::PrimTy(..) | Def::SelfTy(..) | Def::Err => {}
-            _ => self.tcx.check_stability(path.def.def_id(), Some(id), path.span)
+        if let Some(def_id) = path.def.opt_def_id() {
+            self.tcx.check_stability(def_id, Some(id), path.span)
         }
         intravisit::walk_path(self, path)
     }
diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs
index 32f8752c31b..bafabe4e997 100644
--- a/src/librustc_mir/hair/pattern/check_match.rs
+++ b/src/librustc_mir/hair/pattern/check_match.rs
@@ -298,7 +298,8 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
             let label_msg = match pat.node {
                 PatKind::Path(hir::QPath::Resolved(None, ref path))
                         if path.segments.len() == 1 && path.segments[0].args.is_none() => {
-                    format!("interpreted as a {} pattern, not new variable", path.def.kind_name())
+                    format!("interpreted as {} {} pattern, not new variable",
+                            path.def.article(), path.def.kind_name())
                 }
                 _ => format!("pattern `{}` not covered", pattern_string),
             };
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 4b7bd786672..5f8c7daea6e 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -361,9 +361,11 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
             let def_id = self.tcx.hir.local_def_id(id);
             if let Some(exports) = self.tcx.module_exports(def_id) {
                 for export in exports.iter() {
-                    if let Some(node_id) = self.tcx.hir.as_local_node_id(export.def.def_id()) {
-                        if export.vis == ty::Visibility::Public {
-                            self.update(node_id, Some(AccessLevel::Exported));
+                    if export.vis == ty::Visibility::Public {
+                        if let Some(def_id) = export.def.opt_def_id() {
+                            if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
+                                self.update(node_id, Some(AccessLevel::Exported));
+                            }
                         }
                     }
                 }
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index bb451f554d6..72fe7355e4c 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -116,143 +116,35 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
         id: NodeId,
         parent_prefix: &[Segment],
         nested: bool,
-        mut uniform_paths_canary_emitted: bool,
         // The whole `use` item
         parent_scope: ParentScope<'a>,
         item: &Item,
         vis: ty::Visibility,
         root_span: Span,
     ) {
-        debug!("build_reduced_graph_for_use_tree(parent_prefix={:?}, \
-                uniform_paths_canary_emitted={}, \
-                use_tree={:?}, nested={})",
-               parent_prefix, uniform_paths_canary_emitted, use_tree, nested);
-
-        let uniform_paths =
-            self.session.rust_2018() &&
-            self.session.features_untracked().uniform_paths;
-
-        let prefix_iter = || parent_prefix.iter().cloned()
-            .chain(use_tree.prefix.segments.iter().map(|seg| seg.into()));
-        let prefix_start = prefix_iter().next();
-        let starts_with_non_keyword = prefix_start.map_or(false, |seg| {
-            !seg.ident.is_path_segment_keyword()
-        });
-
-        // Imports are resolved as global by default, prepend `CrateRoot`,
-        // unless `#![feature(uniform_paths)]` is enabled.
-        let inject_crate_root =
-            !uniform_paths &&
-            match use_tree.kind {
-                // HACK(eddyb) special-case `use *` to mean `use ::*`.
-                ast::UseTreeKind::Glob if prefix_start.is_none() => true,
-                _ => starts_with_non_keyword,
-            };
-        let root = if inject_crate_root {
-            let span = use_tree.prefix.span.shrink_to_lo();
-            Some(Segment::from_ident(Ident::new(keywords::CrateRoot.name(), span)))
+        debug!("build_reduced_graph_for_use_tree(parent_prefix={:?}, use_tree={:?}, nested={})",
+               parent_prefix, use_tree, nested);
+
+        let mut prefix_iter = parent_prefix.iter().cloned()
+            .chain(use_tree.prefix.segments.iter().map(|seg| seg.into())).peekable();
+
+        // On 2015 edition imports are resolved as crate-relative by default,
+        // 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.
+        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 prefix: Vec<_> = root.into_iter().chain(prefix_iter()).collect();
-
+        let prefix = crate_root.into_iter().chain(prefix_iter).collect::<Vec<_>>();
         debug!("build_reduced_graph_for_use_tree: prefix={:?}", prefix);
 
-        // `#[feature(uniform_paths)]` allows an unqualified import path,
-        // e.g. `use x::...;` to resolve not just globally (`use ::x::...;`)
-        // but also relatively (`use self::x::...;`). To catch ambiguities
-        // that might arise from both of these being available and resolution
-        // silently picking one of them, an artificial `use self::x as _;`
-        // import is injected as a "canary", and an error is emitted if it
-        // successfully resolves while an `x` external crate exists.
-        //
-        // For each block scope around the `use` item, one special canary
-        // import of the form `use x as _;` is also injected, having its
-        // parent set to that scope; `resolve_imports` will only resolve
-        // it within its appropriate scope; if any of them successfully
-        // resolve, an ambiguity error is emitted, since the original
-        // import can't see the item in the block scope (`self::x` only
-        // looks in the enclosing module), but a non-`use` path could.
-        //
-        // Additionally, the canary might be able to catch limitations of the
-        // current implementation, where `::x` may be chosen due to `self::x`
-        // not existing, but `self::x` could appear later, from macro expansion.
-        //
-        // NB. The canary currently only errors if the `x::...` path *could*
-        // resolve as a relative path through the extern crate, i.e. `x` is
-        // in `extern_prelude`, *even though* `::x` might still forcefully
-        // load a non-`extern_prelude` crate.
-        // While always producing an ambiguity errors if `self::x` exists and
-        // a crate *could* be loaded, would be more conservative, imports for
-        // local modules named `test` (or less commonly, `syntax` or `log`),
-        // would need to be qualified (e.g. `self::test`), which is considered
-        // ergonomically unacceptable.
-        let emit_uniform_paths_canary =
-            !uniform_paths_canary_emitted &&
-            self.session.rust_2018() &&
-            starts_with_non_keyword;
-        if emit_uniform_paths_canary {
-            let source = prefix_start.unwrap();
-
-            // Helper closure to emit a canary with the given base path.
-            let emit = |this: &mut Self, base: Option<Segment>| {
-                let subclass = SingleImport {
-                    target: Ident {
-                        name: keywords::Underscore.name().gensymed(),
-                        span: source.ident.span,
-                    },
-                    source: source.ident,
-                    result: PerNS {
-                        type_ns: Cell::new(Err(Undetermined)),
-                        value_ns: Cell::new(Err(Undetermined)),
-                        macro_ns: Cell::new(Err(Undetermined)),
-                    },
-                    type_ns_only: false,
-                };
-                this.add_import_directive(
-                    base.into_iter().collect(),
-                    subclass,
-                    source.ident.span,
-                    id,
-                    root_span,
-                    item.id,
-                    ty::Visibility::Invisible,
-                    parent_scope.clone(),
-                    true, // is_uniform_paths_canary
-                );
-            };
-
-            // A single simple `self::x` canary.
-            emit(self, Some(Segment {
-                ident: Ident {
-                    name: keywords::SelfValue.name(),
-                    span: source.ident.span,
-                },
-                id: source.id
-            }));
-
-            // One special unprefixed canary per block scope around
-            // the import, to detect items unreachable by `self::x`.
-            let orig_current_module = self.current_module;
-            let mut span = source.ident.span.modern();
-            loop {
-                match self.current_module.kind {
-                    ModuleKind::Block(..) => emit(self, None),
-                    ModuleKind::Def(..) => break,
-                }
-                match self.hygienic_lexical_parent(self.current_module, &mut span) {
-                    Some(module) => {
-                        self.current_module = module;
-                    }
-                    None => break,
-                }
-            }
-            self.current_module = orig_current_module;
-
-            uniform_paths_canary_emitted = true;
-        }
-
         let empty_for_self = |prefix: &[Segment]| {
             prefix.is_empty() ||
             prefix.len() == 1 && prefix[0].ident.name == keywords::CrateRoot.name()
@@ -350,7 +242,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
                     item.id,
                     vis,
                     parent_scope,
-                    false, // is_uniform_paths_canary
                 );
             }
             ast::UseTreeKind::Glob => {
@@ -367,7 +258,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
                     item.id,
                     vis,
                     parent_scope,
-                    false, // is_uniform_paths_canary
                 );
             }
             ast::UseTreeKind::Nested(ref items) => {
@@ -396,7 +286,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
                 for &(ref tree, id) in items {
                     self.build_reduced_graph_for_use_tree(
                         // This particular use tree
-                        tree, id, &prefix, true, uniform_paths_canary_emitted,
+                        tree, id, &prefix, true,
                         // The whole `use` item
                         parent_scope.clone(), item, vis, root_span,
                     );
@@ -420,7 +310,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
                     };
                     self.build_reduced_graph_for_use_tree(
                         // This particular use tree
-                        &tree, id, &prefix, true, uniform_paths_canary_emitted,
+                        &tree, id, &prefix, true,
                         // The whole `use` item
                         parent_scope.clone(), item, ty::Visibility::Invisible, root_span,
                     );
@@ -441,7 +331,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
             ItemKind::Use(ref use_tree) => {
                 self.build_reduced_graph_for_use_tree(
                     // This particular use tree
-                    use_tree, item.id, &[], false, false,
+                    use_tree, item.id, &[], false,
                     // The whole `use` item
                     parent_scope, item, vis, use_tree.span,
                 );
@@ -459,6 +349,23 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
                 let used = self.process_legacy_macro_imports(item, module, &parent_scope);
                 let binding =
                     (module, ty::Visibility::Public, sp, expansion).to_name_binding(self.arenas);
+                let directive = self.arenas.alloc_import_directive(ImportDirective {
+                    root_id: item.id,
+                    id: item.id,
+                    parent_scope,
+                    imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))),
+                    subclass: ImportDirectiveSubclass::ExternCrate {
+                        source: orig_name,
+                        target: ident,
+                    },
+                    root_span: item.span,
+                    span: item.span,
+                    module_path: Vec::new(),
+                    vis: Cell::new(vis),
+                    used: Cell::new(used),
+                });
+                self.potentially_unused_imports.push(directive);
+                let imported_binding = self.import(binding, directive);
                 if ptr::eq(self.current_module, self.graph_root) {
                     if let Some(entry) = self.extern_prelude.get(&ident.modern()) {
                         if expansion != Mark::root() && orig_name.is_some() &&
@@ -473,29 +380,11 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
                         extern_crate_item: None,
                         introduced_by_item: true,
                     });
-                    entry.extern_crate_item = Some(binding);
+                    entry.extern_crate_item = Some(imported_binding);
                     if orig_name.is_some() {
                         entry.introduced_by_item = true;
                     }
                 }
-                let directive = self.arenas.alloc_import_directive(ImportDirective {
-                    root_id: item.id,
-                    id: item.id,
-                    parent_scope,
-                    imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))),
-                    subclass: ImportDirectiveSubclass::ExternCrate {
-                        source: orig_name,
-                        target: ident,
-                    },
-                    root_span: item.span,
-                    span: item.span,
-                    module_path: Vec::new(),
-                    vis: Cell::new(vis),
-                    used: Cell::new(used),
-                    is_uniform_paths_canary: false,
-                });
-                self.potentially_unused_imports.push(directive);
-                let imported_binding = self.import(binding, directive);
                 self.define(parent, ident, TypeNS, imported_binding);
             }
 
@@ -905,7 +794,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
             module_path: Vec::new(),
             vis: Cell::new(ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX))),
             used: Cell::new(false),
-            is_uniform_paths_canary: false,
         });
 
         let allow_shadowing = parent_scope.expansion == Mark::root();
@@ -923,6 +811,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
                     ModuleOrUniformRoot::Module(module),
                     ident,
                     MacroNS,
+                    None,
                     false,
                     span,
                 );
@@ -977,7 +866,6 @@ impl<'a, 'b, 'cl> BuildReducedGraphVisitor<'a, 'b, 'cl> {
         let invocation = self.resolver.invocations[&mark];
         invocation.module.set(self.resolver.current_module);
         invocation.parent_legacy_scope.set(self.current_legacy_scope);
-        invocation.output_legacy_scope.set(self.current_legacy_scope);
         invocation
     }
 }
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index c1dc3041d7d..2681295cf9b 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -1253,7 +1253,7 @@ Erroneous code example:
 
 ```compile_fail,E0433
 let map = HashMap::new();
-// error: failed to resolve. Use of undeclared type or module `HashMap`
+// error: failed to resolve: use of undeclared type or module `HashMap`
 ```
 
 Please verify you didn't misspell the type/module's name or that you didn't
diff --git a/src/librustc_resolve/error_reporting.rs b/src/librustc_resolve/error_reporting.rs
index 50ab8ef9c7b..263d23d133e 100644
--- a/src/librustc_resolve/error_reporting.rs
+++ b/src/librustc_resolve/error_reporting.rs
@@ -11,46 +11,39 @@
 use {CrateLint, PathResult, Segment};
 use macros::ParentScope;
 
-use std::collections::BTreeSet;
-
-use syntax::ast::Ident;
-use syntax::symbol::{keywords, Symbol};
+use syntax::symbol::keywords;
 use syntax_pos::Span;
 
 use resolve_imports::ImportResolver;
+use std::cmp::Reverse;
 
 impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
     /// Add suggestions for a path that cannot be resolved.
     pub(crate) fn make_path_suggestion(
         &mut self,
         span: Span,
-        path: Vec<Segment>,
+        mut path: Vec<Segment>,
         parent_scope: &ParentScope<'b>,
     ) -> Option<(Vec<Segment>, Option<String>)> {
         debug!("make_path_suggestion: span={:?} path={:?}", span, path);
-        // If we don't have a path to suggest changes to, then return.
-        if path.is_empty() {
-            return None;
-        }
-
-        // Check whether a ident is a path segment that is not root.
-        let is_special = |ident: Ident| ident.is_path_segment_keyword() &&
-                                        ident.name != keywords::CrateRoot.name();
 
         match (path.get(0), path.get(1)) {
-            // Make suggestions that require at least two non-special path segments.
-            (Some(fst), Some(snd)) if !is_special(fst.ident) && !is_special(snd.ident) => {
-                debug!("make_path_suggestion: fst={:?} snd={:?}", fst, snd);
-
-                self.make_missing_self_suggestion(span, path.clone(), parent_scope)
-                    .or_else(|| self.make_missing_crate_suggestion(span, path.clone(),
-                                                                   parent_scope))
-                    .or_else(|| self.make_missing_super_suggestion(span, path.clone(),
-                                                                   parent_scope))
-                    .or_else(|| self.make_external_crate_suggestion(span, path, parent_scope))
-            },
-            _ => None,
+            // `{{root}}::ident::...` on both editions.
+            // On 2015 `{{root}}` is usually added implicitly.
+            (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() => {
+                // Insert a placeholder that's later replaced by `self`/`super`/etc.
+                path.insert(0, Segment::from_ident(keywords::Invalid.ident()));
+            }
+            _ => return None,
         }
+
+        self.make_missing_self_suggestion(span, path.clone(), parent_scope)
+            .or_else(|| self.make_missing_crate_suggestion(span, path.clone(), parent_scope))
+            .or_else(|| self.make_missing_super_suggestion(span, path.clone(), parent_scope))
+            .or_else(|| self.make_external_crate_suggestion(span, path, parent_scope))
     }
 
     /// Suggest a missing `self::` if that resolves to an correct module.
@@ -58,7 +51,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
     /// ```
     ///    |
     /// LL | use foo::Bar;
-    ///    |     ^^^ Did you mean `self::foo`?
+    ///    |     ^^^ did you mean `self::foo`?
     /// ```
     fn make_missing_self_suggestion(
         &mut self,
@@ -68,7 +61,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
     ) -> Option<(Vec<Segment>, Option<String>)> {
         // Replace first ident with `self` and check if that is valid.
         path[0].ident.name = keywords::SelfValue.name();
-        let result = self.resolve_path(None, &path, None, parent_scope, false, span, CrateLint::No);
+        let result = self.resolve_path(&path, None, parent_scope, false, span, CrateLint::No);
         debug!("make_missing_self_suggestion: path={:?} result={:?}", path, result);
         if let PathResult::Module(..) = result {
             Some((path, None))
@@ -82,7 +75,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
     /// ```
     ///    |
     /// LL | use foo::Bar;
-    ///    |     ^^^ Did you mean `crate::foo`?
+    ///    |     ^^^ did you mean `crate::foo`?
     /// ```
     fn make_missing_crate_suggestion(
         &mut self,
@@ -92,7 +85,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
     ) -> Option<(Vec<Segment>, Option<String>)> {
         // Replace first ident with `crate` and check if that is valid.
         path[0].ident.name = keywords::Crate.name();
-        let result = self.resolve_path(None, &path, None, parent_scope, false, span, CrateLint::No);
+        let result = self.resolve_path(&path, None, parent_scope, false, span, CrateLint::No);
         debug!("make_missing_crate_suggestion:  path={:?} result={:?}", path, result);
         if let PathResult::Module(..) = result {
             Some((
@@ -113,7 +106,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
     /// ```
     ///    |
     /// LL | use foo::Bar;
-    ///    |     ^^^ Did you mean `super::foo`?
+    ///    |     ^^^ did you mean `super::foo`?
     /// ```
     fn make_missing_super_suggestion(
         &mut self,
@@ -123,7 +116,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
     ) -> Option<(Vec<Segment>, Option<String>)> {
         // Replace first ident with `crate` and check if that is valid.
         path[0].ident.name = keywords::Super.name();
-        let result = self.resolve_path(None, &path, None, parent_scope, false, span, CrateLint::No);
+        let result = self.resolve_path(&path, None, parent_scope, false, span, CrateLint::No);
         debug!("make_missing_super_suggestion:  path={:?} result={:?}", path, result);
         if let PathResult::Module(..) = result {
             Some((path, None))
@@ -137,7 +130,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
     /// ```
     ///    |
     /// LL | use foobar::Baz;
-    ///    |     ^^^^^^ Did you mean `baz::foobar`?
+    ///    |     ^^^^^^ did you mean `baz::foobar`?
     /// ```
     ///
     /// Used when importing a submodule of an external crate but missing that crate's
@@ -148,24 +141,21 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
         mut path: Vec<Segment>,
         parent_scope: &ParentScope<'b>,
     ) -> Option<(Vec<Segment>, Option<String>)> {
-        // Need to clone else we can't call `resolve_path` without a borrow error. We also store
-        // into a `BTreeMap` so we can get consistent ordering (and therefore the same diagnostic)
-        // each time.
-        let external_crate_names: BTreeSet<Symbol> = self.resolver.extern_prelude
-            .iter().map(|(ident, _)| ident.name).collect();
+        if !self.session.rust_2018() {
+            return None;
+        }
 
-        // Insert a new path segment that we can replace.
-        let new_path_segment = path[0].clone();
-        path.insert(1, new_path_segment);
+        // Sort extern crate names in reverse order to get
+        // 1) some consistent ordering for emitted dignostics and
+        // 2) `std` suggestions before `core` suggestions.
+        let mut extern_crate_names =
+            self.resolver.extern_prelude.iter().map(|(ident, _)| ident.name).collect::<Vec<_>>();
+        extern_crate_names.sort_by_key(|name| Reverse(name.as_str()));
 
-        // Iterate in reverse so that we start with crates at the end of the alphabet. This means
-        // that we'll always get `std` before `core`.
-        for name in external_crate_names.iter().rev() {
-            // Replace the first after root (a placeholder we inserted) with a crate name
-            // and check if that is valid.
-            path[1].ident.name = *name;
-            let result =
-                self.resolve_path(None, &path, None, parent_scope, false, span, CrateLint::No);
+        for name in extern_crate_names.into_iter() {
+            // Replace first ident with a crate name and check if that is valid.
+            path[0].ident.name = name;
+            let result = self.resolve_path(&path, None, parent_scope, false, span, CrateLint::No);
             debug!("make_external_crate_suggestion: name={:?} path={:?} result={:?}",
                     name, path, result);
             if let PathResult::Module(..) = result {
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 241db271177..7b2d1d4a3d5 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -97,6 +97,11 @@ fn is_known_tool(name: Name) -> bool {
     ["clippy", "rustfmt"].contains(&&*name.as_str())
 }
 
+enum Weak {
+    Yes,
+    No,
+}
+
 /// A free importable items suggested in case of resolution failure.
 struct ImportSuggestion {
     path: Path,
@@ -371,7 +376,7 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver,
         }
         ResolutionError::FailedToResolve(msg) => {
             let mut err = struct_span_err!(resolver.session, span, E0433,
-                                           "failed to resolve. {}", msg);
+                                           "failed to resolve: {}", msg);
             err.span_label(span, msg);
             err
         }
@@ -391,14 +396,13 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver,
             err
         }
         ResolutionError::BindingShadowsSomethingUnacceptable(what_binding, name, binding) => {
-            let shadows_what = PathResolution::new(binding.def()).kind_name();
-            let mut err = struct_span_err!(resolver.session,
-                                           span,
-                                           E0530,
-                                           "{}s cannot shadow {}s", what_binding, shadows_what);
-            err.span_label(span, format!("cannot be named the same as a {}", shadows_what));
+            let shadows_what = binding.descr();
+            let mut err = struct_span_err!(resolver.session, span, E0530, "{}s cannot shadow {}s",
+                                           what_binding, shadows_what);
+            err.span_label(span, format!("cannot be named the same as {} {}",
+                                         binding.article(), shadows_what));
             let participle = if binding.is_import() { "imported" } else { "defined" };
-            let msg = format!("a {} `{}` is {} here", shadows_what, name, participle);
+            let msg = format!("the {} `{}` is {} here", shadows_what, name, participle);
             err.span_label(binding.span, msg);
             err
         }
@@ -993,15 +997,34 @@ impl<'a> LexicalScopeBinding<'a> {
     }
 }
 
+
+#[derive(Clone, Copy, PartialEq, Debug)]
+enum UniformRootKind {
+    CurrentScope,
+    ExternPrelude,
+}
+
 #[derive(Copy, Clone, Debug)]
-pub enum ModuleOrUniformRoot<'a> {
+enum ModuleOrUniformRoot<'a> {
     /// Regular module.
     Module(Module<'a>),
 
-    /// The `{{root}}` (`CrateRoot` aka "global") / `extern` initial segment
-    /// in which external crates resolve, and also `crate` (only in `{{root}}`,
-    /// but *not* `extern`), in the Rust 2018 edition.
-    UniformRoot(Name),
+    /// 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),
+}
+
+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,
+            _ => false,
+        }
+    }
 }
 
 #[derive(Clone, Debug)]
@@ -1045,9 +1068,10 @@ pub struct ModuleData<'a> {
     normal_ancestor_id: DefId,
 
     resolutions: RefCell<FxHashMap<(Ident, Namespace), &'a RefCell<NameResolution<'a>>>>,
-    legacy_macro_resolutions: RefCell<Vec<(Ident, MacroKind, ParentScope<'a>,
-                                           Option<&'a NameBinding<'a>>)>>,
-    macro_resolutions: RefCell<Vec<(Vec<Segment>, ParentScope<'a>, Span)>>,
+    single_segment_macro_resolutions: RefCell<Vec<(Ident, MacroKind, ParentScope<'a>,
+                                                   Option<&'a NameBinding<'a>>)>>,
+    multi_segment_macro_resolutions: RefCell<Vec<(Vec<Segment>, Span, MacroKind, ParentScope<'a>,
+                                                  Option<Def>)>>,
     builtin_attrs: RefCell<Vec<(Ident, ParentScope<'a>)>>,
 
     // Macro invocations that can expand into items in this module.
@@ -1085,8 +1109,8 @@ impl<'a> ModuleData<'a> {
             kind,
             normal_ancestor_id,
             resolutions: Default::default(),
-            legacy_macro_resolutions: RefCell::new(Vec::new()),
-            macro_resolutions: RefCell::new(Vec::new()),
+            single_segment_macro_resolutions: RefCell::new(Vec::new()),
+            multi_segment_macro_resolutions: RefCell::new(Vec::new()),
             builtin_attrs: RefCell::new(Vec::new()),
             unresolved_invocations: Default::default(),
             no_implicit_prelude: false,
@@ -1195,6 +1219,7 @@ enum NameBindingKind<'a> {
         used: Cell<bool>,
     },
     Ambiguity {
+        kind: AmbiguityKind,
         b1: &'a NameBinding<'a>,
         b2: &'a NameBinding<'a>,
     }
@@ -1212,10 +1237,61 @@ struct UseError<'a> {
     better: bool,
 }
 
+#[derive(Clone, Copy, PartialEq, Debug)]
+enum AmbiguityKind {
+    Import,
+    BuiltinAttr,
+    DeriveHelper,
+    LegacyHelperVsPrelude,
+    LegacyVsModern,
+    GlobVsOuter,
+    GlobVsGlob,
+    GlobVsExpanded,
+    MoreExpandedVsOuter,
+}
+
+impl AmbiguityKind {
+    fn descr(self) -> &'static str {
+        match self {
+            AmbiguityKind::Import =>
+                "name vs any other name during import resolution",
+            AmbiguityKind::BuiltinAttr =>
+                "built-in attribute vs any other name",
+            AmbiguityKind::DeriveHelper =>
+                "derive helper attribute vs any other name",
+            AmbiguityKind::LegacyHelperVsPrelude =>
+                "legacy plugin helper attribute vs name from prelude",
+            AmbiguityKind::LegacyVsModern =>
+                "`macro_rules` vs non-`macro_rules` from other module",
+            AmbiguityKind::GlobVsOuter =>
+                "glob import vs any other name from outer scope during import/macro resolution",
+            AmbiguityKind::GlobVsGlob =>
+                "glob import vs glob import in the same module",
+            AmbiguityKind::GlobVsExpanded =>
+                "glob import vs macro-expanded name in the same \
+                 module during import/macro resolution",
+            AmbiguityKind::MoreExpandedVsOuter =>
+                "macro-expanded name vs less macro-expanded name \
+                 from outer scope during import/macro resolution",
+        }
+    }
+}
+
+/// Miscellaneous bits of metadata for better ambiguity error reporting.
+#[derive(Clone, Copy, PartialEq)]
+enum AmbiguityErrorMisc {
+    SuggestSelf,
+    FromPrelude,
+    None,
+}
+
 struct AmbiguityError<'a> {
+    kind: AmbiguityKind,
     ident: Ident,
     b1: &'a NameBinding<'a>,
     b2: &'a NameBinding<'a>,
+    misc1: AmbiguityErrorMisc,
+    misc2: AmbiguityErrorMisc,
 }
 
 impl<'a> NameBinding<'a> {
@@ -1268,6 +1344,9 @@ impl<'a> NameBinding<'a> {
                     subclass: ImportDirectiveSubclass::ExternCrate { .. }, ..
                 }, ..
             } => true,
+            NameBindingKind::Module(
+                &ModuleData { kind: ModuleKind::Def(Def::Mod(def_id), _), .. }
+            ) => def_id.index == CRATE_DEF_INDEX,
             _ => false,
         }
     }
@@ -1313,6 +1392,10 @@ impl<'a> NameBinding<'a> {
         if self.is_extern_crate() { "extern crate" } else { self.def().kind_name() }
     }
 
+    fn article(&self) -> &'static str {
+        if self.is_extern_crate() { "an" } else { self.def().article() }
+    }
+
     // Suppose that we resolved macro invocation with `invoc_parent_expansion` to binding `binding`
     // at some expansion round `max(invoc, binding)` when they both emerged from macros.
     // Then this function returns `true` if `self` may emerge from a macro *after* that
@@ -1423,6 +1506,9 @@ pub struct Resolver<'a, 'b: 'a> {
     /// The current self item if inside an ADT (used for better errors).
     current_self_item: Option<NodeId>,
 
+    /// FIXME: Refactor things so that this is passed through arguments and not resolver.
+    last_import_segment: bool,
+
     /// The idents for the primitive types.
     primitive_type_table: PrimitiveTypeTable,
 
@@ -1661,8 +1747,8 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
         let segments = &path.segments;
         let path = Segment::from_path(&path);
         // FIXME (Manishearth): Intra doc links won't get warned of epoch changes
-        let def = match self.resolve_path_without_parent_scope(None, &path, Some(namespace),
-                                                               true, span, CrateLint::No) {
+        let def = match self.resolve_path_without_parent_scope(&path, Some(namespace), true,
+                                                               span, CrateLint::No) {
             PathResult::Module(ModuleOrUniformRoot::Module(module)) =>
                 module.def().unwrap(),
             PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 =>
@@ -1772,6 +1858,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
             current_trait_ref: None,
             current_self_type: None,
             current_self_item: None,
+            last_import_segment: false,
 
             primitive_type_table: PrimitiveTypeTable::new(),
 
@@ -1873,23 +1960,35 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
         self.arenas.alloc_module(module)
     }
 
-    fn record_use(&mut self, ident: Ident, ns: Namespace, binding: &'a NameBinding<'a>)
-                  -> bool /* true if an error was reported */ {
-        match binding.kind {
-            NameBindingKind::Import { directive, binding, ref used }
-                    if !used.get() => {
+    fn record_use(&mut self, ident: Ident, ns: Namespace,
+                  used_binding: &'a NameBinding<'a>, is_lexical_scope: bool) {
+        match used_binding.kind {
+            NameBindingKind::Import { directive, binding, ref used } if !used.get() => {
+                // Avoid marking `extern crate` items that refer to a name from extern prelude,
+                // but not introduce it, as used if they are accessed from lexical scope.
+                if is_lexical_scope {
+                    if let Some(entry) = self.extern_prelude.get(&ident.modern()) {
+                        if let Some(crate_item) = entry.extern_crate_item {
+                            if ptr::eq(used_binding, crate_item) && !entry.introduced_by_item {
+                                return;
+                            }
+                        }
+                    }
+                }
                 used.set(true);
                 directive.used.set(true);
                 self.used_imports.insert((directive.id, ns));
                 self.add_to_glob_map(directive.id, ident);
-                self.record_use(ident, ns, binding)
+                self.record_use(ident, ns, binding, false);
             }
-            NameBindingKind::Import { .. } => false,
-            NameBindingKind::Ambiguity { b1, b2 } => {
-                self.ambiguity_errors.push(AmbiguityError { ident, b1, b2 });
-                true
+            NameBindingKind::Ambiguity { kind, b1, b2 } => {
+                self.ambiguity_errors.push(AmbiguityError {
+                    kind, ident, b1, b2,
+                    misc1: AmbiguityErrorMisc::None,
+                    misc2: AmbiguityErrorMisc::None,
+                });
             }
-            _ => false
+            _ => {}
         }
     }
 
@@ -1960,7 +2059,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
                 ModuleOrUniformRoot::Module(module),
                 ident,
                 ns,
-                false,
                 record_used,
                 path_span,
             );
@@ -1991,7 +2089,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
                 ModuleOrUniformRoot::Module(module),
                 ident,
                 ns,
-                false,
                 record_used,
                 path_span,
             );
@@ -2024,7 +2121,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
             }
             if ns == TypeNS && is_known_tool(ident.name) {
                 let binding = (Def::ToolMod, ty::Visibility::Public,
-                               ident.span, Mark::root()).to_name_binding(self.arenas);
+                               DUMMY_SP, Mark::root()).to_name_binding(self.arenas);
                 return Some(LexicalScopeBinding::Item(binding));
             }
             if let Some(prelude) = self.prelude {
@@ -2033,7 +2130,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
                     ident,
                     ns,
                     false,
-                    false,
                     path_span,
                 ) {
                     return Some(LexicalScopeBinding::Item(binding));
@@ -2093,23 +2189,31 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
         None
     }
 
-    fn resolve_ident_in_module(&mut self,
-                               module: ModuleOrUniformRoot<'a>,
-                               mut ident: Ident,
-                               ns: Namespace,
-                               record_used: bool,
-                               span: Span)
-                               -> Result<&'a NameBinding<'a>, Determinacy> {
+    fn resolve_ident_in_module(
+        &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> {
         ident.span = ident.span.modern();
         let orig_current_module = self.current_module;
-        if let ModuleOrUniformRoot::Module(module) = module {
-            if let Some(def) = ident.span.adjust(module.expansion) {
-                self.current_module = self.macro_def_scope(def);
+        match module {
+            ModuleOrUniformRoot::Module(module) => {
+                if let Some(def) = ident.span.adjust(module.expansion) {
+                    self.current_module = self.macro_def_scope(def);
+                }
+            }
+            ModuleOrUniformRoot::UniformRoot(UniformRootKind::ExternPrelude) => {
+                ident.span.adjust(Mark::root());
             }
+            _ => {}
         }
-        let result = self.resolve_ident_in_module_unadjusted(
-            module, ident, ns, false, record_used, span,
-        );
+        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
     }
@@ -2250,6 +2354,36 @@ 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() {
+                return;
+            }
+
+            let nss = match use_tree.kind {
+                ast::UseTreeKind::Simple(..) if segments.len() == 1 => &[TypeNS, ValueNS][..],
+                _ => &[TypeNS],
+            };
+            for &ns in nss {
+                if let Some(LexicalScopeBinding::Def(..)) =
+                        self.resolve_ident_in_lexical_scope(ident, ns, None, use_tree.prefix.span) {
+                    let what = if ns == TypeNS { "type parameters" } else { "local variables" };
+                    self.session.span_err(ident.span, &format!("imports cannot refer to {}", what));
+                }
+            }
+        } else if let ast::UseTreeKind::Nested(use_trees) = &use_tree.kind {
+            for (use_tree, _) in use_trees {
+                self.future_proof_import(use_tree);
+            }
+        }
+    }
+
     fn resolve_item(&mut self, item: &Item) {
         let name = item.ident.name;
         debug!("(resolving item) resolving {}", name);
@@ -2343,7 +2477,11 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
                 });
             }
 
-            ItemKind::Use(..) | ItemKind::ExternCrate(..) |
+            ItemKind::Use(ref use_tree) => {
+                self.future_proof_import(use_tree);
+            }
+
+            ItemKind::ExternCrate(..) |
             ItemKind::MacroDef(..) | ItemKind::GlobalAsm(..) => {
                 // do nothing, these are just around to be encoded
             }
@@ -2466,7 +2604,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
                 let span = trait_ref.path.span;
                 if let PathResult::Module(ModuleOrUniformRoot::Module(module)) =
                     self.resolve_path_without_parent_scope(
-                        None,
                         &path,
                         Some(TypeNS),
                         false,
@@ -2607,6 +2744,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
                 ModuleOrUniformRoot::Module(module),
                 ident,
                 ns,
+                None,
                 false,
                 span,
             ).is_err() {
@@ -2863,7 +3001,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
                             Def::Const(..) if is_syntactic_ambiguity => {
                                 // Disambiguate in favor of a unit struct/variant
                                 // or constant pattern.
-                                self.record_use(ident, ValueNS, binding.unwrap());
+                                self.record_use(ident, ValueNS, binding.unwrap(), false);
                                 Some(PathResolution::new(def))
                             }
                             Def::StructCtor(..) | Def::VariantCtor(..) |
@@ -2991,7 +3129,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
                 } else {
                     let mod_path = &path[..path.len() - 1];
                     let mod_prefix = match this.resolve_path_without_parent_scope(
-                        None, mod_path, Some(TypeNS), false, span, CrateLint::No
+                        mod_path, Some(TypeNS), false, span, CrateLint::No
                     ) {
                         PathResult::Module(ModuleOrUniformRoot::Module(module)) =>
                             module.def(),
@@ -3480,7 +3618,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
         }
 
         let result = match self.resolve_path_without_parent_scope(
-            None,
             &path,
             Some(ns),
             true,
@@ -3527,7 +3664,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
            path[0].ident.name != keywords::DollarCrate.name() {
             let unqualified_result = {
                 match self.resolve_path_without_parent_scope(
-                    None,
                     &[*path.last().unwrap()],
                     Some(ns),
                     false,
@@ -3551,9 +3687,8 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
 
     fn resolve_path_without_parent_scope(
         &mut self,
-        base_module: Option<ModuleOrUniformRoot<'a>>,
         path: &[Segment],
-        opt_ns: Option<Namespace>, // `None` indicates a module path
+        opt_ns: Option<Namespace>, // `None` indicates a module path in import
         record_used: bool,
         path_span: Span,
         crate_lint: CrateLint,
@@ -3562,21 +3697,19 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
         // other paths will do okay with parent module alone.
         assert!(opt_ns != None && opt_ns != Some(MacroNS));
         let parent_scope = ParentScope { module: self.current_module, ..self.dummy_parent_scope() };
-        self.resolve_path(base_module, path, opt_ns, &parent_scope,
-                          record_used, path_span, crate_lint)
+        self.resolve_path(path, opt_ns, &parent_scope, record_used, path_span, crate_lint)
     }
 
     fn resolve_path(
         &mut self,
-        base_module: Option<ModuleOrUniformRoot<'a>>,
         path: &[Segment],
-        opt_ns: Option<Namespace>, // `None` indicates a module path
+        opt_ns: Option<Namespace>, // `None` indicates a module path in import
         parent_scope: &ParentScope<'a>,
         record_used: bool,
         path_span: Span,
         crate_lint: CrateLint,
     ) -> PathResult<'a> {
-        let mut module = base_module;
+        let mut module = None;
         let mut allow_super = true;
         let mut second_binding = None;
         self.current_module = parent_scope.module;
@@ -3629,7 +3762,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
                             continue;
                         }
                     }
-                    let msg = "There are too many initial `super`s.".to_string();
+                    let msg = "there are too many initial `super`s.".to_string();
                     return PathResult::Failed(ident.span, msg, false);
                 }
                 if i == 0 {
@@ -3640,9 +3773,9 @@ 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(name));
+                       name == keywords::CrateRoot.name() && self.session.rust_2018() {
+                        module =
+                            Some(ModuleOrUniformRoot::UniformRoot(UniformRootKind::ExternPrelude));
                         continue;
                     }
                     if name == keywords::CrateRoot.name() ||
@@ -3672,11 +3805,12 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
             }
 
             let binding = if let Some(module) = module {
-                self.resolve_ident_in_module(module, ident, ns, record_used, path_span)
-            } else if opt_ns == Some(MacroNS) {
+                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, parent_scope,
-                                                          record_used, record_used, path_span)
+                self.early_resolve_ident_in_lexical_scope(ident, ns, None, opt_ns.is_none(),
+                                                          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 };
@@ -3691,7 +3825,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
                             def, path.len() - 1
                         ));
                     }
-                    _ => Err(if record_used { Determined } else { Undetermined }),
+                    _ => Err(Determinacy::determined(record_used)),
                 }
             };
 
@@ -3722,7 +3856,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
                         ));
                     } else {
                         return PathResult::Failed(ident.span,
-                                                  format!("Not a module `{}`", ident),
+                                                  format!("not a module `{}`", ident),
                                                   is_last);
                     }
                 }
@@ -3747,14 +3881,14 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
                             (c.path.segments.len(), c.path.to_string())
                         });
                         if let Some(candidate) = candidates.get(0) {
-                            format!("Did you mean `{}`?", candidate.path)
+                            format!("did you mean `{}`?", candidate.path)
                         } else {
-                            format!("Maybe a missing `extern crate {};`?", ident)
+                            format!("maybe a missing `extern crate {};`?", ident)
                         }
                     } else if i == 0 {
-                        format!("Use of undeclared type or module `{}`", ident)
+                        format!("use of undeclared type or module `{}`", ident)
                     } else {
-                        format!("Could not find `{}` in `{}`", ident, path[i - 1].ident)
+                        format!("could not find `{}` in `{}`", ident, path[i - 1].ident)
                     };
                     return PathResult::Failed(ident.span, msg, is_last);
                 }
@@ -3763,9 +3897,12 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
 
         self.lint_if_path_starts_with_module(crate_lint, path, path_span, second_binding);
 
-        PathResult::Module(module.unwrap_or_else(|| {
-            span_bug!(path_span, "resolve_path: empty(?) path {:?} has no module", path);
-        }))
+        PathResult::Module(match module {
+            Some(module) => module,
+            None if path.is_empty() =>
+                ModuleOrUniformRoot::UniformRoot(UniformRootKind::CurrentScope),
+            _ => span_bug!(path_span, "resolve_path: non-empty path `{:?}` has no module", path),
+        })
     }
 
     fn lint_if_path_starts_with_module(
@@ -3975,6 +4112,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
                     ModuleOrUniformRoot::Module(module),
                     ident,
                     ns,
+                    None,
                     false,
                     module.span,
                 ) {
@@ -4050,7 +4188,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
             // Search in module.
             let mod_path = &path[..path.len() - 1];
             if let PathResult::Module(module) = self.resolve_path_without_parent_scope(
-                None, mod_path, Some(TypeNS), false, span, CrateLint::No
+                mod_path, Some(TypeNS), false, span, CrateLint::No
             ) {
                 if let ModuleOrUniformRoot::Module(module) = module {
                     add_module_candidates(module, &mut names);
@@ -4297,6 +4435,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
                 ModuleOrUniformRoot::Module(module),
                 ident,
                 ns,
+                None,
                 false,
                 module.span,
             ).is_ok() {
@@ -4352,7 +4491,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
                 ident,
                 ns,
                 false,
-                false,
                 module.span,
             ).is_ok() {
                 let import_id = match binding.kind {
@@ -4634,43 +4772,88 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
         }
     }
 
-    fn report_ambiguity_error(&self, ident: Ident, b1: &NameBinding, b2: &NameBinding) {
-        let participle = |is_import: bool| if is_import { "imported" } else { "defined" };
-        let msg1 =
-            format!("`{}` could refer to the name {} here", ident, participle(b1.is_import()));
-        let msg2 =
-            format!("`{}` could also refer to the name {} here", ident, participle(b2.is_import()));
-        let note = if b1.expansion != Mark::root() {
-            Some(if let Def::Macro(..) = b1.def() {
-                format!("macro-expanded {} do not shadow",
-                        if b1.is_import() { "macro imports" } else { "macros" })
+    fn binding_description(&self, b: &NameBinding, ident: Ident, from_prelude: bool) -> String {
+        if b.span.is_dummy() {
+            let add_built_in = match b.def() {
+                // These already contain the "built-in" prefix or look bad with it.
+                Def::NonMacroAttr(..) | Def::PrimTy(..) | Def::ToolMod => false,
+                _ => true,
+            };
+            let (built_in, from) = if from_prelude {
+                ("", " from prelude")
+            } else if b.is_extern_crate() && !b.is_import() &&
+                        self.session.opts.externs.get(&ident.as_str()).is_some() {
+                ("", " passed with `--extern`")
+            } else if add_built_in {
+                (" built-in", "")
             } else {
-                format!("macro-expanded {} do not shadow when used in a macro invocation path",
-                        if b1.is_import() { "imports" } else { "items" })
-            })
-        } else if b1.is_glob_import() {
-            Some(format!("consider adding an explicit import of `{}` to disambiguate", ident))
+                ("", "")
+            };
+
+            let article = if built_in.is_empty() { b.article() } else { "a" };
+            format!("{a}{built_in} {thing}{from}",
+                    a = article, thing = b.descr(), built_in = built_in, from = from)
         } else {
-            None
+            let introduced = if b.is_import() { "imported" } else { "defined" };
+            format!("the {thing} {introduced} here",
+                    thing = b.descr(), introduced = introduced)
+        }
+    }
+
+    fn report_ambiguity_error(&self, ambiguity_error: &AmbiguityError) {
+        let AmbiguityError { kind, ident, b1, b2, misc1, misc2 } = *ambiguity_error;
+        let (b1, b2, misc1, misc2, swapped) = if b2.span.is_dummy() && !b1.span.is_dummy() {
+            // We have to print the span-less alternative first, otherwise formatting looks bad.
+            (b2, b1, misc2, misc1, true)
+        } else {
+            (b1, b2, misc1, misc2, false)
         };
 
-        let mut err = struct_span_err!(self.session, ident.span, E0659, "`{}` is ambiguous", ident);
+        let mut err = struct_span_err!(self.session, ident.span, E0659,
+                                       "`{ident}` is ambiguous ({why})",
+                                       ident = ident, why = kind.descr());
         err.span_label(ident.span, "ambiguous name");
-        err.span_note(b1.span, &msg1);
-        match b2.def() {
-            Def::Macro(..) if b2.span.is_dummy() =>
-                err.note(&format!("`{}` is also a builtin macro", ident)),
-            _ => err.span_note(b2.span, &msg2),
+
+        let mut could_refer_to = |b: &NameBinding, misc: AmbiguityErrorMisc, also: &str| {
+            let what = self.binding_description(b, ident, misc == AmbiguityErrorMisc::FromPrelude);
+            let note_msg = format!("`{ident}` could{also} refer to {what}",
+                                   ident = ident, also = also, what = what);
+
+            let mut help_msgs = Vec::new();
+            if b.is_glob_import() && (kind == AmbiguityKind::GlobVsGlob ||
+                                      kind == AmbiguityKind::GlobVsExpanded ||
+                                      kind == AmbiguityKind::GlobVsOuter &&
+                                      swapped != also.is_empty()) {
+                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 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() {
+                err.note(&note_msg);
+            } else {
+                err.span_note(b.span, &note_msg);
+            }
+            for (i, help_msg) in help_msgs.iter().enumerate() {
+                let or = if i == 0 { "" } else { "or " };
+                err.help(&format!("{}{}", or, help_msg));
+            }
         };
-        if let Some(note) = note {
-            err.note(&note);
-        }
+
+        could_refer_to(b1, misc1, "");
+        could_refer_to(b2, misc2, " also");
         err.emit();
     }
 
     fn report_errors(&mut self, krate: &Crate) {
         self.report_with_use_injections(krate);
-        let mut reported_spans = FxHashSet::default();
 
         for &(span_use, span_def) in &self.macro_expanded_macro_export_errors {
             let msg = "macro-expanded `macro_export` macros from the current crate \
@@ -4683,12 +4866,11 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
             );
         }
 
-        for &AmbiguityError { ident, b1, b2 } in &self.ambiguity_errors {
-            if reported_spans.insert(ident.span) {
-                self.report_ambiguity_error(ident, b1, b2);
-            }
+        for ambiguity_error in &self.ambiguity_errors {
+            self.report_ambiguity_error(ambiguity_error);
         }
 
+        let mut reported_spans = FxHashSet::default();
         for &PrivacyError(dedup_span, ident, binding) in &self.privacy_errors {
             if reported_spans.insert(dedup_span) {
                 span_err!(self.session, ident.span, E0603, "{} `{}` is private",
@@ -4842,6 +5024,10 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
 
     fn extern_prelude_get(&mut self, ident: Ident, speculative: bool, skip_feature_gate: bool)
                           -> Option<&'a NameBinding<'a>> {
+        if ident.is_path_segment_keyword() {
+            // Make sure `self`, `super` etc produce an error when passed to here.
+            return None;
+        }
         self.extern_prelude.get(&ident.modern()).cloned().and_then(|entry| {
             if let Some(binding) = entry.extern_crate_item {
                 if !speculative && !skip_feature_gate && entry.introduced_by_item &&
@@ -4863,7 +5049,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
                 };
                 let crate_root = self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
                 self.populate_module_if_necessary(&crate_root);
-                Some((crate_root, ty::Visibility::Public, ident.span, Mark::root())
+                Some((crate_root, ty::Visibility::Public, DUMMY_SP, Mark::root())
                     .to_name_binding(self.arenas))
             }
         })
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index db5b516e7b2..921f7568b52 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use {AmbiguityError, CrateLint, Resolver, ResolutionError, is_known_tool, resolve_error};
-use {Module, ModuleKind, NameBinding, NameBindingKind, PathResult, Segment, ToNameBinding};
+use {AmbiguityError, AmbiguityKind, AmbiguityErrorMisc};
+use {CrateLint, Resolver, ResolutionError, Segment, Weak};
+use {Module, ModuleKind, NameBinding, NameBindingKind, PathResult, ToNameBinding};
+use {is_known_tool, resolve_error};
 use ModuleOrUniformRoot;
 use Namespace::{self, *};
 use build_reduced_graph::{BuildReducedGraphVisitor, IsMacroExport};
@@ -53,8 +55,8 @@ pub struct InvocationData<'a> {
     crate parent_legacy_scope: Cell<LegacyScope<'a>>,
     /// Legacy scope *produced* by expanding this macro invocation,
     /// includes all the macro_rules items, other invocations, etc generated by it.
-    /// Set to the parent scope if the macro is not expanded yet (as if the macro produced nothing).
-    crate output_legacy_scope: Cell<LegacyScope<'a>>,
+    /// `None` if the macro is not expanded yet.
+    crate output_legacy_scope: Cell<Option<LegacyScope<'a>>>,
 }
 
 impl<'a> InvocationData<'a> {
@@ -63,7 +65,7 @@ impl<'a> InvocationData<'a> {
             module: Cell::new(graph_root),
             def_index: CRATE_DEF_INDEX,
             parent_legacy_scope: Cell::new(LegacyScope::Empty),
-            output_legacy_scope: Cell::new(LegacyScope::Empty),
+            output_legacy_scope: Cell::new(Some(LegacyScope::Empty)),
         }
     }
 }
@@ -109,7 +111,7 @@ pub struct ParentScope<'a> {
 // Macro namespace is separated into two sub-namespaces, one for bang macros and
 // one for attribute-like macros (attributes, derives).
 // We ignore resolutions from one sub-namespace when searching names in scope for another.
-fn sub_namespace_mismatch(requirement: Option<MacroKind>, candidate: Option<MacroKind>) -> bool {
+fn sub_namespace_match(candidate: Option<MacroKind>, requirement: Option<MacroKind>) -> bool {
     #[derive(PartialEq)]
     enum SubNS { Bang, AttrLike }
     let sub_ns = |kind| match kind {
@@ -120,7 +122,7 @@ fn sub_namespace_mismatch(requirement: Option<MacroKind>, candidate: Option<Macr
     let requirement = requirement.and_then(|kind| sub_ns(kind));
     let candidate = candidate.and_then(|kind| sub_ns(kind));
     // "No specific sub-namespace" means "matches anything" for both requirements and candidates.
-    candidate.is_some() && requirement.is_some() && candidate != requirement
+    candidate.is_none() || requirement.is_none() || candidate == requirement
 }
 
 impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
@@ -135,7 +137,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
             module: Cell::new(module),
             def_index: module.def_id().unwrap().index,
             parent_legacy_scope: Cell::new(LegacyScope::Empty),
-            output_legacy_scope: Cell::new(LegacyScope::Empty),
+            output_legacy_scope: Cell::new(Some(LegacyScope::Empty)),
         }));
         mark
     }
@@ -211,7 +213,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
             expansion: mark,
         };
         fragment.visit_with(&mut visitor);
-        invocation.output_legacy_scope.set(visitor.current_legacy_scope);
+        invocation.output_legacy_scope.set(Some(visitor.current_legacy_scope));
     }
 
     fn add_builtin(&mut self, ident: ast::Ident, ext: Lrc<SyntaxExtension>) {
@@ -225,7 +227,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
         let binding = self.arenas.alloc_name_binding(NameBinding {
             kind: NameBindingKind::Def(Def::Macro(def_id, kind), false),
             span: DUMMY_SP,
-            vis: ty::Visibility::Invisible,
+            vis: ty::Visibility::Public,
             expansion: Mark::root(),
         });
         if self.builtin_macros.insert(ident.name, binding).is_some() {
@@ -325,7 +327,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
         };
 
         let parent_scope = self.invoc_parent_scope(invoc_id, derives_in_scope);
-        let (def, ext) = self.resolve_macro_to_def(path, kind, &parent_scope, force)?;
+        let (def, ext) = self.resolve_macro_to_def(path, kind, &parent_scope, true, force)?;
 
         if let Def::Macro(def_id, _) = def {
             if after_derive {
@@ -348,7 +350,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
                           derives_in_scope: Vec<ast::Path>, force: bool)
                           -> Result<Lrc<SyntaxExtension>, Determinacy> {
         let parent_scope = self.invoc_parent_scope(invoc_id, derives_in_scope);
-        Ok(self.resolve_macro_to_def(path, kind, &parent_scope, force)?.1)
+        Ok(self.resolve_macro_to_def(path, kind, &parent_scope, false, force)?.1)
     }
 
     fn check_unused_macros(&self) {
@@ -370,11 +372,11 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
 }
 
 impl<'a, 'cl> Resolver<'a, 'cl> {
-    pub fn dummy_parent_scope(&mut self) -> ParentScope<'a> {
+    pub fn dummy_parent_scope(&self) -> ParentScope<'a> {
         self.invoc_parent_scope(Mark::root(), Vec::new())
     }
 
-    fn invoc_parent_scope(&mut self, invoc_id: Mark, derives: Vec<ast::Path>) -> ParentScope<'a> {
+    fn invoc_parent_scope(&self, invoc_id: Mark, derives: Vec<ast::Path>) -> ParentScope<'a> {
         let invoc = self.invocations[&invoc_id];
         ParentScope {
             module: invoc.module.get().nearest_item_scope(),
@@ -389,9 +391,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
         path: &ast::Path,
         kind: MacroKind,
         parent_scope: &ParentScope<'a>,
+        trace: bool,
         force: bool,
     ) -> Result<(Def, Lrc<SyntaxExtension>), Determinacy> {
-        let def = self.resolve_macro_to_def_inner(path, kind, parent_scope, force);
+        let def = self.resolve_macro_to_def_inner(path, kind, parent_scope, trace, force);
 
         // Report errors and enforce feature gates for the resolved macro.
         if def != Err(Determinacy::Undetermined) {
@@ -463,6 +466,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
         path: &ast::Path,
         kind: MacroKind,
         parent_scope: &ParentScope<'a>,
+        trace: bool,
         force: bool,
     ) -> Result<Def, Determinacy> {
         let path_span = path.span;
@@ -477,36 +481,28 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
         }
 
         if path.len() > 1 {
-            let def = match self.resolve_path(None, &path, Some(MacroNS), parent_scope,
+            let def = match self.resolve_path(&path, Some(MacroNS), parent_scope,
                                               false, path_span, CrateLint::No) {
-                PathResult::NonModule(path_res) => match path_res.base_def() {
-                    Def::Err => Err(Determinacy::Determined),
-                    def @ _ => {
-                        if path_res.unresolved_segments() > 0 {
-                            self.found_unresolved_macro = true;
-                            self.session.span_err(path_span,
-                                                  "fail to resolve non-ident macro path");
-                            Err(Determinacy::Determined)
-                        } else {
-                            Ok(def)
-                        }
-                    }
-                },
-                PathResult::Module(..) => unreachable!(),
+                PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => {
+                    Ok(path_res.base_def())
+                }
                 PathResult::Indeterminate if !force => return Err(Determinacy::Undetermined),
-                _ => {
+                PathResult::NonModule(..) | PathResult::Indeterminate | PathResult::Failed(..) => {
                     self.found_unresolved_macro = true;
                     Err(Determinacy::Determined)
-                },
+                }
+                PathResult::Module(..) => unreachable!(),
             };
 
-            parent_scope.module.macro_resolutions.borrow_mut()
-                .push((path, parent_scope.clone(), path_span));
+            if trace {
+                parent_scope.module.multi_segment_macro_resolutions.borrow_mut()
+                    .push((path, path_span, kind, parent_scope.clone(), def.ok()));
+            }
 
             def
         } else {
             let binding = self.early_resolve_ident_in_lexical_scope(
-                path[0].ident, MacroNS, Some(kind), parent_scope, false, force, path_span
+                path[0].ident, MacroNS, Some(kind), false, parent_scope, false, force, path_span
             );
             match binding {
                 Ok(..) => {}
@@ -514,8 +510,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
                 Err(Determinacy::Undetermined) => return Err(Determinacy::Undetermined),
             }
 
-            parent_scope.module.legacy_macro_resolutions.borrow_mut()
-                .push((path[0].ident, kind, parent_scope.clone(), binding.ok()));
+            if trace {
+                parent_scope.module.single_segment_macro_resolutions.borrow_mut()
+                    .push((path[0].ident, kind, parent_scope.clone(), binding.ok()));
+            }
 
             binding.map(|binding| binding.def_ignoring_ambiguity())
         }
@@ -525,12 +523,13 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
     // This is a variation of `fn resolve_ident_in_lexical_scope` that can be run during
     // expansion and import resolution (perhaps they can be merged in the future).
     // The function is used for resolving initial segments of macro paths (e.g. `foo` in
-    // `foo::bar!(); or `foo!();`) and can be used for "uniform path" imports in the future.
+    // `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,
-        kind: Option<MacroKind>,
+        macro_kind: Option<MacroKind>,
+        is_import: bool,
         parent_scope: &ParentScope<'a>,
         record_used: bool,
         force: bool,
@@ -596,16 +595,23 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
 
         bitflags! {
             struct Flags: u8 {
-                const DERIVE_HELPERS = 1 << 0;
-                const MACRO_RULES    = 1 << 1;
-                const MODULE         = 1 << 2;
-                const PRELUDE        = 1 << 3;
+                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;
             }
         }
 
         assert!(force || !record_used); // `record_used` implies `force`
+        assert!(macro_kind.is_none() || !is_import); // `is_import` implies no macro kind
         ident = ident.modern();
 
+        // Make sure `self`, `super` etc produce an error when passed to here.
+        if ident.is_path_segment_keyword() {
+            return Err(Determinacy::Determined);
+        }
+
         // This is *the* result, resolution from the scope closest to the resolved identifier.
         // However, sometimes this result is "weak" because it comes from a glob import or
         // a macro expansion, and in this case it cannot shadow names from outer scopes, e.g.
@@ -617,72 +623,103 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
         // }
         // So we have to save the innermost solution and continue searching in outer scopes
         // to detect potential ambiguities.
-        let mut innermost_result: Option<(&NameBinding, Flags, /* conflicts with */ Flags)> = None;
+        let mut innermost_result: Option<(&NameBinding, Flags)> = None;
 
         // Go through all the scopes and try to resolve the name.
-        let mut where_to_resolve = WhereToResolve::DeriveHelpers;
+        let mut where_to_resolve = if ns == MacroNS {
+            WhereToResolve::DeriveHelpers
+        } else {
+            WhereToResolve::Module(parent_scope.module)
+        };
         let mut use_prelude = !parent_scope.module.no_implicit_prelude;
+        let mut determinacy = Determinacy::Determined;
         loop {
             let result = match where_to_resolve {
                 WhereToResolve::DeriveHelpers => {
                     let mut result = Err(Determinacy::Determined);
                     for derive in &parent_scope.derives {
                         let parent_scope = ParentScope { derives: Vec::new(), ..*parent_scope };
-                        if let Ok((_, ext)) = self.resolve_macro_to_def(derive, MacroKind::Derive,
-                                                                        &parent_scope, force) {
-                            if let SyntaxExtension::ProcMacroDerive(_, helper_attrs, _) = &*ext {
-                                if helper_attrs.contains(&ident.name) {
-                                    let binding =
-                                        (Def::NonMacroAttr(NonMacroAttrKind::DeriveHelper),
-                                        ty::Visibility::Public, derive.span, Mark::root())
-                                        .to_name_binding(self.arenas);
-                                    result = Ok((binding, Flags::DERIVE_HELPERS, Flags::all()));
-                                    break;
+                        match self.resolve_macro_to_def(derive, MacroKind::Derive,
+                                                        &parent_scope, true, force) {
+                            Ok((_, ext)) => {
+                                if let SyntaxExtension::ProcMacroDerive(_, helpers, _) = &*ext {
+                                    if helpers.contains(&ident.name) {
+                                        let binding =
+                                            (Def::NonMacroAttr(NonMacroAttrKind::DeriveHelper),
+                                            ty::Visibility::Public, derive.span, Mark::root())
+                                            .to_name_binding(self.arenas);
+                                        result = Ok((binding, Flags::empty()));
+                                        break;
+                                    }
                                 }
                             }
+                            Err(Determinacy::Determined) => {}
+                            Err(Determinacy::Undetermined) =>
+                                result = Err(Determinacy::Undetermined),
                         }
                     }
                     result
                 }
                 WhereToResolve::MacroRules(legacy_scope) => match legacy_scope {
                     LegacyScope::Binding(legacy_binding) if ident == legacy_binding.ident =>
-                        Ok((legacy_binding.binding, Flags::MACRO_RULES, Flags::empty())),
+                        Ok((legacy_binding.binding, Flags::MACRO_RULES)),
+                    LegacyScope::Invocation(invoc) if invoc.output_legacy_scope.get().is_none() =>
+                        Err(Determinacy::Undetermined),
                     _ => 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(
+                    let binding = self.resolve_ident_in_module_unadjusted_ext(
                         ModuleOrUniformRoot::Module(module),
                         ident,
                         ns,
+                        None,
                         true,
                         record_used,
                         path_span,
                     );
                     self.current_module = orig_current_module;
-                    binding.map(|binding| (binding, Flags::MODULE, Flags::empty()))
+                    match binding {
+                        Ok(binding) => {
+                            let misc_flags = if module.is_normal() {
+                                Flags::MISC_SUGGEST_SELF
+                            } else {
+                                Flags::empty()
+                            };
+                            Ok((binding, Flags::MODULE | misc_flags))
+                        }
+                        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::MacroUsePrelude => {
-                    let mut result = Err(Determinacy::Determined);
                     if use_prelude || self.session.rust_2015() {
-                        if let Some(binding) = self.macro_use_prelude.get(&ident.name).cloned() {
-                            result = Ok((binding, Flags::PRELUDE, Flags::empty()));
+                        match self.macro_use_prelude.get(&ident.name).cloned() {
+                            Some(binding) =>
+                                Ok((binding, Flags::PRELUDE | Flags::MISC_FROM_PRELUDE)),
+                            None => Err(Determinacy::determined(
+                                self.graph_root.unresolved_invocations.borrow().is_empty()
+                            ))
                         }
+                    } else {
+                        Err(Determinacy::Determined)
                     }
-                    result
                 }
                 WhereToResolve::BuiltinMacros => {
                     match self.builtin_macros.get(&ident.name).cloned() {
-                        Some(binding) => Ok((binding, Flags::PRELUDE, Flags::empty())),
+                        Some(binding) => Ok((binding, Flags::PRELUDE)),
                         None => Err(Determinacy::Determined),
                     }
                 }
                 WhereToResolve::BuiltinAttrs => {
                     if is_builtin_attr_name(ident.name) {
                         let binding = (Def::NonMacroAttr(NonMacroAttrKind::Builtin),
-                                       ty::Visibility::Public, ident.span, Mark::root())
+                                       ty::Visibility::Public, DUMMY_SP, Mark::root())
                                        .to_name_binding(self.arenas);
-                        Ok((binding, Flags::PRELUDE, Flags::empty()))
+                        Ok((binding, Flags::PRELUDE))
                     } else {
                         Err(Determinacy::Determined)
                     }
@@ -692,28 +729,31 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
                        self.session.plugin_attributes.borrow().iter()
                                                      .any(|(name, _)| ident.name == &**name) {
                         let binding = (Def::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper),
-                                       ty::Visibility::Public, ident.span, Mark::root())
+                                       ty::Visibility::Public, DUMMY_SP, Mark::root())
                                        .to_name_binding(self.arenas);
-                        Ok((binding, Flags::PRELUDE, Flags::PRELUDE))
+                        Ok((binding, Flags::PRELUDE))
                     } else {
                         Err(Determinacy::Determined)
                     }
                 }
                 WhereToResolve::ExternPrelude => {
-                    let mut result = Err(Determinacy::Determined);
                     if use_prelude {
-                        if let Some(binding) = self.extern_prelude_get(ident, !record_used,
-                                                                       innermost_result.is_some()) {
-                            result = Ok((binding, Flags::PRELUDE, Flags::empty()));
+                        match self.extern_prelude_get(ident, !record_used,
+                                                      innermost_result.is_some()) {
+                            Some(binding) => Ok((binding, Flags::PRELUDE)),
+                            None => Err(Determinacy::determined(
+                                self.graph_root.unresolved_invocations.borrow().is_empty()
+                            )),
                         }
+                    } else {
+                        Err(Determinacy::Determined)
                     }
-                    result
                 }
                 WhereToResolve::ToolPrelude => {
                     if use_prelude && is_known_tool(ident.name) {
                         let binding = (Def::ToolMod, ty::Visibility::Public,
-                                       ident.span, Mark::root()).to_name_binding(self.arenas);
-                        Ok((binding, Flags::PRELUDE, Flags::empty()))
+                                       DUMMY_SP, Mark::root()).to_name_binding(self.arenas);
+                        Ok((binding, Flags::PRELUDE))
                     } else {
                         Err(Determinacy::Determined)
                     }
@@ -727,10 +767,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
                                 ident,
                                 ns,
                                 false,
-                                false,
                                 path_span,
                             ) {
-                                result = Ok((binding, Flags::PRELUDE, Flags::empty()));
+                                result = Ok((binding, Flags::PRELUDE | Flags::MISC_FROM_PRELUDE));
                             }
                         }
                     }
@@ -740,105 +779,157 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
                     match self.primitive_type_table.primitive_types.get(&ident.name).cloned() {
                         Some(prim_ty) => {
                             let binding = (Def::PrimTy(prim_ty), ty::Visibility::Public,
-                                           ident.span, Mark::root()).to_name_binding(self.arenas);
-                            Ok((binding, Flags::PRELUDE, Flags::empty()))
+                                           DUMMY_SP, Mark::root()).to_name_binding(self.arenas);
+                            Ok((binding, Flags::PRELUDE))
                         }
                         None => Err(Determinacy::Determined)
                     }
                 }
             };
 
-            macro_rules! continue_search { () => {
-                where_to_resolve = match where_to_resolve {
-                    WhereToResolve::DeriveHelpers =>
-                        WhereToResolve::MacroRules(parent_scope.legacy),
-                    WhereToResolve::MacroRules(legacy_scope) => match legacy_scope {
-                        LegacyScope::Binding(binding) =>
-                            WhereToResolve::MacroRules(binding.parent_legacy_scope),
-                        LegacyScope::Invocation(invocation) =>
-                            WhereToResolve::MacroRules(invocation.output_legacy_scope.get()),
-                        LegacyScope::Empty => WhereToResolve::Module(parent_scope.module),
-                        LegacyScope::Uninitialized => unreachable!(),
-                    }
-                    WhereToResolve::Module(module) => {
-                        match self.hygienic_lexical_parent(module, &mut ident.span) {
-                            Some(parent_module) => WhereToResolve::Module(parent_module),
-                            None => {
-                                use_prelude = !module.no_implicit_prelude;
-                                match ns {
-                                    TypeNS => WhereToResolve::ExternPrelude,
-                                    ValueNS => WhereToResolve::StdLibPrelude,
-                                    MacroNS => WhereToResolve::MacroUsePrelude,
-                                }
-                            }
-                        }
-                    }
-                    WhereToResolve::MacroUsePrelude => WhereToResolve::BuiltinMacros,
-                    WhereToResolve::BuiltinMacros => WhereToResolve::BuiltinAttrs,
-                    WhereToResolve::BuiltinAttrs => WhereToResolve::LegacyPluginHelpers,
-                    WhereToResolve::LegacyPluginHelpers => break, // nowhere else to search
-                    WhereToResolve::ExternPrelude => WhereToResolve::ToolPrelude,
-                    WhereToResolve::ToolPrelude => WhereToResolve::StdLibPrelude,
-                    WhereToResolve::StdLibPrelude => match ns {
-                        TypeNS => WhereToResolve::BuiltinTypes,
-                        ValueNS => break, // nowhere else to search
-                        MacroNS => unreachable!(),
-                    }
-                    WhereToResolve::BuiltinTypes => break, // nowhere else to search
-                };
-
-                continue;
-            }}
-
             match result {
-                Ok((binding, flags, ambig_flags)) => {
-                    if sub_namespace_mismatch(kind, binding.macro_kind()) {
-                        continue_search!();
-                    }
-
+                Ok((binding, flags)) if sub_namespace_match(binding.macro_kind(), macro_kind) => {
                     if !record_used {
                         return Ok(binding);
                     }
 
-                    if let Some((innermost_binding, innermost_flags, innermost_ambig_flags))
-                            = innermost_result {
+                    if let Some((innermost_binding, innermost_flags)) = innermost_result {
                         // Found another solution, if the first one was "weak", report an error.
-                        if binding.def() != innermost_binding.def() &&
-                           (innermost_binding.is_glob_import() ||
-                            innermost_binding.may_appear_after(parent_scope.expansion, binding) ||
-                            innermost_flags.intersects(ambig_flags) ||
-                            flags.intersects(innermost_ambig_flags) ||
-                            (innermost_flags.contains(Flags::MACRO_RULES) &&
-                             flags.contains(Flags::MODULE) &&
-                             !self.disambiguate_legacy_vs_modern(innermost_binding, binding))) {
-                            self.ambiguity_errors.push(AmbiguityError {
-                                ident,
-                                b1: innermost_binding,
-                                b2: binding,
-                            });
-                            return Ok(innermost_binding);
+                        let (def, innermost_def) = (binding.def(), innermost_binding.def());
+                        if def != innermost_def {
+                            let builtin = Def::NonMacroAttr(NonMacroAttrKind::Builtin);
+                            let derive_helper = Def::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
+                            let legacy_helper =
+                                Def::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper);
+
+                            let ambiguity_error_kind = if is_import {
+                                Some(AmbiguityKind::Import)
+                            } else if innermost_def == builtin || def == builtin {
+                                Some(AmbiguityKind::BuiltinAttr)
+                            } else if innermost_def == derive_helper || def == derive_helper {
+                                Some(AmbiguityKind::DeriveHelper)
+                            } else if innermost_def == legacy_helper &&
+                                      flags.contains(Flags::PRELUDE) ||
+                                      def == legacy_helper &&
+                                      innermost_flags.contains(Flags::PRELUDE) {
+                                Some(AmbiguityKind::LegacyHelperVsPrelude)
+                            } else if innermost_flags.contains(Flags::MACRO_RULES) &&
+                                      flags.contains(Flags::MODULE) &&
+                                      !self.disambiguate_legacy_vs_modern(innermost_binding,
+                                                                          binding) {
+                                Some(AmbiguityKind::LegacyVsModern)
+                            } else if innermost_binding.is_glob_import() {
+                                Some(AmbiguityKind::GlobVsOuter)
+                            } else if innermost_binding.may_appear_after(parent_scope.expansion,
+                                                                         binding) {
+                                Some(AmbiguityKind::MoreExpandedVsOuter)
+                            } else {
+                                None
+                            };
+                            if let Some(kind) = ambiguity_error_kind {
+                                let misc = |f: Flags| if f.contains(Flags::MISC_SUGGEST_SELF) {
+                                    AmbiguityErrorMisc::SuggestSelf
+                                } else if f.contains(Flags::MISC_FROM_PRELUDE) {
+                                    AmbiguityErrorMisc::FromPrelude
+                                } else {
+                                    AmbiguityErrorMisc::None
+                                };
+                                self.ambiguity_errors.push(AmbiguityError {
+                                    kind,
+                                    ident,
+                                    b1: innermost_binding,
+                                    b2: binding,
+                                    misc1: misc(innermost_flags),
+                                    misc2: misc(flags),
+                                });
+                                return Ok(innermost_binding);
+                            }
                         }
                     } else {
                         // Found the first solution.
-                        innermost_result = Some((binding, flags, ambig_flags));
+                        innermost_result = Some((binding, flags));
                     }
-
-                    continue_search!();
-                },
-                Err(Determinacy::Determined) => {
-                    continue_search!();
                 }
-                Err(Determinacy::Undetermined) => return Err(Determinacy::determined(force)),
+                Ok(..) | Err(Determinacy::Determined) => {}
+                Err(Determinacy::Undetermined) => determinacy = Determinacy::Undetermined
             }
+
+            where_to_resolve = match where_to_resolve {
+                WhereToResolve::DeriveHelpers =>
+                    WhereToResolve::MacroRules(parent_scope.legacy),
+                WhereToResolve::MacroRules(legacy_scope) => match legacy_scope {
+                    LegacyScope::Binding(binding) => WhereToResolve::MacroRules(
+                        binding.parent_legacy_scope
+                    ),
+                    LegacyScope::Invocation(invoc) => WhereToResolve::MacroRules(
+                        invoc.output_legacy_scope.get().unwrap_or(invoc.parent_legacy_scope.get())
+                    ),
+                    LegacyScope::Empty => WhereToResolve::Module(parent_scope.module),
+                    LegacyScope::Uninitialized => unreachable!(),
+                }
+                WhereToResolve::Module(module) => {
+                    match self.hygienic_lexical_parent(module, &mut ident.span) {
+                        Some(parent_module) => WhereToResolve::Module(parent_module),
+                        None => {
+                            use_prelude = !module.no_implicit_prelude;
+                            match ns {
+                                TypeNS => WhereToResolve::ExternPrelude,
+                                ValueNS => WhereToResolve::StdLibPrelude,
+                                MacroNS => WhereToResolve::MacroUsePrelude,
+                            }
+                        }
+                    }
+                }
+                WhereToResolve::MacroUsePrelude => WhereToResolve::BuiltinMacros,
+                WhereToResolve::BuiltinMacros => WhereToResolve::BuiltinAttrs,
+                WhereToResolve::BuiltinAttrs => WhereToResolve::LegacyPluginHelpers,
+                WhereToResolve::LegacyPluginHelpers => break, // nowhere else to search
+                WhereToResolve::ExternPrelude => WhereToResolve::ToolPrelude,
+                WhereToResolve::ToolPrelude => WhereToResolve::StdLibPrelude,
+                WhereToResolve::StdLibPrelude => match ns {
+                    TypeNS => WhereToResolve::BuiltinTypes,
+                    ValueNS => break, // nowhere else to search
+                    MacroNS => unreachable!(),
+                }
+                WhereToResolve::BuiltinTypes => break, // nowhere else to search
+            };
+
+            continue;
         }
 
         // The first found solution was the only one, return it.
-        if let Some((binding, ..)) = innermost_result {
+        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, false).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(&note_msg);
+                    } else {
+                        err.span_note(binding.span, &note_msg);
+                        err.span_label(binding.span, "not an extern crate passed with `--extern`");
+                    }
+                    err.emit();
+                }
+            }
+
             return Ok(binding);
         }
 
-        let determinacy = Determinacy::determined(force);
-        if determinacy == Determinacy::Determined && kind == Some(MacroKind::Attr) {
+        let determinacy = Determinacy::determined(determinacy == Determinacy::Determined || force);
+        if determinacy == Determinacy::Determined && macro_kind == Some(MacroKind::Attr) {
             // For single-segment attributes interpret determinate "no resolution" as a custom
             // attribute. (Lexical resolution implies the first segment and attr kind should imply
             // the last segment, so we are certainly working with a single-segment attribute here.)
@@ -855,50 +946,69 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
     pub fn finalize_current_module_macro_resolutions(&mut self) {
         let module = self.current_module;
 
+        let check_consistency = |this: &mut Self, path: &[Segment], span,
+                                 kind: MacroKind, initial_def, def| {
+            if let Some(initial_def) = initial_def {
+                if def != initial_def && def != Def::Err && this.ambiguity_errors.is_empty() {
+                    // Make sure compilation does not succeed if preferred macro resolution
+                    // has changed after the macro had been expanded. In theory all such
+                    // situations should be reported as ambiguity errors, so this is a bug.
+                    span_bug!(span, "inconsistent resolution for a macro");
+                }
+            } else {
+                // It's possible that the macro was unresolved (indeterminate) and silently
+                // expanded into a dummy fragment for recovery during expansion.
+                // Now, post-expansion, the resolution may succeed, but we can't change the
+                // past and need to report an error.
+                // However, non-speculative `resolve_path` can successfully return private items
+                // even if speculative `resolve_path` returned nothing previously, so we skip this
+                // less informative error if the privacy error is reported elsewhere.
+                if this.privacy_errors.is_empty() {
+                    let msg = format!("cannot determine resolution for the {} `{}`",
+                                        kind.descr(), Segment::names_to_string(path));
+                    let msg_note = "import resolution is stuck, try simplifying macro imports";
+                    this.session.struct_span_err(span, &msg).note(msg_note).emit();
+                }
+            }
+        };
+
         let macro_resolutions =
-            mem::replace(&mut *module.macro_resolutions.borrow_mut(), Vec::new());
-        for (mut path, parent_scope, path_span) in macro_resolutions {
+            mem::replace(&mut *module.multi_segment_macro_resolutions.borrow_mut(), Vec::new());
+        for (mut path, path_span, kind, parent_scope, initial_def) in macro_resolutions {
             // FIXME: Path resolution will ICE if segment IDs present.
             for seg in &mut path { seg.id = None; }
-            match self.resolve_path(None, &path, Some(MacroNS), &parent_scope,
+            match self.resolve_path(&path, Some(MacroNS), &parent_scope,
                                     true, path_span, CrateLint::No) {
-                PathResult::NonModule(_) => {},
-                PathResult::Failed(span, msg, _) => {
+                PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => {
+                    let def = path_res.base_def();
+                    check_consistency(self, &path, path_span, kind, initial_def, def);
+                }
+                path_res @ PathResult::NonModule(..) | path_res @  PathResult::Failed(..) => {
+                    let (span, msg) = if let PathResult::Failed(span, msg, ..) = path_res {
+                        (span, msg)
+                    } else {
+                        (path_span, format!("partially resolved path in {} {}",
+                                            kind.article(), kind.descr()))
+                    };
                     resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
                 }
-                _ => unreachable!(),
+                PathResult::Module(..) | PathResult::Indeterminate => unreachable!(),
             }
         }
 
-        let legacy_macro_resolutions =
-            mem::replace(&mut *module.legacy_macro_resolutions.borrow_mut(), Vec::new());
-        for (ident, kind, parent_scope, initial_binding) in legacy_macro_resolutions {
-            let binding = self.early_resolve_ident_in_lexical_scope(
-                ident, MacroNS, Some(kind), &parent_scope, true, true, ident.span
-            );
-            match binding {
+        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,
+                                                            &parent_scope, true, true, ident.span) {
                 Ok(binding) => {
+                    let initial_def = initial_binding.map(|initial_binding| {
+                        self.record_use(ident, MacroNS, initial_binding, false);
+                        initial_binding.def_ignoring_ambiguity()
+                    });
                     let def = binding.def_ignoring_ambiguity();
-                    if let Some(initial_binding) = initial_binding {
-                        self.record_use(ident, MacroNS, initial_binding);
-                        let initial_def = initial_binding.def_ignoring_ambiguity();
-                        if self.ambiguity_errors.is_empty() &&
-                           def != initial_def && def != Def::Err {
-                            // Make sure compilation does not succeed if preferred macro resolution
-                            // has changed after the macro had been expanded. In theory all such
-                            // situations should be reported as ambiguity errors, so this is a bug.
-                            span_bug!(ident.span, "inconsistent resolution for a macro");
-                        }
-                    } else {
-                        // It's possible that the macro was unresolved (indeterminate) and silently
-                        // expanded into a dummy fragment for recovery during expansion.
-                        // Now, post-expansion, the resolution may succeed, but we can't change the
-                        // past and need to report an error.
-                        let msg = format!("cannot determine resolution for the {} `{}`",
-                                          kind.descr(), ident);
-                        let msg_note = "import resolution is stuck, try simplifying macro imports";
-                        self.session.struct_span_err(ident.span, &msg).note(msg_note).emit();
-                    }
+                    let seg = Segment::from_ident(ident);
+                    check_consistency(self, &[seg], ident.span, kind, initial_def, def);
                 }
                 Err(..) => {
                     assert!(initial_binding.is_none());
@@ -914,18 +1024,9 @@ 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 binding = self.early_resolve_ident_in_lexical_scope(
-                ident, MacroNS, Some(MacroKind::Attr), &parent_scope, true, true, ident.span
+            let _ = self.early_resolve_ident_in_lexical_scope(
+                ident, MacroNS, Some(MacroKind::Attr), false, &parent_scope, true, true, ident.span
             );
-            if let Ok(binding) = binding {
-                if binding.def_ignoring_ambiguity() !=
-                        Def::NonMacroAttr(NonMacroAttrKind::Builtin) {
-                    let builtin_binding = (Def::NonMacroAttr(NonMacroAttrKind::Builtin),
-                                           ty::Visibility::Public, ident.span, Mark::root())
-                                           .to_name_binding(self.arenas);
-                    self.report_ambiguity_error(ident, binding, builtin_binding);
-                }
-            }
         }
     }
 
@@ -992,7 +1093,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
                     def_index: invoc.def_index,
                     module: Cell::new(graph_root),
                     parent_legacy_scope: Cell::new(LegacyScope::Uninitialized),
-                    output_legacy_scope: Cell::new(LegacyScope::Uninitialized),
+                    output_legacy_scope: Cell::new(None),
                 })
             });
         };
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index 5a91b50f6bc..9e5036b6e50 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -10,7 +10,8 @@
 
 use self::ImportDirectiveSubclass::*;
 
-use {AmbiguityError, CrateLint, Module, ModuleOrUniformRoot, PerNS};
+use {AmbiguityError, AmbiguityKind, AmbiguityErrorMisc};
+use {CrateLint, Module, ModuleOrUniformRoot, PerNS, UniformRootKind, Weak};
 use Namespace::{self, TypeNS, MacroNS};
 use {NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError};
 use {Resolver, Segment};
@@ -22,7 +23,7 @@ use rustc_data_structures::ptr_key::PtrKey;
 use rustc::ty;
 use rustc::lint::builtin::BuiltinLintDiagnostics;
 use rustc::lint::builtin::{DUPLICATE_MACRO_EXPORTS, PUB_USE_OF_PRIVATE_EXTERN_CRATE};
-use rustc::hir::def_id::DefId;
+use rustc::hir::def_id::{CrateNum, DefId};
 use rustc::hir::def::*;
 use rustc::session::DiagnosticMessageId;
 use rustc::util::nodemap::FxHashSet;
@@ -35,7 +36,6 @@ use syntax::util::lev_distance::find_best_match_for_name;
 use syntax_pos::{MultiSpan, Span};
 
 use std::cell::{Cell, RefCell};
-use std::collections::BTreeMap;
 use std::{mem, ptr};
 
 /// Contains data for specific types of import directives.
@@ -61,7 +61,7 @@ pub enum ImportDirectiveSubclass<'a> {
 
 /// One import directive.
 #[derive(Debug,Clone)]
-pub struct ImportDirective<'a> {
+crate struct ImportDirective<'a> {
     /// The id of the `extern crate`, `UseTree` etc that imported this `ImportDirective`.
     ///
     /// In the case where the `ImportDirective` was expanded from a "nested" use tree,
@@ -95,13 +95,6 @@ pub struct ImportDirective<'a> {
     pub subclass: ImportDirectiveSubclass<'a>,
     pub vis: Cell<ty::Visibility>,
     pub used: Cell<bool>,
-
-    /// Whether this import is a "canary" for the `uniform_paths` feature,
-    /// i.e. `use x::...;` results in an `use self::x as _;` canary.
-    /// This flag affects diagnostics: an error is reported if and only if
-    /// the import resolves successfully and an external crate with the same
-    /// name (`x` above) also exists; any resolution failures are ignored.
-    pub is_uniform_paths_canary: bool,
 }
 
 impl<'a> ImportDirective<'a> {
@@ -142,102 +135,73 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
                .or_insert_with(|| self.arenas.alloc_name_resolution())
     }
 
+    crate fn resolve_ident_in_module_unadjusted(
+        &mut self,
+        module: ModuleOrUniformRoot<'a>,
+        ident: Ident,
+        ns: Namespace,
+        record_used: bool,
+        path_span: Span,
+    ) -> Result<&'a NameBinding<'a>, Determinacy> {
+        self.resolve_ident_in_module_unadjusted_ext(
+            module, ident, ns, None, false, record_used, path_span
+        ).map_err(|(determinacy, _)| determinacy)
+    }
+
     /// Attempts to resolve `ident` in namespaces `ns` of `module`.
     /// Invariant: if `record_used` is `Some`, expansion and import resolution must be complete.
-    pub fn resolve_ident_in_module_unadjusted(&mut self,
-                                              module: ModuleOrUniformRoot<'a>,
-                                              ident: Ident,
-                                              ns: Namespace,
-                                              restricted_shadowing: bool,
-                                              record_used: bool,
-                                              path_span: Span)
-                                              -> Result<&'a NameBinding<'a>, Determinacy> {
+    crate fn resolve_ident_in_module_unadjusted_ext(
+        &mut self,
+        module: ModuleOrUniformRoot<'a>,
+        ident: Ident,
+        ns: Namespace,
+        parent_scope: Option<&ParentScope<'a>>,
+        restricted_shadowing: bool,
+        record_used: bool,
+        path_span: Span,
+    ) -> Result<&'a NameBinding<'a>, (Determinacy, Weak)> {
         let module = match module {
             ModuleOrUniformRoot::Module(module) => module,
-            ModuleOrUniformRoot::UniformRoot(root) => {
-                // HACK(eddyb): `resolve_path` uses `keywords::Invalid` to indicate
-                // paths of length 0, and currently these are relative `use` paths.
-                let can_be_relative = !ident.is_path_segment_keyword() &&
-                    root == keywords::Invalid.name();
-                if can_be_relative {
-                    // Relative paths should only get here if the feature-gate is on.
-                    assert!(self.session.rust_2018() &&
-                            self.session.features_untracked().uniform_paths);
-
-                    // Try first to resolve relatively.
-                    let mut ctxt = ident.span.ctxt().modern();
-                    let self_module = self.resolve_self(&mut ctxt, self.current_module);
-
-                    let binding = self.resolve_ident_in_module_unadjusted(
-                        ModuleOrUniformRoot::Module(self_module),
-                        ident,
-                        ns,
-                        restricted_shadowing,
-                        record_used,
-                        path_span,
-                    );
-
-                    // FIXME(eddyb) This may give false negatives, specifically
-                    // if a crate with the same name is found in `extern_prelude`,
-                    // preventing the check below this one from returning `binding`
-                    // in all cases.
-                    //
-                    // That is, if there's no crate with the same name, `binding`
-                    // is always returned, which is the result of doing the exact
-                    // same lookup of `ident`, in the `self` module.
-                    // But when a crate does exist, it will get chosen even when
-                    // macro expansion could result in a success from the lookup
-                    // in the `self` module, later on.
-                    //
-                    // NB. This is currently alleviated by the "ambiguity canaries"
-                    // (see `is_uniform_paths_canary`) that get introduced for the
-                    // maybe-relative imports handled here: if the false negative
-                    // case were to arise, it would *also* cause an ambiguity error.
-                    if binding.is_ok() {
-                        return binding;
+            ModuleOrUniformRoot::UniformRoot(uniform_root_kind) => {
+                assert!(!restricted_shadowing);
+                match uniform_root_kind {
+                    UniformRootKind::ExternPrelude => {
+                        return if let Some(binding) =
+                                self.extern_prelude_get(ident, !record_used, false) {
+                            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_...`.
+                            }
+                        }
 
-                    // Fall back to resolving to an external crate.
-                    if !(
-                        ns == TypeNS &&
-                        !ident.is_path_segment_keyword() &&
-                        self.extern_prelude.contains_key(&ident.modern())
-                    ) {
-                        // ... unless the crate name is not in the `extern_prelude`.
-                        return binding;
+                        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 crate_root = if
-                    ns == TypeNS &&
-                    root != keywords::Extern.name() &&
-                    (
-                        ident.name == keywords::Crate.name() ||
-                        ident.name == keywords::DollarCrate.name()
-                    )
-                {
-                    self.resolve_crate_root(ident)
-                } else if
-                    ns == TypeNS &&
-                    !ident.is_path_segment_keyword()
-                {
-                    if let Some(binding) = self.extern_prelude_get(ident, !record_used, false) {
-                        let module = self.get_module(binding.def().def_id());
-                        self.populate_module_if_necessary(module);
-                        return Ok(binding);
-                    } else if !self.graph_root.unresolved_invocations.borrow().is_empty() {
-                        // Macro-expanded `extern crate`items still can add names to extern prelude.
-                        return Err(Undetermined);
-                    } else {
-                        return Err(Determined);
-                    }
-                } else {
-                    return Err(Determined);
-                };
-                self.populate_module_if_necessary(crate_root);
-                let binding = (crate_root, ty::Visibility::Public,
-                               ident.span, Mark::root()).to_name_binding(self.arenas);
-                return Ok(binding);
             }
         };
 
@@ -245,7 +209,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
 
         let resolution = self.resolution(module, ident, ns)
             .try_borrow_mut()
-            .map_err(|_| Determined)?; // This happens when there is a cycle of imports
+            .map_err(|_| (Determined, Weak::No))?; // This happens when there is a cycle of imports.
 
         if let Some(binding) = resolution.binding {
             if !restricted_shadowing && binding.expansion != Mark::root() {
@@ -255,37 +219,46 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
             }
         }
 
+        let check_usable = |this: &mut Self, binding: &'a NameBinding<'a>| {
+            // `extern crate` are always usable for backwards compatibility, see issue #37020,
+            // remove this together with `PUB_USE_OF_PRIVATE_EXTERN_CRATE`.
+            let usable = this.is_accessible(binding.vis) || binding.is_extern_crate();
+            if usable { Ok(binding) } else { Err((Determined, Weak::No)) }
+        };
+
         if record_used {
-            if let Some(binding) = resolution.binding {
-                if let Some(shadowed_glob) = resolution.shadowed_glob {
-                    // Forbid expanded shadowing to avoid time travel.
-                    if restricted_shadowing &&
-                       binding.expansion != Mark::root() &&
-                       ns != MacroNS && // In MacroNS, `try_define` always forbids this shadowing
-                       binding.def() != shadowed_glob.def() {
-                        self.ambiguity_errors.push(AmbiguityError {
-                            ident,
-                            b1: binding,
-                            b2: shadowed_glob,
-                        });
+            return resolution.binding.ok_or((Determined, Weak::No)).and_then(|binding| {
+                if self.last_import_segment && check_usable(self, binding).is_err() {
+                    Err((Determined, Weak::No))
+                } else {
+                    self.record_use(ident, ns, binding, restricted_shadowing);
+
+                    if let Some(shadowed_glob) = resolution.shadowed_glob {
+                        // Forbid expanded shadowing to avoid time travel.
+                        if restricted_shadowing &&
+                        binding.expansion != Mark::root() &&
+                        binding.def() != shadowed_glob.def() {
+                            self.ambiguity_errors.push(AmbiguityError {
+                                kind: AmbiguityKind::GlobVsExpanded,
+                                ident,
+                                b1: binding,
+                                b2: shadowed_glob,
+                                misc1: AmbiguityErrorMisc::None,
+                                misc2: AmbiguityErrorMisc::None,
+                            });
+                        }
                     }
-                }
-                if self.record_use(ident, ns, binding) {
-                    return Ok(self.dummy_binding);
-                }
-                if !self.is_accessible(binding.vis) {
-                    self.privacy_errors.push(PrivacyError(path_span, ident, binding));
-                }
-            }
 
-            return resolution.binding.ok_or(Determined);
-        }
+                    if !self.is_accessible(binding.vis) &&
+                       // Remove this together with `PUB_USE_OF_PRIVATE_EXTERN_CRATE`
+                       !(self.last_import_segment && binding.is_extern_crate()) {
+                        self.privacy_errors.push(PrivacyError(path_span, ident, binding));
+                    }
 
-        let check_usable = |this: &mut Self, binding: &'a NameBinding<'a>| {
-            // `extern crate` are always usable for backwards compatibility, see issue #37020.
-            let usable = this.is_accessible(binding.vis) || binding.is_extern_crate();
-            if usable { Ok(binding) } else { Err(Determined) }
-        };
+                    Ok(binding)
+                }
+            })
+        }
 
         // Items and single imports are not shadowable, if we have one, then it's determined.
         if let Some(binding) = resolution.binding {
@@ -302,17 +275,19 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
             if !self.is_accessible(single_import.vis.get()) {
                 continue;
             }
-            let module = unwrap_or!(single_import.imported_module.get(), return Err(Undetermined));
+            let module = unwrap_or!(single_import.imported_module.get(),
+                                    return Err((Undetermined, Weak::No)));
             let ident = match single_import.subclass {
                 SingleImport { source, .. } => source,
                 _ => unreachable!(),
             };
-            match self.resolve_ident_in_module(module, ident, ns, false, path_span) {
+            match self.resolve_ident_in_module(module, ident, ns, Some(&single_import.parent_scope),
+                                               false, path_span) {
                 Err(Determined) => continue,
                 Ok(binding) if !self.is_accessible_from(
                     binding.vis, single_import.parent_scope.module
                 ) => continue,
-                Ok(_) | Err(Undetermined) => return Err(Undetermined),
+                Ok(_) | Err(Undetermined) => return Err((Undetermined, Weak::No)),
             }
         }
 
@@ -333,7 +308,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
             if !unexpanded_macros || ns == MacroNS || restricted_shadowing {
                 return check_usable(self, binding);
             } else {
-                return Err(Undetermined);
+                return Err((Undetermined, Weak::No));
             }
         }
 
@@ -342,17 +317,13 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
         // Now we are in situation when new item/import can appear only from a glob or a macro
         // expansion. With restricted shadowing names from globs and macro expansions cannot
         // shadow names from outer scopes, so we can freely fallback from module search to search
-        // in outer scopes. To continue search in outer scopes we have to lie a bit and return
-        // `Determined` to `early_resolve_ident_in_lexical_scope` even if the correct answer
-        // for in-module resolution could be `Undetermined`.
-        if restricted_shadowing {
-            return Err(Determined);
-        }
+        // in outer scopes. For `early_resolve_ident_in_lexical_scope` to continue search in outer
+        // scopes we return `Undetermined` with `Weak::Yes`.
 
         // Check if one of unexpanded macros can still define the name,
         // if it can then our "no resolution" result is not determined and can be invalidated.
         if unexpanded_macros {
-            return Err(Undetermined);
+            return Err((Undetermined, Weak::Yes));
         }
 
         // Check if one of glob imports can still define the name,
@@ -364,7 +335,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
             let module = match glob_import.imported_module.get() {
                 Some(ModuleOrUniformRoot::Module(module)) => module,
                 Some(ModuleOrUniformRoot::UniformRoot(_)) => continue,
-                None => return Err(Undetermined),
+                None => return Err((Undetermined, Weak::Yes)),
             };
             let (orig_current_module, mut ident) = (self.current_module, ident.modern());
             match ident.span.glob_adjust(module.expansion, glob_import.span.ctxt().modern()) {
@@ -377,7 +348,6 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
                 ident,
                 ns,
                 false,
-                false,
                 path_span,
             );
             self.current_module = orig_current_module;
@@ -387,12 +357,12 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
                 Ok(binding) if !self.is_accessible_from(
                     binding.vis, glob_import.parent_scope.module
                 ) => continue,
-                Ok(_) | Err(Undetermined) => return Err(Undetermined),
+                Ok(_) | Err(Undetermined) => return Err((Undetermined, Weak::Yes)),
             }
         }
 
         // No resolution and no one else can define the name - determinate error.
-        Err(Determined)
+        Err((Determined, Weak::No))
     }
 
     // Add an import directive to the current module.
@@ -404,8 +374,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
                                 root_span: Span,
                                 root_id: NodeId,
                                 vis: ty::Visibility,
-                                parent_scope: ParentScope<'a>,
-                                is_uniform_paths_canary: bool) {
+                                parent_scope: ParentScope<'a>) {
         let current_module = parent_scope.module;
         let directive = self.arenas.alloc_import_directive(ImportDirective {
             parent_scope,
@@ -418,7 +387,6 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
             root_id,
             vis: Cell::new(vis),
             used: Cell::new(false),
-            is_uniform_paths_canary,
         });
 
         debug!("add_import_directive({:?})", directive);
@@ -441,8 +409,8 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
 
     // Given a binding and an import directive that resolves to it,
     // return the corresponding binding defined by the import directive.
-    pub fn import(&self, binding: &'a NameBinding<'a>, directive: &'a ImportDirective<'a>)
-                  -> &'a NameBinding<'a> {
+    crate fn import(&self, binding: &'a NameBinding<'a>, directive: &'a ImportDirective<'a>)
+                    -> &'a NameBinding<'a> {
         let vis = if binding.pseudo_vis().is_at_least(directive.vis.get(), self) ||
                      // c.f. `PUB_USE_OF_PRIVATE_EXTERN_CRATE`
                      !directive.is_glob() && binding.is_extern_crate() {
@@ -490,38 +458,48 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
         self.set_binding_parent_module(binding, module);
         self.update_resolution(module, ident, ns, |this, resolution| {
             if let Some(old_binding) = resolution.binding {
-                if binding.is_glob_import() {
-                    if !old_binding.is_glob_import() &&
-                       !(ns == MacroNS && old_binding.expansion != Mark::root()) {
-                        resolution.shadowed_glob = Some(binding);
-                    } else if binding.def() != old_binding.def() {
-                        resolution.binding = Some(this.ambiguity(old_binding, binding));
-                    } else if !old_binding.vis.is_at_least(binding.vis, &*this) {
-                        // We are glob-importing the same item but with greater visibility.
-                        resolution.binding = Some(binding);
+                match (old_binding.is_glob_import(), binding.is_glob_import()) {
+                    (true, true) => {
+                        if binding.def() != old_binding.def() {
+                            resolution.binding = Some(this.ambiguity(AmbiguityKind::GlobVsGlob,
+                                                                     old_binding, binding));
+                        } else if !old_binding.vis.is_at_least(binding.vis, &*this) {
+                            // We are glob-importing the same item but with greater visibility.
+                            resolution.binding = Some(binding);
+                        }
                     }
-                } else if old_binding.is_glob_import() {
-                    if ns == MacroNS && binding.expansion != Mark::root() &&
-                       binding.def() != old_binding.def() {
-                        resolution.binding = Some(this.ambiguity(binding, old_binding));
-                    } else {
-                        resolution.binding = Some(binding);
-                        resolution.shadowed_glob = Some(old_binding);
+                    (old_glob @ true, false) | (old_glob @ false, true) => {
+                        let (glob_binding, nonglob_binding) = if old_glob {
+                            (old_binding, binding)
+                        } else {
+                            (binding, old_binding)
+                        };
+                        if glob_binding.def() != nonglob_binding.def() &&
+                           ns == MacroNS && nonglob_binding.expansion != Mark::root() {
+                            resolution.binding = Some(this.ambiguity(AmbiguityKind::GlobVsExpanded,
+                                                                    nonglob_binding, glob_binding));
+                        } else {
+                            resolution.binding = Some(nonglob_binding);
+                            resolution.shadowed_glob = Some(glob_binding);
+                        }
+                    }
+                    (false, false) => {
+                        if let (&NameBindingKind::Def(_, true), &NameBindingKind::Def(_, true)) =
+                               (&old_binding.kind, &binding.kind) {
+
+                            this.session.buffer_lint_with_diagnostic(
+                                DUPLICATE_MACRO_EXPORTS,
+                                CRATE_NODE_ID,
+                                binding.span,
+                                &format!("a macro named `{}` has already been exported", ident),
+                                BuiltinLintDiagnostics::DuplicatedMacroExports(
+                                    ident, old_binding.span, binding.span));
+
+                            resolution.binding = Some(binding);
+                        } else {
+                            return Err(old_binding);
+                        }
                     }
-                } else if let (&NameBindingKind::Def(_, true), &NameBindingKind::Def(_, true)) =
-                        (&old_binding.kind, &binding.kind) {
-
-                    this.session.buffer_lint_with_diagnostic(
-                        DUPLICATE_MACRO_EXPORTS,
-                        CRATE_NODE_ID,
-                        binding.span,
-                        &format!("a macro named `{}` has already been exported", ident),
-                        BuiltinLintDiagnostics::DuplicatedMacroExports(
-                            ident, old_binding.span, binding.span));
-
-                    resolution.binding = Some(binding);
-                } else {
-                    return Err(old_binding);
                 }
             } else {
                 resolution.binding = Some(binding);
@@ -531,10 +509,10 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
         })
     }
 
-    pub fn ambiguity(&self, b1: &'a NameBinding<'a>, b2: &'a NameBinding<'a>)
+    fn ambiguity(&self, kind: AmbiguityKind, b1: &'a NameBinding<'a>, b2: &'a NameBinding<'a>)
                      -> &'a NameBinding<'a> {
         self.arenas.alloc_name_binding(NameBinding {
-            kind: NameBindingKind::Ambiguity { b1, b2 },
+            kind: NameBindingKind::Ambiguity { kind, b1, b2 },
             vis: if b1.vis.is_at_least(b2.vis, self) { b1.vis } else { b2.vis },
             span: b1.span,
             expansion: Mark::root(),
@@ -648,65 +626,13 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
             self.finalize_resolutions_in(module);
         }
 
-        struct UniformPathsCanaryResults<'a> {
-            name: Name,
-            module_scope: Option<&'a NameBinding<'a>>,
-            block_scopes: Vec<&'a NameBinding<'a>>,
-        }
-
-        // Collect all tripped `uniform_paths` canaries separately.
-        let mut uniform_paths_canaries: BTreeMap<
-            (Span, NodeId, Namespace),
-            UniformPathsCanaryResults,
-        > = BTreeMap::new();
-
         let mut errors = false;
         let mut seen_spans = FxHashSet::default();
         let mut error_vec = Vec::new();
         let mut prev_root_id: NodeId = NodeId::from_u32(0);
         for i in 0 .. self.determined_imports.len() {
             let import = self.determined_imports[i];
-            let error = self.finalize_import(import);
-
-            // For a `#![feature(uniform_paths)]` `use self::x as _` canary,
-            // failure is ignored, while success may cause an ambiguity error.
-            if import.is_uniform_paths_canary {
-                if error.is_some() {
-                    continue;
-                }
-
-                let (name, result) = match import.subclass {
-                    SingleImport { source, ref result, .. } => (source.name, result),
-                    _ => bug!(),
-                };
-
-                let has_explicit_self =
-                    !import.module_path.is_empty() &&
-                    import.module_path[0].ident.name == keywords::SelfValue.name();
-
-                self.per_ns(|_, ns| {
-                    if let Some(result) = result[ns].get().ok() {
-                        let canary_results =
-                            uniform_paths_canaries.entry((import.span, import.id, ns))
-                                .or_insert(UniformPathsCanaryResults {
-                                    name,
-                                    module_scope: None,
-                                    block_scopes: vec![],
-                                });
-
-                        // All the canaries with the same `id` should have the same `name`.
-                        assert_eq!(canary_results.name, name);
-
-                        if has_explicit_self {
-                            // There should only be one `self::x` (module-scoped) canary.
-                            assert!(canary_results.module_scope.is_none());
-                            canary_results.module_scope = Some(result);
-                        } else {
-                            canary_results.block_scopes.push(result);
-                        }
-                    }
-                });
-            } else if let Some((span, err, note)) = error {
+            if let Some((span, err, note)) = self.finalize_import(import) {
                 errors = true;
 
                 if let SingleImport { source, ref result, .. } = import.subclass {
@@ -743,71 +669,6 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
             }
         }
 
-        let uniform_paths_feature = self.session.features_untracked().uniform_paths;
-        for ((span, _, ns), results) in uniform_paths_canaries {
-            let name = results.name;
-            let external_crate = if ns == TypeNS {
-                self.extern_prelude_get(Ident::with_empty_ctxt(name), true, false)
-                    .map(|binding| binding.def())
-            } else {
-                None
-            };
-
-            // Currently imports can't resolve in non-module scopes,
-            // we only have canaries in them for future-proofing.
-            if external_crate.is_none() && results.module_scope.is_none() {
-                continue;
-            }
-
-            {
-                let mut all_results = external_crate.into_iter().chain(
-                    results.module_scope.iter()
-                        .chain(&results.block_scopes)
-                        .map(|binding| binding.def())
-                );
-                let first = all_results.next().unwrap();
-
-                // An ambiguity requires more than one *distinct* possible resolution.
-                let possible_resultions =
-                    1 + all_results.filter(|&def| def != first).count();
-                if possible_resultions <= 1 {
-                    continue;
-                }
-            }
-
-            errors = true;
-
-            let msg = format!("`{}` import is ambiguous", name);
-            let mut err = self.session.struct_span_err(span, &msg);
-            let mut suggestion_choices = vec![];
-            if external_crate.is_some() {
-                suggestion_choices.push(format!("`::{}`", name));
-                err.span_label(span,
-                    format!("can refer to external crate `::{}`", name));
-            }
-            if let Some(result) = results.module_scope {
-                suggestion_choices.push(format!("`self::{}`", name));
-                if uniform_paths_feature {
-                    err.span_label(result.span,
-                        format!("can refer to `self::{}`", name));
-                } else {
-                    err.span_label(result.span,
-                        format!("may refer to `self::{}` in the future", name));
-                }
-            }
-            for result in results.block_scopes {
-                err.span_label(result.span,
-                    format!("shadowed by block-scoped `{}`", name));
-            }
-            err.help(&format!("write {} explicitly instead", suggestion_choices.join(" or ")));
-            if uniform_paths_feature {
-                err.note("relative `use` paths enabled by `#![feature(uniform_paths)]`");
-            } else {
-                err.note("in the future, `#![feature(uniform_paths)]` may become the default");
-            }
-            err.emit();
-        }
-
         if !error_vec.is_empty() {
             self.throw_unresolved_import_error(error_vec.clone(), None);
         }
@@ -816,9 +677,6 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
         // to avoid generating multiple errors on the same import.
         if !errors {
             for import in &self.indeterminate_imports {
-                if import.is_uniform_paths_canary {
-                    continue;
-                }
                 self.throw_unresolved_import_error(error_vec, Some(MultiSpan::from(import.span)));
                 break;
             }
@@ -871,7 +729,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
     /// If successful, the resolved bindings are written into the module.
     fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> bool {
         debug!("(resolving import for module) resolving import `{}::...` in `{}`",
-               Segment::names_to_string(&directive.module_path[..]),
+               Segment::names_to_string(&directive.module_path),
                module_to_string(self.current_module).unwrap_or_else(|| "???".to_string()));
 
         self.current_module = directive.parent_scope.module;
@@ -879,29 +737,23 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
         let module = if let Some(module) = directive.imported_module.get() {
             module
         } else {
-            let vis = directive.vis.get();
-            // For better failure detection, pretend that the import will not define any names
-            // while resolving its module path.
-            directive.vis.set(ty::Visibility::Invisible);
-            let result = self.resolve_path(
-                Some(if directive.is_uniform_paths_canary {
-                    ModuleOrUniformRoot::Module(directive.parent_scope.module)
-                } else {
-                    ModuleOrUniformRoot::UniformRoot(keywords::Invalid.name())
-                }),
-                &directive.module_path[..],
+            // For better failure detection, pretend that the import will
+            // not define any names while resolving its module path.
+            let orig_vis = directive.vis.replace(ty::Visibility::Invisible);
+            let path_res = self.resolve_path(
+                &directive.module_path,
                 None,
                 &directive.parent_scope,
                 false,
                 directive.span,
                 directive.crate_lint(),
             );
-            directive.vis.set(vis);
+            directive.vis.set(orig_vis);
 
-            match result {
+            match path_res {
                 PathResult::Module(module) => module,
                 PathResult::Indeterminate => return false,
-                _ => return true,
+                PathResult::NonModule(..) | PathResult::Failed(..) => return true,
             }
         };
 
@@ -919,11 +771,15 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
         let mut indeterminate = false;
         self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
             if let Err(Undetermined) = result[ns].get() {
-                result[ns].set(this.resolve_ident_in_module(module,
-                                                            source,
-                                                            ns,
-                                                            false,
-                                                            directive.span));
+                // For better failure detection, pretend that the import will
+                // not define any names while resolving its module path.
+                let orig_vis = directive.vis.replace(ty::Visibility::Invisible);
+                let binding = this.resolve_ident_in_module(
+                    module, source, ns, Some(&directive.parent_scope), false, directive.span
+                );
+                directive.vis.set(orig_vis);
+
+                result[ns].set(binding);
             } else {
                 return
             };
@@ -964,50 +820,62 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
         directive: &'b ImportDirective<'b>
     ) -> Option<(Span, String, Option<String>)> {
         self.current_module = directive.parent_scope.module;
-        let ImportDirective { ref module_path, span, .. } = *directive;
 
-        let module_result = self.resolve_path(
-            Some(if directive.is_uniform_paths_canary {
-                ModuleOrUniformRoot::Module(directive.parent_scope.module)
-            } else {
-                ModuleOrUniformRoot::UniformRoot(keywords::Invalid.name())
-            }),
-            &module_path,
-            None,
-            &directive.parent_scope,
-            true,
-            span,
-            directive.crate_lint(),
-        );
-        let module = match module_result {
-            PathResult::Module(module) => module,
+        let orig_vis = directive.vis.replace(ty::Visibility::Invisible);
+        let path_res = self.resolve_path(&directive.module_path, None, &directive.parent_scope,
+                                         true, directive.span, directive.crate_lint());
+        directive.vis.set(orig_vis);
+        let module = match path_res {
+            PathResult::Module(module) => {
+                // Consistency checks, analogous to `finalize_current_module_macro_resolutions`.
+                if let Some(initial_module) = directive.imported_module.get() {
+                    if module != initial_module && self.ambiguity_errors.is_empty() {
+                        span_bug!(directive.span, "inconsistent resolution for an import");
+                    }
+                } else {
+                    if self.privacy_errors.is_empty() {
+                        let msg = "cannot determine resolution for the import";
+                        let msg_note = "import resolution is stuck, try simplifying other imports";
+                        self.session.struct_span_err(directive.span, msg).note(msg_note).emit();
+                    }
+                }
+
+                module
+            }
             PathResult::Failed(span, msg, false) => {
+                assert!(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());
                 return if let Some((suggested_path, note)) = self.make_path_suggestion(
-                    span, module_path.clone(), &directive.parent_scope
+                    span, directive.module_path.clone(), &directive.parent_scope
                 ) {
                     Some((
                         span,
-                        format!("Did you mean `{}`?", Segment::names_to_string(&suggested_path)),
+                        format!("did you mean `{}`?", Segment::names_to_string(&suggested_path)),
                         note,
                     ))
                 } else {
                     Some((span, msg, None))
                 };
-            },
-            _ => return None,
+            }
+            PathResult::NonModule(path_res) if path_res.base_def() == Def::Err => {
+                // The error was already reported earlier.
+                assert!(directive.imported_module.get().is_none());
+                return None;
+            }
+            PathResult::Indeterminate | PathResult::NonModule(..) => unreachable!(),
         };
 
         let (ident, result, type_ns_only) = match directive.subclass {
             SingleImport { source, ref result, type_ns_only, .. } => (source, result, type_ns_only),
             GlobImport { is_prelude, ref max_vis } => {
-                if module_path.len() <= 1 {
+                if directive.module_path.len() <= 1 {
                     // HACK(eddyb) `lint_if_path_starts_with_module` needs at least
                     // 2 segments, so the `resolve_path` above won't trigger it.
-                    let mut full_path = module_path.clone();
+                    let mut full_path = directive.module_path.clone();
                     full_path.push(Segment::from_ident(keywords::Invalid.ident()));
                     self.lint_if_path_starts_with_module(
                         directive.crate_lint(),
@@ -1038,26 +906,47 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
             _ => unreachable!(),
         };
 
-        // Do not record uses from canaries, to avoid interfering with other
-        // diagnostics or suggestions that rely on some items not being used.
-        let record_used = !directive.is_uniform_paths_canary;
-
         let mut all_ns_err = true;
         self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
-            if let Ok(binding) = result[ns].get() {
-                all_ns_err = false;
-                if record_used && this.record_use(ident, ns, binding) {
-                    if let ModuleOrUniformRoot::Module(module) = module {
-                        this.resolution(module, ident, ns).borrow_mut().binding =
-                            Some(this.dummy_binding);
+            let orig_vis = directive.vis.replace(ty::Visibility::Invisible);
+            let orig_last_import_segment = mem::replace(&mut this.last_import_segment, true);
+            let binding = this.resolve_ident_in_module(
+                module, ident, ns, Some(&directive.parent_scope), true, directive.span
+            );
+            this.last_import_segment = orig_last_import_segment;
+            directive.vis.set(orig_vis);
+
+            match binding {
+                Ok(binding) => {
+                    // Consistency checks, analogous to `finalize_current_module_macro_resolutions`.
+                    let initial_def = result[ns].get().map(|initial_binding| {
+                        all_ns_err = false;
+                        this.record_use(ident, ns, initial_binding,
+                                        directive.module_path.is_empty());
+                        initial_binding.def_ignoring_ambiguity()
+                    });
+                    let def = binding.def_ignoring_ambiguity();
+                    if let Ok(initial_def) = initial_def {
+                        if def != initial_def && this.ambiguity_errors.is_empty() {
+                            span_bug!(directive.span, "inconsistent resolution for an import");
+                        }
+                    } else {
+                        if def != Def::Err &&
+                           this.ambiguity_errors.is_empty() && this.privacy_errors.is_empty() {
+                            let msg = "cannot determine resolution for the import";
+                            let msg_note =
+                                "import resolution is stuck, try simplifying other imports";
+                            this.session.struct_span_err(directive.span, msg).note(msg_note).emit();
+                        }
                     }
                 }
-                if record_used && ns == TypeNS {
-                    if let ModuleOrUniformRoot::UniformRoot(..) = module {
-                        // Make sure single-segment import is resolved non-speculatively
-                        // at least once to report the feature error.
-                        this.extern_prelude_get(ident, false, false);
-                    }
+                Err(..) => {
+                    // FIXME: This assert may fire if public glob is later shadowed by a private
+                    // single import (see test `issue-55884-2.rs`). In theory single imports should
+                    // always block globs, even if they are not yet resolved, so that this kind of
+                    // self-inconsistent resolution never happens.
+                    // Reenable the assert when the issue is fixed.
+                    // assert!(result[ns].get().is_err());
                 }
             }
         });
@@ -1065,7 +954,10 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
         if all_ns_err {
             let mut all_ns_failed = true;
             self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
-                if this.resolve_ident_in_module(module, ident, ns, record_used, span).is_ok() {
+                let binding = this.resolve_ident_in_module(
+                    module, ident, ns, Some(&directive.parent_scope), true, directive.span
+                );
+                if binding.is_ok() {
                     all_ns_failed = false;
                 }
             });
@@ -1122,7 +1014,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
                         }
                     }
                 };
-                Some((span, msg, None))
+                Some((directive.span, msg, None))
             } else {
                 // `resolve_ident_in_module` reported a privacy error.
                 self.import_dummy_binding(directive);
@@ -1171,10 +1063,10 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
             }
         }
 
-        if module_path.len() <= 1 {
+        if directive.module_path.len() <= 1 {
             // HACK(eddyb) `lint_if_path_starts_with_module` needs at least
             // 2 segments, so the `resolve_path` above won't trigger it.
-            let mut full_path = module_path.clone();
+            let mut full_path = directive.module_path.clone();
             full_path.push(Segment::from_ident(ident));
             self.per_ns(|this, ns| {
                 if let Ok(binding) = result[ns].get() {
@@ -1192,8 +1084,18 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
         // this may resolve to either a value or a type, but for documentation
         // purposes it's good enough to just favor one over the other.
         self.per_ns(|this, ns| if let Some(binding) = result[ns].get().ok() {
+            let mut def = binding.def();
+            if let Def::Macro(def_id, _) = def {
+                // `DefId`s from the "built-in macro crate" should not leak from resolve because
+                // later stages are not ready to deal with them and produce lots of ICEs. Replace
+                // them with `Def::Err` until some saner scheme is implemented for built-in macros.
+                if def_id.krate == CrateNum::BuiltinMacros {
+                    this.session.span_err(directive.span, "cannot import a built-in macro");
+                    def = Def::Err;
+                }
+            }
             let import = this.import_map.entry(directive.id).or_default();
-            import[ns] = Some(PathResolution::new(binding.def()));
+            import[ns] = Some(PathResolution::new(def));
         });
 
         debug!("(resolving single import) successfully resolved import");
@@ -1262,19 +1164,13 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
                 None => continue,
             };
 
-            // Don't reexport `uniform_path` canaries.
-            let non_canary_import = match binding.kind {
-                NameBindingKind::Import { directive, .. } => {
-                    !directive.is_uniform_paths_canary
-                }
-                _ => false,
-            };
-
-            if non_canary_import || binding.is_macro_def() {
+            if binding.is_import() || binding.is_macro_def() {
                 let def = binding.def();
                 if def != Def::Err {
-                    if !def.def_id().is_local() {
-                        self.cstore.export_macros_untracked(def.def_id().krate);
+                    if let Some(def_id) = def.opt_def_id() {
+                        if !def_id.is_local() && def_id.krate != CrateNum::BuiltinMacros {
+                            self.cstore.export_macros_untracked(def_id.krate);
+                        }
                     }
                     reexports.push(Export {
                         ident: ident.modern(),
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 471ba6345e2..85c9b6ee728 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -477,7 +477,7 @@ fn macro_resolve(cx: &DocContext, path_str: &str) -> Option<Def> {
     let mut resolver = cx.resolver.borrow_mut();
     let parent_scope = resolver.dummy_parent_scope();
     if let Ok(def) = resolver.resolve_macro_to_def_inner(&path, MacroKind::Bang,
-                                                         &parent_scope, false) {
+                                                         &parent_scope, false, false) {
         if let SyntaxExtension::DeclMacro { .. } = *resolver.get_macro(def) {
             return Some(def);
         }
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 88ee80e6088..bb927b62a18 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -595,6 +595,13 @@ impl MacroKind {
             MacroKind::ProcMacroStub => "crate-local procedural macro",
         }
     }
+
+    pub fn article(self) -> &'static str {
+        match self {
+            MacroKind::Attr => "an",
+            _ => "a",
+        }
+    }
 }
 
 /// An enum representing the different kinds of syntax extensions.
diff --git a/src/test/ui-fulldeps/custom-derive/derive-in-mod.rs b/src/test/ui-fulldeps/custom-derive/derive-in-mod.rs
new file mode 100644
index 00000000000..8478ff1a6ae
--- /dev/null
+++ b/src/test/ui-fulldeps/custom-derive/derive-in-mod.rs
@@ -0,0 +1,13 @@
+// compile-pass
+// aux-build:plugin.rs
+
+extern crate plugin;
+
+mod inner {
+    use plugin::WithHelper;
+
+    #[derive(WithHelper)]
+    struct S;
+}
+
+fn main() {}
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 059629c0b62..ee98873064f 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
@@ -1,19 +1,20 @@
-error[E0659]: `helper` is ambiguous
+error[E0659]: `helper` is ambiguous (derive helper attribute vs any other name)
   --> $DIR/helper-attr-blocked-by-import-ambig.rs:10:3
    |
 LL | #[helper] //~ ERROR `helper` is ambiguous
    |   ^^^^^^ ambiguous name
    |
-note: `helper` could refer to the name defined here
+note: `helper` could refer to the derive helper attribute defined here
   --> $DIR/helper-attr-blocked-by-import-ambig.rs:9:10
    |
 LL | #[derive(WithHelper)]
    |          ^^^^^^^^^^
-note: `helper` could also refer to the name imported here
+note: `helper` could also refer to the attribute macro imported here
   --> $DIR/helper-attr-blocked-by-import-ambig.rs:7:5
    |
 LL | use plugin::helper;
    |     ^^^^^^^^^^^^^^
+   = help: use `self::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 ea867faf47b..34b21ea2683 100644
--- a/src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs.stderr
+++ b/src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs.stderr
@@ -1,98 +1,78 @@
-error[E0659]: `repr` is ambiguous
+error[E0425]: cannot find value `NonExistent` in this scope
+  --> $DIR/ambiguous-builtin-attrs.rs:30:5
+   |
+LL |     NonExistent; //~ ERROR cannot find value `NonExistent` in this scope
+   |     ^^^^^^^^^^^ not found in this scope
+
+error[E0659]: `repr` is ambiguous (built-in attribute vs any other name)
   --> $DIR/ambiguous-builtin-attrs.rs:9:3
    |
 LL | #[repr(C)] //~ ERROR `repr` is ambiguous
    |   ^^^^ ambiguous name
    |
-note: `repr` could refer to the name imported here
+   = note: `repr` could refer to a built-in attribute
+note: `repr` could also refer to the attribute macro imported here
   --> $DIR/ambiguous-builtin-attrs.rs:7:5
    |
 LL | use builtin_attrs::*;
    |     ^^^^^^^^^^^^^^^^
-note: `repr` could also refer to the name defined here
-  --> $DIR/ambiguous-builtin-attrs.rs:9:3
-   |
-LL | #[repr(C)] //~ ERROR `repr` is ambiguous
-   |   ^^^^
-   = note: consider adding an explicit import of `repr` to disambiguate
+   = help: use `self::repr` to refer to this attribute macro unambiguously
 
-error[E0659]: `repr` is ambiguous
+error[E0659]: `repr` is ambiguous (built-in attribute vs any other name)
   --> $DIR/ambiguous-builtin-attrs.rs:11:19
    |
 LL | #[cfg_attr(all(), repr(C))] //~ ERROR `repr` is ambiguous
    |                   ^^^^ ambiguous name
    |
-note: `repr` could refer to the name imported here
+   = note: `repr` could refer to a built-in attribute
+note: `repr` could also refer to the attribute macro imported here
   --> $DIR/ambiguous-builtin-attrs.rs:7:5
    |
 LL | use builtin_attrs::*;
    |     ^^^^^^^^^^^^^^^^
-note: `repr` could also refer to the name defined here
-  --> $DIR/ambiguous-builtin-attrs.rs:11:19
-   |
-LL | #[cfg_attr(all(), repr(C))] //~ ERROR `repr` is ambiguous
-   |                   ^^^^
-   = note: consider adding an explicit import of `repr` to disambiguate
+   = help: use `self::repr` to refer to this attribute macro unambiguously
 
-error[E0659]: `repr` is ambiguous
+error[E0659]: `repr` is ambiguous (built-in attribute vs any other name)
   --> $DIR/ambiguous-builtin-attrs.rs:20:34
    |
 LL | fn non_macro_expanded_location<#[repr(C)] T>() { //~ ERROR `repr` is ambiguous
    |                                  ^^^^ ambiguous name
    |
-note: `repr` could refer to the name imported here
+   = note: `repr` could refer to a built-in attribute
+note: `repr` could also refer to the attribute macro imported here
   --> $DIR/ambiguous-builtin-attrs.rs:7:5
    |
 LL | use builtin_attrs::*;
    |     ^^^^^^^^^^^^^^^^
-note: `repr` could also refer to the name defined here
-  --> $DIR/ambiguous-builtin-attrs.rs:20:34
-   |
-LL | fn non_macro_expanded_location<#[repr(C)] T>() { //~ ERROR `repr` is ambiguous
-   |                                  ^^^^
-   = note: consider adding an explicit import of `repr` to disambiguate
+   = help: use `self::repr` to refer to this attribute macro unambiguously
 
-error[E0659]: `repr` is ambiguous
+error[E0659]: `repr` is ambiguous (built-in attribute vs any other name)
   --> $DIR/ambiguous-builtin-attrs.rs:22:11
    |
 LL |         #[repr(C)] //~ ERROR `repr` is ambiguous
    |           ^^^^ ambiguous name
    |
-note: `repr` could refer to the name imported here
+   = note: `repr` could refer to a built-in attribute
+note: `repr` could also refer to the attribute macro imported here
   --> $DIR/ambiguous-builtin-attrs.rs:7:5
    |
 LL | use builtin_attrs::*;
    |     ^^^^^^^^^^^^^^^^
-note: `repr` could also refer to the name defined here
-  --> $DIR/ambiguous-builtin-attrs.rs:22:11
-   |
-LL |         #[repr(C)] //~ ERROR `repr` is ambiguous
-   |           ^^^^
-   = note: consider adding an explicit import of `repr` to disambiguate
+   = help: use `self::repr` to refer to this attribute macro unambiguously
 
-error[E0659]: `feature` is ambiguous
+error[E0659]: `feature` is ambiguous (built-in attribute vs any other name)
   --> $DIR/ambiguous-builtin-attrs.rs:3:4
    |
 LL | #![feature(decl_macro)] //~ ERROR `feature` is ambiguous
    |    ^^^^^^^ ambiguous name
    |
-note: `feature` could refer to the name imported here
+   = note: `feature` could refer to a built-in attribute
+note: `feature` could also refer to the attribute macro imported here
   --> $DIR/ambiguous-builtin-attrs.rs:7:5
    |
 LL | use builtin_attrs::*;
    |     ^^^^^^^^^^^^^^^^
-note: `feature` could also refer to the name defined here
-  --> $DIR/ambiguous-builtin-attrs.rs:3:4
-   |
-LL | #![feature(decl_macro)] //~ ERROR `feature` is ambiguous
-   |    ^^^^^^^
-   = note: consider adding an explicit import of `feature` to disambiguate
-
-error[E0425]: cannot find value `NonExistent` in this scope
-  --> $DIR/ambiguous-builtin-attrs.rs:30:5
-   |
-LL |     NonExistent; //~ ERROR cannot find value `NonExistent` in this scope
-   |     ^^^^^^^^^^^ not found in this scope
+   = help: use `self::feature` to refer to this attribute macro unambiguously
 
 error: aborting due to 6 previous errors
 
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 e0aeae4ba6c..f04782fac4d 100644
--- a/src/test/ui-fulldeps/proc-macro/derive-helper-shadowing.stderr
+++ b/src/test/ui-fulldeps/proc-macro/derive-helper-shadowing.stderr
@@ -1,19 +1,20 @@
-error[E0659]: `my_attr` is ambiguous
+error[E0659]: `my_attr` is ambiguous (derive helper attribute vs any other name)
   --> $DIR/derive-helper-shadowing.rs:6:3
    |
 LL | #[my_attr] //~ ERROR `my_attr` is ambiguous
    |   ^^^^^^^ ambiguous name
    |
-note: `my_attr` could refer to the name defined here
+note: `my_attr` could refer to the derive helper attribute defined here
   --> $DIR/derive-helper-shadowing.rs:7:10
    |
 LL | #[derive(MyTrait)]
    |          ^^^^^^^
-note: `my_attr` could also refer to the name imported here
+note: `my_attr` could also refer to the attribute macro imported here
   --> $DIR/derive-helper-shadowing.rs:4:5
    |
 LL | use derive_helper_shadowing::*;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: use `self::my_attr` to refer to this attribute macro unambiguously
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/absolute-paths-in-nested-use-groups.stderr b/src/test/ui/absolute-paths-in-nested-use-groups.stderr
index e88d26718a0..2bbd7b0ad3a 100644
--- a/src/test/ui/absolute-paths-in-nested-use-groups.stderr
+++ b/src/test/ui/absolute-paths-in-nested-use-groups.stderr
@@ -1,16 +1,16 @@
-error[E0433]: failed to resolve. crate root in paths can only be used in start position
+error[E0433]: failed to resolve: crate root in paths can only be used in start position
   --> $DIR/absolute-paths-in-nested-use-groups.rs:16:5
    |
 LL |     ::bar,       //~ ERROR crate root in paths can only be used in start position
    |     ^ crate root in paths can only be used in start position
 
-error[E0433]: failed to resolve. `super` in paths can only be used in start position
+error[E0433]: failed to resolve: `super` in paths can only be used in start position
   --> $DIR/absolute-paths-in-nested-use-groups.rs:17:5
    |
 LL |     super::bar,  //~ ERROR `super` in paths can only be used in start position
    |     ^^^^^ `super` in paths can only be used in start position
 
-error[E0433]: failed to resolve. `self` in paths can only be used in start position
+error[E0433]: failed to resolve: `self` in paths can only be used in start position
   --> $DIR/absolute-paths-in-nested-use-groups.rs:18:5
    |
 LL |     self::bar,   //~ ERROR `self` in paths can only be used in start position
diff --git a/src/test/ui/bad/bad-module.rs b/src/test/ui/bad/bad-module.rs
index 6987d06ef12..4f38d4ce45e 100644
--- a/src/test/ui/bad/bad-module.rs
+++ b/src/test/ui/bad/bad-module.rs
@@ -10,8 +10,8 @@
 
 fn main() {
     let foo = thing::len(Vec::new());
-    //~^ ERROR failed to resolve. Use of undeclared type or module `thing`
+    //~^ ERROR failed to resolve: use of undeclared type or module `thing`
 
     let foo = foo::bar::baz();
-    //~^ ERROR failed to resolve. Use of undeclared type or module `foo`
+    //~^ ERROR failed to resolve: use of undeclared type or module `foo`
 }
diff --git a/src/test/ui/bad/bad-module.stderr b/src/test/ui/bad/bad-module.stderr
index 8c19922dcab..8bdcceaa191 100644
--- a/src/test/ui/bad/bad-module.stderr
+++ b/src/test/ui/bad/bad-module.stderr
@@ -1,14 +1,14 @@
-error[E0433]: failed to resolve. Use of undeclared type or module `thing`
+error[E0433]: failed to resolve: use of undeclared type or module `thing`
   --> $DIR/bad-module.rs:12:15
    |
 LL |     let foo = thing::len(Vec::new());
-   |               ^^^^^ Use of undeclared type or module `thing`
+   |               ^^^^^ use of undeclared type or module `thing`
 
-error[E0433]: failed to resolve. Use of undeclared type or module `foo`
+error[E0433]: failed to resolve: use of undeclared type or module `foo`
   --> $DIR/bad-module.rs:15:15
    |
 LL |     let foo = foo::bar::baz();
-   |               ^^^ Use of undeclared type or module `foo`
+   |               ^^^ use of undeclared type or module `foo`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/custom-attribute-multisegment.rs b/src/test/ui/custom-attribute-multisegment.rs
index a8d82a35946..354f7173872 100644
--- a/src/test/ui/custom-attribute-multisegment.rs
+++ b/src/test/ui/custom-attribute-multisegment.rs
@@ -14,5 +14,5 @@
 
 mod existent {}
 
-#[existent::nonexistent] //~ ERROR failed to resolve. Could not find `nonexistent` in `existent`
+#[existent::nonexistent] //~ ERROR failed to resolve: could not find `nonexistent` in `existent`
 fn main() {}
diff --git a/src/test/ui/custom-attribute-multisegment.stderr b/src/test/ui/custom-attribute-multisegment.stderr
index ff72d1c36d8..690ba4982ab 100644
--- a/src/test/ui/custom-attribute-multisegment.stderr
+++ b/src/test/ui/custom-attribute-multisegment.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve. Could not find `nonexistent` in `existent`
+error[E0433]: failed to resolve: could not find `nonexistent` in `existent`
   --> $DIR/custom-attribute-multisegment.rs:17:13
    |
-LL | #[existent::nonexistent] //~ ERROR failed to resolve. Could not find `nonexistent` in `existent`
-   |             ^^^^^^^^^^^ Could not find `nonexistent` in `existent`
+LL | #[existent::nonexistent] //~ ERROR failed to resolve: could not find `nonexistent` in `existent`
+   |             ^^^^^^^^^^^ could not find `nonexistent` in `existent`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/derived-errors/issue-31997-1.stderr b/src/test/ui/derived-errors/issue-31997-1.stderr
index 7cdcac3891f..5c5422f091b 100644
--- a/src/test/ui/derived-errors/issue-31997-1.stderr
+++ b/src/test/ui/derived-errors/issue-31997-1.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve. Use of undeclared type or module `HashMap`
+error[E0433]: failed to resolve: use of undeclared type or module `HashMap`
   --> $DIR/issue-31997-1.rs:30:19
    |
 LL |     let mut map = HashMap::new();
-   |                   ^^^^^^^ Use of undeclared type or module `HashMap`
+   |                   ^^^^^^^ use of undeclared type or module `HashMap`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/dollar-crate/dollar-crate-is-keyword-2.stderr b/src/test/ui/dollar-crate/dollar-crate-is-keyword-2.stderr
index 0a0b1d573dd..fe9af74c01d 100644
--- a/src/test/ui/dollar-crate/dollar-crate-is-keyword-2.stderr
+++ b/src/test/ui/dollar-crate/dollar-crate-is-keyword-2.stderr
@@ -1,4 +1,4 @@
-error[E0433]: failed to resolve. `$crate` in paths can only be used in start position
+error[E0433]: failed to resolve: `$crate` in paths can only be used in start position
   --> $DIR/dollar-crate-is-keyword-2.rs:16:16
    |
 LL |         use a::$crate::b; //~ ERROR `$crate` in paths can only be used in start position
@@ -16,7 +16,7 @@ LL |         use a::$crate; //~ ERROR unresolved import `a::$crate`
 LL | m!();
    | ----- in this macro invocation
 
-error[E0433]: failed to resolve. `$crate` in paths can only be used in start position
+error[E0433]: failed to resolve: `$crate` in paths can only be used in start position
   --> $DIR/dollar-crate-is-keyword-2.rs:17:21
    |
 LL |         type A = a::$crate; //~ ERROR `$crate` in paths can only be used in start position
diff --git a/src/test/ui/dyn-trait-compatibility.rs b/src/test/ui/dyn-trait-compatibility.rs
index 454b6d2f566..4297e1b43d3 100644
--- a/src/test/ui/dyn-trait-compatibility.rs
+++ b/src/test/ui/dyn-trait-compatibility.rs
@@ -11,7 +11,7 @@
 type A0 = dyn;
 //~^ ERROR cannot find type `dyn` in this scope
 type A1 = dyn::dyn;
-//~^ ERROR Use of undeclared type or module `dyn`
+//~^ ERROR use of undeclared type or module `dyn`
 type A2 = dyn<dyn, dyn>;
 //~^ ERROR cannot find type `dyn` in this scope
 //~| ERROR cannot find type `dyn` in this scope
@@ -19,6 +19,6 @@ type A2 = dyn<dyn, dyn>;
 type A3 = dyn<<dyn as dyn>::dyn>;
 //~^ ERROR cannot find type `dyn` in this scope
 //~| ERROR cannot find type `dyn` in this scope
-//~| ERROR Use of undeclared type or module `dyn`
+//~| ERROR use of undeclared type or module `dyn`
 
 fn main() {}
diff --git a/src/test/ui/dyn-trait-compatibility.stderr b/src/test/ui/dyn-trait-compatibility.stderr
index 1ff3249371b..93048ccad6f 100644
--- a/src/test/ui/dyn-trait-compatibility.stderr
+++ b/src/test/ui/dyn-trait-compatibility.stderr
@@ -1,14 +1,14 @@
-error[E0433]: failed to resolve. Use of undeclared type or module `dyn`
+error[E0433]: failed to resolve: use of undeclared type or module `dyn`
   --> $DIR/dyn-trait-compatibility.rs:13:11
    |
 LL | type A1 = dyn::dyn;
-   |           ^^^ Use of undeclared type or module `dyn`
+   |           ^^^ use of undeclared type or module `dyn`
 
-error[E0433]: failed to resolve. Use of undeclared type or module `dyn`
+error[E0433]: failed to resolve: use of undeclared type or module `dyn`
   --> $DIR/dyn-trait-compatibility.rs:19:23
    |
 LL | type A3 = dyn<<dyn as dyn>::dyn>;
-   |                       ^^^ Use of undeclared type or module `dyn`
+   |                       ^^^ use of undeclared type or module `dyn`
 
 error[E0412]: cannot find type `dyn` in this scope
   --> $DIR/dyn-trait-compatibility.rs:11:11
diff --git a/src/test/ui/empty/empty-struct-tuple-pat.stderr b/src/test/ui/empty/empty-struct-tuple-pat.stderr
index 3d219b1752f..3708aa36089 100644
--- a/src/test/ui/empty/empty-struct-tuple-pat.stderr
+++ b/src/test/ui/empty/empty-struct-tuple-pat.stderr
@@ -2,7 +2,7 @@ error[E0530]: match bindings cannot shadow tuple structs
   --> $DIR/empty-struct-tuple-pat.rs:32:9
    |
 LL | struct Empty2();
-   | ---------------- a tuple struct `Empty2` is defined here
+   | ---------------- the tuple struct `Empty2` is defined here
 ...
 LL |         Empty2 => () //~ ERROR match bindings cannot shadow tuple structs
    |         ^^^^^^ cannot be named the same as a tuple struct
@@ -11,7 +11,7 @@ error[E0530]: match bindings cannot shadow tuple structs
   --> $DIR/empty-struct-tuple-pat.rs:35:9
    |
 LL | use empty_struct::*;
-   |     --------------- a tuple struct `XEmpty6` is imported here
+   |     --------------- the tuple struct `XEmpty6` is imported here
 ...
 LL |         XEmpty6 => () //~ ERROR match bindings cannot shadow tuple structs
    |         ^^^^^^^ cannot be named the same as a tuple struct
diff --git a/src/test/ui/enum/enum-in-scope.stderr b/src/test/ui/enum/enum-in-scope.stderr
index 1e8d5940495..b294aabb4ed 100644
--- a/src/test/ui/enum/enum-in-scope.stderr
+++ b/src/test/ui/enum/enum-in-scope.stderr
@@ -2,7 +2,7 @@ error[E0530]: let bindings cannot shadow tuple structs
   --> $DIR/enum-in-scope.rs:14:9
    |
 LL | struct hello(isize);
-   | -------------------- a tuple struct `hello` is defined here
+   | -------------------- the tuple struct `hello` is defined here
 ...
 LL |     let hello = 0; //~ERROR let bindings cannot shadow tuple structs
    |         ^^^^^ cannot be named the same as a tuple struct
diff --git a/src/test/ui/error-codes/E0432.stderr b/src/test/ui/error-codes/E0432.stderr
index 291bb450755..d288cd086e7 100644
--- a/src/test/ui/error-codes/E0432.stderr
+++ b/src/test/ui/error-codes/E0432.stderr
@@ -2,7 +2,7 @@ error[E0432]: unresolved import `something`
   --> $DIR/E0432.rs:11:5
    |
 LL | use something::Foo; //~ ERROR E0432
-   |     ^^^^^^^^^ Maybe a missing `extern crate something;`?
+   |     ^^^^^^^^^ maybe a missing `extern crate something;`?
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0433.stderr b/src/test/ui/error-codes/E0433.stderr
index f8cf5f6f92f..8a66e749ba8 100644
--- a/src/test/ui/error-codes/E0433.stderr
+++ b/src/test/ui/error-codes/E0433.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve. Use of undeclared type or module `HashMap`
+error[E0433]: failed to resolve: use of undeclared type or module `HashMap`
   --> $DIR/E0433.rs:12:15
    |
 LL |     let map = HashMap::new(); //~ ERROR E0433
-   |               ^^^^^^^ Use of undeclared type or module `HashMap`
+   |               ^^^^^^^ use of undeclared type or module `HashMap`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0530.stderr b/src/test/ui/error-codes/E0530.stderr
index e157ca9042c..96bc47a1afe 100644
--- a/src/test/ui/error-codes/E0530.stderr
+++ b/src/test/ui/error-codes/E0530.stderr
@@ -2,7 +2,7 @@ error[E0530]: match bindings cannot shadow statics
   --> $DIR/E0530.rs:16:9
    |
 LL |     static TEST: i32 = 0;
-   |     --------------------- a static `TEST` is defined here
+   |     --------------------- the static `TEST` is defined here
 ...
 LL |         TEST => {} //~ ERROR E0530
    |         ^^^^ cannot be named the same as a static
diff --git a/src/test/ui/error-codes/E0659.stderr b/src/test/ui/error-codes/E0659.stderr
index f168b7797ca..7bfe159405b 100644
--- a/src/test/ui/error-codes/E0659.stderr
+++ b/src/test/ui/error-codes/E0659.stderr
@@ -1,20 +1,21 @@
-error[E0659]: `foo` is ambiguous
+error[E0659]: `foo` is ambiguous (glob import vs glob import in the same module)
   --> $DIR/E0659.rs:25:15
    |
 LL |     collider::foo(); //~ ERROR E0659
    |               ^^^ ambiguous name
    |
-note: `foo` could refer to the name imported here
+note: `foo` could refer to the function imported here
   --> $DIR/E0659.rs:20:13
    |
 LL |     pub use moon::*;
    |             ^^^^^^^
-note: `foo` could also refer to the name imported here
+   = help: consider adding an explicit import of `foo` to disambiguate
+note: `foo` could also refer to the function imported here
   --> $DIR/E0659.rs:21:13
    |
 LL |     pub use earth::*;
    |             ^^^^^^^^
-   = note: consider adding an explicit import of `foo` to disambiguate
+   = help: consider adding an explicit import of `foo` to disambiguate
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/export-fully-qualified.rs b/src/test/ui/export-fully-qualified.rs
index 19fa13f8377..422cd251de4 100644
--- a/src/test/ui/export-fully-qualified.rs
+++ b/src/test/ui/export-fully-qualified.rs
@@ -13,7 +13,7 @@
 // want to change eventually.
 
 mod foo {
-    pub fn bar() { foo::baz(); } //~ ERROR failed to resolve. Use of undeclared type or module `foo`
+    pub fn bar() { foo::baz(); } //~ ERROR failed to resolve: use of undeclared type or module `foo`
 
     fn baz() { }
 }
diff --git a/src/test/ui/export-fully-qualified.stderr b/src/test/ui/export-fully-qualified.stderr
index b8409929763..477cb4b1dd1 100644
--- a/src/test/ui/export-fully-qualified.stderr
+++ b/src/test/ui/export-fully-qualified.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve. Use of undeclared type or module `foo`
+error[E0433]: failed to resolve: use of undeclared type or module `foo`
   --> $DIR/export-fully-qualified.rs:16:20
    |
-LL |     pub fn bar() { foo::baz(); } //~ ERROR failed to resolve. Use of undeclared type or module `foo`
-   |                    ^^^ Use of undeclared type or module `foo`
+LL |     pub fn bar() { foo::baz(); } //~ ERROR failed to resolve: use of undeclared type or module `foo`
+   |                    ^^^ use of undeclared type or module `foo`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/export2.rs b/src/test/ui/export2.rs
index dc96ce7f504..4cc9762d975 100644
--- a/src/test/ui/export2.rs
+++ b/src/test/ui/export2.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 mod foo {
-    pub fn x() { bar::x(); } //~ ERROR failed to resolve. Use of undeclared type or module `bar`
+    pub fn x() { bar::x(); } //~ ERROR failed to resolve: use of undeclared type or module `bar`
 }
 
 mod bar {
diff --git a/src/test/ui/export2.stderr b/src/test/ui/export2.stderr
index c76afb8a1e2..7659183c8e0 100644
--- a/src/test/ui/export2.stderr
+++ b/src/test/ui/export2.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve. Use of undeclared type or module `bar`
+error[E0433]: failed to resolve: use of undeclared type or module `bar`
   --> $DIR/export2.rs:12:18
    |
-LL |     pub fn x() { bar::x(); } //~ ERROR failed to resolve. Use of undeclared type or module `bar`
-   |                  ^^^ Use of undeclared type or module `bar`
+LL |     pub fn x() { bar::x(); } //~ ERROR failed to resolve: use of undeclared type or module `bar`
+   |                  ^^^ use of undeclared type or module `bar`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/extern/extern-macro.rs b/src/test/ui/extern/extern-macro.rs
index 4b1bf7d8f79..88a72778a85 100644
--- a/src/test/ui/extern/extern-macro.rs
+++ b/src/test/ui/extern/extern-macro.rs
@@ -12,5 +12,5 @@
 
 fn main() {
     enum Foo {}
-    let _ = Foo::bar!(); //~ ERROR fail to resolve non-ident macro path
+    let _ = Foo::bar!(); //~ ERROR failed to resolve: partially resolved path in a macro
 }
diff --git a/src/test/ui/extern/extern-macro.stderr b/src/test/ui/extern/extern-macro.stderr
index b5515bfcc64..6123d970166 100644
--- a/src/test/ui/extern/extern-macro.stderr
+++ b/src/test/ui/extern/extern-macro.stderr
@@ -1,8 +1,9 @@
-error: fail to resolve non-ident macro path
+error[E0433]: failed to resolve: partially resolved path in a macro
   --> $DIR/extern-macro.rs:15:13
    |
-LL |     let _ = Foo::bar!(); //~ ERROR fail to resolve non-ident macro path
-   |             ^^^^^^^^
+LL |     let _ = Foo::bar!(); //~ ERROR failed to resolve: partially resolved path in a macro
+   |             ^^^^^^^^ partially resolved path in a macro
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0433`.
diff --git a/src/test/ui/feature-gates/feature-gate-extern_absolute_paths.stderr b/src/test/ui/feature-gates/feature-gate-extern_absolute_paths.stderr
index 7a996abc767..7c94200f00f 100644
--- a/src/test/ui/feature-gates/feature-gate-extern_absolute_paths.stderr
+++ b/src/test/ui/feature-gates/feature-gate-extern_absolute_paths.stderr
@@ -2,13 +2,13 @@ error[E0432]: unresolved import `core`
   --> $DIR/feature-gate-extern_absolute_paths.rs:11:5
    |
 LL | use core::default; //~ ERROR unresolved import `core`
-   |     ^^^^ Maybe a missing `extern crate core;`?
+   |     ^^^^ maybe a missing `extern crate core;`?
 
-error[E0433]: failed to resolve. Maybe a missing `extern crate core;`?
+error[E0433]: failed to resolve: maybe a missing `extern crate core;`?
   --> $DIR/feature-gate-extern_absolute_paths.rs:14:19
    |
 LL |     let _: u8 = ::core::default::Default(); //~ ERROR failed to resolve
-   |                   ^^^^ Maybe a missing `extern crate core;`?
+   |                   ^^^^ maybe a missing `extern crate core;`?
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.rs b/src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.rs
index a043b6c2e61..27b9a34ff4e 100644
--- a/src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.rs
+++ b/src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.rs
@@ -1,6 +1,6 @@
 // edition:2018
 
-#![feature(alloc)]
+#![feature(alloc, underscore_imports)]
 
 extern crate alloc;
 
@@ -23,7 +23,7 @@ mod absolute {
 }
 
 mod import_in_scope {
-    use alloc;
+    use alloc as _;
     //~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable
     use alloc::boxed;
     //~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable
diff --git a/src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.stderr b/src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.stderr
index bbd4b630263..103ab79ef84 100644
--- a/src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.stderr
+++ b/src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.stderr
@@ -1,7 +1,7 @@
 error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599)
   --> $DIR/feature-gate-extern_crate_item_prelude.rs:26:9
    |
-LL |     use alloc;
+LL |     use alloc as _;
    |         ^^^^^
    |
    = help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable
diff --git a/src/test/ui/feature-gates/feature-gate-uniform-paths.rs b/src/test/ui/feature-gates/feature-gate-uniform-paths.rs
index 140655d52bd..ca1cc1d2fd0 100644
--- a/src/test/ui/feature-gates/feature-gate-uniform-paths.rs
+++ b/src/test/ui/feature-gates/feature-gate-uniform-paths.rs
@@ -8,15 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// edition:2018
+
 pub mod foo {
-    pub use bar::Bar;
-    //~^ ERROR unresolved import `bar`
+    pub use bar::Bar; //~ ERROR imports can only refer to extern crate names
 
     pub mod bar {
         pub struct Bar;
     }
 }
 
+use inline; //~ ERROR imports can only refer to extern crate names
+
+use Vec; //~ ERROR imports can only refer to extern crate names
+
+use vec; //~ ERROR imports can only refer to extern crate names
+
 fn main() {
     let _ = foo::Bar;
 }
diff --git a/src/test/ui/feature-gates/feature-gate-uniform-paths.stderr b/src/test/ui/feature-gates/feature-gate-uniform-paths.stderr
index 68faacfcbe7..ec8937bbc5f 100644
--- a/src/test/ui/feature-gates/feature-gate-uniform-paths.stderr
+++ b/src/test/ui/feature-gates/feature-gate-uniform-paths.stderr
@@ -1,9 +1,62 @@
-error[E0432]: unresolved import `bar`
-  --> $DIR/feature-gate-uniform-paths.rs:12:13
+error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130)
+  --> $DIR/feature-gate-uniform-paths.rs:14:13
    |
-LL |     pub use bar::Bar;
-   |             ^^^ Did you mean `self::bar`?
+LL |       pub use bar::Bar; //~ ERROR imports can only refer to extern crate names
+   |               ^^^
+LL | 
+LL | /     pub mod bar {
+LL | |         pub struct Bar;
+LL | |     }
+   | |_____- not an extern crate passed with `--extern`
+   |
+   = help: add #![feature(uniform_paths)] to the crate attributes to enable
+note: this import refers to the module defined here
+  --> $DIR/feature-gate-uniform-paths.rs:16:5
+   |
+LL | /     pub mod bar {
+LL | |         pub struct Bar;
+LL | |     }
+   | |_____^
+
+error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130)
+  --> $DIR/feature-gate-uniform-paths.rs:21:5
+   |
+LL | use inline; //~ ERROR imports can only refer to extern crate names
+   |     ^^^^^^ not an extern crate passed with `--extern`
+   |
+   = help: add #![feature(uniform_paths)] to the crate attributes to enable
+note: this import refers to the built-in attribute imported here
+  --> $DIR/feature-gate-uniform-paths.rs:21:5
+   |
+LL | use inline; //~ ERROR imports can only refer to extern crate names
+   |     ^^^^^^
+
+error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130)
+  --> $DIR/feature-gate-uniform-paths.rs:23:5
+   |
+LL | use Vec; //~ ERROR imports can only refer to extern crate names
+   |     ^^^ not an extern crate passed with `--extern`
+   |
+   = help: add #![feature(uniform_paths)] to the crate attributes to enable
+note: this import refers to the struct imported here
+  --> $DIR/feature-gate-uniform-paths.rs:23:5
+   |
+LL | use Vec; //~ ERROR imports can only refer to extern crate names
+   |     ^^^
+
+error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130)
+  --> $DIR/feature-gate-uniform-paths.rs:25:5
+   |
+LL | use vec; //~ ERROR imports can only refer to extern crate names
+   |     ^^^ not an extern crate passed with `--extern`
+   |
+   = help: add #![feature(uniform_paths)] to the crate attributes to enable
+note: this import refers to the macro imported here
+  --> $DIR/feature-gate-uniform-paths.rs:25:5
+   |
+LL | use vec; //~ ERROR imports can only refer to extern crate names
+   |     ^^^
 
-error: aborting due to previous error
+error: aborting due to 4 previous errors
 
-For more information about this error, try `rustc --explain E0432`.
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/hygiene/no_implicit_prelude.stderr b/src/test/ui/hygiene/no_implicit_prelude.stderr
index 463fdbf00ce..73a63a2c7f5 100644
--- a/src/test/ui/hygiene/no_implicit_prelude.stderr
+++ b/src/test/ui/hygiene/no_implicit_prelude.stderr
@@ -1,11 +1,11 @@
-error[E0433]: failed to resolve. Use of undeclared type or module `Vec`
+error[E0433]: failed to resolve: use of undeclared type or module `Vec`
   --> $DIR/no_implicit_prelude.rs:21:9
    |
 LL |     fn f() { ::bar::m!(); }
    |              ------------ in this macro invocation
 ...
 LL |         Vec::new(); //~ ERROR failed to resolve
-   |         ^^^ Use of undeclared type or module `Vec`
+   |         ^^^ use of undeclared type or module `Vec`
 
 error[E0599]: no method named `clone` found for type `()` in the current scope
   --> $DIR/no_implicit_prelude.rs:22:12
diff --git a/src/test/ui/import2.rs b/src/test/ui/import2.rs
index c4bd9ff1e2a..d3bbdf15cd0 100644
--- a/src/test/ui/import2.rs
+++ b/src/test/ui/import2.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use baz::zed::bar; //~ ERROR unresolved import `baz::zed` [E0432]
-                   //~^ Could not find `zed` in `baz`
+                   //~^ could not find `zed` in `baz`
 
 mod baz {}
 mod zed {
diff --git a/src/test/ui/import2.stderr b/src/test/ui/import2.stderr
index c07506845c4..b1973937701 100644
--- a/src/test/ui/import2.stderr
+++ b/src/test/ui/import2.stderr
@@ -2,7 +2,7 @@ error[E0432]: unresolved import `baz::zed`
   --> $DIR/import2.rs:11:10
    |
 LL | use baz::zed::bar; //~ ERROR unresolved import `baz::zed` [E0432]
-   |          ^^^ Could not find `zed` in `baz`
+   |          ^^^ could not find `zed` in `baz`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/import3.stderr b/src/test/ui/import3.stderr
index 5211b862b3d..a4c367fb073 100644
--- a/src/test/ui/import3.stderr
+++ b/src/test/ui/import3.stderr
@@ -2,7 +2,7 @@ error[E0432]: unresolved import `main`
   --> $DIR/import3.rs:12:5
    |
 LL | use main::bar;
-   |     ^^^^ Maybe a missing `extern crate main;`?
+   |     ^^^^ maybe a missing `extern crate main;`?
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/imports/auxiliary/glob-conflict.rs b/src/test/ui/imports/auxiliary/glob-conflict.rs
new file mode 100644
index 00000000000..ac12ed9c81c
--- /dev/null
+++ b/src/test/ui/imports/auxiliary/glob-conflict.rs
@@ -0,0 +1,9 @@
+mod m1 {
+    pub fn f() {}
+}
+mod m2 {
+    pub fn f(_: u8) {}
+}
+
+pub use m1::*;
+pub use m2::*;
diff --git a/src/test/ui/imports/duplicate.stderr b/src/test/ui/imports/duplicate.stderr
index 5d51981e8af..f53ba9cd5de 100644
--- a/src/test/ui/imports/duplicate.stderr
+++ b/src/test/ui/imports/duplicate.stderr
@@ -12,77 +12,81 @@ help: you can use `as` to change the binding name of the import
 LL |     use a::foo as other_foo; //~ ERROR the name `foo` is defined multiple times
    |         ^^^^^^^^^^^^^^^^^^^
 
-error[E0659]: `foo` is ambiguous
+error[E0659]: `foo` is ambiguous (glob import vs glob import in the same module)
   --> $DIR/duplicate.rs:56:15
    |
 LL |     use self::foo::bar; //~ ERROR `foo` is ambiguous
    |               ^^^ ambiguous name
    |
-note: `foo` could refer to the name imported here
+note: `foo` could refer to the module imported here
   --> $DIR/duplicate.rs:53:9
    |
 LL |     use self::m1::*;
    |         ^^^^^^^^^^^
-note: `foo` could also refer to the name imported here
+   = help: consider adding an explicit import of `foo` to disambiguate
+note: `foo` could also refer to the module imported here
   --> $DIR/duplicate.rs:54:9
    |
 LL |     use self::m2::*;
    |         ^^^^^^^^^^^
-   = note: consider adding an explicit import of `foo` to disambiguate
+   = help: consider adding an explicit import of `foo` to disambiguate
 
-error[E0659]: `foo` is ambiguous
+error[E0659]: `foo` is ambiguous (glob import vs glob import in the same module)
   --> $DIR/duplicate.rs:45:8
    |
 LL |     f::foo(); //~ ERROR `foo` is ambiguous
    |        ^^^ ambiguous name
    |
-note: `foo` could refer to the name imported here
+note: `foo` could refer to the function imported here
   --> $DIR/duplicate.rs:34:13
    |
 LL |     pub use a::*;
    |             ^^^^
-note: `foo` could also refer to the name imported here
+   = help: consider adding an explicit import of `foo` to disambiguate
+note: `foo` could also refer to the function imported here
   --> $DIR/duplicate.rs:35:13
    |
 LL |     pub use b::*;
    |             ^^^^
-   = note: consider adding an explicit import of `foo` to disambiguate
+   = help: consider adding an explicit import of `foo` to disambiguate
 
-error[E0659]: `foo` is ambiguous
+error[E0659]: `foo` is ambiguous (glob import vs glob import in the same module)
   --> $DIR/duplicate.rs:46:8
    |
 LL |     g::foo(); //~ ERROR `foo` is ambiguous
    |        ^^^ ambiguous name
    |
-note: `foo` could refer to the name imported here
+note: `foo` could refer to the function imported here
   --> $DIR/duplicate.rs:39:13
    |
 LL |     pub use a::*;
    |             ^^^^
-note: `foo` could also refer to the name imported here
+   = help: consider adding an explicit import of `foo` to disambiguate
+note: `foo` could also refer to the unresolved item imported here
   --> $DIR/duplicate.rs:40:13
    |
 LL |     pub use f::*;
    |             ^^^^
-   = note: consider adding an explicit import of `foo` to disambiguate
+   = help: consider adding an explicit import of `foo` to disambiguate
 
-error[E0659]: `foo` is ambiguous
+error[E0659]: `foo` is ambiguous (glob import vs glob import in the same module)
   --> $DIR/duplicate.rs:59:9
    |
 LL |         foo::bar(); //~ ERROR `foo` is ambiguous
    |         ^^^ ambiguous name
    |
-note: `foo` could refer to the name imported here
+note: `foo` could refer to the module imported here
   --> $DIR/duplicate.rs:53:9
    |
 LL |     use self::m1::*;
    |         ^^^^^^^^^^^
-note: `foo` could also refer to the name imported here
+   = help: consider adding an explicit import of `foo` to disambiguate
+note: `foo` could also refer to the module imported here
   --> $DIR/duplicate.rs:54:9
    |
 LL |     use self::m2::*;
    |         ^^^^^^^^^^^
-   = note: consider adding an explicit import of `foo` to disambiguate
+   = help: consider adding an explicit import of `foo` to disambiguate
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/imports/extern-prelude-extern-crate-fail.rs b/src/test/ui/imports/extern-prelude-extern-crate-fail.rs
index 57b097c9df3..6b70efe0c44 100644
--- a/src/test/ui/imports/extern-prelude-extern-crate-fail.rs
+++ b/src/test/ui/imports/extern-prelude-extern-crate-fail.rs
@@ -7,7 +7,7 @@ mod n {
 
 mod m {
     fn check() {
-        two_macros::m!(); //~ ERROR failed to resolve. Use of undeclared type or module `two_macros`
+        two_macros::m!(); //~ ERROR failed to resolve: use of undeclared type or module `two_macros`
     }
 }
 
diff --git a/src/test/ui/imports/extern-prelude-extern-crate-fail.stderr b/src/test/ui/imports/extern-prelude-extern-crate-fail.stderr
index 8f68d2af34c..baeed02517d 100644
--- a/src/test/ui/imports/extern-prelude-extern-crate-fail.stderr
+++ b/src/test/ui/imports/extern-prelude-extern-crate-fail.stderr
@@ -7,11 +7,11 @@ LL |         extern crate std as non_existent;
 LL | define_std_as_non_existent!();
    | ------------------------------ in this macro invocation
 
-error[E0433]: failed to resolve. Use of undeclared type or module `two_macros`
+error[E0433]: failed to resolve: use of undeclared type or module `two_macros`
   --> $DIR/extern-prelude-extern-crate-fail.rs:10:9
    |
-LL |         two_macros::m!(); //~ ERROR failed to resolve. Use of undeclared type or module `two_macros`
-   |         ^^^^^^^^^^ Use of undeclared type or module `two_macros`
+LL |         two_macros::m!(); //~ ERROR failed to resolve: use of undeclared type or module `two_macros`
+   |         ^^^^^^^^^^ use of undeclared type or module `two_macros`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr
index 6c832e70e49..218dfb796f7 100644
--- a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr
+++ b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr
@@ -1,10 +1,11 @@
-error[E0659]: `Vec` is ambiguous
+error[E0659]: `Vec` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
   --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:15:9
    |
 LL |         Vec::panic!(); //~ ERROR `Vec` is ambiguous
    |         ^^^ ambiguous name
    |
-note: `Vec` could refer to the name defined here
+   = note: `Vec` could refer to a struct from prelude
+note: `Vec` could also refer to the extern crate imported here
   --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:7:9
    |
 LL |         extern crate std as Vec;
@@ -12,8 +13,6 @@ LL |         extern crate std as Vec;
 ...
 LL | define_vec!();
    | -------------- in this macro invocation
-note: `Vec` could also refer to the name defined here
-   = note: macro-expanded items do not shadow when used in a macro invocation path
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/imports/glob-conflict-cross-crate.rs b/src/test/ui/imports/glob-conflict-cross-crate.rs
new file mode 100644
index 00000000000..e02148b19f7
--- /dev/null
+++ b/src/test/ui/imports/glob-conflict-cross-crate.rs
@@ -0,0 +1,7 @@
+// aux-build:glob-conflict.rs
+
+extern crate glob_conflict;
+
+fn main() {
+    glob_conflict::f(); //~ ERROR cannot find function `f` in module `glob_conflict`
+}
diff --git a/src/test/ui/imports/glob-conflict-cross-crate.stderr b/src/test/ui/imports/glob-conflict-cross-crate.stderr
new file mode 100644
index 00000000000..f64637fd6f6
--- /dev/null
+++ b/src/test/ui/imports/glob-conflict-cross-crate.stderr
@@ -0,0 +1,9 @@
+error[E0425]: cannot find function `f` in module `glob_conflict`
+  --> $DIR/glob-conflict-cross-crate.rs:6:20
+   |
+LL |     glob_conflict::f(); //~ ERROR cannot find function `f` in module `glob_conflict`
+   |                    ^ not found in `glob_conflict`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/imports/glob-shadowing.stderr b/src/test/ui/imports/glob-shadowing.stderr
index 33a2963fa29..6a4774facd7 100644
--- a/src/test/ui/imports/glob-shadowing.stderr
+++ b/src/test/ui/imports/glob-shadowing.stderr
@@ -1,48 +1,50 @@
-error[E0659]: `env` is ambiguous
+error[E0659]: `env` is ambiguous (glob import vs any other name from outer scope during import/macro resolution)
   --> $DIR/glob-shadowing.rs:21:17
    |
 LL |         let x = env!("PATH"); //~ ERROR `env` is ambiguous
    |                 ^^^ ambiguous name
    |
-note: `env` could refer to the name imported here
+   = note: `env` could refer to a built-in macro
+note: `env` could also refer to the macro imported here
   --> $DIR/glob-shadowing.rs:19:9
    |
 LL |     use m::*;
    |         ^^^^
-   = note: `env` is also a builtin macro
-   = note: consider adding an explicit import of `env` to disambiguate
+   = help: consider adding an explicit import of `env` to disambiguate
+   = help: or use `self::env` to refer to this macro unambiguously
 
-error[E0659]: `env` is ambiguous
+error[E0659]: `env` is ambiguous (glob import vs any other name from outer scope during import/macro resolution)
   --> $DIR/glob-shadowing.rs:29:21
    |
 LL |             let x = env!("PATH"); //~ ERROR `env` is ambiguous
    |                     ^^^ ambiguous name
    |
-note: `env` could refer to the name imported here
+   = note: `env` could refer to a built-in macro
+note: `env` could also refer to the macro imported here
   --> $DIR/glob-shadowing.rs:27:13
    |
 LL |         use m::*;
    |             ^^^^
-   = note: `env` is also a builtin macro
-   = note: consider adding an explicit import of `env` to disambiguate
+   = help: consider adding an explicit import of `env` to disambiguate
 
-error[E0659]: `fenv` is ambiguous
+error[E0659]: `fenv` is ambiguous (glob import vs any other name from outer scope during import/macro resolution)
   --> $DIR/glob-shadowing.rs:39:21
    |
 LL |             let x = fenv!(); //~ ERROR `fenv` is ambiguous
    |                     ^^^^ ambiguous name
    |
-note: `fenv` could refer to the name imported here
+note: `fenv` could refer to the macro imported here
   --> $DIR/glob-shadowing.rs:37:13
    |
 LL |         use m::*;
    |             ^^^^
-note: `fenv` could also refer to the name defined here
+   = help: consider adding an explicit import of `fenv` to disambiguate
+note: `fenv` could also refer to the macro defined here
   --> $DIR/glob-shadowing.rs:35:5
    |
 LL |     pub macro fenv($e: expr) { $e }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: consider adding an explicit import of `fenv` to disambiguate
+   = help: use `self::fenv` to refer to this macro unambiguously
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/imports/issue-53269.stderr b/src/test/ui/imports/issue-53269.stderr
index e125983151d..0ed26ea6fe6 100644
--- a/src/test/ui/imports/issue-53269.stderr
+++ b/src/test/ui/imports/issue-53269.stderr
@@ -2,24 +2,25 @@ error[E0432]: unresolved import `nonexistent_module`
   --> $DIR/issue-53269.rs:16:9
    |
 LL |     use nonexistent_module::mac; //~ ERROR unresolved import `nonexistent_module`
-   |         ^^^^^^^^^^^^^^^^^^ Maybe a missing `extern crate nonexistent_module;`?
+   |         ^^^^^^^^^^^^^^^^^^ maybe a missing `extern crate nonexistent_module;`?
 
-error[E0659]: `mac` is ambiguous
+error[E0659]: `mac` is ambiguous (`macro_rules` vs non-`macro_rules` from other module)
   --> $DIR/issue-53269.rs:18:5
    |
 LL |     mac!(); //~ ERROR `mac` is ambiguous
    |     ^^^ ambiguous name
    |
-note: `mac` could refer to the name defined here
+note: `mac` could refer to the macro defined here
   --> $DIR/issue-53269.rs:13:1
    |
 LL | macro_rules! mac { () => () }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: `mac` could also refer to the name imported here
+note: `mac` could also refer to the unresolved item imported here
   --> $DIR/issue-53269.rs:16:9
    |
 LL |     use nonexistent_module::mac; //~ ERROR unresolved import `nonexistent_module`
    |         ^^^^^^^^^^^^^^^^^^^^^^^
+   = help: use `self::mac` to refer to this unresolved item unambiguously
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/imports/issue-55457.stderr b/src/test/ui/imports/issue-55457.stderr
index 363dec06237..4ee0332d04b 100644
--- a/src/test/ui/imports/issue-55457.stderr
+++ b/src/test/ui/imports/issue-55457.stderr
@@ -8,7 +8,7 @@ error[E0432]: unresolved import `non_existent`
   --> $DIR/issue-55457.rs:2:5
    |
 LL | use non_existent::non_existent; //~ ERROR unresolved import `non_existent`
-   |     ^^^^^^^^^^^^ Maybe a missing `extern crate non_existent;`?
+   |     ^^^^^^^^^^^^ maybe a missing `extern crate non_existent;`?
 
 error: cannot determine resolution for the derive macro `NonExistent`
   --> $DIR/issue-55457.rs:5:10
diff --git a/src/test/ui/imports/issue-55884-1.rs b/src/test/ui/imports/issue-55884-1.rs
new file mode 100644
index 00000000000..21744aa5d7b
--- /dev/null
+++ b/src/test/ui/imports/issue-55884-1.rs
@@ -0,0 +1,21 @@
+mod m {
+    mod m1 {
+        pub struct S {}
+    }
+    mod m2 {
+        // Note this derive, it makes this struct macro-expanded,
+        // so it doesn't appear in time to participate in the initial resolution of `use m::S`,
+        // only in the later validation pass.
+        #[derive(Default)]
+        pub struct S {}
+    }
+
+    // Create a glob vs glob ambiguity
+    pub use self::m1::*;
+    pub use self::m2::*;
+}
+
+fn main() {
+    use m::S; //~ ERROR `S` is ambiguous
+    let s = S {};
+}
diff --git a/src/test/ui/imports/issue-55884-1.stderr b/src/test/ui/imports/issue-55884-1.stderr
new file mode 100644
index 00000000000..477e859d081
--- /dev/null
+++ b/src/test/ui/imports/issue-55884-1.stderr
@@ -0,0 +1,22 @@
+error[E0659]: `S` is ambiguous (glob import vs glob import in the same module)
+  --> $DIR/issue-55884-1.rs:19:12
+   |
+LL |     use m::S; //~ ERROR `S` is ambiguous
+   |            ^ ambiguous name
+   |
+note: `S` could refer to the struct imported here
+  --> $DIR/issue-55884-1.rs:14:13
+   |
+LL |     pub use self::m1::*;
+   |             ^^^^^^^^^^^
+   = help: consider adding an explicit import of `S` to disambiguate
+note: `S` could also refer to the struct imported here
+  --> $DIR/issue-55884-1.rs:15:13
+   |
+LL |     pub use self::m2::*;
+   |             ^^^^^^^^^^^
+   = help: consider adding an explicit import of `S` to disambiguate
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0659`.
diff --git a/src/test/ui/imports/issue-55884-2.rs b/src/test/ui/imports/issue-55884-2.rs
new file mode 100644
index 00000000000..1b4f652c9fc
--- /dev/null
+++ b/src/test/ui/imports/issue-55884-2.rs
@@ -0,0 +1,14 @@
+mod options {
+    pub struct ParseOptions {}
+}
+
+mod parser {
+    pub use options::*;
+    // Private single import shadows public glob import, but arrives too late for initial
+    // resolution of `use parser::ParseOptions` because it depends on that resolution itself.
+    use ParseOptions;
+}
+
+pub use parser::ParseOptions; //~ ERROR struct `ParseOptions` is private
+
+fn main() {}
diff --git a/src/test/ui/imports/issue-55884-2.stderr b/src/test/ui/imports/issue-55884-2.stderr
new file mode 100644
index 00000000000..f8a6cb4a580
--- /dev/null
+++ b/src/test/ui/imports/issue-55884-2.stderr
@@ -0,0 +1,9 @@
+error[E0603]: struct `ParseOptions` is private
+  --> $DIR/issue-55884-2.rs:12:17
+   |
+LL | pub use parser::ParseOptions; //~ ERROR struct `ParseOptions` is private
+   |                 ^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0603`.
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 9c475451ce3..962294e48ca 100644
--- a/src/test/ui/imports/local-modularized-tricky-fail-1.stderr
+++ b/src/test/ui/imports/local-modularized-tricky-fail-1.stderr
@@ -1,10 +1,10 @@
-error[E0659]: `exported` is ambiguous
+error[E0659]: `exported` is ambiguous (glob import vs macro-expanded name in the same module during import/macro resolution)
   --> $DIR/local-modularized-tricky-fail-1.rs:38:1
    |
 LL | exported!(); //~ ERROR `exported` is ambiguous
    | ^^^^^^^^ ambiguous name
    |
-note: `exported` could refer to the name defined here
+note: `exported` could refer to the macro defined here
   --> $DIR/local-modularized-tricky-fail-1.rs:15:5
    |
 LL | /     macro_rules! exported {
@@ -14,20 +14,21 @@ LL | |     }
 ...
 LL |       define_exported!();
    |       ------------------- in this macro invocation
-note: `exported` could also refer to the name imported here
+note: `exported` could also refer to the macro imported here
   --> $DIR/local-modularized-tricky-fail-1.rs:32:5
    |
 LL | use inner1::*;
    |     ^^^^^^^^^
-   = note: macro-expanded macros do not shadow
+   = help: consider adding an explicit import of `exported` to disambiguate
 
-error[E0659]: `include` is ambiguous
+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
    |
 LL | include!(); //~ ERROR `include` is ambiguous
    | ^^^^^^^ ambiguous name
    |
-note: `include` could refer to the name defined here
+   = note: `include` could refer to a built-in macro
+note: `include` could also refer to the macro defined here
   --> $DIR/local-modularized-tricky-fail-1.rs:27:5
    |
 LL | /     macro_rules! include {
@@ -37,16 +38,16 @@ LL | |     }
 ...
 LL |       define_include!();
    |       ------------------ in this macro invocation
-   = note: `include` is also a builtin macro
-   = note: macro-expanded macros do not shadow
+   = help: use `self::include` to refer to this macro unambiguously
 
-error[E0659]: `panic` is ambiguous
+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
    |
 LL |     panic!(); //~ ERROR `panic` is ambiguous
    |     ^^^^^ ambiguous name
    |
-note: `panic` could refer to the name defined here
+   = note: `panic` could refer to a macro from prelude
+note: `panic` could also refer to the macro defined here
   --> $DIR/local-modularized-tricky-fail-1.rs:21:5
    |
 LL | /     macro_rules! panic {
@@ -56,16 +57,16 @@ LL | |     }
 ...
 LL |       define_panic!();
    |       ---------------- in this macro invocation
-   = note: `panic` is also a builtin macro
-   = note: macro-expanded macros do not shadow
+   = help: use `self::panic` to refer to this macro unambiguously
 
-error[E0659]: `panic` is ambiguous
+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
    |
 LL | (  ) => ( { panic ! ( "explicit panic" ) } ) ; ( $ msg : expr ) => (
    |             ^^^^^ ambiguous name
    |
-note: `panic` could refer to the name defined here
+   = note: `panic` could refer to a macro from prelude
+note: `panic` could also refer to the macro defined here
   --> $DIR/local-modularized-tricky-fail-1.rs:21:5
    |
 LL | /     macro_rules! panic {
@@ -75,8 +76,7 @@ LL | |     }
 ...
 LL |       define_panic!();
    |       ---------------- in this macro invocation
-   = note: `panic` is also a builtin macro
-   = note: macro-expanded macros do not shadow
+   = help: use `self::panic` to refer to this macro unambiguously
 
 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 a612c64c2f4..8e8742f849b 100644
--- a/src/test/ui/imports/macro-paths.stderr
+++ b/src/test/ui/imports/macro-paths.stderr
@@ -1,40 +1,40 @@
-error[E0659]: `bar` is ambiguous
+error[E0659]: `bar` is ambiguous (glob import vs macro-expanded name in the same module during import/macro resolution)
   --> $DIR/macro-paths.rs:23:5
    |
 LL |     bar::m! { //~ ERROR ambiguous
    |     ^^^ ambiguous name
    |
-note: `bar` could refer to the name defined here
+note: `bar` could refer to the module defined here
   --> $DIR/macro-paths.rs:24:9
    |
 LL |         mod bar { pub use two_macros::m; }
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: `bar` could also refer to the name imported here
+note: `bar` could also refer to the module imported here
   --> $DIR/macro-paths.rs:22:9
    |
 LL |     use foo::*;
    |         ^^^^^^
-   = note: macro-expanded items do not shadow when used in a macro invocation path
+   = help: consider adding an explicit import of `bar` to disambiguate
 
-error[E0659]: `baz` is ambiguous
+error[E0659]: `baz` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
   --> $DIR/macro-paths.rs:33:5
    |
 LL |     baz::m! { //~ ERROR ambiguous
    |     ^^^ ambiguous name
    |
-note: `baz` could refer to the name defined here
+note: `baz` could refer to the module defined here
   --> $DIR/macro-paths.rs:34:9
    |
 LL |         mod baz { pub use two_macros::m; }
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: `baz` could also refer to the name defined here
+note: `baz` could also refer to the module defined here
   --> $DIR/macro-paths.rs:28:1
    |
 LL | / pub mod baz {
 LL | |     pub use two_macros::m;
 LL | | }
    | |_^
-   = note: macro-expanded items do not shadow when used in a macro invocation path
+   = help: use `self::baz` to refer to this module unambiguously
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/imports/macros.stderr b/src/test/ui/imports/macros.stderr
index 209d449dfd8..77a0311fa60 100644
--- a/src/test/ui/imports/macros.stderr
+++ b/src/test/ui/imports/macros.stderr
@@ -1,38 +1,38 @@
-error[E0659]: `m` is ambiguous
+error[E0659]: `m` is ambiguous (glob import vs macro-expanded name in the same module during import/macro resolution)
   --> $DIR/macros.rs:26:5
    |
 LL |     m! { //~ ERROR ambiguous
    |     ^ ambiguous name
    |
-note: `m` could refer to the name imported here
+note: `m` could refer to the macro imported here
   --> $DIR/macros.rs:27:13
    |
 LL |         use foo::m;
    |             ^^^^^^
-note: `m` could also refer to the name imported here
+note: `m` could also refer to the macro imported here
   --> $DIR/macros.rs:25:9
    |
 LL |     use two_macros::*;
    |         ^^^^^^^^^^^^^
-   = note: macro-expanded macro imports do not shadow
+   = help: consider adding an explicit import of `m` to disambiguate
 
-error[E0659]: `m` is ambiguous
+error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
   --> $DIR/macros.rs:39:9
    |
 LL |         m! { //~ ERROR ambiguous
    |         ^ ambiguous name
    |
-note: `m` could refer to the name imported here
+note: `m` could refer to the macro imported here
   --> $DIR/macros.rs:40:17
    |
 LL |             use two_macros::n as m;
    |                 ^^^^^^^^^^^^^^^^^^
-note: `m` could also refer to the name imported here
+note: `m` could also refer to the macro imported here
   --> $DIR/macros.rs:32:9
    |
 LL |     use two_macros::m;
    |         ^^^^^^^^^^^^^
-   = note: macro-expanded macro imports do not shadow
+   = help: use `self::m` to refer to this macro unambiguously
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/imports/rfc-1560-warning-cycle.stderr b/src/test/ui/imports/rfc-1560-warning-cycle.stderr
index 91af3a4b6ac..946dc084cd0 100644
--- a/src/test/ui/imports/rfc-1560-warning-cycle.stderr
+++ b/src/test/ui/imports/rfc-1560-warning-cycle.stderr
@@ -1,20 +1,21 @@
-error[E0659]: `Foo` is ambiguous
+error[E0659]: `Foo` is ambiguous (glob import vs glob import in the same module)
   --> $DIR/rfc-1560-warning-cycle.rs:19:17
    |
 LL |         fn f(_: Foo) {} //~ ERROR `Foo` is ambiguous
    |                 ^^^ ambiguous name
    |
-note: `Foo` could refer to the name imported here
+note: `Foo` could refer to the struct imported here
   --> $DIR/rfc-1560-warning-cycle.rs:17:13
    |
 LL |         use *;
    |             ^
-note: `Foo` could also refer to the name imported here
+   = help: consider adding an explicit import of `Foo` to disambiguate
+note: `Foo` could also refer to the struct imported here
   --> $DIR/rfc-1560-warning-cycle.rs:18:13
    |
 LL |         use bar::*;
    |             ^^^^^^
-   = note: consider adding an explicit import of `Foo` to disambiguate
+   = help: consider adding an explicit import of `Foo` to disambiguate
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/imports/shadow_builtin_macros.stderr b/src/test/ui/imports/shadow_builtin_macros.stderr
index 7e5ab0c5abe..b53b7e2700d 100644
--- a/src/test/ui/imports/shadow_builtin_macros.stderr
+++ b/src/test/ui/imports/shadow_builtin_macros.stderr
@@ -1,38 +1,40 @@
-error[E0659]: `panic` is ambiguous
+error[E0659]: `panic` is ambiguous (glob import vs any other name from outer scope during import/macro resolution)
   --> $DIR/shadow_builtin_macros.rs:25:14
    |
 LL |     fn f() { panic!(); } //~ ERROR ambiguous
    |              ^^^^^ ambiguous name
    |
-note: `panic` could refer to the name imported here
+   = note: `panic` could refer to a macro from prelude
+note: `panic` could also refer to the macro imported here
   --> $DIR/shadow_builtin_macros.rs:24:9
    |
 LL |     use foo::*;
    |         ^^^^^^
-   = note: `panic` is also a builtin macro
-   = note: consider adding an explicit import of `panic` to disambiguate
+   = help: consider adding an explicit import of `panic` to disambiguate
+   = help: or use `self::panic` to refer to this macro unambiguously
 
-error[E0659]: `panic` is ambiguous
+error[E0659]: `panic` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
   --> $DIR/shadow_builtin_macros.rs:30:14
    |
 LL |     fn f() { panic!(); } //~ ERROR ambiguous
    |              ^^^^^ ambiguous name
    |
-note: `panic` could refer to the name imported here
+   = note: `panic` could refer to a macro from prelude
+note: `panic` could also refer to the macro imported here
   --> $DIR/shadow_builtin_macros.rs:29:26
    |
 LL |     ::two_macros::m!(use foo::panic;);
    |                          ^^^^^^^^^^
-   = note: `panic` is also a builtin macro
-   = note: macro-expanded macro imports do not shadow
+   = help: use `self::panic` to refer to this macro unambiguously
 
-error[E0659]: `panic` is ambiguous
+error[E0659]: `panic` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
   --> $DIR/shadow_builtin_macros.rs:43:5
    |
 LL |     panic!(); //~ ERROR `panic` is ambiguous
    |     ^^^^^ ambiguous name
    |
-note: `panic` could refer to the name defined here
+   = note: `panic` could refer to a macro from prelude
+note: `panic` could also refer to the macro defined here
   --> $DIR/shadow_builtin_macros.rs:40:9
    |
 LL |         macro_rules! panic { () => {} }
@@ -40,26 +42,25 @@ LL |         macro_rules! panic { () => {} }
 LL |     } }
 LL |     m!();
    |     ----- in this macro invocation
-   = note: `panic` is also a builtin macro
-   = note: macro-expanded macros do not shadow
 
-error[E0659]: `n` is ambiguous
+error[E0659]: `n` is ambiguous (glob import vs any other name from outer scope during import/macro resolution)
   --> $DIR/shadow_builtin_macros.rs:59:5
    |
 LL |     n!(); //~ ERROR ambiguous
    |     ^ ambiguous name
    |
-note: `n` could refer to the name imported here
+note: `n` could refer to the macro imported here
   --> $DIR/shadow_builtin_macros.rs:58:9
    |
 LL |     use bar::*;
    |         ^^^^^^
-note: `n` could also refer to the name imported here
+   = help: consider adding an explicit import of `n` to disambiguate
+   = help: or use `self::n` to refer to this macro unambiguously
+note: `n` could also refer to the macro imported here
   --> $DIR/shadow_builtin_macros.rs:46:13
    |
 LL | #[macro_use(n)]
    |             ^
-   = note: consider adding an explicit import of `n` to disambiguate
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/issues/issue-16149.stderr b/src/test/ui/issues/issue-16149.stderr
index b0b6e9dfcd0..284ed035526 100644
--- a/src/test/ui/issues/issue-16149.stderr
+++ b/src/test/ui/issues/issue-16149.stderr
@@ -2,7 +2,7 @@ error[E0530]: match bindings cannot shadow statics
   --> $DIR/issue-16149.rs:17:9
    |
 LL |     static externalValue: isize;
-   |     ---------------------------- a static `externalValue` is defined here
+   |     ---------------------------- the static `externalValue` is defined here
 ...
 LL |         externalValue => true,
    |         ^^^^^^^^^^^^^ cannot be named the same as a static
diff --git a/src/test/ui/issues/issue-1697.rs b/src/test/ui/issues/issue-1697.rs
index f8a68264339..43f92d8c3de 100644
--- a/src/test/ui/issues/issue-1697.rs
+++ b/src/test/ui/issues/issue-1697.rs
@@ -11,6 +11,6 @@
 // Testing that we don't fail abnormally after hitting the errors
 
 use unresolved::*; //~ ERROR unresolved import `unresolved` [E0432]
-                   //~^ Maybe a missing `extern crate unresolved;`?
+                   //~^ maybe a missing `extern crate unresolved;`?
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-1697.stderr b/src/test/ui/issues/issue-1697.stderr
index 28a7fbcaabe..b588c883264 100644
--- a/src/test/ui/issues/issue-1697.stderr
+++ b/src/test/ui/issues/issue-1697.stderr
@@ -2,7 +2,7 @@ error[E0432]: unresolved import `unresolved`
   --> $DIR/issue-1697.rs:13:5
    |
 LL | use unresolved::*; //~ ERROR unresolved import `unresolved` [E0432]
-   |     ^^^^^^^^^^ Maybe a missing `extern crate unresolved;`?
+   |     ^^^^^^^^^^ maybe a missing `extern crate unresolved;`?
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-17718-patterns.stderr b/src/test/ui/issues/issue-17718-patterns.stderr
index 13cab9a08b1..c49613eb33c 100644
--- a/src/test/ui/issues/issue-17718-patterns.stderr
+++ b/src/test/ui/issues/issue-17718-patterns.stderr
@@ -2,7 +2,7 @@ error[E0530]: match bindings cannot shadow statics
   --> $DIR/issue-17718-patterns.rs:17:9
    |
 LL | static A1: usize = 1;
-   | --------------------- a static `A1` is defined here
+   | --------------------- the static `A1` is defined here
 ...
 LL |         A1 => {} //~ ERROR: match bindings cannot shadow statics
    |         ^^ cannot be named the same as a static
@@ -11,7 +11,7 @@ error[E0530]: match bindings cannot shadow statics
   --> $DIR/issue-17718-patterns.rs:18:9
    |
 LL | static mut A2: usize = 1;
-   | ------------------------- a static `A2` is defined here
+   | ------------------------- the static `A2` is defined here
 ...
 LL |         A2 => {} //~ ERROR: match bindings cannot shadow statics
    |         ^^ cannot be named the same as a static
diff --git a/src/test/ui/issues/issue-23716.stderr b/src/test/ui/issues/issue-23716.stderr
index fd268c1b5a1..c175f197034 100644
--- a/src/test/ui/issues/issue-23716.stderr
+++ b/src/test/ui/issues/issue-23716.stderr
@@ -2,7 +2,7 @@ error[E0530]: function parameters cannot shadow statics
   --> $DIR/issue-23716.rs:13:8
    |
 LL | static foo: i32 = 0;
-   | -------------------- a static `foo` is defined here
+   | -------------------- the static `foo` is defined here
 LL | 
 LL | fn bar(foo: i32) {}
    |        ^^^ cannot be named the same as a static
@@ -11,7 +11,7 @@ error[E0530]: function parameters cannot shadow statics
   --> $DIR/issue-23716.rs:23:13
    |
 LL | use self::submod::answer;
-   |     -------------------- a static `answer` is imported here
+   |     -------------------- the static `answer` is imported here
 LL | 
 LL | fn question(answer: i32) {}
    |             ^^^^^^ cannot be named the same as a static
diff --git a/src/test/ui/issues/issue-27033.stderr b/src/test/ui/issues/issue-27033.stderr
index ba573c3eb6d..dfd635d36e8 100644
--- a/src/test/ui/issues/issue-27033.stderr
+++ b/src/test/ui/issues/issue-27033.stderr
@@ -8,7 +8,7 @@ error[E0530]: match bindings cannot shadow constants
   --> $DIR/issue-27033.rs:17:9
    |
 LL |     const C: u8 = 1;
-   |     ---------------- a constant `C` is defined here
+   |     ---------------- the constant `C` is defined here
 LL |     match 1 {
 LL |         C @ 2 => { //~ ERROR match bindings cannot shadow constant
    |         ^ cannot be named the same as a constant
diff --git a/src/test/ui/issues/issue-30560.rs b/src/test/ui/issues/issue-30560.rs
index 0b1afd75ca9..f033666220d 100644
--- a/src/test/ui/issues/issue-30560.rs
+++ b/src/test/ui/issues/issue-30560.rs
@@ -11,10 +11,10 @@
 type Alias = ();
 use Alias::*;
 //~^ ERROR unresolved import `Alias` [E0432]
-//~| Not a module `Alias`
+//~| not a module `Alias`
 use std::io::Result::*;
 //~^ ERROR unresolved import `std::io::Result` [E0432]
-//~| Not a module `Result`
+//~| not a module `Result`
 
 trait T {}
 use T::*; //~ ERROR items in traits are not importable
diff --git a/src/test/ui/issues/issue-30560.stderr b/src/test/ui/issues/issue-30560.stderr
index cb38c0dabe0..880c565cf9f 100644
--- a/src/test/ui/issues/issue-30560.stderr
+++ b/src/test/ui/issues/issue-30560.stderr
@@ -8,13 +8,13 @@ error[E0432]: unresolved import `Alias`
   --> $DIR/issue-30560.rs:12:5
    |
 LL | use Alias::*;
-   |     ^^^^^ Not a module `Alias`
+   |     ^^^^^ not a module `Alias`
 
 error[E0432]: unresolved import `std::io::Result`
   --> $DIR/issue-30560.rs:15:14
    |
 LL | use std::io::Result::*;
-   |              ^^^^^^ Not a module `Result`
+   |              ^^^^^^ not a module `Result`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/issues/issue-33293.rs b/src/test/ui/issues/issue-33293.rs
index bed577b8b9d..801ba7afcd6 100644
--- a/src/test/ui/issues/issue-33293.rs
+++ b/src/test/ui/issues/issue-33293.rs
@@ -11,6 +11,6 @@
 fn main() {
     match 0 {
         aaa::bbb(_) => ()
-        //~^ ERROR failed to resolve. Use of undeclared type or module `aaa`
+        //~^ ERROR failed to resolve: use of undeclared type or module `aaa`
     };
 }
diff --git a/src/test/ui/issues/issue-33293.stderr b/src/test/ui/issues/issue-33293.stderr
index e94979b6da4..dc288fa71ce 100644
--- a/src/test/ui/issues/issue-33293.stderr
+++ b/src/test/ui/issues/issue-33293.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve. Use of undeclared type or module `aaa`
+error[E0433]: failed to resolve: use of undeclared type or module `aaa`
   --> $DIR/issue-33293.rs:13:9
    |
 LL |         aaa::bbb(_) => ()
-   |         ^^^ Use of undeclared type or module `aaa`
+   |         ^^^ use of undeclared type or module `aaa`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-33464.stderr b/src/test/ui/issues/issue-33464.stderr
index b70fff01c9e..f41a3973625 100644
--- a/src/test/ui/issues/issue-33464.stderr
+++ b/src/test/ui/issues/issue-33464.stderr
@@ -2,19 +2,19 @@ error[E0432]: unresolved import `abc`
   --> $DIR/issue-33464.rs:13:5
    |
 LL | use abc::one_el;
-   |     ^^^ Maybe a missing `extern crate abc;`?
+   |     ^^^ maybe a missing `extern crate abc;`?
 
 error[E0432]: unresolved import `abc`
   --> $DIR/issue-33464.rs:15:5
    |
 LL | use abc::{a, bbb, cccccc};
-   |     ^^^ Maybe a missing `extern crate abc;`?
+   |     ^^^ maybe a missing `extern crate abc;`?
 
 error[E0432]: unresolved import `a_very_long_name`
   --> $DIR/issue-33464.rs:17:5
    |
 LL | use a_very_long_name::{el, el2};
-   |     ^^^^^^^^^^^^^^^^ Maybe a missing `extern crate a_very_long_name;`?
+   |     ^^^^^^^^^^^^^^^^ maybe a missing `extern crate a_very_long_name;`?
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/issues/issue-34047.stderr b/src/test/ui/issues/issue-34047.stderr
index 10804cc6fff..10e4e9c1c12 100644
--- a/src/test/ui/issues/issue-34047.stderr
+++ b/src/test/ui/issues/issue-34047.stderr
@@ -2,7 +2,7 @@ error[E0530]: match bindings cannot shadow constants
   --> $DIR/issue-34047.rs:15:13
    |
 LL | const C: u8 = 0;
-   | ---------------- a constant `C` is defined here
+   | ---------------- the constant `C` is defined here
 ...
 LL |         mut C => {} //~ ERROR match bindings cannot shadow constants
    |             ^ cannot be named the same as a constant
diff --git a/src/test/ui/issues/issue-36881.stderr b/src/test/ui/issues/issue-36881.stderr
index 39132fde762..27effe9e342 100644
--- a/src/test/ui/issues/issue-36881.stderr
+++ b/src/test/ui/issues/issue-36881.stderr
@@ -2,7 +2,7 @@ error[E0432]: unresolved import `issue_36881_aux`
   --> $DIR/issue-36881.rs:16:9
    |
 LL |     use issue_36881_aux::Foo; //~ ERROR unresolved import
-   |         ^^^^^^^^^^^^^^^ Maybe a missing `extern crate issue_36881_aux;`?
+   |         ^^^^^^^^^^^^^^^ maybe a missing `extern crate issue_36881_aux;`?
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-37887.stderr b/src/test/ui/issues/issue-37887.stderr
index 8448466087d..48fb6c2e6fa 100644
--- a/src/test/ui/issues/issue-37887.stderr
+++ b/src/test/ui/issues/issue-37887.stderr
@@ -2,7 +2,7 @@ error[E0432]: unresolved import `libc`
   --> $DIR/issue-37887.rs:13:9
    |
 LL |     use libc::*; //~ ERROR unresolved import
-   |         ^^^^ Maybe a missing `extern crate libc;`?
+   |         ^^^^ maybe a missing `extern crate libc;`?
 
 error[E0658]: use of unstable library feature 'libc': use `libc` from crates.io (see issue #27783)
   --> $DIR/issue-37887.rs:12:5
diff --git a/src/test/ui/issues/issue-38857.rs b/src/test/ui/issues/issue-38857.rs
index b38b1b9fdc6..5217ddb9acb 100644
--- a/src/test/ui/issues/issue-38857.rs
+++ b/src/test/ui/issues/issue-38857.rs
@@ -10,6 +10,6 @@
 
 fn main() {
     let a = std::sys::imp::process::process_common::StdioPipes { ..panic!() };
-    //~^ ERROR failed to resolve. Could not find `imp` in `sys` [E0433]
+    //~^ ERROR failed to resolve: could not find `imp` in `sys` [E0433]
     //~^^ ERROR module `sys` is private [E0603]
 }
diff --git a/src/test/ui/issues/issue-38857.stderr b/src/test/ui/issues/issue-38857.stderr
index f6ed3202671..65026344feb 100644
--- a/src/test/ui/issues/issue-38857.stderr
+++ b/src/test/ui/issues/issue-38857.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve. Could not find `imp` in `sys`
+error[E0433]: failed to resolve: could not find `imp` in `sys`
   --> $DIR/issue-38857.rs:12:23
    |
 LL |     let a = std::sys::imp::process::process_common::StdioPipes { ..panic!() };
-   |                       ^^^ Could not find `imp` in `sys`
+   |                       ^^^ could not find `imp` in `sys`
 
 error[E0603]: module `sys` is private
   --> $DIR/issue-38857.rs:12:18
diff --git a/src/test/ui/keyword/keyword-super-as-identifier.rs b/src/test/ui/keyword/keyword-super-as-identifier.rs
index 54dac771f01..d8941f3e532 100644
--- a/src/test/ui/keyword/keyword-super-as-identifier.rs
+++ b/src/test/ui/keyword/keyword-super-as-identifier.rs
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 fn main() {
-    let super = 22; //~ ERROR failed to resolve. There are too many initial `super`s
+    let super = 22; //~ ERROR failed to resolve: there are too many initial `super`s
 }
diff --git a/src/test/ui/keyword/keyword-super-as-identifier.stderr b/src/test/ui/keyword/keyword-super-as-identifier.stderr
index 649be45c224..9b665748794 100644
--- a/src/test/ui/keyword/keyword-super-as-identifier.stderr
+++ b/src/test/ui/keyword/keyword-super-as-identifier.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve. There are too many initial `super`s.
+error[E0433]: failed to resolve: there are too many initial `super`s.
   --> $DIR/keyword-super-as-identifier.rs:12:9
    |
-LL |     let super = 22; //~ ERROR failed to resolve. There are too many initial `super`s
-   |         ^^^^^ There are too many initial `super`s.
+LL |     let super = 22; //~ ERROR failed to resolve: there are too many initial `super`s
+   |         ^^^^^ there are too many initial `super`s.
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/keyword/keyword-super.rs b/src/test/ui/keyword/keyword-super.rs
index 02047bd639f..87640630818 100644
--- a/src/test/ui/keyword/keyword-super.rs
+++ b/src/test/ui/keyword/keyword-super.rs
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 fn main() {
-    let super: isize; //~ ERROR failed to resolve. There are too many initial `super`s
+    let super: isize; //~ ERROR failed to resolve: there are too many initial `super`s
 }
diff --git a/src/test/ui/keyword/keyword-super.stderr b/src/test/ui/keyword/keyword-super.stderr
index ac692ad45d2..690b684c133 100644
--- a/src/test/ui/keyword/keyword-super.stderr
+++ b/src/test/ui/keyword/keyword-super.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve. There are too many initial `super`s.
+error[E0433]: failed to resolve: there are too many initial `super`s.
   --> $DIR/keyword-super.rs:12:9
    |
-LL |     let super: isize; //~ ERROR failed to resolve. There are too many initial `super`s
-   |         ^^^^^ There are too many initial `super`s.
+LL |     let super: isize; //~ ERROR failed to resolve: there are too many initial `super`s
+   |         ^^^^^ there are too many initial `super`s.
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/macros/ambiguity-legacy-vs-modern.stderr b/src/test/ui/macros/ambiguity-legacy-vs-modern.stderr
index b5e1e751737..2785594585d 100644
--- a/src/test/ui/macros/ambiguity-legacy-vs-modern.stderr
+++ b/src/test/ui/macros/ambiguity-legacy-vs-modern.stderr
@@ -1,32 +1,32 @@
-error[E0659]: `m` is ambiguous
+error[E0659]: `m` is ambiguous (`macro_rules` vs non-`macro_rules` from other module)
   --> $DIR/ambiguity-legacy-vs-modern.rs:31:9
    |
 LL |         m!() //~ ERROR `m` is ambiguous
    |         ^ ambiguous name
    |
-note: `m` could refer to the name defined here
+note: `m` could refer to the macro defined here
   --> $DIR/ambiguity-legacy-vs-modern.rs:26:5
    |
 LL |     macro_rules! m { () => (()) }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: `m` could also refer to the name defined here
+note: `m` could also refer to the macro defined here
   --> $DIR/ambiguity-legacy-vs-modern.rs:29:9
    |
 LL |         macro m() { 0 }
    |         ^^^^^^^^^^^^^^^
 
-error[E0659]: `m` is ambiguous
+error[E0659]: `m` is ambiguous (`macro_rules` vs non-`macro_rules` from other module)
   --> $DIR/ambiguity-legacy-vs-modern.rs:43:5
    |
 LL |     m!() //~ ERROR `m` is ambiguous
    |     ^ ambiguous name
    |
-note: `m` could refer to the name defined here
+note: `m` could refer to the macro defined here
   --> $DIR/ambiguity-legacy-vs-modern.rs:40:9
    |
 LL |         macro_rules! m { () => (()) }
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: `m` could also refer to the name defined here
+note: `m` could also refer to the macro defined here
   --> $DIR/ambiguity-legacy-vs-modern.rs:36:5
    |
 LL |     macro m() { 0 }
diff --git a/src/test/ui/macros/macro-inner-attributes.rs b/src/test/ui/macros/macro-inner-attributes.rs
index 1111b21d455..2a58fd55453 100644
--- a/src/test/ui/macros/macro-inner-attributes.rs
+++ b/src/test/ui/macros/macro-inner-attributes.rs
@@ -25,6 +25,6 @@ test!(b,
 #[qux]
 fn main() {
     a::bar();
-    //~^ ERROR failed to resolve. Use of undeclared type or module `a`
+    //~^ ERROR failed to resolve: use of undeclared type or module `a`
     b::bar();
 }
diff --git a/src/test/ui/macros/macro-inner-attributes.stderr b/src/test/ui/macros/macro-inner-attributes.stderr
index 11922bc448b..47d9469779b 100644
--- a/src/test/ui/macros/macro-inner-attributes.stderr
+++ b/src/test/ui/macros/macro-inner-attributes.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve. Use of undeclared type or module `a`
+error[E0433]: failed to resolve: use of undeclared type or module `a`
   --> $DIR/macro-inner-attributes.rs:27:5
    |
 LL |     a::bar();
-   |     ^ Use of undeclared type or module `a`
+   |     ^ use of undeclared type or module `a`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/macros/macro-path-prelude-fail-1.rs b/src/test/ui/macros/macro-path-prelude-fail-1.rs
index e1181eb741b..bdf3ac0f69f 100644
--- a/src/test/ui/macros/macro-path-prelude-fail-1.rs
+++ b/src/test/ui/macros/macro-path-prelude-fail-1.rs
@@ -12,8 +12,8 @@
 
 mod m {
     fn check() {
-        Vec::clone!(); //~ ERROR failed to resolve. Not a module `Vec`
-        u8::clone!(); //~ ERROR failed to resolve. Not a module `u8`
+        Vec::clone!(); //~ ERROR failed to resolve: not a module `Vec`
+        u8::clone!(); //~ ERROR failed to resolve: not a module `u8`
     }
 }
 
diff --git a/src/test/ui/macros/macro-path-prelude-fail-1.stderr b/src/test/ui/macros/macro-path-prelude-fail-1.stderr
index fc74937d912..590e4f0fd06 100644
--- a/src/test/ui/macros/macro-path-prelude-fail-1.stderr
+++ b/src/test/ui/macros/macro-path-prelude-fail-1.stderr
@@ -1,14 +1,14 @@
-error[E0433]: failed to resolve. Not a module `Vec`
+error[E0433]: failed to resolve: not a module `Vec`
   --> $DIR/macro-path-prelude-fail-1.rs:15:9
    |
-LL |         Vec::clone!(); //~ ERROR failed to resolve. Not a module `Vec`
-   |         ^^^ Not a module `Vec`
+LL |         Vec::clone!(); //~ ERROR failed to resolve: not a module `Vec`
+   |         ^^^ not a module `Vec`
 
-error[E0433]: failed to resolve. Not a module `u8`
+error[E0433]: failed to resolve: not a module `u8`
   --> $DIR/macro-path-prelude-fail-1.rs:16:9
    |
-LL |         u8::clone!(); //~ ERROR failed to resolve. Not a module `u8`
-   |         ^^ Not a module `u8`
+LL |         u8::clone!(); //~ ERROR failed to resolve: not a module `u8`
+   |         ^^ not a module `u8`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/macros/macro-path-prelude-fail-2.rs b/src/test/ui/macros/macro-path-prelude-fail-2.rs
index 82258dac37b..e27c061e195 100644
--- a/src/test/ui/macros/macro-path-prelude-fail-2.rs
+++ b/src/test/ui/macros/macro-path-prelude-fail-2.rs
@@ -10,7 +10,7 @@
 
 mod m {
     fn check() {
-        Result::Ok!(); //~ ERROR fail to resolve non-ident macro path
+        Result::Ok!(); //~ ERROR failed to resolve: partially resolved path in a macro
     }
 }
 
diff --git a/src/test/ui/macros/macro-path-prelude-fail-2.stderr b/src/test/ui/macros/macro-path-prelude-fail-2.stderr
index 876ee2584e9..cf123f43fea 100644
--- a/src/test/ui/macros/macro-path-prelude-fail-2.stderr
+++ b/src/test/ui/macros/macro-path-prelude-fail-2.stderr
@@ -1,8 +1,9 @@
-error: fail to resolve non-ident macro path
+error[E0433]: failed to resolve: partially resolved path in a macro
   --> $DIR/macro-path-prelude-fail-2.rs:13:9
    |
-LL |         Result::Ok!(); //~ ERROR fail to resolve non-ident macro path
-   |         ^^^^^^^^^^
+LL |         Result::Ok!(); //~ ERROR failed to resolve: partially resolved path in a macro
+   |         ^^^^^^^^^^ partially resolved path in a macro
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0433`.
diff --git a/src/test/ui/macros/macro-path-prelude-shadowing.stderr b/src/test/ui/macros/macro-path-prelude-shadowing.stderr
index 688b9dc2797..904eed9f249 100644
--- a/src/test/ui/macros/macro-path-prelude-shadowing.stderr
+++ b/src/test/ui/macros/macro-path-prelude-shadowing.stderr
@@ -1,16 +1,17 @@
-error[E0659]: `std` is ambiguous
+error[E0659]: `std` is ambiguous (glob import vs any other name from outer scope during import/macro resolution)
   --> $DIR/macro-path-prelude-shadowing.rs:39:9
    |
 LL |         std::panic!(); //~ ERROR `std` is ambiguous
    |         ^^^ ambiguous name
    |
-note: `std` could refer to the name imported here
+   = note: `std` could refer to a built-in extern crate
+note: `std` could also refer to the module imported here
   --> $DIR/macro-path-prelude-shadowing.rs:37:9
    |
 LL |     use m2::*; // glob-import user-defined `std`
    |         ^^^^^
-note: `std` could also refer to the name defined here
-   = note: consider adding an explicit import of `std` to disambiguate
+   = help: consider adding an explicit import of `std` to disambiguate
+   = help: or use `self::std` to refer to this module unambiguously
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/macros/macro-shadowing.stderr b/src/test/ui/macros/macro-shadowing.stderr
index d996f3a7041..6985dfcc6c2 100644
--- a/src/test/ui/macros/macro-shadowing.stderr
+++ b/src/test/ui/macros/macro-shadowing.stderr
@@ -9,13 +9,13 @@ LL | m1!();
    |
    = note: macro-expanded `#[macro_use]`s may not shadow existing macros (see RFC 1560)
 
-error[E0659]: `foo` is ambiguous
+error[E0659]: `foo` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
   --> $DIR/macro-shadowing.rs:27:1
    |
 LL | foo!(); //~ ERROR `foo` is ambiguous
    | ^^^ ambiguous name
    |
-note: `foo` could refer to the name defined here
+note: `foo` could refer to the macro defined here
   --> $DIR/macro-shadowing.rs:20:5
    |
 LL |     macro_rules! foo { () => {} }
@@ -23,12 +23,11 @@ LL |     macro_rules! foo { () => {} }
 ...
 LL | m1!();
    | ------ in this macro invocation
-note: `foo` could also refer to the name defined here
+note: `foo` could also refer to the macro defined here
   --> $DIR/macro-shadowing.rs:15:1
    |
 LL | macro_rules! foo { () => {} }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: macro-expanded macros do not shadow
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/macros/macro_path_as_generic_bound.stderr b/src/test/ui/macros/macro_path_as_generic_bound.stderr
index 0f9f0607c5b..8b4fe9f200d 100644
--- a/src/test/ui/macros/macro_path_as_generic_bound.stderr
+++ b/src/test/ui/macros/macro_path_as_generic_bound.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve. Use of undeclared type or module `m`
+error[E0433]: failed to resolve: use of undeclared type or module `m`
   --> $DIR/macro_path_as_generic_bound.rs:17:6
    |
 LL | foo!(m::m2::A); //~ ERROR failed to resolve
-   |      ^ Use of undeclared type or module `m`
+   |      ^ use of undeclared type or module `m`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/macros/restricted-shadowing-legacy.stderr b/src/test/ui/macros/restricted-shadowing-legacy.stderr
index 9e0d40c44b6..2135d63c80e 100644
--- a/src/test/ui/macros/restricted-shadowing-legacy.stderr
+++ b/src/test/ui/macros/restricted-shadowing-legacy.stderr
@@ -1,10 +1,10 @@
-error[E0659]: `m` is ambiguous
+error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
   --> $DIR/restricted-shadowing-legacy.rs:101:13
    |
 LL |             m!(); //~ ERROR `m` is ambiguous
    |             ^ ambiguous name
    |
-note: `m` could refer to the name defined here
+note: `m` could refer to the macro defined here
   --> $DIR/restricted-shadowing-legacy.rs:88:9
    |
 LL |         macro_rules! m { () => { Right } }
@@ -12,7 +12,7 @@ LL |         macro_rules! m { () => { Right } }
 ...
 LL | include!();
    | ----------- in this macro invocation
-note: `m` could also refer to the name defined here
+note: `m` could also refer to the macro defined here
   --> $DIR/restricted-shadowing-legacy.rs:97:9
    |
 LL |         macro_rules! m { () => {} }
@@ -20,15 +20,14 @@ LL |         macro_rules! m { () => {} }
 ...
 LL | include!();
    | ----------- in this macro invocation
-   = note: macro-expanded macros do not shadow
 
-error[E0659]: `m` is ambiguous
+error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
   --> $DIR/restricted-shadowing-legacy.rs:139:42
    |
 LL |         macro_rules! gen_invoc { () => { m!() } } //~ ERROR `m` is ambiguous
    |                                          ^ ambiguous name
    |
-note: `m` could refer to the name defined here
+note: `m` could refer to the macro defined here
   --> $DIR/restricted-shadowing-legacy.rs:88:9
    |
 LL |         macro_rules! m { () => { Right } }
@@ -36,7 +35,7 @@ LL |         macro_rules! m { () => { Right } }
 ...
 LL | include!();
    | ----------- in this macro invocation
-note: `m` could also refer to the name defined here
+note: `m` could also refer to the macro defined here
   --> $DIR/restricted-shadowing-legacy.rs:135:9
    |
 LL |         macro_rules! m { () => {} }
@@ -44,15 +43,14 @@ LL |         macro_rules! m { () => {} }
 ...
 LL | include!();
    | ----------- in this macro invocation
-   = note: macro-expanded macros do not shadow
 
-error[E0659]: `m` is ambiguous
+error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
   --> $DIR/restricted-shadowing-legacy.rs:148:9
    |
 LL |         m!(); //~ ERROR `m` is ambiguous
    |         ^ ambiguous name
    |
-note: `m` could refer to the name defined here
+note: `m` could refer to the macro defined here
   --> $DIR/restricted-shadowing-legacy.rs:88:9
    |
 LL |         macro_rules! m { () => { Right } }
@@ -60,7 +58,7 @@ LL |         macro_rules! m { () => { Right } }
 ...
 LL | include!();
    | ----------- in this macro invocation
-note: `m` could also refer to the name defined here
+note: `m` could also refer to the macro defined here
   --> $DIR/restricted-shadowing-legacy.rs:144:9
    |
 LL |         macro_rules! m { () => {} }
@@ -68,15 +66,14 @@ LL |         macro_rules! m { () => {} }
 ...
 LL | include!();
    | ----------- in this macro invocation
-   = note: macro-expanded macros do not shadow
 
-error[E0659]: `m` is ambiguous
+error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
   --> $DIR/restricted-shadowing-legacy.rs:164:9
    |
 LL |         m!(); //~ ERROR `m` is ambiguous
    |         ^ ambiguous name
    |
-note: `m` could refer to the name defined here
+note: `m` could refer to the macro defined here
   --> $DIR/restricted-shadowing-legacy.rs:88:9
    |
 LL |         macro_rules! m { () => { Right } }
@@ -84,7 +81,7 @@ LL |         macro_rules! m { () => { Right } }
 ...
 LL | include!();
    | ----------- in this macro invocation
-note: `m` could also refer to the name defined here
+note: `m` could also refer to the macro defined here
   --> $DIR/restricted-shadowing-legacy.rs:85:9
    |
 LL |         macro_rules! m { () => { Wrong } }
@@ -92,15 +89,14 @@ LL |         macro_rules! m { () => { Wrong } }
 ...
 LL | include!();
    | ----------- in this macro invocation
-   = note: macro-expanded macros do not shadow
 
-error[E0659]: `m` is ambiguous
+error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
   --> $DIR/restricted-shadowing-legacy.rs:180:13
    |
 LL |             m!(); //~ ERROR `m` is ambiguous
    |             ^ ambiguous name
    |
-note: `m` could refer to the name defined here
+note: `m` could refer to the macro defined here
   --> $DIR/restricted-shadowing-legacy.rs:88:9
    |
 LL |         macro_rules! m { () => { Right } }
@@ -108,7 +104,7 @@ LL |         macro_rules! m { () => { Right } }
 ...
 LL | include!();
    | ----------- in this macro invocation
-note: `m` could also refer to the name defined here
+note: `m` could also refer to the macro defined here
   --> $DIR/restricted-shadowing-legacy.rs:85:9
    |
 LL |         macro_rules! m { () => { Wrong } }
@@ -116,15 +112,14 @@ LL |         macro_rules! m { () => { Wrong } }
 ...
 LL | include!();
    | ----------- in this macro invocation
-   = note: macro-expanded macros do not shadow
 
-error[E0659]: `m` is ambiguous
+error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
   --> $DIR/restricted-shadowing-legacy.rs:218:42
    |
 LL |         macro_rules! gen_invoc { () => { m!() } } //~ ERROR `m` is ambiguous
    |                                          ^ ambiguous name
    |
-note: `m` could refer to the name defined here
+note: `m` could refer to the macro defined here
   --> $DIR/restricted-shadowing-legacy.rs:88:9
    |
 LL |         macro_rules! m { () => { Right } }
@@ -132,7 +127,7 @@ LL |         macro_rules! m { () => { Right } }
 ...
 LL | include!();
    | ----------- in this macro invocation
-note: `m` could also refer to the name defined here
+note: `m` could also refer to the macro defined here
   --> $DIR/restricted-shadowing-legacy.rs:85:9
    |
 LL |         macro_rules! m { () => { Wrong } }
@@ -140,15 +135,14 @@ LL |         macro_rules! m { () => { Wrong } }
 ...
 LL | include!();
    | ----------- in this macro invocation
-   = note: macro-expanded macros do not shadow
 
-error[E0659]: `m` is ambiguous
+error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
   --> $DIR/restricted-shadowing-legacy.rs:232:9
    |
 LL |         m!(); //~ ERROR `m` is ambiguous
    |         ^ ambiguous name
    |
-note: `m` could refer to the name defined here
+note: `m` could refer to the macro defined here
   --> $DIR/restricted-shadowing-legacy.rs:88:9
    |
 LL |         macro_rules! m { () => { Right } }
@@ -156,7 +150,7 @@ LL |         macro_rules! m { () => { Right } }
 ...
 LL | include!();
    | ----------- in this macro invocation
-note: `m` could also refer to the name defined here
+note: `m` could also refer to the macro defined here
   --> $DIR/restricted-shadowing-legacy.rs:227:13
    |
 LL |             macro_rules! m { () => {} }
@@ -164,15 +158,14 @@ LL |             macro_rules! m { () => {} }
 ...
 LL | include!();
    | ----------- in this macro invocation
-   = note: macro-expanded macros do not shadow
 
-error[E0659]: `m` is ambiguous
+error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
   --> $DIR/restricted-shadowing-legacy.rs:262:42
    |
 LL |         macro_rules! gen_invoc { () => { m!() } } //~ ERROR `m` is ambiguous
    |                                          ^ ambiguous name
    |
-note: `m` could refer to the name defined here
+note: `m` could refer to the macro defined here
   --> $DIR/restricted-shadowing-legacy.rs:88:9
    |
 LL |         macro_rules! m { () => { Right } }
@@ -180,7 +173,7 @@ LL |         macro_rules! m { () => { Right } }
 ...
 LL | include!();
    | ----------- in this macro invocation
-note: `m` could also refer to the name defined here
+note: `m` could also refer to the macro defined here
   --> $DIR/restricted-shadowing-legacy.rs:257:13
    |
 LL |             macro_rules! m { () => {} }
@@ -188,7 +181,6 @@ LL |             macro_rules! m { () => {} }
 ...
 LL | include!();
    | ----------- in this macro invocation
-   = note: macro-expanded macros do not shadow
 
 error: aborting due to 8 previous errors
 
diff --git a/src/test/ui/macros/restricted-shadowing-modern.stderr b/src/test/ui/macros/restricted-shadowing-modern.stderr
index 0462438be78..2449e8512d3 100644
--- a/src/test/ui/macros/restricted-shadowing-modern.stderr
+++ b/src/test/ui/macros/restricted-shadowing-modern.stderr
@@ -1,10 +1,10 @@
-error[E0659]: `m` is ambiguous
+error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
   --> $DIR/restricted-shadowing-modern.rs:106:17
    |
 LL |                 m!(); //~ ERROR `m` is ambiguous
    |                 ^ ambiguous name
    |
-note: `m` could refer to the name defined here
+note: `m` could refer to the macro defined here
   --> $DIR/restricted-shadowing-modern.rs:91:9
    |
 LL |         macro m() { Right }
@@ -12,7 +12,7 @@ LL |         macro m() { Right }
 ...
 LL | include!();
    | ----------- in this macro invocation
-note: `m` could also refer to the name defined here
+note: `m` could also refer to the macro defined here
   --> $DIR/restricted-shadowing-modern.rs:101:9
    |
 LL |         macro m() {}
@@ -20,15 +20,14 @@ LL |         macro m() {}
 ...
 LL | include!();
    | ----------- in this macro invocation
-   = note: macro-expanded macros do not shadow
 
-error[E0659]: `m` is ambiguous
+error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
   --> $DIR/restricted-shadowing-modern.rs:149:33
    |
 LL |             macro gen_invoc() { m!() } //~ ERROR `m` is ambiguous
    |                                 ^ ambiguous name
    |
-note: `m` could refer to the name defined here
+note: `m` could refer to the macro defined here
   --> $DIR/restricted-shadowing-modern.rs:91:9
    |
 LL |         macro m() { Right }
@@ -36,7 +35,7 @@ LL |         macro m() { Right }
 ...
 LL | include!();
    | ----------- in this macro invocation
-note: `m` could also refer to the name defined here
+note: `m` could also refer to the macro defined here
   --> $DIR/restricted-shadowing-modern.rs:145:9
    |
 LL |         macro m() {}
@@ -44,15 +43,14 @@ LL |         macro m() {}
 ...
 LL | include!();
    | ----------- in this macro invocation
-   = note: macro-expanded macros do not shadow
 
-error[E0659]: `m` is ambiguous
+error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
   --> $DIR/restricted-shadowing-modern.rs:158:13
    |
 LL |             m!(); //~ ERROR `m` is ambiguous
    |             ^ ambiguous name
    |
-note: `m` could refer to the name defined here
+note: `m` could refer to the macro defined here
   --> $DIR/restricted-shadowing-modern.rs:91:9
    |
 LL |         macro m() { Right }
@@ -60,7 +58,7 @@ LL |         macro m() { Right }
 ...
 LL | include!();
    | ----------- in this macro invocation
-note: `m` could also refer to the name defined here
+note: `m` could also refer to the macro defined here
   --> $DIR/restricted-shadowing-modern.rs:155:9
    |
 LL |         macro m() {}
@@ -68,15 +66,14 @@ LL |         macro m() {}
 ...
 LL | include!();
    | ----------- in this macro invocation
-   = note: macro-expanded macros do not shadow
 
-error[E0659]: `m` is ambiguous
+error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
   --> $DIR/restricted-shadowing-modern.rs:174:13
    |
 LL |             m!(); //~ ERROR `m` is ambiguous
    |             ^ ambiguous name
    |
-note: `m` could refer to the name defined here
+note: `m` could refer to the macro defined here
   --> $DIR/restricted-shadowing-modern.rs:91:9
    |
 LL |         macro m() { Right }
@@ -84,7 +81,7 @@ LL |         macro m() { Right }
 ...
 LL | include!();
    | ----------- in this macro invocation
-note: `m` could also refer to the name defined here
+note: `m` could also refer to the macro defined here
   --> $DIR/restricted-shadowing-modern.rs:87:9
    |
 LL |         macro m() { Wrong }
@@ -92,15 +89,14 @@ LL |         macro m() { Wrong }
 ...
 LL | include!();
    | ----------- in this macro invocation
-   = note: macro-expanded macros do not shadow
 
-error[E0659]: `m` is ambiguous
+error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
   --> $DIR/restricted-shadowing-modern.rs:192:17
    |
 LL |                 m!(); //~ ERROR `m` is ambiguous
    |                 ^ ambiguous name
    |
-note: `m` could refer to the name defined here
+note: `m` could refer to the macro defined here
   --> $DIR/restricted-shadowing-modern.rs:91:9
    |
 LL |         macro m() { Right }
@@ -108,7 +104,7 @@ LL |         macro m() { Right }
 ...
 LL | include!();
    | ----------- in this macro invocation
-note: `m` could also refer to the name defined here
+note: `m` could also refer to the macro defined here
   --> $DIR/restricted-shadowing-modern.rs:87:9
    |
 LL |         macro m() { Wrong }
@@ -116,15 +112,14 @@ LL |         macro m() { Wrong }
 ...
 LL | include!();
    | ----------- in this macro invocation
-   = note: macro-expanded macros do not shadow
 
-error[E0659]: `m` is ambiguous
+error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
   --> $DIR/restricted-shadowing-modern.rs:235:33
    |
 LL |             macro gen_invoc() { m!() } //~ ERROR `m` is ambiguous
    |                                 ^ ambiguous name
    |
-note: `m` could refer to the name defined here
+note: `m` could refer to the macro defined here
   --> $DIR/restricted-shadowing-modern.rs:91:9
    |
 LL |         macro m() { Right }
@@ -132,7 +127,7 @@ LL |         macro m() { Right }
 ...
 LL | include!();
    | ----------- in this macro invocation
-note: `m` could also refer to the name defined here
+note: `m` could also refer to the macro defined here
   --> $DIR/restricted-shadowing-modern.rs:87:9
    |
 LL |         macro m() { Wrong }
@@ -140,7 +135,6 @@ LL |         macro m() { Wrong }
 ...
 LL | include!();
    | ----------- in this macro invocation
-   = note: macro-expanded macros do not shadow
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/out-of-order-shadowing.stderr b/src/test/ui/out-of-order-shadowing.stderr
index d96a802cb3f..4696e205728 100644
--- a/src/test/ui/out-of-order-shadowing.stderr
+++ b/src/test/ui/out-of-order-shadowing.stderr
@@ -1,20 +1,19 @@
-error[E0659]: `bar` is ambiguous
+error[E0659]: `bar` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
   --> $DIR/out-of-order-shadowing.rs:15:1
    |
 LL | bar!(); //~ ERROR `bar` is ambiguous
    | ^^^ ambiguous name
    |
-note: `bar` could refer to the name defined here
+note: `bar` could refer to the macro defined here
   --> $DIR/out-of-order-shadowing.rs:14:1
    |
 LL | define_macro!(bar);
    | ^^^^^^^^^^^^^^^^^^^
-note: `bar` could also refer to the name defined here
+note: `bar` could also refer to the macro defined here
   --> $DIR/out-of-order-shadowing.rs:13:1
    |
 LL | macro_rules! bar { () => {} }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: macro-expanded macros do not shadow
    = 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/pattern/pat-shadow-in-nested-binding.stderr b/src/test/ui/pattern/pat-shadow-in-nested-binding.stderr
index 9dd6a318e98..994c78d575e 100644
--- a/src/test/ui/pattern/pat-shadow-in-nested-binding.stderr
+++ b/src/test/ui/pattern/pat-shadow-in-nested-binding.stderr
@@ -2,7 +2,7 @@ error[E0530]: let bindings cannot shadow tuple structs
   --> $DIR/pat-shadow-in-nested-binding.rs:14:10
    |
 LL | struct foo(usize);
-   | ------------------ a tuple struct `foo` is defined here
+   | ------------------ the tuple struct `foo` is defined here
 ...
 LL |     let (foo, _) = (2, 3); //~ ERROR let bindings cannot shadow tuple structs
    |          ^^^ cannot be named the same as a tuple struct
diff --git a/src/test/ui/pattern/pattern-binding-disambiguation.stderr b/src/test/ui/pattern/pattern-binding-disambiguation.stderr
index 7acdb07e10d..5d14610b8a1 100644
--- a/src/test/ui/pattern/pattern-binding-disambiguation.stderr
+++ b/src/test/ui/pattern/pattern-binding-disambiguation.stderr
@@ -2,7 +2,7 @@ error[E0530]: match bindings cannot shadow tuple structs
   --> $DIR/pattern-binding-disambiguation.rs:34:9
    |
 LL | struct TupleStruct();
-   | --------------------- a tuple struct `TupleStruct` is defined here
+   | --------------------- the tuple struct `TupleStruct` is defined here
 ...
 LL |         TupleStruct => {} //~ ERROR match bindings cannot shadow tuple structs
    |         ^^^^^^^^^^^ cannot be named the same as a tuple struct
@@ -11,7 +11,7 @@ error[E0530]: match bindings cannot shadow tuple variants
   --> $DIR/pattern-binding-disambiguation.rs:43:9
    |
 LL | use E::*;
-   |     ---- a tuple variant `TupleVariant` is imported here
+   |     ---- the tuple variant `TupleVariant` is imported here
 ...
 LL |         TupleVariant => {} //~ ERROR match bindings cannot shadow tuple variants
    |         ^^^^^^^^^^^^ cannot be named the same as a tuple variant
@@ -20,7 +20,7 @@ error[E0530]: match bindings cannot shadow struct variants
   --> $DIR/pattern-binding-disambiguation.rs:46:9
    |
 LL | use E::*;
-   |     ---- a struct variant `BracedVariant` is imported here
+   |     ---- the struct variant `BracedVariant` is imported here
 ...
 LL |         BracedVariant => {} //~ ERROR match bindings cannot shadow struct variants
    |         ^^^^^^^^^^^^^ cannot be named the same as a struct variant
@@ -29,7 +29,7 @@ error[E0530]: match bindings cannot shadow statics
   --> $DIR/pattern-binding-disambiguation.rs:52:9
    |
 LL | static STATIC: () = ();
-   | ----------------------- a static `STATIC` is defined here
+   | ----------------------- the static `STATIC` is defined here
 ...
 LL |         STATIC => {} //~ ERROR match bindings cannot shadow statics
    |         ^^^^^^ cannot be named the same as a static
@@ -38,7 +38,7 @@ error[E0530]: let bindings cannot shadow tuple structs
   --> $DIR/pattern-binding-disambiguation.rs:59:9
    |
 LL | struct TupleStruct();
-   | --------------------- a tuple struct `TupleStruct` is defined here
+   | --------------------- the tuple struct `TupleStruct` is defined here
 ...
 LL |     let TupleStruct = doesnt_matter; //~ ERROR let bindings cannot shadow tuple structs
    |         ^^^^^^^^^^^ cannot be named the same as a tuple struct
@@ -47,7 +47,7 @@ error[E0530]: let bindings cannot shadow tuple variants
   --> $DIR/pattern-binding-disambiguation.rs:62:9
    |
 LL | use E::*;
-   |     ---- a tuple variant `TupleVariant` is imported here
+   |     ---- the tuple variant `TupleVariant` is imported here
 ...
 LL |     let TupleVariant = doesnt_matter; //~ ERROR let bindings cannot shadow tuple variants
    |         ^^^^^^^^^^^^ cannot be named the same as a tuple variant
@@ -56,7 +56,7 @@ error[E0530]: let bindings cannot shadow struct variants
   --> $DIR/pattern-binding-disambiguation.rs:63:9
    |
 LL | use E::*;
-   |     ---- a struct variant `BracedVariant` is imported here
+   |     ---- the struct variant `BracedVariant` is imported here
 ...
 LL |     let BracedVariant = doesnt_matter; //~ ERROR let bindings cannot shadow struct variants
    |         ^^^^^^^^^^^^^ cannot be named the same as a struct variant
@@ -65,7 +65,7 @@ error[E0530]: let bindings cannot shadow statics
   --> $DIR/pattern-binding-disambiguation.rs:65:9
    |
 LL | static STATIC: () = ();
-   | ----------------------- a static `STATIC` is defined here
+   | ----------------------- the static `STATIC` is defined here
 ...
 LL |     let STATIC = doesnt_matter; //~ ERROR let bindings cannot shadow statics
    |         ^^^^^^ cannot be named the same as a static
diff --git a/src/test/ui/pattern/pattern-error-continue.rs b/src/test/ui/pattern/pattern-error-continue.rs
index e63b84594aa..c544ca4e304 100644
--- a/src/test/ui/pattern/pattern-error-continue.rs
+++ b/src/test/ui/pattern/pattern-error-continue.rs
@@ -42,6 +42,6 @@ fn main() {
     //~| expected char, found bool
 
     match () {
-        E::V => {} //~ ERROR failed to resolve. Use of undeclared type or module `E`
+        E::V => {} //~ ERROR failed to resolve: use of undeclared type or module `E`
     }
 }
diff --git a/src/test/ui/pattern/pattern-error-continue.stderr b/src/test/ui/pattern/pattern-error-continue.stderr
index b24366c48bc..f2c35ef872d 100644
--- a/src/test/ui/pattern/pattern-error-continue.stderr
+++ b/src/test/ui/pattern/pattern-error-continue.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve. Use of undeclared type or module `E`
+error[E0433]: failed to resolve: use of undeclared type or module `E`
   --> $DIR/pattern-error-continue.rs:45:9
    |
-LL |         E::V => {} //~ ERROR failed to resolve. Use of undeclared type or module `E`
-   |         ^ Use of undeclared type or module `E`
+LL |         E::V => {} //~ ERROR failed to resolve: use of undeclared type or module `E`
+   |         ^ use of undeclared type or module `E`
 
 error[E0532]: expected tuple struct/variant, found unit variant `A::D`
   --> $DIR/pattern-error-continue.rs:28:9
diff --git a/src/test/ui/privacy/decl-macro.rs b/src/test/ui/privacy/decl-macro.rs
new file mode 100644
index 00000000000..1eb49bd5301
--- /dev/null
+++ b/src/test/ui/privacy/decl-macro.rs
@@ -0,0 +1,9 @@
+#![feature(decl_macro)]
+
+mod m {
+    macro mac() {}
+}
+
+fn main() {
+    m::mac!(); //~ ERROR macro `mac` is private
+}
diff --git a/src/test/ui/privacy/decl-macro.stderr b/src/test/ui/privacy/decl-macro.stderr
new file mode 100644
index 00000000000..c8b043d1b5f
--- /dev/null
+++ b/src/test/ui/privacy/decl-macro.stderr
@@ -0,0 +1,9 @@
+error[E0603]: macro `mac` is private
+  --> $DIR/decl-macro.rs:8:8
+   |
+LL |     m::mac!(); //~ ERROR macro `mac` is private
+   |        ^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0603`.
diff --git a/src/test/ui/privacy/restricted/test.rs b/src/test/ui/privacy/restricted/test.rs
index 8c1d609e244..2b2d9b76bdd 100644
--- a/src/test/ui/privacy/restricted/test.rs
+++ b/src/test/ui/privacy/restricted/test.rs
@@ -57,6 +57,6 @@ fn main() {
 }
 
 mod pathological {
-    pub(in bad::path) mod m1 {} //~ ERROR failed to resolve. Maybe a missing `extern crate bad;`?
+    pub(in bad::path) mod m1 {} //~ ERROR failed to resolve: maybe a missing `extern crate bad;`?
     pub(in foo) mod m2 {} //~ ERROR visibilities can only be restricted to ancestor modules
 }
diff --git a/src/test/ui/privacy/restricted/test.stderr b/src/test/ui/privacy/restricted/test.stderr
index afc3ee2db4b..01e224910a5 100644
--- a/src/test/ui/privacy/restricted/test.stderr
+++ b/src/test/ui/privacy/restricted/test.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve. Maybe a missing `extern crate bad;`?
+error[E0433]: failed to resolve: maybe a missing `extern crate bad;`?
   --> $DIR/test.rs:60:12
    |
-LL |     pub(in bad::path) mod m1 {} //~ ERROR failed to resolve. Maybe a missing `extern crate bad;`?
-   |            ^^^ Maybe a missing `extern crate bad;`?
+LL |     pub(in bad::path) mod m1 {} //~ ERROR failed to resolve: maybe a missing `extern crate bad;`?
+   |            ^^^ maybe a missing `extern crate bad;`?
 
 error: visibilities can only be restricted to ancestor modules
   --> $DIR/test.rs:61:12
diff --git a/src/test/ui/resolve/resolve-variant-assoc-item.rs b/src/test/ui/resolve/resolve-variant-assoc-item.rs
index 869eed5a8d7..01f493e954b 100644
--- a/src/test/ui/resolve/resolve-variant-assoc-item.rs
+++ b/src/test/ui/resolve/resolve-variant-assoc-item.rs
@@ -12,6 +12,6 @@ enum E { V }
 use E::V;
 
 fn main() {
-    E::V::associated_item; //~ ERROR failed to resolve. Not a module `V`
-    V::associated_item; //~ ERROR failed to resolve. Not a module `V`
+    E::V::associated_item; //~ ERROR failed to resolve: not a module `V`
+    V::associated_item; //~ ERROR failed to resolve: not a module `V`
 }
diff --git a/src/test/ui/resolve/resolve-variant-assoc-item.stderr b/src/test/ui/resolve/resolve-variant-assoc-item.stderr
index a80a7c39249..ef2d0a71b5b 100644
--- a/src/test/ui/resolve/resolve-variant-assoc-item.stderr
+++ b/src/test/ui/resolve/resolve-variant-assoc-item.stderr
@@ -1,14 +1,14 @@
-error[E0433]: failed to resolve. Not a module `V`
+error[E0433]: failed to resolve: not a module `V`
   --> $DIR/resolve-variant-assoc-item.rs:15:8
    |
-LL |     E::V::associated_item; //~ ERROR failed to resolve. Not a module `V`
-   |        ^ Not a module `V`
+LL |     E::V::associated_item; //~ ERROR failed to resolve: not a module `V`
+   |        ^ not a module `V`
 
-error[E0433]: failed to resolve. Not a module `V`
+error[E0433]: failed to resolve: not a module `V`
   --> $DIR/resolve-variant-assoc-item.rs:16:5
    |
-LL |     V::associated_item; //~ ERROR failed to resolve. Not a module `V`
-   |     ^ Not a module `V`
+LL |     V::associated_item; //~ ERROR failed to resolve: not a module `V`
+   |     ^ not a module `V`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/resolve_self_super_hint.rs b/src/test/ui/resolve_self_super_hint.rs
index a30e73cf02d..2ce2d765832 100644
--- a/src/test/ui/resolve_self_super_hint.rs
+++ b/src/test/ui/resolve_self_super_hint.rs
@@ -15,19 +15,19 @@ mod a {
     extern crate alloc;
     use alloc::HashMap;
     //~^ ERROR unresolved import `alloc` [E0432]
-    //~| Did you mean `self::alloc`?
+    //~| did you mean `self::alloc`?
     mod b {
         use alloc::HashMap;
         //~^ ERROR unresolved import `alloc` [E0432]
-        //~| Did you mean `super::alloc`?
+        //~| did you mean `super::alloc`?
         mod c {
             use alloc::HashMap;
             //~^ ERROR unresolved import `alloc` [E0432]
-            //~| Did you mean `std::alloc`?
+            //~| did you mean `a::alloc`?
             mod d {
                 use alloc::HashMap;
                 //~^ ERROR unresolved import `alloc` [E0432]
-                //~| Did you mean `std::alloc`?
+                //~| did you mean `a::alloc`?
             }
         }
     }
diff --git a/src/test/ui/resolve_self_super_hint.stderr b/src/test/ui/resolve_self_super_hint.stderr
index b58a23724e4..613107712b2 100644
--- a/src/test/ui/resolve_self_super_hint.stderr
+++ b/src/test/ui/resolve_self_super_hint.stderr
@@ -2,25 +2,25 @@ error[E0432]: unresolved import `alloc`
   --> $DIR/resolve_self_super_hint.rs:16:9
    |
 LL |     use alloc::HashMap;
-   |         ^^^^^ Did you mean `self::alloc`?
+   |         ^^^^^ did you mean `self::alloc`?
 
 error[E0432]: unresolved import `alloc`
   --> $DIR/resolve_self_super_hint.rs:20:13
    |
 LL |         use alloc::HashMap;
-   |             ^^^^^ Did you mean `super::alloc`?
+   |             ^^^^^ did you mean `super::alloc`?
 
 error[E0432]: unresolved import `alloc`
   --> $DIR/resolve_self_super_hint.rs:24:17
    |
 LL |             use alloc::HashMap;
-   |                 ^^^^^ Did you mean `std::alloc`?
+   |                 ^^^^^ did you mean `a::alloc`?
 
 error[E0432]: unresolved import `alloc`
   --> $DIR/resolve_self_super_hint.rs:28:21
    |
 LL |                 use alloc::HashMap;
-   |                     ^^^^^ Did you mean `std::alloc`?
+   |                     ^^^^^ did you mean `a::alloc`?
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/rfc-2126-crate-paths/crate-path-non-absolute.stderr b/src/test/ui/rfc-2126-crate-paths/crate-path-non-absolute.stderr
index f16c8496077..2751d8cb285 100644
--- a/src/test/ui/rfc-2126-crate-paths/crate-path-non-absolute.stderr
+++ b/src/test/ui/rfc-2126-crate-paths/crate-path-non-absolute.stderr
@@ -1,10 +1,10 @@
-error[E0433]: failed to resolve. `crate` in paths can only be used in start position
+error[E0433]: failed to resolve: `crate` in paths can only be used in start position
   --> $DIR/crate-path-non-absolute.rs:17:22
    |
 LL |         let s = ::m::crate::S; //~ ERROR failed to resolve
    |                      ^^^^^ `crate` in paths can only be used in start position
 
-error[E0433]: failed to resolve. global paths cannot start with `crate`
+error[E0433]: failed to resolve: global paths cannot start with `crate`
   --> $DIR/crate-path-non-absolute.rs:18:20
    |
 LL |         let s1 = ::crate::S; //~ ERROR failed to resolve
diff --git a/src/test/ui/rfc-2126-extern-absolute-paths/non-existent-1.stderr b/src/test/ui/rfc-2126-extern-absolute-paths/non-existent-1.stderr
index 1a8ceec5dac..39b2db7a19f 100644
--- a/src/test/ui/rfc-2126-extern-absolute-paths/non-existent-1.stderr
+++ b/src/test/ui/rfc-2126-extern-absolute-paths/non-existent-1.stderr
@@ -2,7 +2,7 @@ error[E0432]: unresolved import `xcrate`
   --> $DIR/non-existent-1.rs:13:5
    |
 LL | use xcrate::S; //~ ERROR unresolved import `xcrate`
-   |     ^^^^^^ Could not find `xcrate` in `{{root}}`
+   |     ^^^^^^ use of undeclared type or module `xcrate`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rfc-2126-extern-absolute-paths/non-existent-2.rs b/src/test/ui/rfc-2126-extern-absolute-paths/non-existent-2.rs
index 41adb974f21..a07c3f17d6f 100644
--- a/src/test/ui/rfc-2126-extern-absolute-paths/non-existent-2.rs
+++ b/src/test/ui/rfc-2126-extern-absolute-paths/non-existent-2.rs
@@ -12,5 +12,5 @@
 
 fn main() {
     let s = ::xcrate::S;
-    //~^ ERROR failed to resolve. Could not find `xcrate` in `{{root}}`
+    //~^ ERROR failed to resolve: could not find `xcrate` in `{{root}}`
 }
diff --git a/src/test/ui/rfc-2126-extern-absolute-paths/non-existent-2.stderr b/src/test/ui/rfc-2126-extern-absolute-paths/non-existent-2.stderr
index b46576b0143..30e5b0ad1df 100644
--- a/src/test/ui/rfc-2126-extern-absolute-paths/non-existent-2.stderr
+++ b/src/test/ui/rfc-2126-extern-absolute-paths/non-existent-2.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve. Could not find `xcrate` in `{{root}}`
+error[E0433]: failed to resolve: could not find `xcrate` in `{{root}}`
   --> $DIR/non-existent-2.rs:14:15
    |
 LL |     let s = ::xcrate::S;
-   |               ^^^^^^ Could not find `xcrate` in `{{root}}`
+   |               ^^^^^^ could not find `xcrate` in `{{root}}`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.rs b/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.rs
index f95961d2a9b..bfe7e4da845 100644
--- a/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.rs
+++ b/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.rs
@@ -10,10 +10,12 @@
 
 // edition:2018
 
+#![feature(uniform_paths)]
+
 // Tests that arbitrary crates (other than `core`, `std` and `meta`)
 // aren't allowed without `--extern`, even if they're in the sysroot.
 use alloc; //~ ERROR unresolved import `alloc`
-use test; //~ ERROR unresolved import `test`
-use proc_macro; //~ ERROR unresolved import `proc_macro`
+use test; //~ ERROR cannot import a built-in macro
+use proc_macro; // OK, imports the built-in `proc_macro` attribute, but not the `proc_macro` crate.
 
 fn main() {}
diff --git a/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.stderr b/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.stderr
index 0865bd6bea5..06c11b894dd 100644
--- a/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.stderr
+++ b/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.stderr
@@ -1,21 +1,15 @@
-error[E0432]: unresolved import `alloc`
-  --> $DIR/not-whitelisted.rs:15:5
-   |
-LL | use alloc; //~ ERROR unresolved import `alloc`
-   |     ^^^^^ no `alloc` external crate
-
-error[E0432]: unresolved import `test`
-  --> $DIR/not-whitelisted.rs:16:5
+error: cannot import a built-in macro
+  --> $DIR/not-whitelisted.rs:18:5
    |
-LL | use test; //~ ERROR unresolved import `test`
-   |     ^^^^ no `test` external crate
+LL | use test; //~ ERROR cannot import a built-in macro
+   |     ^^^^
 
-error[E0432]: unresolved import `proc_macro`
+error[E0432]: unresolved import `alloc`
   --> $DIR/not-whitelisted.rs:17:5
    |
-LL | use proc_macro; //~ ERROR unresolved import `proc_macro`
-   |     ^^^^^^^^^^ no `proc_macro` external crate
+LL | use alloc; //~ ERROR unresolved import `alloc`
+   |     ^^^^^ no `alloc` external crate
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0432`.
diff --git a/src/test/ui/rfc-2126-extern-in-paths/non-existent-1.stderr b/src/test/ui/rfc-2126-extern-in-paths/non-existent-1.stderr
index 55b8b625507..47ea4b8dfcb 100644
--- a/src/test/ui/rfc-2126-extern-in-paths/non-existent-1.stderr
+++ b/src/test/ui/rfc-2126-extern-in-paths/non-existent-1.stderr
@@ -2,7 +2,7 @@ error[E0432]: unresolved import `extern::xcrate`
   --> $DIR/non-existent-1.rs:13:13
    |
 LL | use extern::xcrate::S; //~ ERROR unresolved import `extern::xcrate`
-   |             ^^^^^^ Could not find `xcrate` in `extern`
+   |             ^^^^^^ could not find `xcrate` in `extern`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rfc-2126-extern-in-paths/non-existent-2.rs b/src/test/ui/rfc-2126-extern-in-paths/non-existent-2.rs
index 128ecf41a30..8d7c3993c62 100644
--- a/src/test/ui/rfc-2126-extern-in-paths/non-existent-2.rs
+++ b/src/test/ui/rfc-2126-extern-in-paths/non-existent-2.rs
@@ -12,5 +12,5 @@
 
 fn main() {
     let s = extern::xcrate::S;
-    //~^ ERROR failed to resolve. Could not find `xcrate` in `extern`
+    //~^ ERROR failed to resolve: could not find `xcrate` in `extern`
 }
diff --git a/src/test/ui/rfc-2126-extern-in-paths/non-existent-2.stderr b/src/test/ui/rfc-2126-extern-in-paths/non-existent-2.stderr
index 7fbe50a9202..89630adb5a8 100644
--- a/src/test/ui/rfc-2126-extern-in-paths/non-existent-2.stderr
+++ b/src/test/ui/rfc-2126-extern-in-paths/non-existent-2.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve. Could not find `xcrate` in `extern`
+error[E0433]: failed to resolve: could not find `xcrate` in `extern`
   --> $DIR/non-existent-2.rs:14:21
    |
 LL |     let s = extern::xcrate::S;
-   |                     ^^^^^^ Could not find `xcrate` in `extern`
+   |                     ^^^^^^ could not find `xcrate` in `extern`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rust-2018/future-proofing-locals.rs b/src/test/ui/rust-2018/future-proofing-locals.rs
new file mode 100644
index 00000000000..d2e6dbbb954
--- /dev/null
+++ b/src/test/ui/rust-2018/future-proofing-locals.rs
@@ -0,0 +1,49 @@
+// edition:2018
+
+#![feature(uniform_paths, underscore_imports)]
+
+mod T {
+    pub struct U;
+}
+mod x {
+    pub struct y;
+}
+
+fn type_param<T>() {
+    use T as _; //~ ERROR imports cannot refer to type parameters
+    use T::U; //~ ERROR imports cannot refer to type parameters
+    use T::*; //~ ERROR imports cannot refer to type parameters
+}
+
+fn self_import<T>() {
+    use T; // FIXME Should be an error, but future-proofing fails due to `T` being "self-shadowed"
+}
+
+fn let_binding() {
+    let x = 10;
+
+    use x as _; //~ ERROR imports cannot refer to local variables
+    use x::y; // OK
+    use x::*; // OK
+}
+
+fn param_binding(x: u8) {
+    use x; //~ ERROR imports cannot refer to local variables
+}
+
+fn match_binding() {
+    match 0 {
+        x => {
+            use x; //~ ERROR imports cannot refer to local variables
+        }
+    }
+}
+
+fn nested<T>() {
+    let x = 10;
+
+    use {T as _, x}; //~ ERROR imports cannot refer to type parameters
+                     //~| ERROR imports cannot refer to local variables
+}
+
+fn main() {}
diff --git a/src/test/ui/rust-2018/future-proofing-locals.stderr b/src/test/ui/rust-2018/future-proofing-locals.stderr
new file mode 100644
index 00000000000..68354b332a9
--- /dev/null
+++ b/src/test/ui/rust-2018/future-proofing-locals.stderr
@@ -0,0 +1,50 @@
+error: imports cannot refer to type parameters
+  --> $DIR/future-proofing-locals.rs:13:9
+   |
+LL |     use T as _; //~ ERROR imports cannot refer to type parameters
+   |         ^
+
+error: imports cannot refer to type parameters
+  --> $DIR/future-proofing-locals.rs:14:9
+   |
+LL |     use T::U; //~ ERROR imports cannot refer to type parameters
+   |         ^
+
+error: imports cannot refer to type parameters
+  --> $DIR/future-proofing-locals.rs:15:9
+   |
+LL |     use T::*; //~ ERROR imports cannot refer to type parameters
+   |         ^
+
+error: imports cannot refer to local variables
+  --> $DIR/future-proofing-locals.rs:25:9
+   |
+LL |     use x as _; //~ ERROR imports cannot refer to local variables
+   |         ^
+
+error: imports cannot refer to local variables
+  --> $DIR/future-proofing-locals.rs:31:9
+   |
+LL |     use x; //~ ERROR imports cannot refer to local variables
+   |         ^
+
+error: imports cannot refer to local variables
+  --> $DIR/future-proofing-locals.rs:37:17
+   |
+LL |             use x; //~ ERROR imports cannot refer to local variables
+   |                 ^
+
+error: imports cannot refer to type parameters
+  --> $DIR/future-proofing-locals.rs:45:10
+   |
+LL |     use {T as _, x}; //~ ERROR imports cannot refer to type parameters
+   |          ^
+
+error: imports cannot refer to local variables
+  --> $DIR/future-proofing-locals.rs:45:18
+   |
+LL |     use {T as _, x}; //~ ERROR imports cannot refer to type parameters
+   |                  ^
+
+error: aborting due to 8 previous errors
+
diff --git a/src/test/ui/rust-2018/issue-54006.stderr b/src/test/ui/rust-2018/issue-54006.stderr
index 268a16e5d2a..5f92574c23f 100644
--- a/src/test/ui/rust-2018/issue-54006.stderr
+++ b/src/test/ui/rust-2018/issue-54006.stderr
@@ -2,7 +2,7 @@ error[E0432]: unresolved import `alloc`
   --> $DIR/issue-54006.rs:16:5
    |
 LL | use alloc::vec;
-   |     ^^^^^ Did you mean `core::alloc`?
+   |     ^^^^^ did you mean `core::alloc`?
 
 error: cannot determine resolution for the macro `vec`
   --> $DIR/issue-54006.rs:20:18
diff --git a/src/test/ui/rust-2018/local-path-suggestions-2015.stderr b/src/test/ui/rust-2018/local-path-suggestions-2015.stderr
index d7580507ce4..741b2ca0826 100644
--- a/src/test/ui/rust-2018/local-path-suggestions-2015.stderr
+++ b/src/test/ui/rust-2018/local-path-suggestions-2015.stderr
@@ -2,7 +2,7 @@ error[E0432]: unresolved import `foobar`
   --> $DIR/local-path-suggestions-2015.rs:34:5
    |
 LL | use foobar::Baz;
-   |     ^^^^^^ Did you mean `aux_baz::foobar`?
+   |     ^^^^^^ did you mean `aux_baz::foobar`?
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rust-2018/local-path-suggestions-2018.rs b/src/test/ui/rust-2018/local-path-suggestions-2018.rs
index 147dae401f6..0d4aefff931 100644
--- a/src/test/ui/rust-2018/local-path-suggestions-2018.rs
+++ b/src/test/ui/rust-2018/local-path-suggestions-2018.rs
@@ -12,12 +12,14 @@
 // compile-flags:--extern baz
 // edition:2018
 
+#![feature(uniform_paths)]
+
 mod foo {
     pub type Bar = u32;
 }
 
-mod baz {
-    use foo::Bar;
+mod bazz {
+    use foo::Bar; //~ ERROR unresolved import `foo`
 
     fn baz() {
         let x: Bar = 22;
@@ -26,6 +28,6 @@ mod baz {
 
 use foo::Bar;
 
-use foobar::Baz;
+use foobar::Baz; //~ ERROR unresolved import `foobar`
 
 fn main() { }
diff --git a/src/test/ui/rust-2018/local-path-suggestions-2018.stderr b/src/test/ui/rust-2018/local-path-suggestions-2018.stderr
index 2293f4b0017..a445a4c612b 100644
--- a/src/test/ui/rust-2018/local-path-suggestions-2018.stderr
+++ b/src/test/ui/rust-2018/local-path-suggestions-2018.stderr
@@ -1,23 +1,17 @@
 error[E0432]: unresolved import `foo`
-  --> $DIR/local-path-suggestions-2018.rs:20:9
+  --> $DIR/local-path-suggestions-2018.rs:22:9
    |
-LL |     use foo::Bar;
-   |         ^^^ Did you mean `crate::foo`?
+LL |     use foo::Bar; //~ ERROR unresolved import `foo`
+   |         ^^^ did you mean `crate::foo`?
    |
    = note: `use` statements changed in Rust 2018; read more at <https://doc.rust-lang.org/edition-guide/rust-2018/module-system/path-clarity.html>
 
-error[E0432]: unresolved import `foo`
-  --> $DIR/local-path-suggestions-2018.rs:27:5
-   |
-LL | use foo::Bar;
-   |     ^^^ Did you mean `self::foo`?
-
 error[E0432]: unresolved import `foobar`
-  --> $DIR/local-path-suggestions-2018.rs:29:5
+  --> $DIR/local-path-suggestions-2018.rs:31:5
    |
-LL | use foobar::Baz;
-   |     ^^^^^^ Did you mean `baz::foobar`?
+LL | use foobar::Baz; //~ ERROR unresolved import `foobar`
+   |     ^^^^^^ did you mean `baz::foobar`?
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0432`.
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
index 590e83b0781..4819711115c 100644
--- 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
@@ -14,7 +14,7 @@
 
 mod foo {
     pub use std::io;
-    //~^ ERROR `std` import is ambiguous
+    //~^ ERROR `std` is ambiguous
 
     macro_rules! m {
         () => {
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
index 948043cff76..204e0a7e141 100644
--- 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
@@ -1,16 +1,23 @@
-error: `std` import is ambiguous
+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;
-   |               ^^^ can refer to external crate `::std`
-...
+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 | |             }
-   | |_____________- may refer to `self::std` in the future
-   |
-   = help: write `::std` or `self::std` explicitly instead
-   = note: in the future, `#![feature(uniform_paths)]` may become the default
+   | |_____________^
+...
+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
index 861efba14f8..148320de556 100644
--- 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
@@ -13,7 +13,7 @@
 // This test is similar to `ambiguity.rs`, but with macros defining local items.
 
 use std::io;
-//~^ ERROR `std` import is ambiguous
+//~^ ERROR `std` is ambiguous
 
 macro_rules! m {
     () => {
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
index 40cceea2440..ac8d3b9d0cb 100644
--- 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
@@ -1,16 +1,23 @@
-error: `std` import is ambiguous
+error[E0659]: `std` is ambiguous (name vs any other name during import resolution)
   --> $DIR/ambiguity-macros.rs:15:5
    |
-LL |   use std::io;
-   |       ^^^ can refer to external crate `::std`
-...
+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 | |         }
-   | |_________- may refer to `self::std` in the future
-   |
-   = help: write `::std` or `self::std` explicitly instead
-   = note: in the future, `#![feature(uniform_paths)]` may become the default
+   | |_________^
+...
+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
index a69eb101917..2791d4580da 100644
--- 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
@@ -14,7 +14,7 @@
 
 mod foo {
     pub use std::io;
-    //~^ ERROR `std` import is ambiguous
+    //~^ ERROR `std` is ambiguous
 
     mod std {
         pub struct io;
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
index 7538d3d2d91..7bcfc563d39 100644
--- 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
@@ -1,16 +1,20 @@
-error: `std` import is ambiguous
+error[E0659]: `std` is ambiguous (name vs any other name during import resolution)
   --> $DIR/ambiguity-nested.rs:16:13
    |
-LL |       pub use std::io;
-   |               ^^^ can refer to external crate `::std`
-...
+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 | |     }
-   | |_____- may refer to `self::std` in the future
-   |
-   = help: write `::std` or `self::std` explicitly instead
-   = note: in the future, `#![feature(uniform_paths)]` may become the default
+   | |_____^
+   = 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
index 500e9f6c63f..2bfbb6b2871 100644
--- a/src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity.rs
+++ b/src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity.rs
@@ -11,7 +11,7 @@
 // edition:2018
 
 use std::io;
-//~^ ERROR `std` import is ambiguous
+//~^ ERROR `std` is ambiguous
 
 mod std {
     pub struct io;
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
index 7b64b8f0246..beeb74654e5 100644
--- a/src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity.stderr
+++ b/src/test/ui/rust-2018/uniform-paths-forward-compat/ambiguity.stderr
@@ -1,16 +1,20 @@
-error: `std` import is ambiguous
+error[E0659]: `std` is ambiguous (name vs any other name during import resolution)
   --> $DIR/ambiguity.rs:13:5
    |
-LL |   use std::io;
-   |       ^^^ can refer to external crate `::std`
-...
+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 | | }
-   | |_- may refer to `self::std` in the future
-   |
-   = help: write `::std` or `self::std` explicitly instead
-   = note: in the future, `#![feature(uniform_paths)]` may become the default
+   | |_^
+   = 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
index ca488fec516..2853b4b3a5b 100644
--- 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
@@ -16,6 +16,6 @@ fn main() {
     fn std() {}
     enum std {}
     use std as foo;
-    //~^ ERROR `std` import is ambiguous
-    //~| ERROR `std` import is ambiguous
+    //~^ 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
index 27e0e883691..5d539e2d59f 100644
--- 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
@@ -1,31 +1,39 @@
-error: `std` import is ambiguous
+error[E0659]: `std` is ambiguous (name vs any other name during import resolution)
   --> $DIR/block-scoped-shadow.rs:18:9
    |
-LL | struct std;
-   | ----------- may refer to `self::std` in the future
-...
-LL |     enum std {}
-   |     ----------- shadowed by block-scoped `std`
 LL |     use std as foo;
-   |         ^^^ can refer to external crate `::std`
+   |         ^^^ ambiguous name
    |
-   = help: write `::std` or `self::std` explicitly instead
-   = note: in the future, `#![feature(uniform_paths)]` may become the default
+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: `std` import is ambiguous
+error[E0659]: `std` is ambiguous (name vs any other name during import resolution)
   --> $DIR/block-scoped-shadow.rs:18:9
    |
-LL | struct std;
-   | ----------- may refer to `self::std` in the future
-...
-LL |     fn std() {}
-   |     ----------- shadowed by block-scoped `std`
-LL |     enum std {}
 LL |     use std as foo;
-   |         ^^^
+   |         ^^^ ambiguous name
+   |
+note: `std` could refer to the function defined here
+  --> $DIR/block-scoped-shadow.rs:16:5
    |
-   = help: write `self::std` explicitly instead
-   = note: in the future, `#![feature(uniform_paths)]` may become the default
+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
index 1f19a05d7a7..ef2a1e3c70c 100644
--- 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
@@ -10,7 +10,7 @@
 
 // edition:2018
 
-// Dummy import to introduce `uniform_paths` canaries.
+// Dummy import that previously introduced uniform path canaries.
 use std;
 
 // fn version() -> &'static str {""}
diff --git a/src/test/ui/rust-2018/uniform-paths/ambiguity-macros-nested.rs b/src/test/ui/rust-2018/uniform-paths/ambiguity-macros-nested.rs
index e0992c90666..4819711115c 100644
--- a/src/test/ui/rust-2018/uniform-paths/ambiguity-macros-nested.rs
+++ b/src/test/ui/rust-2018/uniform-paths/ambiguity-macros-nested.rs
@@ -10,13 +10,11 @@
 
 // edition:2018
 
-#![feature(uniform_paths)]
-
 // This test is similar to `ambiguity-macros.rs`, but nested in a module.
 
 mod foo {
     pub use std::io;
-    //~^ ERROR `std` import is ambiguous
+    //~^ ERROR `std` is ambiguous
 
     macro_rules! m {
         () => {
diff --git a/src/test/ui/rust-2018/uniform-paths/ambiguity-macros-nested.stderr b/src/test/ui/rust-2018/uniform-paths/ambiguity-macros-nested.stderr
index 154ee412e72..204e0a7e141 100644
--- a/src/test/ui/rust-2018/uniform-paths/ambiguity-macros-nested.stderr
+++ b/src/test/ui/rust-2018/uniform-paths/ambiguity-macros-nested.stderr
@@ -1,16 +1,23 @@
-error: `std` import is ambiguous
-  --> $DIR/ambiguity-macros-nested.rs:18:13
+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 |       pub use std::io;
-   |               ^^^ can refer to external crate `::std`
-...
 LL | /             mod std {
 LL | |                 pub struct io;
 LL | |             }
-   | |_____________- can refer to `self::std`
-   |
-   = help: write `::std` or `self::std` explicitly instead
-   = note: relative `use` paths enabled by `#![feature(uniform_paths)]`
+   | |_____________^
+...
+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/ambiguity-macros.rs b/src/test/ui/rust-2018/uniform-paths/ambiguity-macros.rs
index 9439d92aa71..148320de556 100644
--- a/src/test/ui/rust-2018/uniform-paths/ambiguity-macros.rs
+++ b/src/test/ui/rust-2018/uniform-paths/ambiguity-macros.rs
@@ -10,12 +10,10 @@
 
 // edition:2018
 
-#![feature(uniform_paths)]
-
 // This test is similar to `ambiguity.rs`, but with macros defining local items.
 
 use std::io;
-//~^ ERROR `std` import is ambiguous
+//~^ ERROR `std` is ambiguous
 
 macro_rules! m {
     () => {
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 3c0d5601f9c..ac8d3b9d0cb 100644
--- a/src/test/ui/rust-2018/uniform-paths/ambiguity-macros.stderr
+++ b/src/test/ui/rust-2018/uniform-paths/ambiguity-macros.stderr
@@ -1,16 +1,23 @@
-error: `std` import is ambiguous
-  --> $DIR/ambiguity-macros.rs:17:5
+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 |   use std::io;
-   |       ^^^ can refer to external crate `::std`
-...
 LL | /         mod std {
 LL | |             pub struct io;
 LL | |         }
-   | |_________- can refer to `self::std`
-   |
-   = help: write `::std` or `self::std` explicitly instead
-   = note: relative `use` paths enabled by `#![feature(uniform_paths)]`
+   | |_________^
+...
+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/ambiguity-nested.rs b/src/test/ui/rust-2018/uniform-paths/ambiguity-nested.rs
index 1756acc6057..2791d4580da 100644
--- a/src/test/ui/rust-2018/uniform-paths/ambiguity-nested.rs
+++ b/src/test/ui/rust-2018/uniform-paths/ambiguity-nested.rs
@@ -10,13 +10,11 @@
 
 // edition:2018
 
-#![feature(uniform_paths)]
-
 // This test is similar to `ambiguity.rs`, but nested in a module.
 
 mod foo {
     pub use std::io;
-    //~^ ERROR `std` import is ambiguous
+    //~^ ERROR `std` is ambiguous
 
     mod std {
         pub struct io;
diff --git a/src/test/ui/rust-2018/uniform-paths/ambiguity-nested.stderr b/src/test/ui/rust-2018/uniform-paths/ambiguity-nested.stderr
index a607eeb0b43..7bcfc563d39 100644
--- a/src/test/ui/rust-2018/uniform-paths/ambiguity-nested.stderr
+++ b/src/test/ui/rust-2018/uniform-paths/ambiguity-nested.stderr
@@ -1,16 +1,20 @@
-error: `std` import is ambiguous
-  --> $DIR/ambiguity-nested.rs:18:13
+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 |       pub use std::io;
-   |               ^^^ can refer to external crate `::std`
-...
 LL | /     mod std {
 LL | |         pub struct io;
 LL | |     }
-   | |_____- can refer to `self::std`
-   |
-   = help: write `::std` or `self::std` explicitly instead
-   = note: relative `use` paths enabled by `#![feature(uniform_paths)]`
+   | |_____^
+   = 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/ambiguity.rs b/src/test/ui/rust-2018/uniform-paths/ambiguity.rs
index 9ae3d79c22c..2bfbb6b2871 100644
--- a/src/test/ui/rust-2018/uniform-paths/ambiguity.rs
+++ b/src/test/ui/rust-2018/uniform-paths/ambiguity.rs
@@ -10,10 +10,8 @@
 
 // edition:2018
 
-#![feature(uniform_paths)]
-
 use std::io;
-//~^ ERROR `std` import is ambiguous
+//~^ ERROR `std` is ambiguous
 
 mod std {
     pub struct io;
diff --git a/src/test/ui/rust-2018/uniform-paths/ambiguity.stderr b/src/test/ui/rust-2018/uniform-paths/ambiguity.stderr
index c65db3072f4..beeb74654e5 100644
--- a/src/test/ui/rust-2018/uniform-paths/ambiguity.stderr
+++ b/src/test/ui/rust-2018/uniform-paths/ambiguity.stderr
@@ -1,16 +1,20 @@
-error: `std` import is ambiguous
-  --> $DIR/ambiguity.rs:15:5
+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 |   use std::io;
-   |       ^^^ can refer to external crate `::std`
-...
 LL | / mod std {
 LL | |     pub struct io;
 LL | | }
-   | |_- can refer to `self::std`
-   |
-   = help: write `::std` or `self::std` explicitly instead
-   = note: relative `use` paths enabled by `#![feature(uniform_paths)]`
+   | |_^
+   = 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/block-scoped-shadow-nested.rs b/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.rs
new file mode 100644
index 00000000000..19be7dc9640
--- /dev/null
+++ b/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.rs
@@ -0,0 +1,22 @@
+// edition:2018
+
+#![feature(uniform_paths)]
+
+mod my {
+    pub mod sub {
+        pub fn bar() {}
+    }
+}
+
+mod sub {
+    pub fn bar() {}
+}
+
+fn foo() {
+    use my::sub;
+    {
+        use sub::bar; //~ ERROR `sub` is ambiguous
+    }
+}
+
+fn main() {}
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
new file mode 100644
index 00000000000..aa46947f93f
--- /dev/null
+++ b/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.stderr
@@ -0,0 +1,23 @@
+error[E0659]: `sub` is ambiguous (name vs any other name during import resolution)
+  --> $DIR/block-scoped-shadow-nested.rs:18:13
+   |
+LL |         use sub::bar; //~ ERROR `sub` is ambiguous
+   |             ^^^ ambiguous name
+   |
+note: `sub` could refer to the module imported here
+  --> $DIR/block-scoped-shadow-nested.rs:16:9
+   |
+LL |     use my::sub;
+   |         ^^^^^^^
+note: `sub` could also refer to the module defined here
+  --> $DIR/block-scoped-shadow-nested.rs:11:1
+   |
+LL | / mod sub {
+LL | |     pub fn bar() {}
+LL | | }
+   | |_^
+   = help: use `self::sub` 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/block-scoped-shadow.rs b/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow.rs
index ee141d444b2..ec0479ce8f1 100644
--- a/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow.rs
+++ b/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow.rs
@@ -10,22 +10,20 @@
 
 // edition:2018
 
-#![feature(uniform_paths)]
-
-enum Foo { A, B }
+enum Foo {}
 
 struct std;
 
 fn main() {
-    enum Foo {}
+    enum Foo { A, B }
     use Foo::*;
-    //~^ ERROR `Foo` import is ambiguous
+    //~^ ERROR `Foo` is ambiguous
 
     let _ = (A, B);
 
     fn std() {}
     enum std {}
     use std as foo;
-    //~^ ERROR `std` import is ambiguous
-    //~| ERROR `std` import is ambiguous
+    //~^ ERROR `std` is ambiguous
+    //~| ERROR `std` is ambiguous
 }
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 86d95f2ac45..010b9efad39 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
@@ -1,45 +1,57 @@
-error: `Foo` import is ambiguous
-  --> $DIR/block-scoped-shadow.rs:21:9
-   |
-LL | enum Foo { A, B }
-   | ----------------- can refer to `self::Foo`
-...
-LL |     enum Foo {}
-   |     ----------- shadowed by block-scoped `Foo`
+error[E0659]: `Foo` is ambiguous (name vs any other name during import resolution)
+  --> $DIR/block-scoped-shadow.rs:19:9
+   |
 LL |     use Foo::*;
-   |         ^^^
+   |         ^^^ ambiguous name
+   |
+note: `Foo` could refer to the enum defined here
+  --> $DIR/block-scoped-shadow.rs:18:5
    |
-   = help: write `self::Foo` explicitly instead
-   = note: relative `use` paths enabled by `#![feature(uniform_paths)]`
+LL |     enum Foo { A, B }
+   |     ^^^^^^^^^^^^^^^^^
+note: `Foo` could also refer to the enum defined here
+  --> $DIR/block-scoped-shadow.rs:13:1
+   |
+LL | enum Foo {}
+   | ^^^^^^^^^^^
+   = help: use `self::Foo` to refer to this enum unambiguously
 
-error: `std` import is ambiguous
-  --> $DIR/block-scoped-shadow.rs:28:9
+error[E0659]: `std` is ambiguous (name vs any other name during import resolution)
+  --> $DIR/block-scoped-shadow.rs:26:9
    |
-LL | struct std;
-   | ----------- can refer to `self::std`
-...
-LL |     enum std {}
-   |     ----------- shadowed by block-scoped `std`
 LL |     use std as foo;
-   |         ^^^ can refer to external crate `::std`
+   |         ^^^ ambiguous name
    |
-   = help: write `::std` or `self::std` explicitly instead
-   = note: relative `use` paths enabled by `#![feature(uniform_paths)]`
-
-error: `std` import is ambiguous
-  --> $DIR/block-scoped-shadow.rs:28:9
+note: `std` could refer to the enum defined here
+  --> $DIR/block-scoped-shadow.rs:25:5
    |
-LL | struct std;
-   | ----------- can refer to `self::std`
-...
-LL |     fn std() {}
-   |     ----------- shadowed by block-scoped `std`
 LL |     enum std {}
+   |     ^^^^^^^^^^^
+note: `std` could also refer to the struct defined here
+  --> $DIR/block-scoped-shadow.rs:15: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:26:9
+   |
 LL |     use std as foo;
-   |         ^^^
+   |         ^^^ ambiguous name
    |
-   = help: write `self::std` explicitly instead
-   = note: relative `use` paths enabled by `#![feature(uniform_paths)]`
+note: `std` could refer to the function defined here
+  --> $DIR/block-scoped-shadow.rs:24:5
+   |
+LL |     fn std() {}
+   |     ^^^^^^^^^^^
+note: `std` could also refer to the unit struct defined here
+  --> $DIR/block-scoped-shadow.rs:15:1
+   |
+LL | struct std;
+   | ^^^^^^^^^^^
+   = help: use `self::std` to refer to this unit struct unambiguously
 
 error: aborting due to 3 previous errors
 
+For more information about this error, try `rustc --explain E0659`.
diff --git a/src/test/ui/rust-2018/uniform-paths/deadlock.rs b/src/test/ui/rust-2018/uniform-paths/deadlock.rs
new file mode 100644
index 00000000000..3228d799083
--- /dev/null
+++ b/src/test/ui/rust-2018/uniform-paths/deadlock.rs
@@ -0,0 +1,7 @@
+// edition:2018
+// compile-flags:--extern foo --extern bar
+
+use foo::bar; //~ ERROR unresolved import
+use bar::foo;
+
+fn main() {}
diff --git a/src/test/ui/rust-2018/uniform-paths/deadlock.stderr b/src/test/ui/rust-2018/uniform-paths/deadlock.stderr
new file mode 100644
index 00000000000..8bbc8f33039
--- /dev/null
+++ b/src/test/ui/rust-2018/uniform-paths/deadlock.stderr
@@ -0,0 +1,9 @@
+error[E0432]: unresolved import
+  --> $DIR/deadlock.rs:4:5
+   |
+LL | use foo::bar; //~ ERROR unresolved import
+   |     ^^^^^^^^
+
+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/fn-local-enum.rs b/src/test/ui/rust-2018/uniform-paths/fn-local-enum.rs
new file mode 100644
index 00000000000..a7bc625bbf0
--- /dev/null
+++ b/src/test/ui/rust-2018/uniform-paths/fn-local-enum.rs
@@ -0,0 +1,15 @@
+// compile-pass
+// edition:2018
+
+#![feature(uniform_paths)]
+
+fn main() {
+    enum E { A, B, C }
+
+    use E::*;
+    match A {
+        A => {}
+        B => {}
+        C => {}
+    }
+}
diff --git a/src/test/ui/rust-2018/uniform-paths/from-decl-macro.rs b/src/test/ui/rust-2018/uniform-paths/from-decl-macro.rs
new file mode 100644
index 00000000000..5c3c753f9a7
--- /dev/null
+++ b/src/test/ui/rust-2018/uniform-paths/from-decl-macro.rs
@@ -0,0 +1,12 @@
+// compile-pass
+// edition:2018
+
+#![feature(decl_macro)]
+
+macro check() {
+    ::std::vec::Vec::<u8>::new()
+}
+
+fn main() {
+    check!();
+}
diff --git a/src/test/ui/rust-2018/uniform-paths/issue-54253.rs b/src/test/ui/rust-2018/uniform-paths/issue-54253.rs
index 7ca5c9e9eae..ef2a1e3c70c 100644
--- a/src/test/ui/rust-2018/uniform-paths/issue-54253.rs
+++ b/src/test/ui/rust-2018/uniform-paths/issue-54253.rs
@@ -10,9 +10,7 @@
 
 // edition:2018
 
-#![feature(uniform_paths)]
-
-// Dummy import to introduce `uniform_paths` canaries.
+// Dummy import that previously introduced uniform path canaries.
 use std;
 
 // fn version() -> &'static str {""}
diff --git a/src/test/ui/rust-2018/uniform-paths/issue-54253.stderr b/src/test/ui/rust-2018/uniform-paths/issue-54253.stderr
index 0016e21ef4d..6dcc451c60a 100644
--- a/src/test/ui/rust-2018/uniform-paths/issue-54253.stderr
+++ b/src/test/ui/rust-2018/uniform-paths/issue-54253.stderr
@@ -1,5 +1,5 @@
 error[E0432]: unresolved import `crate::version`
-  --> $DIR/issue-54253.rs:22:9
+  --> $DIR/issue-54253.rs:20:9
    |
 LL |     use crate::version; //~ ERROR unresolved import `crate::version`
    |         ^^^^^^^^^^^^^^ no `version` in the root
diff --git a/src/test/ui/rust-2018/uniform-paths/issue-54390.rs b/src/test/ui/rust-2018/uniform-paths/issue-54390.rs
new file mode 100644
index 00000000000..536cc25e35a
--- /dev/null
+++ b/src/test/ui/rust-2018/uniform-paths/issue-54390.rs
@@ -0,0 +1,11 @@
+// edition:2018
+
+#![deny(unused)]
+
+use std::fmt;
+
+// No "unresolved import" + "unused import" combination here.
+use fmt::Write; //~ ERROR imports can only refer to extern crate names
+                //~| ERROR unused import: `fmt::Write`
+
+fn main() {}
diff --git a/src/test/ui/rust-2018/uniform-paths/issue-54390.stderr b/src/test/ui/rust-2018/uniform-paths/issue-54390.stderr
new file mode 100644
index 00000000000..8f86698c9c1
--- /dev/null
+++ b/src/test/ui/rust-2018/uniform-paths/issue-54390.stderr
@@ -0,0 +1,32 @@
+error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130)
+  --> $DIR/issue-54390.rs:8:5
+   |
+LL | use std::fmt;
+   |     -------- not an extern crate passed with `--extern`
+...
+LL | use fmt::Write; //~ ERROR imports can only refer to extern crate names
+   |     ^^^
+   |
+   = help: add #![feature(uniform_paths)] to the crate attributes to enable
+note: this import refers to the module imported here
+  --> $DIR/issue-54390.rs:5:5
+   |
+LL | use std::fmt;
+   |     ^^^^^^^^
+
+error: unused import: `fmt::Write`
+  --> $DIR/issue-54390.rs:8:5
+   |
+LL | use fmt::Write; //~ ERROR imports can only refer to extern crate names
+   |     ^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/issue-54390.rs:3:9
+   |
+LL | #![deny(unused)]
+   |         ^^^^^^
+   = note: #[deny(unused_imports)] implied by #[deny(unused)]
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/rust-2018/uniform-paths/macro-rules.rs b/src/test/ui/rust-2018/uniform-paths/macro-rules.rs
new file mode 100644
index 00000000000..e8098a46790
--- /dev/null
+++ b/src/test/ui/rust-2018/uniform-paths/macro-rules.rs
@@ -0,0 +1,44 @@
+// edition:2018
+
+// For the time being `macro_rules` items are treated as *very* private...
+
+#![feature(underscore_imports, decl_macro, uniform_paths)]
+
+mod m1 {
+    macro_rules! legacy_macro { () => () }
+
+    // ... so they can't be imported by themselves, ...
+    use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported
+}
+
+mod m2 {
+    macro_rules! legacy_macro { () => () }
+
+    type legacy_macro = u8;
+
+    // ... but don't prevent names from other namespaces from being imported, ...
+    use legacy_macro as _; // OK
+}
+
+mod m3 {
+    macro legacy_macro() {}
+
+    fn f() {
+        macro_rules! legacy_macro { () => () }
+
+        // ... but still create ambiguities with other names in the same namespace.
+        use legacy_macro as _; //~ ERROR `legacy_macro` is ambiguous
+                               //~| ERROR `legacy_macro` is private, and cannot be re-exported
+    }
+}
+
+mod exported {
+    // Exported macros are treated as private as well,
+    // some better rules need to be figured out later.
+    #[macro_export]
+    macro_rules! legacy_macro { () => () }
+
+    use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported
+}
+
+fn main() {}
diff --git a/src/test/ui/rust-2018/uniform-paths/macro-rules.stderr b/src/test/ui/rust-2018/uniform-paths/macro-rules.stderr
new file mode 100644
index 00000000000..d7bb233dfe9
--- /dev/null
+++ b/src/test/ui/rust-2018/uniform-paths/macro-rules.stderr
@@ -0,0 +1,58 @@
+error[E0364]: `legacy_macro` is private, and cannot be re-exported
+  --> $DIR/macro-rules.rs:11:9
+   |
+LL |     use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported
+   |         ^^^^^^^^^^^^^^^^^
+   |
+note: consider marking `legacy_macro` as `pub` in the imported module
+  --> $DIR/macro-rules.rs:11:9
+   |
+LL |     use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported
+   |         ^^^^^^^^^^^^^^^^^
+
+error[E0364]: `legacy_macro` is private, and cannot be re-exported
+  --> $DIR/macro-rules.rs:30:13
+   |
+LL |         use legacy_macro as _; //~ ERROR `legacy_macro` is ambiguous
+   |             ^^^^^^^^^^^^^^^^^
+   |
+note: consider marking `legacy_macro` as `pub` in the imported module
+  --> $DIR/macro-rules.rs:30:13
+   |
+LL |         use legacy_macro as _; //~ ERROR `legacy_macro` is ambiguous
+   |             ^^^^^^^^^^^^^^^^^
+
+error[E0364]: `legacy_macro` is private, and cannot be re-exported
+  --> $DIR/macro-rules.rs:41:9
+   |
+LL |     use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported
+   |         ^^^^^^^^^^^^^^^^^
+   |
+note: consider marking `legacy_macro` as `pub` in the imported module
+  --> $DIR/macro-rules.rs:41:9
+   |
+LL |     use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported
+   |         ^^^^^^^^^^^^^^^^^
+
+error[E0659]: `legacy_macro` is ambiguous (name vs any other name during import resolution)
+  --> $DIR/macro-rules.rs:30:13
+   |
+LL |         use legacy_macro as _; //~ ERROR `legacy_macro` is ambiguous
+   |             ^^^^^^^^^^^^ ambiguous name
+   |
+note: `legacy_macro` could refer to the macro defined here
+  --> $DIR/macro-rules.rs:27:9
+   |
+LL |         macro_rules! legacy_macro { () => () }
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: `legacy_macro` could also refer to the macro defined here
+  --> $DIR/macro-rules.rs:24:5
+   |
+LL |     macro legacy_macro() {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   = help: use `self::legacy_macro` to refer to this macro unambiguously
+
+error: aborting due to 4 previous errors
+
+Some errors occurred: E0364, E0659.
+For more information about an error, try `rustc --explain E0364`.
diff --git a/src/test/ui/rust-2018/uniform-paths/prelude-fail.rs b/src/test/ui/rust-2018/uniform-paths/prelude-fail.rs
new file mode 100644
index 00000000000..c5bd50f2f56
--- /dev/null
+++ b/src/test/ui/rust-2018/uniform-paths/prelude-fail.rs
@@ -0,0 +1,13 @@
+// edition:2018
+
+#![feature(uniform_paths)]
+
+// Built-in macro
+use env as env_imported; //~ ERROR cannot import a built-in macro
+
+// Tool attribute
+use rustfmt::skip as imported_rustfmt_skip; //~ ERROR unresolved import `rustfmt`
+
+fn main() {
+    env_imported!("PATH");
+}
diff --git a/src/test/ui/rust-2018/uniform-paths/prelude-fail.stderr b/src/test/ui/rust-2018/uniform-paths/prelude-fail.stderr
new file mode 100644
index 00000000000..794d986b82e
--- /dev/null
+++ b/src/test/ui/rust-2018/uniform-paths/prelude-fail.stderr
@@ -0,0 +1,15 @@
+error: cannot import a built-in macro
+  --> $DIR/prelude-fail.rs:6:5
+   |
+LL | use env as env_imported; //~ ERROR cannot import a built-in macro
+   |     ^^^^^^^^^^^^^^^^^^^
+
+error[E0432]: unresolved import `rustfmt`
+  --> $DIR/prelude-fail.rs:9:5
+   |
+LL | use rustfmt::skip as imported_rustfmt_skip; //~ ERROR unresolved import `rustfmt`
+   |     ^^^^^^^ not a module `rustfmt`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0432`.
diff --git a/src/test/ui/rust-2018/uniform-paths/prelude.rs b/src/test/ui/rust-2018/uniform-paths/prelude.rs
new file mode 100644
index 00000000000..5aab5fc3a40
--- /dev/null
+++ b/src/test/ui/rust-2018/uniform-paths/prelude.rs
@@ -0,0 +1,28 @@
+// compile-pass
+// edition:2018
+
+#![feature(uniform_paths)]
+
+// Macro imported with `#[macro_use] extern crate`
+use vec as imported_vec;
+
+// Built-in attribute
+use inline as imported_inline;
+
+// Tool module
+use rustfmt as imported_rustfmt;
+
+// Standard library prelude
+use Vec as ImportedVec;
+
+// Built-in type
+use u8 as imported_u8;
+
+type A = imported_u8;
+
+#[imported_inline]
+#[imported_rustfmt::skip]
+fn main() {
+    imported_vec![0];
+    ImportedVec::<u8>::new();
+}
diff --git a/src/test/ui/rust-2018/uniform-paths/redundant.rs b/src/test/ui/rust-2018/uniform-paths/redundant.rs
index 745ac18e059..05048cfd451 100644
--- a/src/test/ui/rust-2018/uniform-paths/redundant.rs
+++ b/src/test/ui/rust-2018/uniform-paths/redundant.rs
@@ -11,8 +11,6 @@
 // run-pass
 // edition:2018
 
-#![feature(uniform_paths)]
-
 use std;
 use std::io;
 
diff --git a/src/test/ui/span/macro-ty-params.stderr b/src/test/ui/span/macro-ty-params.stderr
index 3988dec88d5..8a40556a6cd 100644
--- a/src/test/ui/span/macro-ty-params.stderr
+++ b/src/test/ui/span/macro-ty-params.stderr
@@ -5,6 +5,12 @@ LL |     m!(MyTrait<>); //~ ERROR generic arguments in macro path
    |        ^^^^^^^^^
 
 error: generic arguments in macro path
+  --> $DIR/macro-ty-params.rs:20:15
+   |
+LL |     m!(MyTrait<>); //~ ERROR generic arguments in macro path
+   |               ^^
+
+error: generic arguments in macro path
   --> $DIR/macro-ty-params.rs:18:8
    |
 LL |     foo::<T>!(); //~ ERROR generic arguments in macro path
@@ -16,11 +22,5 @@ error: generic arguments in macro path
 LL |     foo::<>!(); //~ ERROR generic arguments in macro path
    |        ^^^^
 
-error: generic arguments in macro path
-  --> $DIR/macro-ty-params.rs:20:15
-   |
-LL |     m!(MyTrait<>); //~ ERROR generic arguments in macro path
-   |               ^^
-
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/span/non-existing-module-import.stderr b/src/test/ui/span/non-existing-module-import.stderr
index 5518b42ac65..1f001530f36 100644
--- a/src/test/ui/span/non-existing-module-import.stderr
+++ b/src/test/ui/span/non-existing-module-import.stderr
@@ -2,7 +2,7 @@ error[E0432]: unresolved import `std::bar`
   --> $DIR/non-existing-module-import.rs:11:10
    |
 LL | use std::bar::{foo1, foo2}; //~ ERROR unresolved import
-   |          ^^^ Could not find `bar` in `std`
+   |          ^^^ could not find `bar` in `std`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/static/static-mut-not-pat.stderr b/src/test/ui/static/static-mut-not-pat.stderr
index 123cf7b3ac6..96dc06ee524 100644
--- a/src/test/ui/static/static-mut-not-pat.stderr
+++ b/src/test/ui/static/static-mut-not-pat.stderr
@@ -2,7 +2,7 @@ error[E0530]: match bindings cannot shadow statics
   --> $DIR/static-mut-not-pat.rs:23:9
    |
 LL | static mut a: isize = 3;
-   | ------------------------ a static `a` is defined here
+   | ------------------------ the static `a` is defined here
 ...
 LL |         a => {} //~ ERROR match bindings cannot shadow statics
    |         ^ cannot be named the same as a static
@@ -11,7 +11,7 @@ error[E0530]: match bindings cannot shadow statics
   --> $DIR/static-mut-not-pat.rs:46:9
    |
 LL | static mut STATIC_MUT_FOO: Foo = Foo { bar: Some(Direction::West), baz: NEW_FALSE };
-   | ------------------------------------------------------------------------------------ a static `STATIC_MUT_FOO` is defined here
+   | ------------------------------------------------------------------------------------ the static `STATIC_MUT_FOO` is defined here
 ...
 LL |         STATIC_MUT_FOO => (),
    |         ^^^^^^^^^^^^^^ cannot be named the same as a static
diff --git a/src/test/ui/super-at-top-level.rs b/src/test/ui/super-at-top-level.rs
index c607711c44f..96d099c7655 100644
--- a/src/test/ui/super-at-top-level.rs
+++ b/src/test/ui/super-at-top-level.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use super::f; //~ ERROR There are too many initial `super`s
+use super::f; //~ ERROR there are too many initial `super`s
 
 fn main() {
 }
diff --git a/src/test/ui/super-at-top-level.stderr b/src/test/ui/super-at-top-level.stderr
index b4af73055a0..8402daad19e 100644
--- a/src/test/ui/super-at-top-level.stderr
+++ b/src/test/ui/super-at-top-level.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve. There are too many initial `super`s.
+error[E0433]: failed to resolve: there are too many initial `super`s.
   --> $DIR/super-at-top-level.rs:11:5
    |
-LL | use super::f; //~ ERROR There are too many initial `super`s
-   |     ^^^^^ There are too many initial `super`s.
+LL | use super::f; //~ ERROR there are too many initial `super`s
+   |     ^^^^^ there are too many initial `super`s.
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/tool-attributes/tool-attributes-shadowing.rs b/src/test/ui/tool-attributes/tool-attributes-shadowing.rs
index b6a24ccf748..11e28857afe 100644
--- a/src/test/ui/tool-attributes/tool-attributes-shadowing.rs
+++ b/src/test/ui/tool-attributes/tool-attributes-shadowing.rs
@@ -10,5 +10,5 @@
 
 mod rustfmt {}
 
-#[rustfmt::skip] //~ ERROR failed to resolve. Could not find `skip` in `rustfmt`
+#[rustfmt::skip] //~ ERROR failed to resolve: could not find `skip` in `rustfmt`
 fn main() {}
diff --git a/src/test/ui/tool-attributes/tool-attributes-shadowing.stderr b/src/test/ui/tool-attributes/tool-attributes-shadowing.stderr
index d593350f123..0839e363c36 100644
--- a/src/test/ui/tool-attributes/tool-attributes-shadowing.stderr
+++ b/src/test/ui/tool-attributes/tool-attributes-shadowing.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve. Could not find `skip` in `rustfmt`
+error[E0433]: failed to resolve: could not find `skip` in `rustfmt`
   --> $DIR/tool-attributes-shadowing.rs:13:12
    |
-LL | #[rustfmt::skip] //~ ERROR failed to resolve. Could not find `skip` in `rustfmt`
-   |            ^^^^ Could not find `skip` in `rustfmt`
+LL | #[rustfmt::skip] //~ ERROR failed to resolve: could not find `skip` in `rustfmt`
+   |            ^^^^ could not find `skip` in `rustfmt`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/type/type-path-err-node-types.stderr b/src/test/ui/type/type-path-err-node-types.stderr
index c28b30b5456..df7d442239b 100644
--- a/src/test/ui/type/type-path-err-node-types.stderr
+++ b/src/test/ui/type/type-path-err-node-types.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve. Use of undeclared type or module `NonExistent`
+error[E0433]: failed to resolve: use of undeclared type or module `NonExistent`
   --> $DIR/type-path-err-node-types.rs:25:5
    |
 LL |     NonExistent::Assoc::<u8>; //~ ERROR undeclared type or module `NonExistent`
-   |     ^^^^^^^^^^^ Use of undeclared type or module `NonExistent`
+   |     ^^^^^^^^^^^ use of undeclared type or module `NonExistent`
 
 error[E0412]: cannot find type `Nonexistent` in this scope
   --> $DIR/type-path-err-node-types.rs:17:12
diff --git a/src/test/ui/ufcs/ufcs-partially-resolved.rs b/src/test/ui/ufcs/ufcs-partially-resolved.rs
index f7120ddb114..db10197ded1 100644
--- a/src/test/ui/ufcs/ufcs-partially-resolved.rs
+++ b/src/test/ui/ufcs/ufcs-partially-resolved.rs
@@ -55,9 +55,9 @@ fn main() {
     <u8 as E::N>::NN; //~ ERROR cannot find method or associated constant `NN` in `E::N`
     <u8 as A::N>::NN; //~ ERROR cannot find method or associated constant `NN` in `A::N`
     let _: <u8 as Tr::Y>::NN; //~ ERROR cannot find associated type `NN` in `Tr::Y`
-    let _: <u8 as E::Y>::NN; //~ ERROR failed to resolve. Not a module `Y`
+    let _: <u8 as E::Y>::NN; //~ ERROR failed to resolve: not a module `Y`
     <u8 as Tr::Y>::NN; //~ ERROR cannot find method or associated constant `NN` in `Tr::Y`
-    <u8 as E::Y>::NN; //~ ERROR failed to resolve. Not a module `Y`
+    <u8 as E::Y>::NN; //~ ERROR failed to resolve: not a module `Y`
 
     let _: <u8 as Dr>::Z; //~ ERROR expected associated type, found method `Dr::Z`
     <u8 as Dr>::X; //~ ERROR expected method or associated constant, found associated type `Dr::X`
diff --git a/src/test/ui/ufcs/ufcs-partially-resolved.stderr b/src/test/ui/ufcs/ufcs-partially-resolved.stderr
index 77d887f1d68..cb571be661d 100644
--- a/src/test/ui/ufcs/ufcs-partially-resolved.stderr
+++ b/src/test/ui/ufcs/ufcs-partially-resolved.stderr
@@ -1,14 +1,14 @@
-error[E0433]: failed to resolve. Not a module `Y`
+error[E0433]: failed to resolve: not a module `Y`
   --> $DIR/ufcs-partially-resolved.rs:58:22
    |
-LL |     let _: <u8 as E::Y>::NN; //~ ERROR failed to resolve. Not a module `Y`
-   |                      ^ Not a module `Y`
+LL |     let _: <u8 as E::Y>::NN; //~ ERROR failed to resolve: not a module `Y`
+   |                      ^ not a module `Y`
 
-error[E0433]: failed to resolve. Not a module `Y`
+error[E0433]: failed to resolve: not a module `Y`
   --> $DIR/ufcs-partially-resolved.rs:60:15
    |
-LL |     <u8 as E::Y>::NN; //~ ERROR failed to resolve. Not a module `Y`
-   |               ^ Not a module `Y`
+LL |     <u8 as E::Y>::NN; //~ ERROR failed to resolve: not a module `Y`
+   |               ^ not a module `Y`
 
 error[E0576]: cannot find associated type `N` in trait `Tr`
   --> $DIR/ufcs-partially-resolved.rs:29:24
diff --git a/src/test/ui/unknown-tool-name.rs b/src/test/ui/unknown-tool-name.rs
index cd2aeb7494a..8d7a6225529 100644
--- a/src/test/ui/unknown-tool-name.rs
+++ b/src/test/ui/unknown-tool-name.rs
@@ -8,5 +8,5 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[foo::bar] //~ ERROR failed to resolve. Use of undeclared type or module `foo`
+#[foo::bar] //~ ERROR failed to resolve: use of undeclared type or module `foo`
 fn main() {}
diff --git a/src/test/ui/unknown-tool-name.stderr b/src/test/ui/unknown-tool-name.stderr
index 8381c6de83a..55096614fcd 100644
--- a/src/test/ui/unknown-tool-name.stderr
+++ b/src/test/ui/unknown-tool-name.stderr
@@ -1,8 +1,8 @@
-error[E0433]: failed to resolve. Use of undeclared type or module `foo`
+error[E0433]: failed to resolve: use of undeclared type or module `foo`
   --> $DIR/unknown-tool-name.rs:11:3
    |
-LL | #[foo::bar] //~ ERROR failed to resolve. Use of undeclared type or module `foo`
-   |   ^^^ Use of undeclared type or module `foo`
+LL | #[foo::bar] //~ ERROR failed to resolve: use of undeclared type or module `foo`
+   |   ^^^ use of undeclared type or module `foo`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/unresolved/unresolved-import.rs b/src/test/ui/unresolved/unresolved-import.rs
index efa74946476..4592289beeb 100644
--- a/src/test/ui/unresolved/unresolved-import.rs
+++ b/src/test/ui/unresolved/unresolved-import.rs
@@ -11,7 +11,7 @@
 // ignore-tidy-linelength
 
 use foo::bar; //~ ERROR unresolved import `foo` [E0432]
-              //~^ Maybe a missing `extern crate foo;`?
+              //~^ maybe a missing `extern crate foo;`?
 
 use bar::Baz as x; //~ ERROR unresolved import `bar::Baz` [E0432]
                    //~^ no `Baz` in `bar`. Did you mean to use `Bar`?
@@ -42,7 +42,7 @@ mod m {
     }
 
     use MyEnum::*; //~ ERROR unresolved import `MyEnum` [E0432]
-                   //~^ Did you mean `self::MyEnum`?
+                   //~^ did you mean `self::MyEnum`?
 }
 
 mod items {
@@ -51,7 +51,7 @@ mod items {
     }
 
     use Enum::*; //~ ERROR unresolved import `Enum` [E0432]
-                 //~^ Did you mean `self::Enum`?
+                 //~^ did you mean `self::Enum`?
 
     fn item() {}
 }
diff --git a/src/test/ui/unresolved/unresolved-import.stderr b/src/test/ui/unresolved/unresolved-import.stderr
index 9bcebb0011a..7e98a41af10 100644
--- a/src/test/ui/unresolved/unresolved-import.stderr
+++ b/src/test/ui/unresolved/unresolved-import.stderr
@@ -2,7 +2,7 @@ error[E0432]: unresolved import `foo`
   --> $DIR/unresolved-import.rs:13:5
    |
 LL | use foo::bar; //~ ERROR unresolved import `foo` [E0432]
-   |     ^^^ Maybe a missing `extern crate foo;`?
+   |     ^^^ maybe a missing `extern crate foo;`?
 
 error[E0432]: unresolved import `bar::Baz`
   --> $DIR/unresolved-import.rs:16:5
@@ -26,13 +26,13 @@ error[E0432]: unresolved import `MyEnum`
   --> $DIR/unresolved-import.rs:44:9
    |
 LL |     use MyEnum::*; //~ ERROR unresolved import `MyEnum` [E0432]
-   |         ^^^^^^ Did you mean `self::MyEnum`?
+   |         ^^^^^^ did you mean `self::MyEnum`?
 
 error[E0432]: unresolved import `Enum`
   --> $DIR/unresolved-import.rs:53:9
    |
 LL |     use Enum::*; //~ ERROR unresolved import `Enum` [E0432]
-   |         ^^^^ Did you mean `self::Enum`?
+   |         ^^^^ did you mean `self::Enum`?
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/use/use-from-trait-xc.stderr b/src/test/ui/use/use-from-trait-xc.stderr
index f8e5e18097b..6c643dff796 100644
--- a/src/test/ui/use/use-from-trait-xc.stderr
+++ b/src/test/ui/use/use-from-trait-xc.stderr
@@ -20,19 +20,19 @@ error[E0432]: unresolved import `use_from_trait_xc::Foo`
   --> $DIR/use-from-trait-xc.rs:24:24
    |
 LL | use use_from_trait_xc::Foo::new; //~ ERROR struct `Foo` is private
-   |                        ^^^ Not a module `Foo`
+   |                        ^^^ not a module `Foo`
 
 error[E0432]: unresolved import `use_from_trait_xc::Foo`
   --> $DIR/use-from-trait-xc.rs:27:24
    |
 LL | use use_from_trait_xc::Foo::C; //~ ERROR struct `Foo` is private
-   |                        ^^^ Not a module `Foo`
+   |                        ^^^ not a module `Foo`
 
 error[E0432]: unresolved import `use_from_trait_xc::Bar`
   --> $DIR/use-from-trait-xc.rs:30:24
    |
 LL | use use_from_trait_xc::Bar::new as bnew;
-   |                        ^^^ Not a module `Bar`
+   |                        ^^^ not a module `Bar`
 
 error[E0432]: unresolved import `use_from_trait_xc::Baz::new`
   --> $DIR/use-from-trait-xc.rs:33:5
diff --git a/src/test/ui/use/use-from-trait.rs b/src/test/ui/use/use-from-trait.rs
index 29db949acd0..afa76320582 100644
--- a/src/test/ui/use/use-from-trait.rs
+++ b/src/test/ui/use/use-from-trait.rs
@@ -18,11 +18,11 @@ use Trait::C;
 
 use Foo::new;
 //~^ ERROR unresolved import `Foo` [E0432]
-//~| Not a module `Foo`
+//~| not a module `Foo`
 
 use Foo::C2;
 //~^ ERROR unresolved import `Foo` [E0432]
-//~| Not a module `Foo`
+//~| not a module `Foo`
 
 pub trait Trait {
     fn foo();
diff --git a/src/test/ui/use/use-from-trait.stderr b/src/test/ui/use/use-from-trait.stderr
index b43a32988ca..cb0fd94fa6e 100644
--- a/src/test/ui/use/use-from-trait.stderr
+++ b/src/test/ui/use/use-from-trait.stderr
@@ -20,13 +20,13 @@ error[E0432]: unresolved import `Foo`
   --> $DIR/use-from-trait.rs:19:5
    |
 LL | use Foo::new;
-   |     ^^^ Not a module `Foo`
+   |     ^^^ not a module `Foo`
 
 error[E0432]: unresolved import `Foo`
   --> $DIR/use-from-trait.rs:23:5
    |
 LL | use Foo::C2;
-   |     ^^^ Not a module `Foo`
+   |     ^^^ not a module `Foo`
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/use/use-mod/use-mod-4.stderr b/src/test/ui/use/use-mod/use-mod-4.stderr
index 9a6d608faac..33366b2457b 100644
--- a/src/test/ui/use/use-mod/use-mod-4.stderr
+++ b/src/test/ui/use/use-mod/use-mod-4.stderr
@@ -14,7 +14,7 @@ error[E0432]: unresolved import `foo`
   --> $DIR/use-mod-4.rs:11:5
    |
 LL | use foo::self; //~ ERROR unresolved import `foo`
-   |     ^^^ Maybe a missing `extern crate foo;`?
+   |     ^^^ maybe a missing `extern crate foo;`?
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/use/use-self-type.rs b/src/test/ui/use/use-self-type.rs
index 6b5286bf0a7..1b49d358261 100644
--- a/src/test/ui/use/use-self-type.rs
+++ b/src/test/ui/use/use-self-type.rs
@@ -14,7 +14,7 @@ impl S {
     fn f() {}
     fn g() {
         use Self::f; //~ ERROR unresolved import
-        pub(in Self::f) struct Z; //~ ERROR Use of undeclared type or module `Self`
+        pub(in Self::f) struct Z; //~ ERROR use of undeclared type or module `Self`
     }
 }
 
diff --git a/src/test/ui/use/use-self-type.stderr b/src/test/ui/use/use-self-type.stderr
index 5a1e5ea2595..e4cb0f9f3d8 100644
--- a/src/test/ui/use/use-self-type.stderr
+++ b/src/test/ui/use/use-self-type.stderr
@@ -1,14 +1,14 @@
-error[E0433]: failed to resolve. Use of undeclared type or module `Self`
+error[E0433]: failed to resolve: use of undeclared type or module `Self`
   --> $DIR/use-self-type.rs:17:16
    |
-LL |         pub(in Self::f) struct Z; //~ ERROR Use of undeclared type or module `Self`
-   |                ^^^^ Use of undeclared type or module `Self`
+LL |         pub(in Self::f) struct Z; //~ ERROR use of undeclared type or module `Self`
+   |                ^^^^ use of undeclared type or module `Self`
 
 error[E0432]: unresolved import `Self`
   --> $DIR/use-self-type.rs:16:13
    |
 LL |         use Self::f; //~ ERROR unresolved import
-   |             ^^^^ Use of undeclared type or module `Self`
+   |             ^^^^ use of undeclared type or module `Self`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/use/use-super-global-path.stderr b/src/test/ui/use/use-super-global-path.stderr
index 4730653dbf9..fc4455c7d6e 100644
--- a/src/test/ui/use/use-super-global-path.stderr
+++ b/src/test/ui/use/use-super-global-path.stderr
@@ -1,10 +1,10 @@
-error[E0433]: failed to resolve. global paths cannot start with `super`
+error[E0433]: failed to resolve: global paths cannot start with `super`
   --> $DIR/use-super-global-path.rs:17:11
    |
 LL |     use ::super::{S, Z}; //~ ERROR global paths cannot start with `super`
    |           ^^^^^ global paths cannot start with `super`
 
-error[E0433]: failed to resolve. global paths cannot start with `super`
+error[E0433]: failed to resolve: global paths cannot start with `super`
   --> $DIR/use-super-global-path.rs:20:15
    |
 LL |         use ::super::main; //~ ERROR global paths cannot start with `super`