From 3724f162a295c3e14a05fe262cb10dbf222e1244 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 31 Oct 2018 00:22:19 +0300 Subject: [PATCH 01/18] resolve: Prohibit relative paths in visibilities on 2018 edition --- src/librustc_resolve/lib.rs | 13 ++++++++++++- src/test/ui/privacy/restricted/relative-2018.rs | 13 +++++++++++++ .../ui/privacy/restricted/relative-2018.stderr | 16 ++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/privacy/restricted/relative-2018.rs create mode 100644 src/test/ui/privacy/restricted/relative-2018.stderr diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index e30b5cfa37782..e3ba180d215c7 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -4496,7 +4496,18 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { ty::Visibility::Restricted(self.current_module.normal_ancestor_id) } ast::VisibilityKind::Restricted { ref path, id, .. } => { - // Visibilities are resolved as global by default, add starting root segment. + // For visibilities we are not ready to provide correct implementation of "uniform + // paths" right now, so on 2018 edition we only allow module-relative paths for now. + let first_ident = path.segments[0].ident; + if self.session.rust_2018() && !first_ident.is_path_segment_keyword() { + let msg = "relative paths are not supported in visibilities on 2018 edition"; + self.session.struct_span_err(first_ident.span, msg) + .span_suggestion(path.span, "try", format!("crate::{}", path)) + .emit(); + return ty::Visibility::Public; + } + // On 2015 visibilities are resolved as crate-relative by default, + // add starting root segment if necessary. let segments = path.make_root().iter().chain(path.segments.iter()) .map(|seg| seg.ident) .collect::>(); diff --git a/src/test/ui/privacy/restricted/relative-2018.rs b/src/test/ui/privacy/restricted/relative-2018.rs new file mode 100644 index 0000000000000..69b7c1e4d4f3c --- /dev/null +++ b/src/test/ui/privacy/restricted/relative-2018.rs @@ -0,0 +1,13 @@ +// edition:2018 + +mod m { + pub(in crate) struct S1; // OK + pub(in super) struct S2; // OK + pub(in self) struct S3; // OK + pub(in ::core) struct S4; + //~^ ERROR visibilities can only be restricted to ancestor modules + pub(in a::b) struct S5; + //~^ ERROR relative paths are not supported in visibilities on 2018 edition +} + +fn main() {} diff --git a/src/test/ui/privacy/restricted/relative-2018.stderr b/src/test/ui/privacy/restricted/relative-2018.stderr new file mode 100644 index 0000000000000..61effc463e98f --- /dev/null +++ b/src/test/ui/privacy/restricted/relative-2018.stderr @@ -0,0 +1,16 @@ +error: visibilities can only be restricted to ancestor modules + --> $DIR/relative-2018.rs:7:12 + | +LL | pub(in ::core) struct S4; + | ^^^^^^ + +error: relative paths are not supported in visibilities on 2018 edition + --> $DIR/relative-2018.rs:9:12 + | +LL | pub(in a::b) struct S5; + | ^--- + | | + | help: try: `crate::a::b` + +error: aborting due to 2 previous errors + From c8aacf21d1c4da08ba9634ffbafe8a95bc3252de Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 3 Nov 2018 19:41:44 +0300 Subject: [PATCH 02/18] resolve: Stop generating uniform path canaries --- src/librustc_resolve/build_reduced_graph.rs | 109 +------------ src/librustc_resolve/resolve_imports.rs | 170 +------------------- 2 files changed, 13 insertions(+), 266 deletions(-) diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 1b7225123abca..534f891dd2a56 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -116,17 +116,14 @@ impl<'a, 'cl> Resolver<'a, 'cl> { id: NodeId, parent_prefix: &[Ident], 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); + debug!("build_reduced_graph_for_use_tree(parent_prefix={:?}, use_tree={:?}, nested={})", + parent_prefix, use_tree, nested); let uniform_paths = self.session.rust_2018() && @@ -158,98 +155,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> { let prefix: Vec<_> = root.into_iter().chain(prefix_iter()).collect(); 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| { - let subclass = SingleImport { - target: Ident { - name: keywords::Underscore.name().gensymed(), - span: source.span, - }, - source, - 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.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(Ident { - name: keywords::SelfValue.name(), - span: source.span, - })); - - // 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.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: &[Ident]| { prefix.is_empty() || prefix.len() == 1 && prefix[0].name == keywords::CrateRoot.name() @@ -344,7 +249,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> { item.id, vis, parent_scope, - false, // is_uniform_paths_canary ); } ast::UseTreeKind::Glob => { @@ -361,7 +265,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> { item.id, vis, parent_scope, - false, // is_uniform_paths_canary ); } ast::UseTreeKind::Nested(ref items) => { @@ -390,7 +293,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, ); @@ -414,7 +317,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, ); @@ -435,7 +338,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, ); @@ -486,7 +389,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> { 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); @@ -899,7 +801,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(); diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 285025bed4af4..949d69cb7c696 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -35,7 +35,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. @@ -95,13 +94,6 @@ pub struct ImportDirective<'a> { pub subclass: ImportDirectiveSubclass<'a>, pub vis: Cell, pub used: Cell, - - /// 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> { @@ -188,11 +180,6 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { // 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; } @@ -404,8 +391,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 +404,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); @@ -648,18 +633,6 @@ 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(); @@ -667,46 +640,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { 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].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)) = error { errors = true; if let SingleImport { source, ref result, .. } = import.subclass { @@ -741,71 +675,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); } @@ -814,9 +683,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; } @@ -882,11 +748,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { // 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()) - }), + Some(ModuleOrUniformRoot::UniformRoot(keywords::Invalid.name())), &directive.module_path[..], None, &directive.parent_scope, @@ -965,11 +827,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { 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()) - }), + Some(ModuleOrUniformRoot::UniformRoot(keywords::Invalid.name())), &module_path, None, &directive.parent_scope, @@ -1036,21 +894,17 @@ 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 this.record_use(ident, ns, binding) { if let ModuleOrUniformRoot::Module(module) = module { this.resolution(module, ident, ns).borrow_mut().binding = Some(this.dummy_binding); } } - if record_used && ns == TypeNS { + if ns == TypeNS { if let ModuleOrUniformRoot::UniformRoot(..) = module { // Make sure single-segment import is resolved non-speculatively // at least once to report the feature error. @@ -1063,7 +917,7 @@ 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() { + if this.resolve_ident_in_module(module, ident, ns, true, span).is_ok() { all_ns_failed = false; } }); @@ -1260,15 +1114,7 @@ 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() { From 8e8e33b5bcafe0d76bc3d2d3680099ffbf560c16 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 3 Nov 2018 22:02:36 +0300 Subject: [PATCH 03/18] resolve: Resolve multi-segment imports using in-scope resolution on 2018 edition --- src/librustc_resolve/build_reduced_graph.rs | 38 +++++++-------------- src/librustc_resolve/error_reporting.rs | 9 +++-- src/librustc_resolve/lib.rs | 35 +++++++++---------- src/librustc_resolve/macros.rs | 23 +++++++------ src/librustc_resolve/resolve_imports.rs | 6 ---- 5 files changed, 46 insertions(+), 65 deletions(-) diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 534f891dd2a56..ff83fc424f233 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -125,36 +125,24 @@ impl<'a, 'cl> Resolver<'a, 'cl> { debug!("build_reduced_graph_for_use_tree(parent_prefix={:?}, use_tree={:?}, nested={})", parent_prefix, 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.ident)); - let prefix_start = prefix_iter().next(); - let starts_with_non_keyword = prefix_start.map_or(false, |ident| { - !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(Ident::new(keywords::CrateRoot.name(), span)) + let mut prefix_iter = parent_prefix.iter().cloned() + .chain(use_tree.prefix.segments.iter().map(|seg| seg.ident)).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, |ident| !ident.is_path_segment_keyword()) { + Some(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::>(); debug!("build_reduced_graph_for_use_tree: prefix={:?}", prefix); + let empty_for_self = |prefix: &[Ident]| { prefix.is_empty() || prefix.len() == 1 && prefix[0].name == keywords::CrateRoot.name() diff --git a/src/librustc_resolve/error_reporting.rs b/src/librustc_resolve/error_reporting.rs index 887eea4c8f9f0..58cab2430319e 100644 --- a/src/librustc_resolve/error_reporting.rs +++ b/src/librustc_resolve/error_reporting.rs @@ -68,7 +68,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { ) -> Option<(Vec, Option)> { // Replace first ident with `self` and check if that is valid. path[0].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)) @@ -92,7 +92,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { ) -> Option<(Vec, Option)> { // Replace first ident with `crate` and check if that is valid. path[0].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(( @@ -123,7 +123,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { ) -> Option<(Vec, Option)> { // Replace first ident with `crate` and check if that is valid. path[0].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)) @@ -164,8 +164,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { // Replace the first after root (a placeholder we inserted) with a crate name // and check if that is valid. path[1].name = *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_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 e3ba180d215c7..9a0a6436444f5 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1621,7 +1621,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { let hir::Path { ref segments, span, ref mut def } = *path; let path: Vec<_> = segments.iter().map(|seg| seg.ident).collect(); // FIXME (Manishearth): Intra doc links won't get warned of epoch changes - match self.resolve_path_without_parent_scope(None, &path, Some(namespace), true, span, + match self.resolve_path_without_parent_scope(&path, Some(namespace), true, span, CrateLint::No) { PathResult::Module(ModuleOrUniformRoot::Module(module)) => *def = module.def().unwrap(), @@ -2409,7 +2409,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, @@ -2930,7 +2929,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(), @@ -3416,7 +3415,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } let result = match self.resolve_path_without_parent_scope( - None, &path, Some(ns), true, @@ -3463,7 +3461,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { path[0].name != keywords::DollarCrate.name() { let unqualified_result = { match self.resolve_path_without_parent_scope( - None, &[*path.last().unwrap()], Some(ns), false, @@ -3487,9 +3484,8 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { fn resolve_path_without_parent_scope( &mut self, - base_module: Option>, path: &[Ident], - opt_ns: Option, // `None` indicates a module path + opt_ns: Option, // `None` indicates a module path in import record_used: bool, path_span: Span, crate_lint: CrateLint, @@ -3498,21 +3494,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>, path: &[Ident], - opt_ns: Option, // `None` indicates a module path + opt_ns: Option, // `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; @@ -3598,10 +3592,11 @@ 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) { + } 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 }; @@ -3686,9 +3681,11 @@ 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(keywords::Invalid.name()), + _ => span_bug!(path_span, "resolve_path: non-empty path `{:?}` has no module", path), + }) } fn lint_if_path_starts_with_module( @@ -3973,7 +3970,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); diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 89d011d2bd45e..e1fd8d5ba4cf8 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -473,7 +473,7 @@ 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), @@ -502,7 +502,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { def } else { let binding = self.early_resolve_ident_in_lexical_scope( - path[0], MacroNS, Some(kind), parent_scope, false, force, path_span + path[0], MacroNS, Some(kind), false, parent_scope, false, force, path_span ); match binding { Ok(..) => {} @@ -521,12 +521,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, + macro_kind: Option, + is_import: bool, parent_scope: &ParentScope<'a>, record_used: bool, force: bool, @@ -600,6 +601,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } assert!(force || !record_used); // `record_used` implies `force` + assert!(macro_kind.is_none() || !is_import); // `is_import` implies no macro kind ident = ident.modern(); // This is *the* result, resolution from the scope closest to the resolved identifier. @@ -788,7 +790,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { match result { Ok((binding, flags, ambig_flags)) => { - if sub_namespace_mismatch(kind, binding.macro_kind()) { + if sub_namespace_mismatch(macro_kind, binding.macro_kind()) { continue_search!(); } @@ -800,7 +802,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> { = 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() || + (is_import || + innermost_binding.is_glob_import() || innermost_binding.may_appear_after(parent_scope.expansion, binding) || innermost_flags.intersects(ambig_flags) || flags.intersects(innermost_ambig_flags) || @@ -834,7 +837,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } let determinacy = Determinacy::determined(force); - if determinacy == Determinacy::Determined && kind == Some(MacroKind::Attr) { + 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.) @@ -854,7 +857,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { let macro_resolutions = mem::replace(&mut *module.macro_resolutions.borrow_mut(), Vec::new()); for (path, parent_scope, path_span) in macro_resolutions { - 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, _) => { @@ -868,7 +871,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { 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 + ident, MacroNS, Some(kind), false, &parent_scope, true, true, ident.span ); match binding { Ok(binding) => { @@ -909,7 +912,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { let builtin_attrs = mem::replace(&mut *module.builtin_attrs.borrow_mut(), Vec::new()); for (ident, parent_scope) in builtin_attrs { let binding = self.early_resolve_ident_in_lexical_scope( - ident, MacroNS, Some(MacroKind::Attr), &parent_scope, true, true, ident.span + ident, MacroNS, Some(MacroKind::Attr), false, &parent_scope, true, true, ident.span ); if let Ok(binding) = binding { if binding.def_ignoring_ambiguity() != diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 949d69cb7c696..6a87b351dd3bc 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -152,10 +152,6 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { 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); @@ -748,7 +744,6 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { // while resolving its module path. directive.vis.set(ty::Visibility::Invisible); let result = self.resolve_path( - Some(ModuleOrUniformRoot::UniformRoot(keywords::Invalid.name())), &directive.module_path[..], None, &directive.parent_scope, @@ -827,7 +822,6 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { let ImportDirective { ref module_path, span, .. } = *directive; let module_result = self.resolve_path( - Some(ModuleOrUniformRoot::UniformRoot(keywords::Invalid.name())), &module_path, None, &directive.parent_scope, From 3ba2761bc29ae951270eb5c5c03015a502c6657c Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 5 Nov 2018 01:00:31 +0300 Subject: [PATCH 04/18] resolve: Simplify ambiguity checking for built-in attributes --- src/librustc_resolve/macros.rs | 13 ++----------- .../proc-macro/ambiguous-builtin-attrs.stderr | 12 ++++++------ 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index e1fd8d5ba4cf8..0212258be9f59 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -680,7 +680,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { let binding = (Def::NonMacroAttr(NonMacroAttrKind::Builtin), ty::Visibility::Public, ident.span, Mark::root()) .to_name_binding(self.arenas); - Ok((binding, Flags::PRELUDE, Flags::empty())) + Ok((binding, Flags::PRELUDE, Flags::all())) } else { Err(Determinacy::Determined) } @@ -911,18 +911,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( + 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); - } - } } } 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 ea867faf47bb6..0720ccb7cf9df 100644 --- a/src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs.stderr +++ b/src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs.stderr @@ -1,3 +1,9 @@ +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 --> $DIR/ambiguous-builtin-attrs.rs:9:3 | @@ -88,12 +94,6 @@ 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 - error: aborting due to 6 previous errors Some errors occurred: E0425, E0659. From dcaecedf1a59d69d3bb1cfab8e460942fbbe40b8 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 5 Nov 2018 01:11:59 +0300 Subject: [PATCH 05/18] resolve: Improve diagnostics for resolution ambiguities --- src/librustc/hir/def.rs | 16 +- src/librustc_mir/hair/pattern/check_match.rs | 3 +- src/librustc_resolve/build_reduced_graph.rs | 36 ++-- src/librustc_resolve/lib.rs | 184 ++++++++++++++---- src/librustc_resolve/macros.rs | 120 ++++++++---- src/librustc_resolve/resolve_imports.rs | 83 ++++---- ...helper-attr-blocked-by-import-ambig.stderr | 7 +- .../proc-macro/ambiguous-builtin-attrs.stderr | 60 ++---- .../proc-macro/derive-helper-shadowing.stderr | 7 +- src/test/ui/error-codes/E0659.stderr | 9 +- src/test/ui/imports/duplicate.stderr | 36 ++-- ...e-extern-crate-restricted-shadowing.stderr | 7 +- src/test/ui/imports/glob-shadowing.stderr | 26 +-- src/test/ui/imports/issue-53269.stderr | 7 +- .../local-modularized-tricky-fail-1.stderr | 32 +-- src/test/ui/imports/macro-paths.stderr | 16 +- src/test/ui/imports/macros.stderr | 16 +- .../ui/imports/rfc-1560-warning-cycle.stderr | 9 +- .../ui/imports/shadow_builtin_macros.stderr | 33 ++-- .../macros/ambiguity-legacy-vs-modern.stderr | 12 +- .../macro-path-prelude-shadowing.stderr | 9 +- src/test/ui/macros/macro-shadowing.stderr | 7 +- .../macros/restricted-shadowing-legacy.stderr | 56 +++--- .../macros/restricted-shadowing-modern.stderr | 42 ++-- src/test/ui/out-of-order-shadowing.stderr | 7 +- .../ambiguity-macros-nested.rs | 2 +- .../ambiguity-macros-nested.stderr | 23 ++- .../ambiguity-macros.rs | 2 +- .../ambiguity-macros.stderr | 23 ++- .../ambiguity-nested.rs | 2 +- .../ambiguity-nested.stderr | 20 +- .../uniform-paths-forward-compat/ambiguity.rs | 2 +- .../ambiguity.stderr | 20 +- .../uniform-paths/ambiguity-macros-nested.rs | 2 +- .../ambiguity-macros-nested.stderr | 23 ++- .../uniform-paths/ambiguity-macros.rs | 2 +- .../uniform-paths/ambiguity-macros.stderr | 23 ++- .../uniform-paths/ambiguity-nested.rs | 2 +- .../uniform-paths/ambiguity-nested.stderr | 20 +- .../ui/rust-2018/uniform-paths/ambiguity.rs | 2 +- .../rust-2018/uniform-paths/ambiguity.stderr | 20 +- 41 files changed, 603 insertions(+), 425 deletions(-) diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs index 5d9d4deb0abc9..1b82cde33cc38 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. @@ -333,4 +325,12 @@ 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", + _ => "a", + } + } } diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index f2ae5774da875..52826661651d8 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_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index ff83fc424f233..c6d3e7a9e2639 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -344,6 +344,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() && @@ -358,28 +375,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), - }); - self.potentially_unused_imports.push(directive); - let imported_binding = self.import(binding, directive); self.define(parent, ident, TypeNS, imported_binding); } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 9a0a6436444f5..ac8f2fbc9e8e9 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -391,14 +391,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, article) = (binding.descr(), binding.article()); + 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 {} {}", + 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!("{} {} `{}` is {} here", article, shadows_what, name, participle); err.span_label(binding.span, msg); err } @@ -1158,6 +1157,7 @@ enum NameBindingKind<'a> { used: Cell, }, Ambiguity { + kind: AmbiguityKind, b1: &'a NameBinding<'a>, b2: &'a NameBinding<'a>, } @@ -1175,10 +1175,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> { @@ -1231,6 +1282,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, } } @@ -1276,6 +1330,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 @@ -1826,8 +1884,12 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { self.record_use(ident, ns, binding) } NameBindingKind::Import { .. } => false, - NameBindingKind::Ambiguity { b1, b2 } => { - self.ambiguity_errors.push(AmbiguityError { ident, b1, b2 }); + NameBindingKind::Ambiguity { kind, b1, b2 } => { + self.ambiguity_errors.push(AmbiguityError { + kind, ident, b1, b2, + misc1: AmbiguityErrorMisc::None, + misc2: AmbiguityErrorMisc::None, + }); true } _ => false @@ -1965,7 +2027,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 { @@ -4565,37 +4627,79 @@ 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" }) - } 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)) + 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 { - None + (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 = 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 misc == AmbiguityErrorMisc::FromPrelude { + ("", " 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 { + ("", "") + }; + + 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 { + let participle = if b.is_import() { "imported" } else { "defined" }; + format!("the {thing} {introduced} here", + thing = b.descr(), introduced = participle) + }; + 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 the {thing} unambiguously", + ident = ident, thing = b.descr())) + } + if misc == AmbiguityErrorMisc::SuggestSelf { + help_msgs.push(format!("use `self::{ident}` to refer to the {thing} unambiguously", + ident = ident, thing = b.descr())) + } + + if b.span.is_dummy() { + err.note(¬e_msg); + } else { + err.span_note(b.span, ¬e_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(¬e); - } + + could_refer_to(b1, misc1, ""); + could_refer_to(b2, misc2, " also"); err.emit(); } @@ -4614,9 +4718,9 @@ 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 { + if reported_spans.insert(ambiguity_error.ident.span) { + self.report_ambiguity_error(ambiguity_error); } } @@ -4794,7 +4898,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 0212258be9f59..72cc1940a4c08 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -8,7 +8,8 @@ // 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 {AmbiguityError, AmbiguityKind, AmbiguityErrorMisc}; +use {CrateLint, Resolver, ResolutionError, is_known_tool, resolve_error}; use {Module, ModuleKind, NameBinding, NameBindingKind, PathResult, ToNameBinding}; use ModuleOrUniformRoot; use Namespace::{self, *}; @@ -593,10 +594,11 @@ 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; } } @@ -615,7 +617,7 @@ 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; @@ -634,7 +636,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { (Def::NonMacroAttr(NonMacroAttrKind::DeriveHelper), ty::Visibility::Public, derive.span, Mark::root()) .to_name_binding(self.arenas); - result = Ok((binding, Flags::DERIVE_HELPERS, Flags::all())); + result = Ok((binding, Flags::empty())); break; } } @@ -644,7 +646,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } 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)), _ => Err(Determinacy::Determined), } WhereToResolve::Module(module) => { @@ -658,29 +660,34 @@ impl<'a, 'cl> Resolver<'a, 'cl> { path_span, ); self.current_module = orig_current_module; - binding.map(|binding| (binding, Flags::MODULE, Flags::empty())) + let misc_flags = if module.is_normal() { + Flags::MISC_SUGGEST_SELF + } else { + Flags::empty() + }; + binding.map(|binding| (binding, Flags::MODULE | misc_flags)) } 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())); + result = Ok((binding, Flags::PRELUDE | Flags::MISC_FROM_PRELUDE)); } } 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::all())) + Ok((binding, Flags::PRELUDE)) } else { Err(Determinacy::Determined) } @@ -690,9 +697,9 @@ 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) } @@ -702,7 +709,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { 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())); + result = Ok((binding, Flags::PRELUDE)); } } result @@ -710,8 +717,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> { 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) } @@ -728,7 +735,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { false, path_span, ) { - result = Ok((binding, Flags::PRELUDE, Flags::empty())); + result = Ok((binding, Flags::PRELUDE | Flags::MISC_FROM_PRELUDE)); } } } @@ -738,8 +745,8 @@ 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) } @@ -789,7 +796,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { }} match result { - Ok((binding, flags, ambig_flags)) => { + Ok((binding, flags)) => { if sub_namespace_mismatch(macro_kind, binding.macro_kind()) { continue_search!(); } @@ -798,28 +805,61 @@ impl<'a, 'cl> Resolver<'a, 'cl> { 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() && - (is_import || - 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!(); diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 6a87b351dd3bc..0998834fe9f7b 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}; use Namespace::{self, TypeNS, MacroNS}; use {NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError}; use Resolver; @@ -219,7 +220,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { }; self.populate_module_if_necessary(crate_root); let binding = (crate_root, ty::Visibility::Public, - ident.span, Mark::root()).to_name_binding(self.arenas); + crate_root.span, Mark::root()).to_name_binding(self.arenas); return Ok(binding); } }; @@ -244,12 +245,14 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { // 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 { + kind: AmbiguityKind::GlobVsExpanded, ident, b1: binding, b2: shadowed_glob, + misc1: AmbiguityErrorMisc::None, + misc2: AmbiguityErrorMisc::None, }); } } @@ -471,38 +474,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); @@ -512,10 +525,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(), 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 059629c0b62d5..fc55dc1eef67a 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 the 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 0720ccb7cf9df..00f5cfc2613a0 100644 --- a/src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs.stderr +++ b/src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs.stderr @@ -4,95 +4,75 @@ error[E0425]: cannot find value `NonExistent` in this scope LL | NonExistent; //~ ERROR cannot find value `NonExistent` in this scope | ^^^^^^^^^^^ not found in this scope -error[E0659]: `repr` is ambiguous +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 the 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 the 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 the 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 the 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 + = help: use `self::feature` to refer to the 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 e0aeae4ba6c54..4950b016d3766 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 the attribute macro unambiguously error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0659.stderr b/src/test/ui/error-codes/E0659.stderr index f168b7797ca6d..7bfe159405bea 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/imports/duplicate.stderr b/src/test/ui/imports/duplicate.stderr index 5d51981e8afa9..f53ba9cd5de8e 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-restricted-shadowing.stderr b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr index 6c832e70e49a7..218dfb796f77a 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-shadowing.stderr b/src/test/ui/imports/glob-shadowing.stderr index 33a2963fa2947..93d3fa969efc3 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 the 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 the 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 e125983151d2b..9fa438e91cd22 100644 --- a/src/test/ui/imports/issue-53269.stderr +++ b/src/test/ui/imports/issue-53269.stderr @@ -4,22 +4,23 @@ error[E0432]: unresolved import `nonexistent_module` LL | use nonexistent_module::mac; //~ ERROR unresolved import `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 the unresolved item unambiguously error: aborting due to 2 previous errors 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 9c475451ce32f..91e569d176461 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 the 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 the 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 the 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 a612c64c2f470..96880492e285f 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 the 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 209d449dfd840..ade49e6be2483 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 the 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 91af3a4b6ac73..946dc084cd0f8 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 7e5ab0c5abe07..4d6c1aa3ea5e7 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 the 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 the 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 the 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/macros/ambiguity-legacy-vs-modern.stderr b/src/test/ui/macros/ambiguity-legacy-vs-modern.stderr index b5e1e751737b4..2785594585dd8 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-path-prelude-shadowing.stderr b/src/test/ui/macros/macro-path-prelude-shadowing.stderr index 688b9dc2797d0..3e0ea82364265 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 the 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 d996f3a704195..6985dfcc6c27e 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/restricted-shadowing-legacy.stderr b/src/test/ui/macros/restricted-shadowing-legacy.stderr index 9e0d40c44b683..2135d63c80ec2 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 0462438be7807..2449e8512d3cd 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 d96a802cb3f8f..4696e2057282a 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/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 590e83b07819a..4819711115c27 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 948043cff7614..b8cbabeea2c8e 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 the 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 the 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 861efba14f80c..148320de556d3 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 40cceea2440b9..5c9ab11085454 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 the 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 the 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 a69eb101917fa..2791d4580daf1 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 7538d3d2d917a..e98b9ad9a2ae6 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 the 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 the 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 500e9f6c63ff8..2bfbb6b287153 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 7b64b8f02464a..75387454015b9 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 the 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 the 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-nested.rs b/src/test/ui/rust-2018/uniform-paths/ambiguity-macros-nested.rs index e0992c9066632..9f440d71fb003 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 @@ -16,7 +16,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/ambiguity-macros-nested.stderr b/src/test/ui/rust-2018/uniform-paths/ambiguity-macros-nested.stderr index 154ee412e7282..f18de7edcdcbc 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 +error[E0659]: `std` is ambiguous (name vs any other name during import resolution) --> $DIR/ambiguity-macros-nested.rs:18: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 the extern crate unambiguously +note: `std` could also refer to the module defined here + --> $DIR/ambiguity-macros-nested.rs:23:13 + | 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 the 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 9439d92aa710b..f1ed48150c0b8 100644 --- a/src/test/ui/rust-2018/uniform-paths/ambiguity-macros.rs +++ b/src/test/ui/rust-2018/uniform-paths/ambiguity-macros.rs @@ -15,7 +15,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/ambiguity-macros.stderr b/src/test/ui/rust-2018/uniform-paths/ambiguity-macros.stderr index 3c0d5601f9c8a..16e083b098083 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 +error[E0659]: `std` is ambiguous (name vs any other name during import resolution) --> $DIR/ambiguity-macros.rs:17: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 the extern crate unambiguously +note: `std` could also refer to the module defined here + --> $DIR/ambiguity-macros.rs:22:9 + | 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 the 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 1756acc6057f2..0d0d34df1f833 100644 --- a/src/test/ui/rust-2018/uniform-paths/ambiguity-nested.rs +++ b/src/test/ui/rust-2018/uniform-paths/ambiguity-nested.rs @@ -16,7 +16,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/ambiguity-nested.stderr b/src/test/ui/rust-2018/uniform-paths/ambiguity-nested.stderr index a607eeb0b43e0..cb38102c5997e 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 +error[E0659]: `std` is ambiguous (name vs any other name during import resolution) --> $DIR/ambiguity-nested.rs:18: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 the extern crate unambiguously +note: `std` could also refer to the module defined here + --> $DIR/ambiguity-nested.rs:21:5 + | 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 the 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 9ae3d79c22cf2..259f451e4d22d 100644 --- a/src/test/ui/rust-2018/uniform-paths/ambiguity.rs +++ b/src/test/ui/rust-2018/uniform-paths/ambiguity.rs @@ -13,7 +13,7 @@ #![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 c65db3072f440..ce0c64b226b59 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 +error[E0659]: `std` is ambiguous (name vs any other name during import resolution) --> $DIR/ambiguity.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 the extern crate unambiguously +note: `std` could also refer to the module defined here + --> $DIR/ambiguity.rs:18:1 + | 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 the module unambiguously error: aborting due to previous error +For more information about this error, try `rustc --explain E0659`. From 35b778f65b50ed5a45dd33193082dc31d8b18813 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 8 Nov 2018 00:39:07 +0300 Subject: [PATCH 06/18] resolve: More precise determinacy tracking during import/macro resolution --- src/librustc_resolve/build_reduced_graph.rs | 1 - src/librustc_resolve/lib.rs | 12 +- src/librustc_resolve/macros.rs | 200 +++++++++++--------- src/librustc_resolve/resolve_imports.rs | 74 +++++--- src/test/ui/span/macro-ty-params.stderr | 12 +- 5 files changed, 166 insertions(+), 133 deletions(-) diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index c6d3e7a9e2639..3ec64edaa485e 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -860,7 +860,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/lib.rs b/src/librustc_resolve/lib.rs index ac8f2fbc9e8e9..6f5127cee2d57 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -97,6 +97,12 @@ fn is_known_tool(name: Name) -> bool { ["clippy", "rustfmt"].contains(&&*name.as_str()) } +enum DeterminacyExt { + Determined, + Undetermined, + WeakUndetermined, +} + /// A free importable items suggested in case of resolution failure. struct ImportSuggestion { path: Path, @@ -1963,7 +1969,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { ModuleOrUniformRoot::Module(module), ident, ns, - false, record_used, path_span, ); @@ -1994,7 +1999,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { ModuleOrUniformRoot::Module(module), ident, ns, - false, record_used, path_span, ); @@ -2036,7 +2040,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { ident, ns, false, - false, path_span, ) { return Some(LexicalScopeBinding::Item(binding)); @@ -2111,7 +2114,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } } let result = self.resolve_ident_in_module_unadjusted( - module, ident, ns, false, record_used, span, + module, ident, ns, record_used, span, ); self.current_module = orig_current_module; result @@ -4334,7 +4337,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { ident, ns, false, - false, module.span, ).is_ok() { let import_id = match binding.kind { diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 72cc1940a4c08..fc3143b5e8f60 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -9,7 +9,7 @@ // except according to those terms. use {AmbiguityError, AmbiguityKind, AmbiguityErrorMisc}; -use {CrateLint, Resolver, ResolutionError, is_known_tool, resolve_error}; +use {CrateLint, DeterminacyExt, Resolver, ResolutionError, is_known_tool, resolve_error}; use {Module, ModuleKind, NameBinding, NameBindingKind, PathResult, ToNameBinding}; use ModuleOrUniformRoot; use Namespace::{self, *}; @@ -54,8 +54,8 @@ pub struct InvocationData<'a> { crate parent_legacy_scope: Cell>, /// 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>, + /// `None` if the macro is not expanded yet. + crate output_legacy_scope: Cell>>, } impl<'a> InvocationData<'a> { @@ -64,7 +64,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)), } } } @@ -110,7 +110,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, candidate: Option) -> bool { +fn sub_namespace_match(candidate: Option, requirement: Option) -> bool { #[derive(PartialEq)] enum SubNS { Bang, AttrLike } let sub_ns = |kind| match kind { @@ -121,7 +121,7 @@ fn sub_namespace_mismatch(requirement: Option, candidate: Option base::Resolver for Resolver<'a, 'crateloader> { @@ -136,7 +136,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 } @@ -212,7 +212,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) { @@ -620,26 +620,36 @@ impl<'a, 'cl> Resolver<'a, 'cl> { let mut innermost_result: Option<(&NameBinding, Flags)> = None; // Go through all the scopes and try to resolve the name. - let mut where_to_resolve = 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::empty())); - break; + match self.resolve_macro_to_def(derive, MacroKind::Derive, + &parent_scope, 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 @@ -647,11 +657,13 @@ impl<'a, 'cl> Resolver<'a, 'cl> { WhereToResolve::MacroRules(legacy_scope) => match legacy_scope { LegacyScope::Binding(legacy_binding) if ident == legacy_binding.ident => 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, @@ -660,21 +672,33 @@ impl<'a, 'cl> Resolver<'a, 'cl> { path_span, ); self.current_module = orig_current_module; - let misc_flags = if module.is_normal() { - Flags::MISC_SUGGEST_SELF - } else { - Flags::empty() - }; - binding.map(|binding| (binding, Flags::MODULE | misc_flags)) + 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(DeterminacyExt::Undetermined) => + return Err(Determinacy::determined(force)), + Err(DeterminacyExt::WeakUndetermined) => Err(Determinacy::Undetermined), + Err(DeterminacyExt::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::MISC_FROM_PRELUDE)); + 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() { @@ -705,14 +729,17 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } } 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)); + 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) { @@ -732,7 +759,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> { ident, ns, false, - false, path_span, ) { result = Ok((binding, Flags::PRELUDE | Flags::MISC_FROM_PRELUDE)); @@ -753,54 +779,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } }; - 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)) => { - if sub_namespace_mismatch(macro_kind, binding.macro_kind()) { - continue_search!(); - } - + Ok((binding, flags)) if sub_namespace_match(binding.macro_kind(), macro_kind) => { if !record_used { return Ok(binding); } @@ -861,14 +841,52 @@ impl<'a, 'cl> Resolver<'a, 'cl> { // Found the first solution. 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. @@ -876,7 +894,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { return Ok(binding); } - let determinacy = Determinacy::determined(force); + 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 @@ -1020,7 +1038,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 0998834fe9f7b..f822e2afa762c 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -11,7 +11,7 @@ use self::ImportDirectiveSubclass::*; use {AmbiguityError, AmbiguityKind, AmbiguityErrorMisc}; -use {CrateLint, Module, ModuleOrUniformRoot, PerNS}; +use {CrateLint, DeterminacyExt, Module, ModuleOrUniformRoot, PerNS}; use Namespace::{self, TypeNS, MacroNS}; use {NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError}; use Resolver; @@ -135,16 +135,33 @@ 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, false, record_used, path_span + ).map_err(|determinacy_ext| match determinacy_ext { + DeterminacyExt::Determined => Determined, + DeterminacyExt::Undetermined | DeterminacyExt::WeakUndetermined => Undetermined, + }) + } + /// 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, + restricted_shadowing: bool, + record_used: bool, + path_span: Span, + ) -> Result<&'a NameBinding<'a>, DeterminacyExt> { let module = match module { ModuleOrUniformRoot::Module(module) => module, ModuleOrUniformRoot::UniformRoot(root) => { @@ -157,7 +174,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { 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( + let binding = self.resolve_ident_in_module_unadjusted_ext( ModuleOrUniformRoot::Module(self_module), ident, ns, @@ -211,12 +228,12 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { 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); + return Err(DeterminacyExt::Undetermined); } else { - return Err(Determined); + return Err(DeterminacyExt::Determined); } } else { - return Err(Determined); + return Err(DeterminacyExt::Determined); }; self.populate_module_if_necessary(crate_root); let binding = (crate_root, ty::Visibility::Public, @@ -229,7 +246,8 @@ 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 + // This happens when there is a cycle of imports. + .map_err(|_| DeterminacyExt::Determined)?; if let Some(binding) = resolution.binding { if !restricted_shadowing && binding.expansion != Mark::root() { @@ -264,13 +282,13 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { } } - return resolution.binding.ok_or(Determined); + return resolution.binding.ok_or(DeterminacyExt::Determined); } 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) } + if usable { Ok(binding) } else { Err(DeterminacyExt::Determined) } }; // Items and single imports are not shadowable, if we have one, then it's determined. @@ -288,7 +306,8 @@ 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(DeterminacyExt::Undetermined)); let ident = match single_import.subclass { SingleImport { source, .. } => source, _ => unreachable!(), @@ -298,7 +317,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { 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(DeterminacyExt::Undetermined), } } @@ -319,7 +338,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(DeterminacyExt::Undetermined); } } @@ -328,17 +347,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 `WeakUndetermined` instead of full `Undetermined`. // 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(DeterminacyExt::WeakUndetermined); } // Check if one of glob imports can still define the name, @@ -350,7 +365,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(DeterminacyExt::WeakUndetermined), }; let (orig_current_module, mut ident) = (self.current_module, ident.modern()); match ident.span.glob_adjust(module.expansion, glob_import.span.ctxt().modern()) { @@ -363,7 +378,6 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { ident, ns, false, - false, path_span, ); self.current_module = orig_current_module; @@ -373,12 +387,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(DeterminacyExt::WeakUndetermined), } } // No resolution and no one else can define the name - determinate error. - Err(Determined) + Err(DeterminacyExt::Determined) } // Add an import directive to the current module. diff --git a/src/test/ui/span/macro-ty-params.stderr b/src/test/ui/span/macro-ty-params.stderr index 3988dec88d5a8..8a40556a6cd0e 100644 --- a/src/test/ui/span/macro-ty-params.stderr +++ b/src/test/ui/span/macro-ty-params.stderr @@ -4,6 +4,12 @@ error: unexpected generic arguments in path 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 | @@ -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 From 82ee839699e1b9f184b989b410b5d856509f8784 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 9 Nov 2018 01:29:07 +0300 Subject: [PATCH 07/18] resolve: Resolve single-segment imports using in-scope resolution on 2018 edition --- src/librustc_resolve/build_reduced_graph.rs | 1 + src/librustc_resolve/lib.rs | 80 ++++++--- src/librustc_resolve/macros.rs | 10 +- src/librustc_resolve/resolve_imports.rs | 163 ++++++++---------- .../feature-gate-extern_crate_item_prelude.rs | 4 +- ...ture-gate-extern_crate_item_prelude.stderr | 2 +- .../uniform-paths/from-decl-macro.rs | 12 ++ 7 files changed, 148 insertions(+), 124 deletions(-) create mode 100644 src/test/ui/rust-2018/uniform-paths/from-decl-macro.rs diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 3ec64edaa485e..023a7477cee1b 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -806,6 +806,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { ModuleOrUniformRoot::Module(module), ident, MacroNS, + None, false, span, ); diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 6f5127cee2d57..8892f6e83dcd5 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -103,6 +103,15 @@ enum DeterminacyExt { WeakUndetermined, } +impl DeterminacyExt { + fn to_determinacy(self) -> Determinacy { + match self { + DeterminacyExt::Determined => Determined, + DeterminacyExt::Undetermined | DeterminacyExt::WeakUndetermined => Undetermined, + } + } +} + /// A free importable items suggested in case of resolution failure. struct ImportSuggestion { path: Path, @@ -961,15 +970,22 @@ 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), } #[derive(Clone, Debug)] @@ -2099,23 +2115,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, record_used, span, - ); + let result = self.resolve_ident_in_module_unadjusted_ext( + module, ident, ns, parent_scope, false, record_used, path_span, + ).map_err(DeterminacyExt::to_determinacy); self.current_module = orig_current_module; result } @@ -2614,6 +2638,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { ModuleOrUniformRoot::Module(module), ident, ns, + None, false, span, ).is_err() { @@ -3624,9 +3649,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() || @@ -3656,7 +3681,7 @@ 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) + self.resolve_ident_in_module(module, ident, ns, None, record_used, path_span) } else if opt_ns.is_none() || opt_ns == Some(MacroNS) { assert!(ns == TypeNS); self.early_resolve_ident_in_lexical_scope(ident, ns, None, opt_ns.is_none(), @@ -3675,7 +3700,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { def, path.len() - 1 )); } - _ => Err(if record_used { Determined } else { Undetermined }), + _ => Err(Determinacy::determined(record_used)), } }; @@ -3748,7 +3773,8 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { PathResult::Module(match module { Some(module) => module, - None if path.is_empty() => ModuleOrUniformRoot::UniformRoot(keywords::Invalid.name()), + None if path.is_empty() => + ModuleOrUniformRoot::UniformRoot(UniformRootKind::CurrentScope), _ => span_bug!(path_span, "resolve_path: non-empty path `{:?}` has no module", path), }) } @@ -3960,6 +3986,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { ModuleOrUniformRoot::Module(module), ident, ns, + None, false, module.span, ) { @@ -4282,6 +4309,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { ModuleOrUniformRoot::Module(module), ident, ns, + None, false, module.span, ).is_ok() { @@ -4879,6 +4907,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 && diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index fc3143b5e8f60..c6cd6f1cd64e9 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -371,11 +371,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) -> ParentScope<'a> { + fn invoc_parent_scope(&self, invoc_id: Mark, derives: Vec) -> ParentScope<'a> { let invoc = self.invocations[&invoc_id]; ParentScope { module: invoc.module.get().nearest_item_scope(), @@ -606,6 +606,11 @@ impl<'a, 'cl> Resolver<'a, 'cl> { 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. @@ -667,6 +672,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { ModuleOrUniformRoot::Module(module), ident, ns, + None, true, record_used, path_span, diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index f822e2afa762c..f496ab2b44b1d 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -11,7 +11,7 @@ use self::ImportDirectiveSubclass::*; use {AmbiguityError, AmbiguityKind, AmbiguityErrorMisc}; -use {CrateLint, DeterminacyExt, Module, ModuleOrUniformRoot, PerNS}; +use {CrateLint, DeterminacyExt, Module, ModuleOrUniformRoot, PerNS, UniformRootKind}; use Namespace::{self, TypeNS, MacroNS}; use {NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError}; use Resolver; @@ -23,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; @@ -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, @@ -144,11 +144,8 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { path_span: Span, ) -> Result<&'a NameBinding<'a>, Determinacy> { self.resolve_ident_in_module_unadjusted_ext( - module, ident, ns, false, record_used, path_span - ).map_err(|determinacy_ext| match determinacy_ext { - DeterminacyExt::Determined => Determined, - DeterminacyExt::Undetermined | DeterminacyExt::WeakUndetermined => Undetermined, - }) + module, ident, ns, None, false, record_used, path_span + ).map_err(DeterminacyExt::to_determinacy) } /// Attempts to resolve `ident` in namespaces `ns` of `module`. @@ -158,87 +155,55 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { 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>, DeterminacyExt> { 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 { - // 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_ext( - 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. - 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(DeterminacyExt::Undetermined) + } else { + Err(DeterminacyExt::Determined) + } } + 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 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| match determinacy { + Determined => DeterminacyExt::Determined, + Undetermined => DeterminacyExt::Undetermined, + }); } } - - 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(DeterminacyExt::Undetermined); - } else { - return Err(DeterminacyExt::Determined); - } - } else { - return Err(DeterminacyExt::Determined); - }; - self.populate_module_if_necessary(crate_root); - let binding = (crate_root, ty::Visibility::Public, - crate_root.span, Mark::root()).to_name_binding(self.arenas); - return Ok(binding); } }; @@ -312,7 +277,8 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { 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 @@ -439,8 +405,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() { @@ -766,10 +732,9 @@ 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); + // 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 result = self.resolve_path( &directive.module_path[..], None, @@ -778,7 +743,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { directive.span, directive.crate_lint(), ); - directive.vis.set(vis); + directive.vis.set(orig_vis); match result { PathResult::Module(module) => module, @@ -801,11 +766,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 }; @@ -938,7 +907,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, true, span).is_ok() { + let binding = this.resolve_ident_in_module( + module, ident, ns, Some(&directive.parent_scope), true, span + ); + if binding.is_ok() { all_ns_failed = false; } }); @@ -1138,8 +1110,9 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { 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); + let def_id = def.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/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 a043b6c2e6107..27b9a34ff4eb7 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 cabfb56d7a840..ac65dcb4d54fc 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 #54658) --> $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/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 0000000000000..5c3c753f9a785 --- /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::::new() +} + +fn main() { + check!(); +} From e8bc1d1c23f0f9ae07636c3f01ad2a16cf84bbb5 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 10 Nov 2018 18:58:37 +0300 Subject: [PATCH 08/18] resolve: Check resolution consistency for import paths and multi-segment macro paths --- src/librustc/hir/def.rs | 1 + src/librustc/hir/def_id.rs | 4 +- src/librustc_resolve/lib.rs | 45 +++-- src/librustc_resolve/macros.rs | 116 +++++++----- src/librustc_resolve/resolve_imports.rs | 178 +++++++++++------- src/libsyntax/ext/base.rs | 7 + src/test/ui/extern/extern-macro.rs | 2 +- src/test/ui/extern/extern-macro.stderr | 7 +- .../ui/macros/macro-path-prelude-fail-2.rs | 2 +- .../macros/macro-path-prelude-fail-2.stderr | 7 +- src/test/ui/privacy/decl-macro.rs | 9 + src/test/ui/privacy/decl-macro.stderr | 9 + .../non-existent-1.stderr | 2 +- .../block-scoped-shadow.rs | 4 +- .../block-scoped-shadow.stderr | 46 +++-- .../block-scoped-shadow-nested.rs | 20 ++ .../block-scoped-shadow-nested.stderr | 23 +++ .../uniform-paths/block-scoped-shadow.rs | 10 +- .../uniform-paths/block-scoped-shadow.stderr | 68 ++++--- .../rust-2018/uniform-paths/fn-local-enum.rs | 13 ++ 20 files changed, 371 insertions(+), 202 deletions(-) create mode 100644 src/test/ui/privacy/decl-macro.rs create mode 100644 src/test/ui/privacy/decl-macro.stderr create mode 100644 src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.rs create mode 100644 src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.stderr create mode 100644 src/test/ui/rust-2018/uniform-paths/fn-local-enum.rs diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs index 1b82cde33cc38..fa6b80ab9714d 100644 --- a/src/librustc/hir/def.rs +++ b/src/librustc/hir/def.rs @@ -330,6 +330,7 @@ impl Def { 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 e378e1b8be0e9..319d63f66c465 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_resolve/lib.rs b/src/librustc_resolve/lib.rs index 8892f6e83dcd5..f875ba511ec36 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -988,6 +988,18 @@ enum ModuleOrUniformRoot<'a> { 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)] enum PathResult<'a> { Module(ModuleOrUniformRoot<'a>), @@ -1029,9 +1041,10 @@ pub struct ModuleData<'a> { normal_ancestor_id: DefId, resolutions: RefCell>>>, - legacy_macro_resolutions: RefCell, - Option<&'a NameBinding<'a>>)>>, - macro_resolutions: RefCell, ParentScope<'a>, Span)>>, + single_segment_macro_resolutions: RefCell, + Option<&'a NameBinding<'a>>)>>, + multi_segment_macro_resolutions: RefCell, Span, MacroKind, ParentScope<'a>, + Option)>>, builtin_attrs: RefCell)>>, // Macro invocations that can expand into items in this module. @@ -1069,8 +1082,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, @@ -1466,6 +1479,9 @@ pub struct Resolver<'a, 'b: 'a> { /// The current self item if inside an ADT (used for better errors). current_self_item: Option, + /// 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, @@ -1793,6 +1809,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(), @@ -1894,27 +1911,23 @@ 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 */ { + fn record_use(&mut self, ident: Ident, ns: Namespace, binding: &'a NameBinding<'a>) { match binding.kind { - NameBindingKind::Import { directive, binding, ref used } - if !used.get() => { + NameBindingKind::Import { directive, binding, ref used } if !used.get() => { 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); } - NameBindingKind::Import { .. } => false, NameBindingKind::Ambiguity { kind, b1, b2 } => { self.ambiguity_errors.push(AmbiguityError { kind, ident, b1, b2, misc1: AmbiguityErrorMisc::None, misc2: AmbiguityErrorMisc::None, }); - true } - _ => false + _ => {} } } @@ -4735,7 +4748,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { 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 \ @@ -4749,11 +4761,10 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } for ambiguity_error in &self.ambiguity_errors { - if reported_spans.insert(ambiguity_error.ident.span) { - self.report_ambiguity_error(ambiguity_error); - } + 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", diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index c6cd6f1cd64e9..e0fce11de7f7e 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -9,8 +9,9 @@ // except according to those terms. use {AmbiguityError, AmbiguityKind, AmbiguityErrorMisc}; -use {CrateLint, DeterminacyExt, Resolver, ResolutionError, is_known_tool, resolve_error}; +use {CrateLint, DeterminacyExt, Resolver, ResolutionError}; use {Module, ModuleKind, NameBinding, NameBindingKind, PathResult, ToNameBinding}; +use {is_known_tool, names_to_string, resolve_error}; use ModuleOrUniformRoot; use Namespace::{self, *}; use build_reduced_graph::{BuildReducedGraphVisitor, IsMacroExport}; @@ -450,6 +451,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> { return Err(Determinacy::Determined); } } + Def::Err => { + return Err(Determinacy::Determined); + } _ => panic!("expected `Def::Macro` or `Def::NonMacroAttr`"), } @@ -476,29 +480,19 @@ impl<'a, 'cl> Resolver<'a, 'cl> { if path.len() > 1 { 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)); + parent_scope.module.multi_segment_macro_resolutions.borrow_mut() + .push((path, path_span, kind, parent_scope.clone(), def.ok())); def } else { @@ -511,7 +505,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { Err(Determinacy::Undetermined) => return Err(Determinacy::Undetermined), } - parent_scope.module.legacy_macro_resolutions.borrow_mut() + parent_scope.module.single_segment_macro_resolutions.borrow_mut() .push((path[0], kind, parent_scope.clone(), binding.ok())); binding.map(|binding| binding.def_ignoring_ambiguity()) @@ -918,48 +912,66 @@ 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: &[Ident], 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(), 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 (path, parent_scope, path_span) in macro_resolutions { + mem::replace(&mut *module.multi_segment_macro_resolutions.borrow_mut(), Vec::new()); + for (path, path_span, kind, parent_scope, initial_def) in macro_resolutions { 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), false, &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 def = binding.def_ignoring_ambiguity(); - if let Some(initial_binding) = initial_binding { + let initial_def = initial_binding.map(|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(); - } + initial_binding.def_ignoring_ambiguity() + }); + let def = binding.def_ignoring_ambiguity(); + check_consistency(self, &[ident], ident.span, kind, initial_def, def); } Err(..) => { assert!(initial_binding.is_none()); diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index f496ab2b44b1d..b43b207e6062b 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -222,40 +222,47 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { } } - 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() && - 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(DeterminacyExt::Determined); - } - let check_usable = |this: &mut Self, binding: &'a NameBinding<'a>| { - // `extern crate` are always usable for backwards compatibility, see issue #37020. + // `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(DeterminacyExt::Determined) } }; + if record_used { + return resolution.binding.ok_or(DeterminacyExt::Determined).and_then(|binding| { + if self.last_import_segment && check_usable(self, binding).is_err() { + Err(DeterminacyExt::Determined) + } else { + self.record_use(ident, ns, binding); + + 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.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)); + } + + Ok(binding) + } + }) + } + // Items and single imports are not shadowable, if we have one, then it's determined. if let Some(binding) = resolution.binding { if !binding.is_glob_import() { @@ -628,8 +635,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { let mut prev_root_id: NodeId = NodeId::new(0); for i in 0 .. self.determined_imports.len() { let import = self.determined_imports[i]; - let error = self.finalize_import(import); - 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 { @@ -724,7 +730,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 `{}`", - names_to_string(&directive.module_path[..]), + names_to_string(&directive.module_path), module_to_string(self.current_module).unwrap_or_else(|| "???".to_string())); self.current_module = directive.parent_scope.module; @@ -735,8 +741,8 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { // 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 result = self.resolve_path( - &directive.module_path[..], + let path_res = self.resolve_path( + &directive.module_path, None, &directive.parent_scope, false, @@ -745,10 +751,10 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { ); 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, } }; @@ -815,25 +821,37 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { directive: &'b ImportDirective<'b> ) -> Option<(Span, String, Option)> { self.current_module = directive.parent_scope.module; - let ImportDirective { ref module_path, span, .. } = *directive; - let module_result = self.resolve_path( - &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, @@ -843,17 +861,22 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { } 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(keywords::Invalid.ident()); self.lint_if_path_starts_with_module( directive.crate_lint(), @@ -886,20 +909,39 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { 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 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, MacroNS, initial_binding); + 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 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(..) => { + assert!(result[ns].get().is_err()); } } }); @@ -908,7 +950,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { let mut all_ns_failed = true; self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS { let binding = this.resolve_ident_in_module( - module, ident, ns, Some(&directive.parent_scope), true, span + module, ident, ns, Some(&directive.parent_scope), true, directive.span ); if binding.is_ok() { all_ns_failed = false; @@ -967,7 +1009,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); @@ -1016,10 +1058,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(ident); self.per_ns(|this, ns| { if let Ok(binding) = result[ns].get() { diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 5bf1a7dd663cc..7e625dba43c7f 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -585,6 +585,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/extern/extern-macro.rs b/src/test/ui/extern/extern-macro.rs index 4b1bf7d8f7923..fcba5cb4f07a1 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 b5515bfcc6423..159fefdd2696b 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/macros/macro-path-prelude-fail-2.rs b/src/test/ui/macros/macro-path-prelude-fail-2.rs index 82258dac37b86..d9f99aa0119ce 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 876ee2584e9aa..31e45b320ad73 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/privacy/decl-macro.rs b/src/test/ui/privacy/decl-macro.rs new file mode 100644 index 0000000000000..1eb49bd530176 --- /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 0000000000000..c8b043d1b5f31 --- /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/rfc-2126-extern-absolute-paths/non-existent-1.stderr b/src/test/ui/rfc-2126-extern-absolute-paths/non-existent-1.stderr index 1a8ceec5dac06..ba44f20facfd2 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/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 ca488fec5162d..2853b4b3a5b3f 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 27e0e88369127..d0e3d002b0885 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 the 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 the 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/block-scoped-shadow-nested.rs b/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.rs new file mode 100644 index 0000000000000..3f5897901a056 --- /dev/null +++ b/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.rs @@ -0,0 +1,20 @@ +// edition:2018 + +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 0000000000000..32f5cb30177b7 --- /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:16: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:14:9 + | +LL | use my::sub; + | ^^^^^^^ +note: `sub` could also refer to the module defined here + --> $DIR/block-scoped-shadow-nested.rs:9:1 + | +LL | / mod sub { +LL | | pub fn bar() {} +LL | | } + | |_^ + = help: use `self::sub` to refer to the 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 ee141d444b2cf..36d996fc4f930 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 @@ -12,20 +12,20 @@ #![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 86d95f2ac4567..a1db1c3e0be6c 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 +error[E0659]: `Foo` is ambiguous (name vs any other name during import resolution) --> $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` LL | use Foo::*; - | ^^^ + | ^^^ ambiguous name | - = help: write `self::Foo` explicitly instead - = note: relative `use` paths enabled by `#![feature(uniform_paths)]` +note: `Foo` could refer to the enum defined here + --> $DIR/block-scoped-shadow.rs:20:5 + | +LL | enum Foo { A, B } + | ^^^^^^^^^^^^^^^^^ +note: `Foo` could also refer to the enum defined here + --> $DIR/block-scoped-shadow.rs:15:1 + | +LL | enum Foo {} + | ^^^^^^^^^^^ + = help: use `self::Foo` to refer to the enum unambiguously -error: `std` import is ambiguous +error[E0659]: `std` is ambiguous (name vs any other name during import resolution) --> $DIR/block-scoped-shadow.rs:28: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)]` +note: `std` could refer to the enum defined here + --> $DIR/block-scoped-shadow.rs:27:5 + | +LL | enum std {} + | ^^^^^^^^^^^ +note: `std` could also refer to the struct defined here + --> $DIR/block-scoped-shadow.rs:17:1 + | +LL | struct std; + | ^^^^^^^^^^^ + = help: use `self::std` to refer to the 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:28:9 | -LL | struct std; - | ----------- can refer to `self::std` -... -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:26:5 | - = help: write `self::std` explicitly instead - = note: relative `use` paths enabled by `#![feature(uniform_paths)]` +LL | fn std() {} + | ^^^^^^^^^^^ +note: `std` could also refer to the unit struct defined here + --> $DIR/block-scoped-shadow.rs:17:1 + | +LL | struct std; + | ^^^^^^^^^^^ + = help: use `self::std` to refer to the 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/fn-local-enum.rs b/src/test/ui/rust-2018/uniform-paths/fn-local-enum.rs new file mode 100644 index 0000000000000..0c2da1884b758 --- /dev/null +++ b/src/test/ui/rust-2018/uniform-paths/fn-local-enum.rs @@ -0,0 +1,13 @@ +// compile-pass +// edition:2018 + +fn main() { + enum E { A, B, C } + + use E::*; + match A { + A => {} + B => {} + C => {} + } +} From f62f8a568ddf1e6355a1c875e3423f32a92934e0 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 11 Nov 2018 17:35:23 +0300 Subject: [PATCH 09/18] resolve: Recover "did you mean" suggestions in imports --- src/librustc_resolve/error_reporting.rs | 70 ++++++++----------- src/test/ui/resolve_self_super_hint.rs | 4 +- src/test/ui/resolve_self_super_hint.stderr | 4 +- .../rust-2018/local-path-suggestions-2018.rs | 2 +- .../local-path-suggestions-2018.stderr | 8 +-- 5 files changed, 36 insertions(+), 52 deletions(-) diff --git a/src/librustc_resolve/error_reporting.rs b/src/librustc_resolve/error_reporting.rs index 58cab2430319e..6c0989e1179d2 100644 --- a/src/librustc_resolve/error_reporting.rs +++ b/src/librustc_resolve/error_reporting.rs @@ -11,46 +11,40 @@ use {CrateLint, PathResult}; 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, + mut path: Vec, parent_scope: &ParentScope<'b>, ) -> Option<(Vec, Option)> { 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) && !is_special(*snd) => { - 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.name == keywords::CrateRoot.name() && + !snd.is_path_segment_keyword() => {} + // `ident::...` on 2018 + (Some(fst), _) if self.session.rust_2018() && !fst.is_path_segment_keyword() => { + // Insert a placeholder that's later replaced by `self`/`super`/etc. + path.insert(0, 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. @@ -148,22 +142,20 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { mut path: Vec, parent_scope: &ParentScope<'b>, ) -> Option<(Vec, Option)> { - // 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 = 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::>(); + 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].name = *name; + for name in extern_crate_names.into_iter() { + // Replace first ident with a crate name and check if that is valid. + path[0].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); @@ -172,8 +164,6 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { } } - // Remove our placeholder segment. - path.remove(1); None } } diff --git a/src/test/ui/resolve_self_super_hint.rs b/src/test/ui/resolve_self_super_hint.rs index a30e73cf02d12..a24f92fdc6d65 100644 --- a/src/test/ui/resolve_self_super_hint.rs +++ b/src/test/ui/resolve_self_super_hint.rs @@ -23,11 +23,11 @@ mod a { 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 b58a23724e413..924788bdaabfe 100644 --- a/src/test/ui/resolve_self_super_hint.stderr +++ b/src/test/ui/resolve_self_super_hint.stderr @@ -14,13 +14,13 @@ 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/rust-2018/local-path-suggestions-2018.rs b/src/test/ui/rust-2018/local-path-suggestions-2018.rs index 147dae401f6ac..2a673bdbad206 100644 --- a/src/test/ui/rust-2018/local-path-suggestions-2018.rs +++ b/src/test/ui/rust-2018/local-path-suggestions-2018.rs @@ -16,7 +16,7 @@ mod foo { pub type Bar = u32; } -mod baz { +mod bazz { use foo::Bar; fn baz() { 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 2293f4b001749..b8a786bcbb485 100644 --- a/src/test/ui/rust-2018/local-path-suggestions-2018.stderr +++ b/src/test/ui/rust-2018/local-path-suggestions-2018.stderr @@ -6,18 +6,12 @@ LL | use foo::Bar; | = note: `use` statements changed in Rust 2018; read more at -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 | LL | use foobar::Baz; | ^^^^^^ 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`. From 9355653fc44d924f3de7cc84883b73387f54a5d6 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 11 Nov 2018 19:46:04 +0300 Subject: [PATCH 10/18] resolve: Tweak some articles in ambiguity diagnostics --- src/librustc_resolve/lib.rs | 10 +++++----- .../helper-attr-blocked-by-import-ambig.stderr | 2 +- .../proc-macro/ambiguous-builtin-attrs.stderr | 10 +++++----- .../proc-macro/derive-helper-shadowing.stderr | 2 +- src/test/ui/empty/empty-struct-tuple-pat.stderr | 4 ++-- src/test/ui/enum/enum-in-scope.stderr | 2 +- src/test/ui/error-codes/E0530.stderr | 2 +- src/test/ui/imports/glob-shadowing.stderr | 4 ++-- src/test/ui/imports/issue-53269.stderr | 2 +- .../local-modularized-tricky-fail-1.stderr | 6 +++--- src/test/ui/imports/macro-paths.stderr | 2 +- src/test/ui/imports/macros.stderr | 2 +- src/test/ui/imports/shadow_builtin_macros.stderr | 6 +++--- src/test/ui/issues/issue-16149.stderr | 2 +- src/test/ui/issues/issue-17718-patterns.stderr | 4 ++-- src/test/ui/issues/issue-23716.stderr | 4 ++-- src/test/ui/issues/issue-27033.stderr | 2 +- src/test/ui/issues/issue-34047.stderr | 2 +- .../macros/macro-path-prelude-shadowing.stderr | 2 +- .../pattern/pat-shadow-in-nested-binding.stderr | 2 +- .../pattern-binding-disambiguation.stderr | 16 ++++++++-------- .../ambiguity-macros-nested.stderr | 4 ++-- .../ambiguity-macros.stderr | 4 ++-- .../ambiguity-nested.stderr | 4 ++-- .../ambiguity.stderr | 4 ++-- .../block-scoped-shadow.stderr | 4 ++-- .../uniform-paths/ambiguity-macros-nested.stderr | 4 ++-- .../uniform-paths/ambiguity-macros.stderr | 4 ++-- .../uniform-paths/ambiguity-nested.stderr | 4 ++-- .../ui/rust-2018/uniform-paths/ambiguity.stderr | 4 ++-- .../block-scoped-shadow-nested.stderr | 2 +- .../uniform-paths/block-scoped-shadow.stderr | 6 +++--- src/test/ui/static/static-mut-not-pat.stderr | 4 ++-- 33 files changed, 68 insertions(+), 68 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index f875ba511ec36..7e0e2e27984a9 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -406,13 +406,13 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver, err } ResolutionError::BindingShadowsSomethingUnacceptable(what_binding, name, binding) => { - let (shadows_what, article) = (binding.descr(), binding.article()); + 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 {} {}", - article, shadows_what)); + binding.article(), shadows_what)); let participle = if binding.is_import() { "imported" } else { "defined" }; - let msg = format!("{} {} `{}` is {} here", article, shadows_what, name, participle); + let msg = format!("the {} `{}` is {} here", shadows_what, name, participle); err.span_label(binding.span, msg); err } @@ -4722,11 +4722,11 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { `{ident}` to disambiguate", ident = ident)) } if b.is_extern_crate() && self.session.rust_2018() { - help_msgs.push(format!("use `::{ident}` to refer to the {thing} unambiguously", + 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 the {thing} unambiguously", + help_msgs.push(format!("use `self::{ident}` to refer to this {thing} unambiguously", ident = ident, thing = b.descr())) } 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 fc55dc1eef67a..ee98873064fc4 100644 --- a/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.stderr +++ b/src/test/ui-fulldeps/custom-derive/helper-attr-blocked-by-import-ambig.stderr @@ -14,7 +14,7 @@ note: `helper` could also refer to the attribute macro imported here | LL | use plugin::helper; | ^^^^^^^^^^^^^^ - = help: use `self::helper` to refer to the attribute macro unambiguously + = 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 00f5cfc2613a0..34b21ea26830c 100644 --- a/src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs.stderr +++ b/src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs.stderr @@ -16,7 +16,7 @@ note: `repr` could also refer to the attribute macro imported here | LL | use builtin_attrs::*; | ^^^^^^^^^^^^^^^^ - = help: use `self::repr` to refer to the attribute macro unambiguously + = help: use `self::repr` to refer to this attribute macro unambiguously error[E0659]: `repr` is ambiguous (built-in attribute vs any other name) --> $DIR/ambiguous-builtin-attrs.rs:11:19 @@ -30,7 +30,7 @@ note: `repr` could also refer to the attribute macro imported here | LL | use builtin_attrs::*; | ^^^^^^^^^^^^^^^^ - = help: use `self::repr` to refer to the attribute macro unambiguously + = help: use `self::repr` to refer to this attribute macro unambiguously error[E0659]: `repr` is ambiguous (built-in attribute vs any other name) --> $DIR/ambiguous-builtin-attrs.rs:20:34 @@ -44,7 +44,7 @@ note: `repr` could also refer to the attribute macro imported here | LL | use builtin_attrs::*; | ^^^^^^^^^^^^^^^^ - = help: use `self::repr` to refer to the attribute macro unambiguously + = help: use `self::repr` to refer to this attribute macro unambiguously error[E0659]: `repr` is ambiguous (built-in attribute vs any other name) --> $DIR/ambiguous-builtin-attrs.rs:22:11 @@ -58,7 +58,7 @@ note: `repr` could also refer to the attribute macro imported here | LL | use builtin_attrs::*; | ^^^^^^^^^^^^^^^^ - = help: use `self::repr` to refer to the attribute macro unambiguously + = help: use `self::repr` to refer to this attribute macro unambiguously error[E0659]: `feature` is ambiguous (built-in attribute vs any other name) --> $DIR/ambiguous-builtin-attrs.rs:3:4 @@ -72,7 +72,7 @@ note: `feature` could also refer to the attribute macro imported here | LL | use builtin_attrs::*; | ^^^^^^^^^^^^^^^^ - = help: use `self::feature` to refer to the attribute macro unambiguously + = 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 4950b016d3766..f04782fac4d2d 100644 --- a/src/test/ui-fulldeps/proc-macro/derive-helper-shadowing.stderr +++ b/src/test/ui-fulldeps/proc-macro/derive-helper-shadowing.stderr @@ -14,7 +14,7 @@ note: `my_attr` could also refer to the attribute macro imported here | LL | use derive_helper_shadowing::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: use `self::my_attr` to refer to the attribute macro unambiguously + = help: use `self::my_attr` to refer to this attribute macro unambiguously error: aborting due to previous error diff --git a/src/test/ui/empty/empty-struct-tuple-pat.stderr b/src/test/ui/empty/empty-struct-tuple-pat.stderr index 3d219b1752f67..3708aa3608969 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 1e8d594049542..b294aabb4edb9 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/E0530.stderr b/src/test/ui/error-codes/E0530.stderr index e157ca9042cd9..96bc47a1afecf 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/imports/glob-shadowing.stderr b/src/test/ui/imports/glob-shadowing.stderr index 93d3fa969efc3..6a4774facd77c 100644 --- a/src/test/ui/imports/glob-shadowing.stderr +++ b/src/test/ui/imports/glob-shadowing.stderr @@ -11,7 +11,7 @@ note: `env` could also refer to the macro imported here LL | use m::*; | ^^^^ = help: consider adding an explicit import of `env` to disambiguate - = help: or use `self::env` to refer to the macro unambiguously + = help: or use `self::env` to refer to this macro unambiguously error[E0659]: `env` is ambiguous (glob import vs any other name from outer scope during import/macro resolution) --> $DIR/glob-shadowing.rs:29:21 @@ -44,7 +44,7 @@ note: `fenv` could also refer to the macro defined here | LL | pub macro fenv($e: expr) { $e } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: use `self::fenv` to refer to the macro unambiguously + = 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 9fa438e91cd22..781595212f8c4 100644 --- a/src/test/ui/imports/issue-53269.stderr +++ b/src/test/ui/imports/issue-53269.stderr @@ -20,7 +20,7 @@ note: `mac` could also refer to the unresolved item imported here | LL | use nonexistent_module::mac; //~ ERROR unresolved import `nonexistent_module` | ^^^^^^^^^^^^^^^^^^^^^^^ - = help: use `self::mac` to refer to the unresolved item unambiguously + = 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/local-modularized-tricky-fail-1.stderr b/src/test/ui/imports/local-modularized-tricky-fail-1.stderr index 91e569d176461..962294e48caef 100644 --- a/src/test/ui/imports/local-modularized-tricky-fail-1.stderr +++ b/src/test/ui/imports/local-modularized-tricky-fail-1.stderr @@ -38,7 +38,7 @@ LL | | } ... LL | define_include!(); | ------------------ in this macro invocation - = help: use `self::include` to refer to the macro unambiguously + = help: use `self::include` to refer to this macro unambiguously error[E0659]: `panic` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) --> $DIR/local-modularized-tricky-fail-1.rs:45:5 @@ -57,7 +57,7 @@ LL | | } ... LL | define_panic!(); | ---------------- in this macro invocation - = help: use `self::panic` to refer to the macro unambiguously + = help: use `self::panic` to refer to this macro unambiguously error[E0659]: `panic` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) --> <::std::macros::panic macros>:1:13 @@ -76,7 +76,7 @@ LL | | } ... LL | define_panic!(); | ---------------- in this macro invocation - = help: use `self::panic` to refer to the macro unambiguously + = 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 96880492e285f..8e8742f849bf0 100644 --- a/src/test/ui/imports/macro-paths.stderr +++ b/src/test/ui/imports/macro-paths.stderr @@ -34,7 +34,7 @@ LL | / pub mod baz { LL | | pub use two_macros::m; LL | | } | |_^ - = help: use `self::baz` to refer to the module unambiguously + = 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 ade49e6be2483..77a0311fa6055 100644 --- a/src/test/ui/imports/macros.stderr +++ b/src/test/ui/imports/macros.stderr @@ -32,7 +32,7 @@ note: `m` could also refer to the macro imported here | LL | use two_macros::m; | ^^^^^^^^^^^^^ - = help: use `self::m` to refer to the macro unambiguously + = help: use `self::m` to refer to this macro unambiguously error: aborting due to 2 previous errors diff --git a/src/test/ui/imports/shadow_builtin_macros.stderr b/src/test/ui/imports/shadow_builtin_macros.stderr index 4d6c1aa3ea5e7..b53b7e2700db8 100644 --- a/src/test/ui/imports/shadow_builtin_macros.stderr +++ b/src/test/ui/imports/shadow_builtin_macros.stderr @@ -11,7 +11,7 @@ note: `panic` could also refer to the macro imported here LL | use foo::*; | ^^^^^^ = help: consider adding an explicit import of `panic` to disambiguate - = help: or use `self::panic` to refer to the macro unambiguously + = help: or use `self::panic` to refer to this macro unambiguously error[E0659]: `panic` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) --> $DIR/shadow_builtin_macros.rs:30:14 @@ -25,7 +25,7 @@ note: `panic` could also refer to the macro imported here | LL | ::two_macros::m!(use foo::panic;); | ^^^^^^^^^^ - = help: use `self::panic` to refer to the macro unambiguously + = help: use `self::panic` to refer to this macro unambiguously error[E0659]: `panic` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) --> $DIR/shadow_builtin_macros.rs:43:5 @@ -55,7 +55,7 @@ note: `n` could refer to the macro imported here LL | use bar::*; | ^^^^^^ = help: consider adding an explicit import of `n` to disambiguate - = help: or use `self::n` to refer to the macro unambiguously + = 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 | diff --git a/src/test/ui/issues/issue-16149.stderr b/src/test/ui/issues/issue-16149.stderr index b0b6e9dfcd03d..284ed03552639 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-17718-patterns.stderr b/src/test/ui/issues/issue-17718-patterns.stderr index 13cab9a08b1de..c49613eb33c51 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 fd268c1b5a190..c175f197034b4 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 ba573c3eb6db8..dfd635d36e8c6 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-34047.stderr b/src/test/ui/issues/issue-34047.stderr index 10804cc6fff4b..10e4e9c1c1223 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/macros/macro-path-prelude-shadowing.stderr b/src/test/ui/macros/macro-path-prelude-shadowing.stderr index 3e0ea82364265..904eed9f2499f 100644 --- a/src/test/ui/macros/macro-path-prelude-shadowing.stderr +++ b/src/test/ui/macros/macro-path-prelude-shadowing.stderr @@ -11,7 +11,7 @@ note: `std` could also refer to the module imported here LL | use m2::*; // glob-import user-defined `std` | ^^^^^ = help: consider adding an explicit import of `std` to disambiguate - = help: or use `self::std` to refer to the module unambiguously + = help: or use `self::std` to refer to this module unambiguously 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 9dd6a318e98df..994c78d575e27 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 7acdb07e10da6..5d14610b8a1ab 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/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 b8cbabeea2c8e..204e0a7e1411e 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 @@ -5,7 +5,7 @@ LL | pub use std::io; | ^^^ ambiguous name | = note: `std` could refer to a built-in extern crate - = help: use `::std` to refer to the extern crate unambiguously + = 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 | @@ -16,7 +16,7 @@ LL | | } ... LL | m!(); | ----- in this macro invocation - = help: use `self::std` to refer to the module unambiguously + = help: use `self::std` to refer to this module unambiguously error: aborting due to previous error 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 5c9ab11085454..ac8d3b9d0cbe4 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 @@ -5,7 +5,7 @@ LL | use std::io; | ^^^ ambiguous name | = note: `std` could refer to a built-in extern crate - = help: use `::std` to refer to the extern crate unambiguously + = 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 | @@ -16,7 +16,7 @@ LL | | } ... LL | m!(); | ----- in this macro invocation - = help: use `self::std` to refer to the module unambiguously + = help: use `self::std` to refer to this module unambiguously error: aborting due to previous error 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 e98b9ad9a2ae6..7bcfc563d39fc 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 @@ -5,7 +5,7 @@ LL | pub use std::io; | ^^^ ambiguous name | = note: `std` could refer to a built-in extern crate - = help: use `::std` to refer to the extern crate unambiguously + = 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 | @@ -13,7 +13,7 @@ LL | / mod std { LL | | pub struct io; LL | | } | |_____^ - = help: use `self::std` to refer to the module unambiguously + = help: use `self::std` to refer to this module unambiguously error: aborting due to previous error 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 75387454015b9..beeb74654e5b5 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 @@ -5,7 +5,7 @@ LL | use std::io; | ^^^ ambiguous name | = note: `std` could refer to a built-in extern crate - = help: use `::std` to refer to the extern crate unambiguously + = 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 | @@ -13,7 +13,7 @@ LL | / mod std { LL | | pub struct io; LL | | } | |_^ - = help: use `self::std` to refer to the module unambiguously + = help: use `self::std` to refer to this module unambiguously error: aborting due to previous error 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 d0e3d002b0885..5d539e2d59f15 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 @@ -14,7 +14,7 @@ note: `std` could also refer to the struct defined here | LL | struct std; | ^^^^^^^^^^^ - = help: use `self::std` to refer to the struct unambiguously + = help: use `self::std` to refer to this struct unambiguously error[E0659]: `std` is ambiguous (name vs any other name during import resolution) --> $DIR/block-scoped-shadow.rs:18:9 @@ -32,7 +32,7 @@ note: `std` could also refer to the unit struct defined here | LL | struct std; | ^^^^^^^^^^^ - = help: use `self::std` to refer to the unit struct unambiguously + = help: use `self::std` to refer to this unit struct unambiguously error: aborting due to 2 previous errors 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 f18de7edcdcbc..8b893cf26fbf1 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 @@ -5,7 +5,7 @@ LL | pub use std::io; | ^^^ ambiguous name | = note: `std` could refer to a built-in extern crate - = help: use `::std` to refer to the extern crate unambiguously + = 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:23:13 | @@ -16,7 +16,7 @@ LL | | } ... LL | m!(); | ----- in this macro invocation - = help: use `self::std` to refer to the module unambiguously + = help: use `self::std` to refer to this module unambiguously error: aborting due to previous error 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 16e083b098083..4b81a9860dbdd 100644 --- a/src/test/ui/rust-2018/uniform-paths/ambiguity-macros.stderr +++ b/src/test/ui/rust-2018/uniform-paths/ambiguity-macros.stderr @@ -5,7 +5,7 @@ LL | use std::io; | ^^^ ambiguous name | = note: `std` could refer to a built-in extern crate - = help: use `::std` to refer to the extern crate unambiguously + = help: use `::std` to refer to this extern crate unambiguously note: `std` could also refer to the module defined here --> $DIR/ambiguity-macros.rs:22:9 | @@ -16,7 +16,7 @@ LL | | } ... LL | m!(); | ----- in this macro invocation - = help: use `self::std` to refer to the module unambiguously + = help: use `self::std` to refer to this module unambiguously error: aborting due to previous error 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 cb38102c5997e..6415f46b38a3c 100644 --- a/src/test/ui/rust-2018/uniform-paths/ambiguity-nested.stderr +++ b/src/test/ui/rust-2018/uniform-paths/ambiguity-nested.stderr @@ -5,7 +5,7 @@ LL | pub use std::io; | ^^^ ambiguous name | = note: `std` could refer to a built-in extern crate - = help: use `::std` to refer to the extern crate unambiguously + = help: use `::std` to refer to this extern crate unambiguously note: `std` could also refer to the module defined here --> $DIR/ambiguity-nested.rs:21:5 | @@ -13,7 +13,7 @@ LL | / mod std { LL | | pub struct io; LL | | } | |_____^ - = help: use `self::std` to refer to the module unambiguously + = help: use `self::std` to refer to this module unambiguously error: aborting due to previous error diff --git a/src/test/ui/rust-2018/uniform-paths/ambiguity.stderr b/src/test/ui/rust-2018/uniform-paths/ambiguity.stderr index ce0c64b226b59..93044ff2222c9 100644 --- a/src/test/ui/rust-2018/uniform-paths/ambiguity.stderr +++ b/src/test/ui/rust-2018/uniform-paths/ambiguity.stderr @@ -5,7 +5,7 @@ LL | use std::io; | ^^^ ambiguous name | = note: `std` could refer to a built-in extern crate - = help: use `::std` to refer to the extern crate unambiguously + = help: use `::std` to refer to this extern crate unambiguously note: `std` could also refer to the module defined here --> $DIR/ambiguity.rs:18:1 | @@ -13,7 +13,7 @@ LL | / mod std { LL | | pub struct io; LL | | } | |_^ - = help: use `self::std` to refer to the module unambiguously + = help: use `self::std` to refer to this module unambiguously error: aborting due to previous error diff --git a/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.stderr b/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.stderr index 32f5cb30177b7..e0064fe8fe224 100644 --- a/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.stderr +++ b/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.stderr @@ -16,7 +16,7 @@ LL | / mod sub { LL | | pub fn bar() {} LL | | } | |_^ - = help: use `self::sub` to refer to the module unambiguously + = help: use `self::sub` to refer to this module unambiguously error: aborting due to previous error diff --git a/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow.stderr b/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow.stderr index a1db1c3e0be6c..3b40c3d36fa6a 100644 --- a/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow.stderr +++ b/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow.stderr @@ -14,7 +14,7 @@ note: `Foo` could also refer to the enum defined here | LL | enum Foo {} | ^^^^^^^^^^^ - = help: use `self::Foo` to refer to the enum unambiguously + = help: use `self::Foo` to refer to this enum unambiguously error[E0659]: `std` is ambiguous (name vs any other name during import resolution) --> $DIR/block-scoped-shadow.rs:28:9 @@ -32,7 +32,7 @@ note: `std` could also refer to the struct defined here | LL | struct std; | ^^^^^^^^^^^ - = help: use `self::std` to refer to the struct unambiguously + = 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:28:9 @@ -50,7 +50,7 @@ note: `std` could also refer to the unit struct defined here | LL | struct std; | ^^^^^^^^^^^ - = help: use `self::std` to refer to the unit struct unambiguously + = help: use `self::std` to refer to this unit struct unambiguously error: aborting due to 3 previous errors diff --git a/src/test/ui/static/static-mut-not-pat.stderr b/src/test/ui/static/static-mut-not-pat.stderr index 123cf7b3ac6bd..96dc06ee5241a 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 From e4a8bb75c8c1d7bb641d97bc9060ae8215f46738 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 11 Nov 2018 20:28:56 +0300 Subject: [PATCH 11/18] Fix ICEs from imports of items not defined in modules --- src/librustc/hir/def.rs | 14 +++-- src/librustc/middle/dead.rs | 2 +- src/librustc/middle/stability.rs | 6 +- src/librustc_privacy/lib.rs | 8 ++- src/librustc_resolve/macros.rs | 2 +- src/librustc_resolve/resolve_imports.rs | 19 ++++-- .../not-whitelisted.rs | 4 +- .../not-whitelisted.stderr | 20 +++---- .../ui/rust-2018/uniform-paths/macro-rules.rs | 44 ++++++++++++++ .../uniform-paths/macro-rules.stderr | 58 +++++++++++++++++++ .../rust-2018/uniform-paths/prelude-fail.rs | 11 ++++ .../uniform-paths/prelude-fail.stderr | 15 +++++ .../ui/rust-2018/uniform-paths/prelude.rs | 26 +++++++++ 13 files changed, 197 insertions(+), 32 deletions(-) create mode 100644 src/test/ui/rust-2018/uniform-paths/macro-rules.rs create mode 100644 src/test/ui/rust-2018/uniform-paths/macro-rules.stderr create mode 100644 src/test/ui/rust-2018/uniform-paths/prelude-fail.rs create mode 100644 src/test/ui/rust-2018/uniform-paths/prelude-fail.stderr create mode 100644 src/test/ui/rust-2018/uniform-paths/prelude.rs diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs index fa6b80ab9714d..fc51d1de8251a 100644 --- a/src/librustc/hir/def.rs +++ b/src/librustc/hir/def.rs @@ -261,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 { match *self { Def::Fn(id) | Def::Mod(id) | Def::Static(id, _) | Def::Variant(id) | Def::VariantCtor(id, ..) | Def::Enum(id) | @@ -268,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(..) | @@ -278,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 } } } diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index dc5f736172503..81c48740e1b3e 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 ba79cf66d0848..f19aa67a839ef 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_privacy/lib.rs b/src/librustc_privacy/lib.rs index 4b7bd7866727b..5f8c7daea6e9b 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/macros.rs b/src/librustc_resolve/macros.rs index e0fce11de7f7e..6d1b5f8cd25a4 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -227,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() { diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index b43b207e6062b..97e19ff2259b1 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -1079,8 +1079,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"); @@ -1152,9 +1162,10 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { if binding.is_import() || binding.is_macro_def() { let def = binding.def(); if def != Def::Err { - let def_id = def.def_id(); - if !def_id.is_local() && def_id.krate != CrateNum::BuiltinMacros { - self.cstore.export_macros_untracked(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/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.rs b/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.rs index f95961d2a9b56..92541afc0c1ce 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 @@ -13,7 +13,7 @@ // 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 0865bd6bea52a..e70a359b5752b 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: cannot import a built-in macro + --> $DIR/not-whitelisted.rs:16:5 + | +LL | use test; //~ ERROR cannot import a built-in macro + | ^^^^ + 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 - | -LL | use test; //~ ERROR unresolved import `test` - | ^^^^ no `test` external crate - -error[E0432]: unresolved import `proc_macro` - --> $DIR/not-whitelisted.rs:17:5 - | -LL | use proc_macro; //~ ERROR unresolved import `proc_macro` - | ^^^^^^^^^^ no `proc_macro` 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/rust-2018/uniform-paths/macro-rules.rs b/src/test/ui/rust-2018/uniform-paths/macro-rules.rs new file mode 100644 index 0000000000000..1f722228e7da2 --- /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)] + +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 0000000000000..d7bb233dfe99e --- /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 0000000000000..d717884c901b3 --- /dev/null +++ b/src/test/ui/rust-2018/uniform-paths/prelude-fail.rs @@ -0,0 +1,11 @@ +// edition:2018 + +// 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 0000000000000..0ce856c3a3157 --- /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:4:5 + | +LL | use env as env_imported; //~ ERROR cannot import a built-in macro + | ^^^^^^^^^^^^^^^^^^^ + +error[E0432]: unresolved import `rustfmt` + --> $DIR/prelude-fail.rs:7: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 0000000000000..ea2dfbb58ce61 --- /dev/null +++ b/src/test/ui/rust-2018/uniform-paths/prelude.rs @@ -0,0 +1,26 @@ +// compile-pass +// edition:2018 + +// 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::::new(); +} From a0929dc5468dfa7143c7d8529084c599b5e72f45 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 12 Nov 2018 03:58:39 +0300 Subject: [PATCH 12/18] resolve: Reintroduce feature gate for uniform paths in imports --- .../src/language-features/extern-in-paths.md | 4 +- src/librustc_resolve/lib.rs | 54 ++++++++------- src/librustc_resolve/macros.rs | 28 +++++++- .../feature-gate-uniform-paths.rs | 11 +++- .../feature-gate-uniform-paths.stderr | 65 +++++++++++++++++-- .../not-whitelisted.rs | 2 + .../not-whitelisted.stderr | 4 +- .../rust-2018/local-path-suggestions-2018.rs | 2 + .../local-path-suggestions-2018.stderr | 4 +- .../issue-54253.rs | 2 +- .../uniform-paths/ambiguity-macros-nested.rs | 2 - .../ambiguity-macros-nested.stderr | 4 +- .../uniform-paths/ambiguity-macros.rs | 2 - .../uniform-paths/ambiguity-macros.stderr | 4 +- .../uniform-paths/ambiguity-nested.rs | 2 - .../uniform-paths/ambiguity-nested.stderr | 4 +- .../ui/rust-2018/uniform-paths/ambiguity.rs | 2 - .../rust-2018/uniform-paths/ambiguity.stderr | 4 +- .../block-scoped-shadow-nested.rs | 2 + .../block-scoped-shadow-nested.stderr | 6 +- .../uniform-paths/block-scoped-shadow.rs | 2 - .../uniform-paths/block-scoped-shadow.stderr | 18 ++--- .../rust-2018/uniform-paths/fn-local-enum.rs | 2 + .../ui/rust-2018/uniform-paths/issue-54253.rs | 4 +- .../uniform-paths/issue-54253.stderr | 2 +- .../ui/rust-2018/uniform-paths/macro-rules.rs | 2 +- .../rust-2018/uniform-paths/prelude-fail.rs | 2 + .../uniform-paths/prelude-fail.stderr | 4 +- .../ui/rust-2018/uniform-paths/prelude.rs | 2 + .../ui/rust-2018/uniform-paths/redundant.rs | 2 - 30 files changed, 168 insertions(+), 80 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 3ae6cc29df0b8..9979d7742291e 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_resolve/lib.rs b/src/librustc_resolve/lib.rs index 7e0e2e27984a9..fd518c14f0294 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -4670,6 +4670,34 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } } + 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 { + ("", "") + }; + + 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 { + 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() { @@ -4685,31 +4713,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { err.span_label(ident.span, "ambiguous name"); let mut could_refer_to = |b: &NameBinding, misc: AmbiguityErrorMisc, also: &str| { - let what = 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 misc == AmbiguityErrorMisc::FromPrelude { - ("", " 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 { - ("", "") - }; - - 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 { - let participle = if b.is_import() { "imported" } else { "defined" }; - format!("the {thing} {introduced} here", - thing = b.descr(), introduced = participle) - }; + 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); diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 6d1b5f8cd25a4..3135c5ec1ff4e 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -890,7 +890,33 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } // 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(¬e_msg); + } else { + err.span_note(binding.span, ¬e_msg); + err.span_label(binding.span, "not an extern crate passed with `--extern`"); + } + err.emit(); + } + } + return Ok(binding); } 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 140655d52bd46..ca1cc1d2fd0e4 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 68faacfcbe75e..ec8937bbc5f5c 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/rfc-2126-extern-absolute-paths/not-whitelisted.rs b/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.rs index 92541afc0c1ce..bfe7e4da84562 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,6 +10,8 @@ // 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` 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 e70a359b5752b..06c11b894ddc3 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,11 +1,11 @@ error: cannot import a built-in macro - --> $DIR/not-whitelisted.rs:16:5 + --> $DIR/not-whitelisted.rs:18:5 | LL | use test; //~ ERROR cannot import a built-in macro | ^^^^ error[E0432]: unresolved import `alloc` - --> $DIR/not-whitelisted.rs:15:5 + --> $DIR/not-whitelisted.rs:17:5 | LL | use alloc; //~ ERROR unresolved import `alloc` | ^^^^^ no `alloc` external crate 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 2a673bdbad206..8c9583cfa1bbc 100644 --- a/src/test/ui/rust-2018/local-path-suggestions-2018.rs +++ b/src/test/ui/rust-2018/local-path-suggestions-2018.rs @@ -12,6 +12,8 @@ // compile-flags:--extern baz // edition:2018 +#![feature(uniform_paths)] + mod foo { pub type Bar = u32; } 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 b8a786bcbb485..41d7e186c36e7 100644 --- a/src/test/ui/rust-2018/local-path-suggestions-2018.stderr +++ b/src/test/ui/rust-2018/local-path-suggestions-2018.stderr @@ -1,5 +1,5 @@ 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`? @@ -7,7 +7,7 @@ LL | use foo::Bar; = note: `use` statements changed in Rust 2018; read more at 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`? 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 1f19a05d7a7f6..ef2a1e3c70c6f 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 9f440d71fb003..4819711115c27 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,8 +10,6 @@ // edition:2018 -#![feature(uniform_paths)] - // This test is similar to `ambiguity-macros.rs`, but nested in a module. mod foo { 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 8b893cf26fbf1..204e0a7e1411e 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,5 +1,5 @@ error[E0659]: `std` is ambiguous (name vs any other name during import resolution) - --> $DIR/ambiguity-macros-nested.rs:18:13 + --> $DIR/ambiguity-macros-nested.rs:16:13 | LL | pub use std::io; | ^^^ ambiguous name @@ -7,7 +7,7 @@ LL | pub use std::io; = 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:23:13 + --> $DIR/ambiguity-macros-nested.rs:21:13 | LL | / mod std { LL | | pub struct io; 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 f1ed48150c0b8..148320de556d3 100644 --- a/src/test/ui/rust-2018/uniform-paths/ambiguity-macros.rs +++ b/src/test/ui/rust-2018/uniform-paths/ambiguity-macros.rs @@ -10,8 +10,6 @@ // edition:2018 -#![feature(uniform_paths)] - // This test is similar to `ambiguity.rs`, but with macros defining local items. use std::io; 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 4b81a9860dbdd..ac8d3b9d0cbe4 100644 --- a/src/test/ui/rust-2018/uniform-paths/ambiguity-macros.stderr +++ b/src/test/ui/rust-2018/uniform-paths/ambiguity-macros.stderr @@ -1,5 +1,5 @@ error[E0659]: `std` is ambiguous (name vs any other name during import resolution) - --> $DIR/ambiguity-macros.rs:17:5 + --> $DIR/ambiguity-macros.rs:15:5 | LL | use std::io; | ^^^ ambiguous name @@ -7,7 +7,7 @@ LL | use std::io; = 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:22:9 + --> $DIR/ambiguity-macros.rs:20:9 | LL | / mod std { LL | | pub struct io; 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 0d0d34df1f833..2791d4580daf1 100644 --- a/src/test/ui/rust-2018/uniform-paths/ambiguity-nested.rs +++ b/src/test/ui/rust-2018/uniform-paths/ambiguity-nested.rs @@ -10,8 +10,6 @@ // edition:2018 -#![feature(uniform_paths)] - // This test is similar to `ambiguity.rs`, but nested in a module. mod foo { 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 6415f46b38a3c..7bcfc563d39fc 100644 --- a/src/test/ui/rust-2018/uniform-paths/ambiguity-nested.stderr +++ b/src/test/ui/rust-2018/uniform-paths/ambiguity-nested.stderr @@ -1,5 +1,5 @@ error[E0659]: `std` is ambiguous (name vs any other name during import resolution) - --> $DIR/ambiguity-nested.rs:18:13 + --> $DIR/ambiguity-nested.rs:16:13 | LL | pub use std::io; | ^^^ ambiguous name @@ -7,7 +7,7 @@ LL | pub use std::io; = 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:21:5 + --> $DIR/ambiguity-nested.rs:19:5 | LL | / mod std { LL | | pub struct io; diff --git a/src/test/ui/rust-2018/uniform-paths/ambiguity.rs b/src/test/ui/rust-2018/uniform-paths/ambiguity.rs index 259f451e4d22d..2bfbb6b287153 100644 --- a/src/test/ui/rust-2018/uniform-paths/ambiguity.rs +++ b/src/test/ui/rust-2018/uniform-paths/ambiguity.rs @@ -10,8 +10,6 @@ // edition:2018 -#![feature(uniform_paths)] - use std::io; //~^ ERROR `std` is ambiguous diff --git a/src/test/ui/rust-2018/uniform-paths/ambiguity.stderr b/src/test/ui/rust-2018/uniform-paths/ambiguity.stderr index 93044ff2222c9..beeb74654e5b5 100644 --- a/src/test/ui/rust-2018/uniform-paths/ambiguity.stderr +++ b/src/test/ui/rust-2018/uniform-paths/ambiguity.stderr @@ -1,5 +1,5 @@ error[E0659]: `std` is ambiguous (name vs any other name during import resolution) - --> $DIR/ambiguity.rs:15:5 + --> $DIR/ambiguity.rs:13:5 | LL | use std::io; | ^^^ ambiguous name @@ -7,7 +7,7 @@ LL | use std::io; = 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:18:1 + --> $DIR/ambiguity.rs:16:1 | LL | / mod std { LL | | pub struct io; 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 index 3f5897901a056..19be7dc964040 100644 --- 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 @@ -1,5 +1,7 @@ // edition:2018 +#![feature(uniform_paths)] + mod my { pub mod sub { pub fn bar() {} diff --git a/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.stderr b/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.stderr index e0064fe8fe224..aa46947f93f4b 100644 --- a/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.stderr +++ b/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.stderr @@ -1,16 +1,16 @@ error[E0659]: `sub` is ambiguous (name vs any other name during import resolution) - --> $DIR/block-scoped-shadow-nested.rs:16:13 + --> $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:14:9 + --> $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:9:1 + --> $DIR/block-scoped-shadow-nested.rs:11:1 | LL | / mod sub { LL | | pub fn bar() {} 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 36d996fc4f930..ec0479ce8f15e 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,8 +10,6 @@ // edition:2018 -#![feature(uniform_paths)] - enum Foo {} struct std; 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 3b40c3d36fa6a..010b9efad393b 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,52 +1,52 @@ error[E0659]: `Foo` is ambiguous (name vs any other name during import resolution) - --> $DIR/block-scoped-shadow.rs:21:9 + --> $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:20:5 + --> $DIR/block-scoped-shadow.rs:18:5 | LL | enum Foo { A, B } | ^^^^^^^^^^^^^^^^^ note: `Foo` could also refer to the enum defined here - --> $DIR/block-scoped-shadow.rs:15:1 + --> $DIR/block-scoped-shadow.rs:13:1 | LL | enum Foo {} | ^^^^^^^^^^^ = help: use `self::Foo` to refer to this enum unambiguously error[E0659]: `std` is ambiguous (name vs any other name during import resolution) - --> $DIR/block-scoped-shadow.rs:28:9 + --> $DIR/block-scoped-shadow.rs:26:9 | LL | use std as foo; | ^^^ ambiguous name | note: `std` could refer to the enum defined here - --> $DIR/block-scoped-shadow.rs:27:5 + --> $DIR/block-scoped-shadow.rs:25:5 | LL | enum std {} | ^^^^^^^^^^^ note: `std` could also refer to the struct defined here - --> $DIR/block-scoped-shadow.rs:17:1 + --> $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:28:9 + --> $DIR/block-scoped-shadow.rs:26:9 | LL | use std as foo; | ^^^ ambiguous name | note: `std` could refer to the function defined here - --> $DIR/block-scoped-shadow.rs:26:5 + --> $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:17:1 + --> $DIR/block-scoped-shadow.rs:15:1 | LL | struct std; | ^^^^^^^^^^^ 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 index 0c2da1884b758..a7bc625bbf0a4 100644 --- a/src/test/ui/rust-2018/uniform-paths/fn-local-enum.rs +++ b/src/test/ui/rust-2018/uniform-paths/fn-local-enum.rs @@ -1,6 +1,8 @@ // compile-pass // edition:2018 +#![feature(uniform_paths)] + fn main() { enum E { A, B, C } 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 7ca5c9e9eaefd..ef2a1e3c70c6f 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 0016e21ef4d55..6dcc451c60a61 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/macro-rules.rs b/src/test/ui/rust-2018/uniform-paths/macro-rules.rs index 1f722228e7da2..e8098a467904e 100644 --- a/src/test/ui/rust-2018/uniform-paths/macro-rules.rs +++ b/src/test/ui/rust-2018/uniform-paths/macro-rules.rs @@ -2,7 +2,7 @@ // For the time being `macro_rules` items are treated as *very* private... -#![feature(underscore_imports, decl_macro)] +#![feature(underscore_imports, decl_macro, uniform_paths)] mod m1 { macro_rules! legacy_macro { () => () } diff --git a/src/test/ui/rust-2018/uniform-paths/prelude-fail.rs b/src/test/ui/rust-2018/uniform-paths/prelude-fail.rs index d717884c901b3..c5bd50f2f567f 100644 --- a/src/test/ui/rust-2018/uniform-paths/prelude-fail.rs +++ b/src/test/ui/rust-2018/uniform-paths/prelude-fail.rs @@ -1,5 +1,7 @@ // edition:2018 +#![feature(uniform_paths)] + // Built-in macro use env as env_imported; //~ ERROR cannot import a built-in macro diff --git a/src/test/ui/rust-2018/uniform-paths/prelude-fail.stderr b/src/test/ui/rust-2018/uniform-paths/prelude-fail.stderr index 0ce856c3a3157..a02775eabf42a 100644 --- a/src/test/ui/rust-2018/uniform-paths/prelude-fail.stderr +++ b/src/test/ui/rust-2018/uniform-paths/prelude-fail.stderr @@ -1,11 +1,11 @@ error: cannot import a built-in macro - --> $DIR/prelude-fail.rs:4:5 + --> $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:7:5 + --> $DIR/prelude-fail.rs:9:5 | LL | use rustfmt::skip as imported_rustfmt_skip; //~ ERROR unresolved import `rustfmt` | ^^^^^^^ Not a module `rustfmt` diff --git a/src/test/ui/rust-2018/uniform-paths/prelude.rs b/src/test/ui/rust-2018/uniform-paths/prelude.rs index ea2dfbb58ce61..5aab5fc3a4018 100644 --- a/src/test/ui/rust-2018/uniform-paths/prelude.rs +++ b/src/test/ui/rust-2018/uniform-paths/prelude.rs @@ -1,6 +1,8 @@ // compile-pass // edition:2018 +#![feature(uniform_paths)] + // Macro imported with `#[macro_use] extern crate` use vec as imported_vec; diff --git a/src/test/ui/rust-2018/uniform-paths/redundant.rs b/src/test/ui/rust-2018/uniform-paths/redundant.rs index 745ac18e059b9..05048cfd45105 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; From 342138757131334c09905f29a6d265e739e41fda Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 14 Nov 2018 02:17:40 +0300 Subject: [PATCH 13/18] resolve: Avoid marking `extern crate` items as used in certain cases --- src/librustc_resolve/lib.rs | 20 ++++++++++++++++---- src/librustc_resolve/macros.rs | 2 +- src/librustc_resolve/resolve_imports.rs | 5 +++-- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index fd518c14f0294..ed2c5cc8712e9 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1911,14 +1911,26 @@ 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>) { - match binding.kind { + 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::Ambiguity { kind, b1, b2 } => { self.ambiguity_errors.push(AmbiguityError { @@ -2908,7 +2920,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(..) | diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 3135c5ec1ff4e..5e8eb47a8dc29 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -993,7 +993,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { &parent_scope, true, true, ident.span) { Ok(binding) => { let initial_def = initial_binding.map(|initial_binding| { - self.record_use(ident, MacroNS, initial_binding); + self.record_use(ident, MacroNS, initial_binding, false); initial_binding.def_ignoring_ambiguity() }); let def = binding.def_ignoring_ambiguity(); diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 97e19ff2259b1..915aa5de92374 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -234,7 +234,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { if self.last_import_segment && check_usable(self, binding).is_err() { Err(DeterminacyExt::Determined) } else { - self.record_use(ident, ns, binding); + self.record_use(ident, ns, binding, restricted_shadowing); if let Some(shadowed_glob) = resolution.shadowed_glob { // Forbid expanded shadowing to avoid time travel. @@ -922,7 +922,8 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { // 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, MacroNS, initial_binding); + this.record_use(ident, ns, initial_binding, + directive.module_path.is_empty()); initial_binding.def_ignoring_ambiguity() }); let def = binding.def_ignoring_ambiguity(); From 738d27fa21d6f71a08264259f1fc9a8973ec5dc6 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 14 Nov 2018 02:20:59 +0300 Subject: [PATCH 14/18] resolve: Support resolving macros without leaving traces --- src/librustc_resolve/macros.rs | 22 ++++++++++++------- .../passes/collect_intra_doc_links.rs | 2 +- .../custom-derive/derive-in-mod.rs | 13 +++++++++++ 3 files changed, 28 insertions(+), 9 deletions(-) create mode 100644 src/test/ui-fulldeps/custom-derive/derive-in-mod.rs diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 5e8eb47a8dc29..30772ec374b00 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -327,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 { @@ -350,7 +350,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> { derives_in_scope: Vec, force: bool) -> Result, 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) { @@ -391,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), 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) { @@ -465,6 +466,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { path: &ast::Path, kind: MacroKind, parent_scope: &ParentScope<'a>, + trace: bool, force: bool, ) -> Result { let path_span = path.span; @@ -491,8 +493,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> { PathResult::Module(..) => unreachable!(), }; - parent_scope.module.multi_segment_macro_resolutions.borrow_mut() - .push((path, path_span, kind, parent_scope.clone(), def.ok())); + if trace { + parent_scope.module.multi_segment_macro_resolutions.borrow_mut() + .push((path, path_span, kind, parent_scope.clone(), def.ok())); + } def } else { @@ -505,8 +509,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> { Err(Determinacy::Undetermined) => return Err(Determinacy::Undetermined), } - parent_scope.module.single_segment_macro_resolutions.borrow_mut() - .push((path[0], kind, parent_scope.clone(), binding.ok())); + if trace { + parent_scope.module.single_segment_macro_resolutions.borrow_mut() + .push((path[0], kind, parent_scope.clone(), binding.ok())); + } binding.map(|binding| binding.def_ignoring_ambiguity()) } @@ -633,7 +639,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { for derive in &parent_scope.derives { let parent_scope = ParentScope { derives: Vec::new(), ..*parent_scope }; match self.resolve_macro_to_def(derive, MacroKind::Derive, - &parent_scope, force) { + &parent_scope, true, force) { Ok((_, ext)) => { if let SyntaxExtension::ProcMacroDerive(_, helpers, _) = &*ext { if helpers.contains(&ident.name) { diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index a780322e85e86..3325faa1a1777 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 { 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/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 0000000000000..8478ff1a6ae6c --- /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() {} From 696fbc0adc14f1e3ee4b3d11dde960f5785b5680 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 14 Nov 2018 02:52:26 +0300 Subject: [PATCH 15/18] resolve: Avoid sentence breaks in diagnostics --- src/librustc_resolve/diagnostics.rs | 2 +- src/librustc_resolve/error_reporting.rs | 8 ++++---- src/librustc_resolve/lib.rs | 14 +++++++------- src/librustc_resolve/resolve_imports.rs | 2 +- .../ui/absolute-paths-in-nested-use-groups.stderr | 6 +++--- src/test/ui/bad/bad-module.rs | 4 ++-- src/test/ui/bad/bad-module.stderr | 8 ++++---- src/test/ui/custom-attribute-multisegment.rs | 2 +- src/test/ui/custom-attribute-multisegment.stderr | 6 +++--- src/test/ui/derived-errors/issue-31997-1.stderr | 4 ++-- .../dollar-crate/dollar-crate-is-keyword-2.stderr | 4 ++-- src/test/ui/dyn-trait-compatibility.rs | 4 ++-- src/test/ui/dyn-trait-compatibility.stderr | 8 ++++---- src/test/ui/error-codes/E0432.stderr | 2 +- src/test/ui/error-codes/E0433.stderr | 4 ++-- src/test/ui/export-fully-qualified.rs | 2 +- src/test/ui/export-fully-qualified.stderr | 6 +++--- src/test/ui/export2.rs | 2 +- src/test/ui/export2.stderr | 6 +++--- src/test/ui/extern/extern-macro.rs | 2 +- src/test/ui/extern/extern-macro.stderr | 4 ++-- .../feature-gate-extern_absolute_paths.stderr | 6 +++--- src/test/ui/hygiene/no_implicit_prelude.stderr | 4 ++-- src/test/ui/import2.rs | 2 +- src/test/ui/import2.stderr | 2 +- src/test/ui/import3.stderr | 2 +- .../ui/imports/extern-prelude-extern-crate-fail.rs | 2 +- .../extern-prelude-extern-crate-fail.stderr | 6 +++--- src/test/ui/imports/issue-53269.stderr | 2 +- src/test/ui/issues/issue-1697.rs | 2 +- src/test/ui/issues/issue-1697.stderr | 2 +- src/test/ui/issues/issue-30560.rs | 4 ++-- src/test/ui/issues/issue-30560.stderr | 4 ++-- src/test/ui/issues/issue-33293.rs | 2 +- src/test/ui/issues/issue-33293.stderr | 4 ++-- src/test/ui/issues/issue-33464.stderr | 6 +++--- src/test/ui/issues/issue-36881.stderr | 2 +- src/test/ui/issues/issue-37887.stderr | 2 +- src/test/ui/issues/issue-38857.rs | 2 +- src/test/ui/issues/issue-38857.stderr | 4 ++-- src/test/ui/keyword/keyword-super-as-identifier.rs | 2 +- .../ui/keyword/keyword-super-as-identifier.stderr | 6 +++--- src/test/ui/keyword/keyword-super.rs | 2 +- src/test/ui/keyword/keyword-super.stderr | 6 +++--- src/test/ui/macros/macro-inner-attributes.rs | 2 +- src/test/ui/macros/macro-inner-attributes.stderr | 4 ++-- src/test/ui/macros/macro-path-prelude-fail-1.rs | 4 ++-- .../ui/macros/macro-path-prelude-fail-1.stderr | 12 ++++++------ src/test/ui/macros/macro-path-prelude-fail-2.rs | 2 +- .../ui/macros/macro-path-prelude-fail-2.stderr | 4 ++-- .../ui/macros/macro_path_as_generic_bound.stderr | 4 ++-- src/test/ui/pattern/pattern-error-continue.rs | 2 +- src/test/ui/pattern/pattern-error-continue.stderr | 6 +++--- src/test/ui/privacy/restricted/test.rs | 2 +- src/test/ui/privacy/restricted/test.stderr | 6 +++--- src/test/ui/resolve/resolve-variant-assoc-item.rs | 4 ++-- .../ui/resolve/resolve-variant-assoc-item.stderr | 12 ++++++------ src/test/ui/resolve_self_super_hint.rs | 8 ++++---- src/test/ui/resolve_self_super_hint.stderr | 8 ++++---- .../crate-path-non-absolute.stderr | 4 ++-- .../non-existent-1.stderr | 2 +- .../non-existent-2.rs | 2 +- .../non-existent-2.stderr | 4 ++-- .../rfc-2126-extern-in-paths/non-existent-1.stderr | 2 +- .../ui/rfc-2126-extern-in-paths/non-existent-2.rs | 2 +- .../rfc-2126-extern-in-paths/non-existent-2.stderr | 4 ++-- src/test/ui/rust-2018/issue-54006.stderr | 2 +- .../rust-2018/local-path-suggestions-2015.stderr | 2 +- .../rust-2018/local-path-suggestions-2018.stderr | 4 ++-- .../ui/rust-2018/uniform-paths/prelude-fail.stderr | 2 +- src/test/ui/span/non-existing-module-import.stderr | 2 +- src/test/ui/super-at-top-level.rs | 2 +- src/test/ui/super-at-top-level.stderr | 6 +++--- .../tool-attributes/tool-attributes-shadowing.rs | 2 +- .../tool-attributes-shadowing.stderr | 6 +++--- src/test/ui/type/type-path-err-node-types.stderr | 4 ++-- src/test/ui/ufcs/ufcs-partially-resolved.rs | 4 ++-- src/test/ui/ufcs/ufcs-partially-resolved.stderr | 12 ++++++------ src/test/ui/unknown-tool-name.rs | 2 +- src/test/ui/unknown-tool-name.stderr | 6 +++--- src/test/ui/unresolved/unresolved-import.rs | 6 +++--- src/test/ui/unresolved/unresolved-import.stderr | 6 +++--- src/test/ui/use/use-from-trait-xc.stderr | 6 +++--- src/test/ui/use/use-from-trait.rs | 4 ++-- src/test/ui/use/use-from-trait.stderr | 4 ++-- src/test/ui/use/use-mod/use-mod-4.stderr | 2 +- src/test/ui/use/use-self-type.rs | 2 +- src/test/ui/use/use-self-type.stderr | 8 ++++---- src/test/ui/use/use-super-global-path.stderr | 4 ++-- 89 files changed, 187 insertions(+), 187 deletions(-) diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index c1dc3041d7d17..2681295cf9bf1 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 6c0989e1179d2..728023908678d 100644 --- a/src/librustc_resolve/error_reporting.rs +++ b/src/librustc_resolve/error_reporting.rs @@ -52,7 +52,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, @@ -76,7 +76,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, @@ -107,7 +107,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, @@ -131,7 +131,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 diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index ed2c5cc8712e9..ac54085ad1f9d 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -386,7 +386,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 } @@ -3663,7 +3663,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 { @@ -3755,7 +3755,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); } } @@ -3780,14 +3780,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]) + format!("could not find `{}` in `{}`", ident, path[i - 1]) }; return PathResult::Failed(ident.span, msg, is_last); } diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 915aa5de92374..3d445db1ff4e3 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -855,7 +855,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { ) { Some(( span, - format!("Did you mean `{}`?", names_to_string(&suggested_path[..])), + format!("did you mean `{}`?", names_to_string(&suggested_path[..])), note, )) } else { 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 e88d26718a01e..2bbd7b0ad3ad7 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 6987d06ef12c3..4f38d4ce45e81 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 8c19922dcabe9..8bdcceaa1918c 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 a8d82a3594649..354f7173872e6 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 ff72d1c36d852..690ba4982ab74 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 7cdcac3891fc9..5c5422f091ba0 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 0a0b1d573dd04..fe9af74c01d9e 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 454b6d2f566eb..4297e1b43d3d1 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; //~^ ERROR cannot find type `dyn` in this scope //~| ERROR cannot find type `dyn` in this scope @@ -19,6 +19,6 @@ type A2 = dyn; type A3 = 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 1ff3249371b9d..93048ccad6fa4 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>; - | ^^^ 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/error-codes/E0432.stderr b/src/test/ui/error-codes/E0432.stderr index 291bb45075593..d288cd086e777 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 f8cf5f6f92f66..8a66e749ba8cf 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/export-fully-qualified.rs b/src/test/ui/export-fully-qualified.rs index 19fa13f8377db..422cd251de420 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 b8409929763b6..477cb4b1dd189 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 dc96ce7f50496..4cc9762d975d9 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 c76afb8a1e2c6..7659183c8e02f 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 fcba5cb4f07a1..88a72778a85c6 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 failed to resolve. partially resolved path in a macro + 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 159fefdd2696b..6123d97016607 100644 --- a/src/test/ui/extern/extern-macro.stderr +++ b/src/test/ui/extern/extern-macro.stderr @@ -1,7 +1,7 @@ -error[E0433]: failed to resolve. partially resolved path in a macro +error[E0433]: failed to resolve: partially resolved path in a macro --> $DIR/extern-macro.rs:15:13 | -LL | let _ = Foo::bar!(); //~ ERROR failed to resolve. partially resolved path in a macro +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 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 7a996abc76755..7c94200f00f4f 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/hygiene/no_implicit_prelude.stderr b/src/test/ui/hygiene/no_implicit_prelude.stderr index 463fdbf00ce54..73a63a2c7f593 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 c4bd9ff1e2abe..d3bbdf15cd005 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 c07506845c4cc..b19739377015d 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 5211b862b3dc5..a4c367fb0736e 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/extern-prelude-extern-crate-fail.rs b/src/test/ui/imports/extern-prelude-extern-crate-fail.rs index 57b097c9df318..6b70efe0c4486 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 8f68d2af34ca3..baeed02517d18 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/issue-53269.stderr b/src/test/ui/imports/issue-53269.stderr index 781595212f8c4..0ed26ea6fe642 100644 --- a/src/test/ui/imports/issue-53269.stderr +++ b/src/test/ui/imports/issue-53269.stderr @@ -2,7 +2,7 @@ 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 (`macro_rules` vs non-`macro_rules` from other module) --> $DIR/issue-53269.rs:18:5 diff --git a/src/test/ui/issues/issue-1697.rs b/src/test/ui/issues/issue-1697.rs index f8a68264339b9..43f92d8c3deed 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 28a7fbcaabee8..b588c88326438 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-30560.rs b/src/test/ui/issues/issue-30560.rs index 0b1afd75ca935..f033666220d91 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 cb38c0dabe0a3..880c565cf9f69 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 bed577b8b9d10..801ba7afcd600 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 e94979b6da4d5..dc288fa71ce8a 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 b70fff01c9ef4..f41a397362550 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-36881.stderr b/src/test/ui/issues/issue-36881.stderr index 39132fde7625c..27effe9e342e0 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 8448466087d66..48fb6c2e6faa7 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 b38b1b9fdc6d1..5217ddb9acb7d 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 f6ed320267179..65026344febef 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 54dac771f01ed..d8941f3e532dd 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 649be45c22459..9b665748794c5 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 02047bd639ff9..8764063081874 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 ac692ad45d2bd..690b684c13372 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/macro-inner-attributes.rs b/src/test/ui/macros/macro-inner-attributes.rs index 1111b21d4550c..2a58fd55453be 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 11922bc448bc4..47d9469779bb0 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 e1181eb741bf9..bdf3ac0f69f40 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 fc74937d91200..590e4f0fd062e 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 d9f99aa0119ce..e27c061e19502 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 failed to resolve. partially resolved path in a macro + 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 31e45b320ad73..cf123f43fea3d 100644 --- a/src/test/ui/macros/macro-path-prelude-fail-2.stderr +++ b/src/test/ui/macros/macro-path-prelude-fail-2.stderr @@ -1,7 +1,7 @@ -error[E0433]: failed to resolve. partially resolved path in a macro +error[E0433]: failed to resolve: partially resolved path in a macro --> $DIR/macro-path-prelude-fail-2.rs:13:9 | -LL | Result::Ok!(); //~ ERROR failed to resolve. partially resolved path in a macro +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 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 0f9f0607c5bf2..8b4fe9f200dce 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/pattern/pattern-error-continue.rs b/src/test/ui/pattern/pattern-error-continue.rs index e63b84594aa94..c544ca4e304f0 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 b24366c48bcbf..f2c35ef872d36 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/restricted/test.rs b/src/test/ui/privacy/restricted/test.rs index 8c1d609e24467..2b2d9b76bddad 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 afc3ee2db4b8f..01e224910a5eb 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 869eed5a8d774..01f493e954b13 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 a80a7c392496b..ef2d0a71b5b85 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 a24f92fdc6d65..2ce2d76583232 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 `a::alloc`? + //~| did you mean `a::alloc`? mod d { use alloc::HashMap; //~^ ERROR unresolved import `alloc` [E0432] - //~| Did you mean `a::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 924788bdaabfe..613107712b214 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 `a::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 `a::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 f16c849607766..2751d8cb285a3 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 ba44f20facfd2..39b2db7a19f70 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` - | ^^^^^^ Use of undeclared type or module `xcrate` + | ^^^^^^ 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 41adb974f2176..a07c3f17d6f7b 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 b46576b014367..30e5b0ad1dfb7 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-in-paths/non-existent-1.stderr b/src/test/ui/rfc-2126-extern-in-paths/non-existent-1.stderr index 55b8b6255073e..47ea4b8dfcb8a 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 128ecf41a303d..8d7c3993c6273 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 7fbe50a92022b..89630adb5a824 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/issue-54006.stderr b/src/test/ui/rust-2018/issue-54006.stderr index 268a16e5d2a0f..5f92574c23ffe 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 d7580507ce425..741b2ca0826ce 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.stderr b/src/test/ui/rust-2018/local-path-suggestions-2018.stderr index 41d7e186c36e7..27ea6642eb01e 100644 --- a/src/test/ui/rust-2018/local-path-suggestions-2018.stderr +++ b/src/test/ui/rust-2018/local-path-suggestions-2018.stderr @@ -2,7 +2,7 @@ error[E0432]: unresolved import `foo` --> $DIR/local-path-suggestions-2018.rs:22:9 | LL | use foo::Bar; - | ^^^ Did you mean `crate::foo`? + | ^^^ did you mean `crate::foo`? | = note: `use` statements changed in Rust 2018; read more at @@ -10,7 +10,7 @@ error[E0432]: unresolved import `foobar` --> $DIR/local-path-suggestions-2018.rs:31:5 | LL | use foobar::Baz; - | ^^^^^^ Did you mean `baz::foobar`? + | ^^^^^^ did you mean `baz::foobar`? error: aborting due to 2 previous errors diff --git a/src/test/ui/rust-2018/uniform-paths/prelude-fail.stderr b/src/test/ui/rust-2018/uniform-paths/prelude-fail.stderr index a02775eabf42a..794d986b82ef1 100644 --- a/src/test/ui/rust-2018/uniform-paths/prelude-fail.stderr +++ b/src/test/ui/rust-2018/uniform-paths/prelude-fail.stderr @@ -8,7 +8,7 @@ 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` + | ^^^^^^^ not a module `rustfmt` error: aborting due to 2 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 5518b42ac652e..1f001530f364c 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/super-at-top-level.rs b/src/test/ui/super-at-top-level.rs index c607711c44f37..96d099c765557 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 b4af73055a01d..8402daad19e0b 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 b6a24ccf748e1..11e28857afe03 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 d593350f123c6..0839e363c36f9 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 c28b30b5456d0..df7d442239b39 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::; //~ 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 f7120ddb11402..db10197ded1a7 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() { ::NN; //~ ERROR cannot find method or associated constant `NN` in `E::N` ::NN; //~ ERROR cannot find method or associated constant `NN` in `A::N` let _: ::NN; //~ ERROR cannot find associated type `NN` in `Tr::Y` - let _: ::NN; //~ ERROR failed to resolve. Not a module `Y` + let _: ::NN; //~ ERROR failed to resolve: not a module `Y` ::NN; //~ ERROR cannot find method or associated constant `NN` in `Tr::Y` - ::NN; //~ ERROR failed to resolve. Not a module `Y` + ::NN; //~ ERROR failed to resolve: not a module `Y` let _: ::Z; //~ ERROR expected associated type, found method `Dr::Z` ::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 77d887f1d68d8..cb571be661d6a 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 _: ::NN; //~ ERROR failed to resolve. Not a module `Y` - | ^ Not a module `Y` +LL | let _: ::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 | ::NN; //~ ERROR failed to resolve. Not a module `Y` - | ^ Not a module `Y` +LL | ::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 cd2aeb7494a5a..8d7a62255299c 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 8381c6de83a67..55096614fcd32 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 efa7494647691..4592289beeb87 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 9bcebb0011a75..7e98a41af10bd 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 f8e5e18097ba4..6c643dff79602 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 29db949acd04a..afa7632058257 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 b43a32988cafd..cb0fd94fa6e39 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 9a6d608faacca..33366b2457b54 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 6b5286bf0a7da..1b49d358261df 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 5a1e5ea259552..e4cb0f9f3d835 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 4730653dbf906..fc4455c7d6e4e 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` From 22a13ef1584a06cd5b08c57b285925d5b4ebf0b6 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 17 Nov 2018 20:00:00 +0300 Subject: [PATCH 16/18] resolve: Future-proof against imports referring to local variables and generic parameters --- src/librustc_resolve/lib.rs | 36 ++++++++++++- .../ui/rust-2018/future-proofing-locals.rs | 49 ++++++++++++++++++ .../rust-2018/future-proofing-locals.stderr | 50 +++++++++++++++++++ 3 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/rust-2018/future-proofing-locals.rs create mode 100644 src/test/ui/rust-2018/future-proofing-locals.stderr diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index ac54085ad1f9d..465018e8e0036 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2305,6 +2305,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); @@ -2398,7 +2428,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 } 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 0000000000000..d2e6dbbb95412 --- /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() { + 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() { + 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() { + 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 0000000000000..68354b332a9c6 --- /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 + From 10ac9577f88e157d6a2c30929d97dfa42a7993d4 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 17 Nov 2018 20:13:25 +0300 Subject: [PATCH 17/18] resolve: Refactor away `DeterminacyExt` --- src/librustc_resolve/lib.rs | 18 +++-------- src/librustc_resolve/macros.rs | 9 +++--- src/librustc_resolve/resolve_imports.rs | 40 +++++++++++-------------- 3 files changed, 27 insertions(+), 40 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 465018e8e0036..0387b53bff968 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -97,19 +97,9 @@ fn is_known_tool(name: Name) -> bool { ["clippy", "rustfmt"].contains(&&*name.as_str()) } -enum DeterminacyExt { - Determined, - Undetermined, - WeakUndetermined, -} - -impl DeterminacyExt { - fn to_determinacy(self) -> Determinacy { - match self { - DeterminacyExt::Determined => Determined, - DeterminacyExt::Undetermined | DeterminacyExt::WeakUndetermined => Undetermined, - } - } +enum Weak { + Yes, + No, } /// A free importable items suggested in case of resolution failure. @@ -2164,7 +2154,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } let result = self.resolve_ident_in_module_unadjusted_ext( module, ident, ns, parent_scope, false, record_used, path_span, - ).map_err(DeterminacyExt::to_determinacy); + ).map_err(|(determinacy, _)| determinacy); self.current_module = orig_current_module; result } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 30772ec374b00..2877e6a436795 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -9,7 +9,7 @@ // except according to those terms. use {AmbiguityError, AmbiguityKind, AmbiguityErrorMisc}; -use {CrateLint, DeterminacyExt, Resolver, ResolutionError}; +use {CrateLint, Resolver, ResolutionError, Weak}; use {Module, ModuleKind, NameBinding, NameBindingKind, PathResult, ToNameBinding}; use {is_known_tool, names_to_string, resolve_error}; use ModuleOrUniformRoot; @@ -687,10 +687,11 @@ impl<'a, 'cl> Resolver<'a, 'cl> { }; Ok((binding, Flags::MODULE | misc_flags)) } - Err(DeterminacyExt::Undetermined) => + Err((Determinacy::Undetermined, Weak::No)) => return Err(Determinacy::determined(force)), - Err(DeterminacyExt::WeakUndetermined) => Err(Determinacy::Undetermined), - Err(DeterminacyExt::Determined) => Err(Determinacy::Determined), + Err((Determinacy::Undetermined, Weak::Yes)) => + Err(Determinacy::Undetermined), + Err((Determinacy::Determined, _)) => Err(Determinacy::Determined), } } WhereToResolve::MacroUsePrelude => { diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 3d445db1ff4e3..d75ece47aca56 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -11,7 +11,7 @@ use self::ImportDirectiveSubclass::*; use {AmbiguityError, AmbiguityKind, AmbiguityErrorMisc}; -use {CrateLint, DeterminacyExt, Module, ModuleOrUniformRoot, PerNS, UniformRootKind}; +use {CrateLint, Module, ModuleOrUniformRoot, PerNS, UniformRootKind, Weak}; use Namespace::{self, TypeNS, MacroNS}; use {NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError}; use Resolver; @@ -145,7 +145,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { ) -> Result<&'a NameBinding<'a>, Determinacy> { self.resolve_ident_in_module_unadjusted_ext( module, ident, ns, None, false, record_used, path_span - ).map_err(DeterminacyExt::to_determinacy) + ).map_err(|(determinacy, _)| determinacy) } /// Attempts to resolve `ident` in namespaces `ns` of `module`. @@ -159,7 +159,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { restricted_shadowing: bool, record_used: bool, path_span: Span, - ) -> Result<&'a NameBinding<'a>, DeterminacyExt> { + ) -> Result<&'a NameBinding<'a>, (Determinacy, Weak)> { let module = match module { ModuleOrUniformRoot::Module(module) => module, ModuleOrUniformRoot::UniformRoot(uniform_root_kind) => { @@ -171,9 +171,9 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { Ok(binding) } else if !self.graph_root.unresolved_invocations.borrow().is_empty() { // Macro-expanded `extern crate` items can add names to extern prelude. - Err(DeterminacyExt::Undetermined) + Err((Undetermined, Weak::No)) } else { - Err(DeterminacyExt::Determined) + Err((Determined, Weak::No)) } } UniformRootKind::CurrentScope => { @@ -198,10 +198,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { 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| match determinacy { - Determined => DeterminacyExt::Determined, - Undetermined => DeterminacyExt::Undetermined, - }); + return binding.map_err(|determinacy| (determinacy, Weak::No)); } } } @@ -211,8 +208,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { let resolution = self.resolution(module, ident, ns) .try_borrow_mut() - // This happens when there is a cycle of imports. - .map_err(|_| DeterminacyExt::Determined)?; + .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() { @@ -226,13 +222,13 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { // `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(DeterminacyExt::Determined) } + if usable { Ok(binding) } else { Err((Determined, Weak::No)) } }; if record_used { - return resolution.binding.ok_or(DeterminacyExt::Determined).and_then(|binding| { + return resolution.binding.ok_or((Determined, Weak::No)).and_then(|binding| { if self.last_import_segment && check_usable(self, binding).is_err() { - Err(DeterminacyExt::Determined) + Err((Determined, Weak::No)) } else { self.record_use(ident, ns, binding, restricted_shadowing); @@ -279,7 +275,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { continue; } let module = unwrap_or!(single_import.imported_module.get(), - return Err(DeterminacyExt::Undetermined)); + return Err((Undetermined, Weak::No))); let ident = match single_import.subclass { SingleImport { source, .. } => source, _ => unreachable!(), @@ -290,7 +286,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { Ok(binding) if !self.is_accessible_from( binding.vis, single_import.parent_scope.module ) => continue, - Ok(_) | Err(Undetermined) => return Err(DeterminacyExt::Undetermined), + Ok(_) | Err(Undetermined) => return Err((Undetermined, Weak::No)), } } @@ -311,7 +307,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { if !unexpanded_macros || ns == MacroNS || restricted_shadowing { return check_usable(self, binding); } else { - return Err(DeterminacyExt::Undetermined); + return Err((Undetermined, Weak::No)); } } @@ -321,12 +317,12 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { // 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. For `early_resolve_ident_in_lexical_scope` to continue search in outer - // scopes we return `WeakUndetermined` instead of full `Undetermined`. + // 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(DeterminacyExt::WeakUndetermined); + return Err((Undetermined, Weak::Yes)); } // Check if one of glob imports can still define the name, @@ -338,7 +334,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(DeterminacyExt::WeakUndetermined), + 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()) { @@ -360,12 +356,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(DeterminacyExt::WeakUndetermined), + Ok(_) | Err(Undetermined) => return Err((Undetermined, Weak::Yes)), } } // No resolution and no one else can define the name - determinate error. - Err(DeterminacyExt::Determined) + Err((Determined, Weak::No)) } // Add an import directive to the current module. From b3664152ae5b47ab484c8dfbab907dcdf9a49a25 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 17 Nov 2018 20:34:25 +0300 Subject: [PATCH 18/18] Add a couple more tests + address review comments --- src/librustc_resolve/resolve_imports.rs | 8 ++++- .../ui/imports/auxiliary/glob-conflict.rs | 9 ++++++ .../ui/imports/glob-conflict-cross-crate.rs | 7 ++++ .../imports/glob-conflict-cross-crate.stderr | 9 ++++++ src/test/ui/imports/issue-55884-1.rs | 21 ++++++++++++ src/test/ui/imports/issue-55884-1.stderr | 22 +++++++++++++ src/test/ui/imports/issue-55884-2.rs | 14 ++++++++ src/test/ui/imports/issue-55884-2.stderr | 9 ++++++ .../rust-2018/local-path-suggestions-2018.rs | 4 +-- .../local-path-suggestions-2018.stderr | 4 +-- .../ui/rust-2018/uniform-paths/deadlock.rs | 7 ++++ .../rust-2018/uniform-paths/deadlock.stderr | 9 ++++++ .../ui/rust-2018/uniform-paths/issue-54390.rs | 11 +++++++ .../uniform-paths/issue-54390.stderr | 32 +++++++++++++++++++ 14 files changed, 161 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/imports/auxiliary/glob-conflict.rs create mode 100644 src/test/ui/imports/glob-conflict-cross-crate.rs create mode 100644 src/test/ui/imports/glob-conflict-cross-crate.stderr create mode 100644 src/test/ui/imports/issue-55884-1.rs create mode 100644 src/test/ui/imports/issue-55884-1.stderr create mode 100644 src/test/ui/imports/issue-55884-2.rs create mode 100644 src/test/ui/imports/issue-55884-2.stderr create mode 100644 src/test/ui/rust-2018/uniform-paths/deadlock.rs create mode 100644 src/test/ui/rust-2018/uniform-paths/deadlock.stderr create mode 100644 src/test/ui/rust-2018/uniform-paths/issue-54390.rs create mode 100644 src/test/ui/rust-2018/uniform-paths/issue-54390.stderr diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index d75ece47aca56..e744fae7cafff 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -192,6 +192,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { 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_...`. } } @@ -938,7 +939,12 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { } } Err(..) => { - assert!(result[ns].get().is_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()); } } }); 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 0000000000000..ac12ed9c81c77 --- /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/glob-conflict-cross-crate.rs b/src/test/ui/imports/glob-conflict-cross-crate.rs new file mode 100644 index 0000000000000..e02148b19f786 --- /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 0000000000000..f64637fd6f625 --- /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/issue-55884-1.rs b/src/test/ui/imports/issue-55884-1.rs new file mode 100644 index 0000000000000..21744aa5d7bfa --- /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 0000000000000..477e859d0815e --- /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 0000000000000..1b4f652c9fc2f --- /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 0000000000000..f8a6cb4a58090 --- /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/rust-2018/local-path-suggestions-2018.rs b/src/test/ui/rust-2018/local-path-suggestions-2018.rs index 8c9583cfa1bbc..0d4aefff9316c 100644 --- a/src/test/ui/rust-2018/local-path-suggestions-2018.rs +++ b/src/test/ui/rust-2018/local-path-suggestions-2018.rs @@ -19,7 +19,7 @@ mod foo { } mod bazz { - use foo::Bar; + use foo::Bar; //~ ERROR unresolved import `foo` fn baz() { let x: Bar = 22; @@ -28,6 +28,6 @@ mod bazz { 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 27ea6642eb01e..a445a4c612bb9 100644 --- a/src/test/ui/rust-2018/local-path-suggestions-2018.stderr +++ b/src/test/ui/rust-2018/local-path-suggestions-2018.stderr @@ -1,7 +1,7 @@ error[E0432]: unresolved import `foo` --> $DIR/local-path-suggestions-2018.rs:22:9 | -LL | use foo::Bar; +LL | use foo::Bar; //~ ERROR unresolved import `foo` | ^^^ did you mean `crate::foo`? | = note: `use` statements changed in Rust 2018; read more at @@ -9,7 +9,7 @@ LL | use foo::Bar; error[E0432]: unresolved import `foobar` --> $DIR/local-path-suggestions-2018.rs:31:5 | -LL | use foobar::Baz; +LL | use foobar::Baz; //~ ERROR unresolved import `foobar` | ^^^^^^ did you mean `baz::foobar`? error: aborting due to 2 previous errors 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 0000000000000..3228d799083fb --- /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 0000000000000..8bbc8f33039b9 --- /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/issue-54390.rs b/src/test/ui/rust-2018/uniform-paths/issue-54390.rs new file mode 100644 index 0000000000000..536cc25e35ac1 --- /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 0000000000000..8f86698c9c11a --- /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`.