diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 43cfe05ac230e..ec5a8c4a0b896 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -6,8 +6,7 @@ //! Imports are also considered items and placed into modules here, but not resolved yet. use crate::def_collector::collect_definitions; -use crate::imports::ImportDirective; -use crate::imports::ImportDirectiveSubclass::{self, GlobImport, SingleImport}; +use crate::imports::{Import, ImportKind}; use crate::macros::{LegacyBinding, LegacyScope}; use crate::Namespace::{self, MacroNS, TypeNS, ValueNS}; use crate::{CrateLint, Determinacy, PathResult, ResolutionError, VisResolutionError}; @@ -308,11 +307,11 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { }) } - // Add an import directive to the current module. - fn add_import_directive( + // Add an import to the current module. + fn add_import( &mut self, module_path: Vec, - subclass: ImportDirectiveSubclass<'a>, + kind: ImportKind<'a>, span: Span, id: NodeId, item: &ast::Item, @@ -321,11 +320,11 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { vis: ty::Visibility, ) { let current_module = self.parent_scope.module; - let directive = self.r.arenas.alloc_import_directive(ImportDirective { + let import = self.r.arenas.alloc_import(Import { + kind, parent_scope: self.parent_scope, module_path, imported_module: Cell::new(None), - subclass, span, id, use_span: item.span, @@ -337,25 +336,25 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { used: Cell::new(false), }); - debug!("add_import_directive({:?})", directive); + debug!("add_import({:?})", import); - self.r.indeterminate_imports.push(directive); - match directive.subclass { + self.r.indeterminate_imports.push(import); + match import.kind { // Don't add unresolved underscore imports to modules - SingleImport { target: Ident { name: kw::Underscore, .. }, .. } => {} - SingleImport { target, type_ns_only, .. } => { + ImportKind::Single { target: Ident { name: kw::Underscore, .. }, .. } => {} + ImportKind::Single { target, type_ns_only, .. } => { self.r.per_ns(|this, ns| { if !type_ns_only || ns == TypeNS { let key = this.new_key(target, ns); let mut resolution = this.resolution(current_module, key).borrow_mut(); - resolution.add_single_import(directive); + resolution.add_single_import(import); } }); } // We don't add prelude imports to the globs since they only affect lexical scopes, // which are not relevant to import resolution. - GlobImport { is_prelude: true, .. } => {} - GlobImport { .. } => current_module.globs.borrow_mut().push(directive), + ImportKind::Glob { is_prelude: true, .. } => {} + ImportKind::Glob { .. } => current_module.globs.borrow_mut().push(import), _ => unreachable!(), } } @@ -480,7 +479,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { ); } - let subclass = SingleImport { + let kind = ImportKind::Single { source: source.ident, target: ident, source_bindings: PerNS { @@ -496,9 +495,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { type_ns_only, nested, }; - self.add_import_directive( + self.add_import( module_path, - subclass, + kind, use_tree.span, id, item, @@ -508,20 +507,11 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { ); } ast::UseTreeKind::Glob => { - let subclass = GlobImport { + let kind = ImportKind::Glob { is_prelude: attr::contains_name(&item.attrs, sym::prelude_import), max_vis: Cell::new(ty::Visibility::Invisible), }; - self.add_import_directive( - prefix, - subclass, - use_tree.span, - id, - item, - root_span, - item.id, - vis, - ); + self.add_import(prefix, kind, use_tree.span, id, item, root_span, item.id, vis); } ast::UseTreeKind::Nested(ref items) => { // Ensure there is at most one `self` in the list @@ -637,15 +627,12 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { let used = self.process_legacy_macro_imports(item, module); let binding = (module, ty::Visibility::Public, sp, expansion).to_name_binding(self.r.arenas); - let directive = self.r.arenas.alloc_import_directive(ImportDirective { + let import = self.r.arenas.alloc_import(Import { + kind: ImportKind::ExternCrate { source: orig_name, target: ident }, root_id: item.id, id: item.id, parent_scope: self.parent_scope, imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))), - subclass: ImportDirectiveSubclass::ExternCrate { - source: orig_name, - target: ident, - }, has_attributes: !item.attrs.is_empty(), use_span_with_attributes: item.span_with_attributes(), use_span: item.span, @@ -655,8 +642,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { vis: Cell::new(vis), used: Cell::new(used), }); - self.r.potentially_unused_imports.push(directive); - let imported_binding = self.r.import(binding, directive); + self.r.potentially_unused_imports.push(import); + let imported_binding = self.r.import(binding, import); if ptr::eq(parent, self.r.graph_root) { if let Some(entry) = self.r.extern_prelude.get(&ident.modern()) { if expansion != ExpnId::root() @@ -992,13 +979,13 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { } } - let macro_use_directive = |this: &Self, span| { - this.r.arenas.alloc_import_directive(ImportDirective { + let macro_use_import = |this: &Self, span| { + this.r.arenas.alloc_import(Import { + kind: ImportKind::MacroUse, root_id: item.id, id: item.id, parent_scope: this.parent_scope, imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))), - subclass: ImportDirectiveSubclass::MacroUse, use_span_with_attributes: item.span_with_attributes(), has_attributes: !item.attrs.is_empty(), use_span: item.span, @@ -1012,11 +999,11 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { let allow_shadowing = self.parent_scope.expansion == ExpnId::root(); if let Some(span) = import_all { - let directive = macro_use_directive(self, span); - self.r.potentially_unused_imports.push(directive); + let import = macro_use_import(self, span); + self.r.potentially_unused_imports.push(import); module.for_each_child(self, |this, ident, ns, binding| { if ns == MacroNS { - let imported_binding = this.r.import(binding, directive); + let imported_binding = this.r.import(binding, import); this.legacy_import_macro(ident.name, imported_binding, span, allow_shadowing); } }); @@ -1031,9 +1018,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { ident.span, ); if let Ok(binding) = result { - let directive = macro_use_directive(self, ident.span); - self.r.potentially_unused_imports.push(directive); - let imported_binding = self.r.import(binding, directive); + let import = macro_use_import(self, ident.span); + self.r.potentially_unused_imports.push(import); + let imported_binding = self.r.import(binding, import); self.legacy_import_macro( ident.name, imported_binding, diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index 659a54b169b39..722f843ab6e7e 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -3,7 +3,7 @@ // // Although this is mostly a lint pass, it lives in here because it depends on // resolve data structures and because it finalises the privacy information for -// `use` directives. +// `use` items. // // Unused trait imports can't be checked until the method resolution. We save // candidates here, and do the actual check in librustc_typeck/check_unused.rs. @@ -23,7 +23,7 @@ // - `check_crate` finally emits the diagnostics based on the data generated // in the last step -use crate::imports::ImportDirectiveSubclass; +use crate::imports::ImportKind; use crate::Resolver; use rustc::{lint, ty}; @@ -58,7 +58,7 @@ struct UnusedImportCheckVisitor<'a, 'b> { } impl<'a, 'b> UnusedImportCheckVisitor<'a, 'b> { - // We have information about whether `use` (import) directives are actually + // We have information about whether `use` (import) items are actually // used now. If an import is not used at all, we signal a lint error. fn check_import(&mut self, id: ast::NodeId) { let mut used = false; @@ -223,33 +223,33 @@ fn calc_unused_spans( impl Resolver<'_> { crate fn check_unused(&mut self, krate: &ast::Crate) { - for directive in self.potentially_unused_imports.iter() { - match directive.subclass { - _ if directive.used.get() - || directive.vis.get() == ty::Visibility::Public - || directive.span.is_dummy() => + for import in self.potentially_unused_imports.iter() { + match import.kind { + _ if import.used.get() + || import.vis.get() == ty::Visibility::Public + || import.span.is_dummy() => { - if let ImportDirectiveSubclass::MacroUse = directive.subclass { - if !directive.span.is_dummy() { + if let ImportKind::MacroUse = import.kind { + if !import.span.is_dummy() { self.lint_buffer.buffer_lint( lint::builtin::MACRO_USE_EXTERN_CRATE, - directive.id, - directive.span, - "deprecated `#[macro_use]` directive used to \ + import.id, + import.span, + "deprecated `#[macro_use]` attribute used to \ import macros should be replaced at use sites \ - with a `use` statement to import the macro \ + with a `use` item to import the macro \ instead", ); } } } - ImportDirectiveSubclass::ExternCrate { .. } => { - self.maybe_unused_extern_crates.push((directive.id, directive.span)); + ImportKind::ExternCrate { .. } => { + self.maybe_unused_extern_crates.push((import.id, import.span)); } - ImportDirectiveSubclass::MacroUse => { + ImportKind::MacroUse => { let lint = lint::builtin::UNUSED_IMPORTS; let msg = "unused `#[macro_use]` import"; - self.lint_buffer.buffer_lint(lint, directive.id, directive.span, msg); + self.lint_buffer.buffer_lint(lint, import.id, import.span, msg); } _ => {} } diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 3b747a56499f5..47a05ec90d42f 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -18,7 +18,7 @@ use rustc_span::source_map::SourceMap; use rustc_span::symbol::{kw, Symbol}; use rustc_span::{BytePos, MultiSpan, Span}; -use crate::imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver}; +use crate::imports::{Import, ImportKind, ImportResolver}; use crate::path_names_to_string; use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind}; use crate::{BindingError, CrateLint, HasGenericParams, LegacyScope, Module, ModuleOrUniformRoot}; @@ -1125,7 +1125,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { /// ``` pub(crate) fn check_for_module_export_macro( &mut self, - directive: &'b ImportDirective<'b>, + import: &'b Import<'b>, module: ModuleOrUniformRoot<'b>, ident: Ident, ) -> Option<(Option, Vec)> { @@ -1150,28 +1150,26 @@ impl<'a, 'b> ImportResolver<'a, 'b> { let binding = resolution.borrow().binding()?; if let Res::Def(DefKind::Macro(MacroKind::Bang), _) = binding.res() { let module_name = crate_module.kind.name().unwrap(); - let import = match directive.subclass { - ImportDirectiveSubclass::SingleImport { source, target, .. } - if source != target => - { + let import_snippet = match import.kind { + ImportKind::Single { source, target, .. } if source != target => { format!("{} as {}", source, target) } _ => format!("{}", ident), }; let mut corrections: Vec<(Span, String)> = Vec::new(); - if !directive.is_nested() { + if !import.is_nested() { // Assume this is the easy case of `use issue_59764::foo::makro;` and just remove // intermediate segments. - corrections.push((directive.span, format!("{}::{}", module_name, import))); + corrections.push((import.span, format!("{}::{}", module_name, import_snippet))); } else { // Find the binding span (and any trailing commas and spaces). // ie. `use a::b::{c, d, e};` // ^^^ let (found_closing_brace, binding_span) = find_span_of_binding_until_next_binding( self.r.session, - directive.span, - directive.use_span, + import.span, + import.use_span, ); debug!( "check_for_module_export_macro: found_closing_brace={:?} binding_span={:?}", @@ -1208,7 +1206,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { let (has_nested, after_crate_name) = find_span_immediately_after_crate_name( self.r.session, module_name, - directive.use_span, + import.use_span, ); debug!( "check_for_module_export_macro: has_nested={:?} after_crate_name={:?}", @@ -1224,11 +1222,11 @@ impl<'a, 'b> ImportResolver<'a, 'b> { start_point, if has_nested { // In this case, `start_snippet` must equal '{'. - format!("{}{}, ", start_snippet, import) + format!("{}{}, ", start_snippet, import_snippet) } else { // In this case, add a `{`, then the moved import, then whatever // was there before. - format!("{{{}, {}", import, start_snippet) + format!("{{{}, {}", import_snippet, start_snippet) }, )); } diff --git a/src/librustc_resolve/imports.rs b/src/librustc_resolve/imports.rs index 5d4df992b949a..485b86636a0ba 100644 --- a/src/librustc_resolve/imports.rs +++ b/src/librustc_resolve/imports.rs @@ -1,7 +1,5 @@ //! A bunch of methods and structures more or less related to resolving imports. -use ImportDirectiveSubclass::*; - use crate::diagnostics::Suggestion; use crate::Determinacy::{self, *}; use crate::Namespace::{self, MacroNS, TypeNS}; @@ -36,10 +34,10 @@ use std::{mem, ptr}; type Res = def::Res; -/// Contains data for specific types of import directives. +/// Contains data for specific kinds of imports. #[derive(Clone, Debug)] -pub enum ImportDirectiveSubclass<'a> { - SingleImport { +pub enum ImportKind<'a> { + Single { /// `source` in `use prefix::source as target`. source: Ident, /// `target` in `use prefix::source as target`. @@ -53,7 +51,7 @@ pub enum ImportDirectiveSubclass<'a> { /// Did this import result from a nested import? ie. `use foo::{bar, baz};` nested: bool, }, - GlobImport { + Glob { is_prelude: bool, max_vis: Cell, // The visibility of the greatest re-export. // n.b. `max_vis` is only used in `finalize_import` to check for re-export errors. @@ -65,19 +63,21 @@ pub enum ImportDirectiveSubclass<'a> { MacroUse, } -/// One import directive. +/// One import. #[derive(Debug, Clone)] -crate struct ImportDirective<'a> { - /// The ID of the `extern crate`, `UseTree` etc that imported this `ImportDirective`. +crate struct Import<'a> { + pub kind: ImportKind<'a>, + + /// The ID of the `extern crate`, `UseTree` etc that imported this `Import`. /// - /// In the case where the `ImportDirective` was expanded from a "nested" use tree, + /// In the case where the `Import` was expanded from a "nested" use tree, /// this id is the ID of the leaf tree. For example: /// /// ```ignore (pacify the mercilous tidy) /// use foo::bar::{a, b} /// ``` /// - /// If this is the import directive for `foo::bar::a`, we would have the ID of the `UseTree` + /// If this is the import for `foo::bar::a`, we would have the ID of the `UseTree` /// for `a` in this field. pub id: NodeId, @@ -107,22 +107,21 @@ crate struct ImportDirective<'a> { pub module_path: Vec, /// The resolution of `module_path`. pub imported_module: Cell>>, - pub subclass: ImportDirectiveSubclass<'a>, pub vis: Cell, pub used: Cell, } -impl<'a> ImportDirective<'a> { +impl<'a> Import<'a> { pub fn is_glob(&self) -> bool { - match self.subclass { - ImportDirectiveSubclass::GlobImport { .. } => true, + match self.kind { + ImportKind::Glob { .. } => true, _ => false, } } pub fn is_nested(&self) -> bool { - match self.subclass { - ImportDirectiveSubclass::SingleImport { nested, .. } => nested, + match self.kind { + ImportKind::Single { nested, .. } => nested, _ => false, } } @@ -136,8 +135,8 @@ impl<'a> ImportDirective<'a> { /// Records information about the resolution of a name in a namespace of a module. pub struct NameResolution<'a> { /// Single imports that may define the name in the namespace. - /// Import directives are arena-allocated, so it's ok to use pointers as keys. - single_imports: FxHashSet>>, + /// Imports are arena-allocated, so it's ok to use pointers as keys. + single_imports: FxHashSet>>, /// The least shadowable known binding for this name, or None if there are no known bindings. pub binding: Option<&'a NameBinding<'a>>, shadowed_glob: Option<&'a NameBinding<'a>>, @@ -155,8 +154,8 @@ impl<'a> NameResolution<'a> { }) } - crate fn add_single_import(&mut self, directive: &'a ImportDirective<'a>) { - self.single_imports.insert(PtrKey(directive)); + crate fn add_single_import(&mut self, import: &'a Import<'a>) { + self.single_imports.insert(PtrKey(import)); } } @@ -348,8 +347,8 @@ impl<'a> Resolver<'a> { single_import.imported_module.get(), return Err((Undetermined, Weak::No)) ); - let ident = match single_import.subclass { - SingleImport { source, .. } => source, + let ident = match single_import.kind { + ImportKind::Single { source, .. } => source, _ => unreachable!(), }; match self.resolve_ident_in_module( @@ -451,34 +450,34 @@ impl<'a> Resolver<'a> { Err((Determined, Weak::No)) } - // Given a binding and an import directive that resolves to it, - // return the corresponding binding defined by the import directive. + // Given a binding and an import that resolves to it, + // return the corresponding binding defined by the import. crate fn import( &self, binding: &'a NameBinding<'a>, - directive: &'a ImportDirective<'a>, + import: &'a Import<'a>, ) -> &'a NameBinding<'a> { - let vis = if binding.pseudo_vis().is_at_least(directive.vis.get(), self) || + let vis = if binding.pseudo_vis().is_at_least(import.vis.get(), self) || // cf. `PUB_USE_OF_PRIVATE_EXTERN_CRATE` - !directive.is_glob() && binding.is_extern_crate() + !import.is_glob() && binding.is_extern_crate() { - directive.vis.get() + import.vis.get() } else { binding.pseudo_vis() }; - if let GlobImport { ref max_vis, .. } = directive.subclass { - if vis == directive.vis.get() || vis.is_at_least(max_vis.get(), self) { + if let ImportKind::Glob { ref max_vis, .. } = import.kind { + if vis == import.vis.get() || vis.is_at_least(max_vis.get(), self) { max_vis.set(vis) } } self.arenas.alloc_name_binding(NameBinding { - kind: NameBindingKind::Import { binding, directive, used: Cell::new(false) }, + kind: NameBindingKind::Import { binding, import, used: Cell::new(false) }, ambiguity: None, - span: directive.span, + span: import.span, vis, - expansion: directive.parent_scope.expansion, + expansion: import.parent_scope.expansion, }) } @@ -577,17 +576,17 @@ impl<'a> Resolver<'a> { }; // Define `binding` in `module`s glob importers. - for directive in module.glob_importers.borrow_mut().iter() { + for import in module.glob_importers.borrow_mut().iter() { let mut ident = key.ident; - let scope = match ident.span.reverse_glob_adjust(module.expansion, directive.span) { + let scope = match ident.span.reverse_glob_adjust(module.expansion, import.span) { Some(Some(def)) => self.macro_def_scope(def), - Some(None) => directive.parent_scope.module, + Some(None) => import.parent_scope.module, None => continue, }; if self.is_accessible_from(binding.vis, scope) { - let imported_binding = self.import(binding, directive); + let imported_binding = self.import(binding, import); let key = BindingKey { ident, ..key }; - let _ = self.try_define(directive.parent_scope.module, key, imported_binding); + let _ = self.try_define(import.parent_scope.module, key, imported_binding); } } @@ -596,13 +595,13 @@ impl<'a> Resolver<'a> { // Define a "dummy" resolution containing a Res::Err as a placeholder for a // failed resolution - fn import_dummy_binding(&mut self, directive: &'a ImportDirective<'a>) { - if let SingleImport { target, .. } = directive.subclass { + fn import_dummy_binding(&mut self, import: &'a Import<'a>) { + if let ImportKind::Single { target, .. } = import.kind { let dummy_binding = self.dummy_binding; - let dummy_binding = self.import(dummy_binding, directive); + let dummy_binding = self.import(dummy_binding, import); self.per_ns(|this, ns| { let key = this.new_key(target, ns); - let _ = this.try_define(directive.parent_scope.module, key, dummy_binding); + let _ = this.try_define(import.parent_scope.module, key, dummy_binding); // Consider erroneous imports used to avoid duplicate diagnostics. this.record_use(target, ns, dummy_binding, false); }); @@ -671,7 +670,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { .chain(indeterminate_imports.into_iter().map(|i| (true, i))) { if let Some(err) = self.finalize_import(import) { - if let SingleImport { source, ref source_bindings, .. } = import.subclass { + if let ImportKind::Single { source, ref source_bindings, .. } = import.kind { if source.name == kw::SelfLower { // Silence `unresolved import` error if E0429 is already emitted if let Err(Determined) = source_bindings.value_ns.get() { @@ -695,7 +694,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { if seen_spans.insert(err.span) { let path = import_path_to_string( &import.module_path.iter().map(|seg| seg.ident).collect::>(), - &import.subclass, + &import.kind, err.span, ); errors.push((path, err)); @@ -706,7 +705,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { self.r.used_imports.insert((import.id, TypeNS)); let path = import_path_to_string( &import.module_path.iter().map(|seg| seg.ident).collect::>(), - &import.subclass, + &import.kind, import.span, ); let err = UnresolvedImportError { @@ -767,28 +766,28 @@ impl<'a, 'b> ImportResolver<'a, 'b> { /// Attempts to resolve the given import, returning true if its resolution is determined. /// If successful, the resolved bindings are written into the module. - fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> bool { + fn resolve_import(&mut self, import: &'b Import<'b>) -> bool { debug!( "(resolving import for module) resolving import `{}::...` in `{}`", - Segment::names_to_string(&directive.module_path), - module_to_string(directive.parent_scope.module).unwrap_or_else(|| "???".to_string()), + Segment::names_to_string(&import.module_path), + module_to_string(import.parent_scope.module).unwrap_or_else(|| "???".to_string()), ); - let module = if let Some(module) = directive.imported_module.get() { + let module = if let Some(module) = import.imported_module.get() { module } else { // 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 orig_vis = import.vis.replace(ty::Visibility::Invisible); let path_res = self.r.resolve_path( - &directive.module_path, + &import.module_path, None, - &directive.parent_scope, + &import.parent_scope, false, - directive.span, - directive.crate_lint(), + import.span, + import.crate_lint(), ); - directive.vis.set(orig_vis); + import.vis.set(orig_vis); match path_res { PathResult::Module(module) => module, @@ -797,23 +796,22 @@ impl<'a, 'b> ImportResolver<'a, 'b> { } }; - directive.imported_module.set(Some(module)); - let (source, target, source_bindings, target_bindings, type_ns_only) = - match directive.subclass { - SingleImport { - source, - target, - ref source_bindings, - ref target_bindings, - type_ns_only, - .. - } => (source, target, source_bindings, target_bindings, type_ns_only), - GlobImport { .. } => { - self.resolve_glob_import(directive); - return true; - } - _ => unreachable!(), - }; + import.imported_module.set(Some(module)); + let (source, target, source_bindings, target_bindings, type_ns_only) = match import.kind { + ImportKind::Single { + source, + target, + ref source_bindings, + ref target_bindings, + type_ns_only, + .. + } => (source, target, source_bindings, target_bindings, type_ns_only), + ImportKind::Glob { .. } => { + self.resolve_glob_import(import); + return true; + } + _ => unreachable!(), + }; let mut indeterminate = false; self.r.per_ns(|this, ns| { @@ -821,23 +819,23 @@ impl<'a, 'b> ImportResolver<'a, 'b> { if let Err(Undetermined) = source_bindings[ns].get() { // 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 orig_vis = import.vis.replace(ty::Visibility::Invisible); let binding = this.resolve_ident_in_module( module, source, ns, - &directive.parent_scope, + &import.parent_scope, false, - directive.span, + import.span, ); - directive.vis.set(orig_vis); + import.vis.set(orig_vis); source_bindings[ns].set(binding); } else { return; }; - let parent = directive.parent_scope.module; + let parent = import.parent_scope.module; match source_bindings[ns].get() { Err(Undetermined) => indeterminate = true, // Don't update the resolution, because it was never added. @@ -845,20 +843,20 @@ impl<'a, 'b> ImportResolver<'a, 'b> { Err(Determined) => { let key = this.new_key(target, ns); this.update_resolution(parent, key, |_, resolution| { - resolution.single_imports.remove(&PtrKey(directive)); + resolution.single_imports.remove(&PtrKey(import)); }); } Ok(binding) if !binding.is_importable() => { let msg = format!("`{}` is not directly importable", target); - struct_span_err!(this.session, directive.span, E0253, "{}", &msg) - .span_label(directive.span, "cannot be imported directly") + struct_span_err!(this.session, import.span, E0253, "{}", &msg) + .span_label(import.span, "cannot be imported directly") .emit(); // Do not import this illegal binding. Import a dummy binding and pretend // everything is fine - this.import_dummy_binding(directive); + this.import_dummy_binding(import); } Ok(binding) => { - let imported_binding = this.import(binding, directive); + let imported_binding = this.import(binding, import); target_bindings[ns].set(Some(imported_binding)); this.define(parent, target, ns, imported_binding); } @@ -873,38 +871,35 @@ impl<'a, 'b> ImportResolver<'a, 'b> { /// /// Optionally returns an unresolved import error. This error is buffered and used to /// consolidate multiple unresolved import errors into a single diagnostic. - fn finalize_import( - &mut self, - directive: &'b ImportDirective<'b>, - ) -> Option { - let orig_vis = directive.vis.replace(ty::Visibility::Invisible); + fn finalize_import(&mut self, import: &'b Import<'b>) -> Option { + let orig_vis = import.vis.replace(ty::Visibility::Invisible); let prev_ambiguity_errors_len = self.r.ambiguity_errors.len(); let path_res = self.r.resolve_path( - &directive.module_path, + &import.module_path, None, - &directive.parent_scope, + &import.parent_scope, true, - directive.span, - directive.crate_lint(), + import.span, + import.crate_lint(), ); let no_ambiguity = self.r.ambiguity_errors.len() == prev_ambiguity_errors_len; - directive.vis.set(orig_vis); + import.vis.set(orig_vis); if let PathResult::Failed { .. } | PathResult::NonModule(..) = path_res { // Consider erroneous imports used to avoid duplicate diagnostics. - self.r.used_imports.insert((directive.id, TypeNS)); + self.r.used_imports.insert((import.id, TypeNS)); } let module = match path_res { PathResult::Module(module) => { // Consistency checks, analogous to `finalize_macro_resolutions`. - if let Some(initial_module) = directive.imported_module.get() { + if let Some(initial_module) = import.imported_module.get() { if !ModuleOrUniformRoot::same_def(module, initial_module) && no_ambiguity { - span_bug!(directive.span, "inconsistent resolution for an import"); + span_bug!(import.span, "inconsistent resolution for an import"); } } else { if self.r.privacy_errors.is_empty() { let msg = "cannot determine resolution for the import"; let msg_note = "import resolution is stuck, try simplifying other imports"; - self.r.session.struct_span_err(directive.span, msg).note(msg_note).emit(); + self.r.session.struct_span_err(import.span, msg).note(msg_note).emit(); } } @@ -912,7 +907,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { } PathResult::Failed { is_error_from_last_segment: false, span, label, suggestion } => { if no_ambiguity { - assert!(directive.imported_module.get().is_none()); + assert!(import.imported_module.get().is_none()); self.r .report_error(span, ResolutionError::FailedToResolve { label, suggestion }); } @@ -920,11 +915,11 @@ impl<'a, 'b> ImportResolver<'a, 'b> { } PathResult::Failed { is_error_from_last_segment: true, span, label, suggestion } => { if no_ambiguity { - assert!(directive.imported_module.get().is_none()); + assert!(import.imported_module.get().is_none()); let err = match self.make_path_suggestion( span, - directive.module_path.clone(), - &directive.parent_scope, + import.module_path.clone(), + &import.parent_scope, ) { Some((suggestion, note)) => UnresolvedImportError { span, @@ -949,7 +944,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { } PathResult::NonModule(path_res) if path_res.base_res() == Res::Err => { if no_ambiguity { - assert!(directive.imported_module.get().is_none()); + assert!(import.imported_module.get().is_none()); } // The error was already reported earlier. return None; @@ -957,10 +952,8 @@ impl<'a, 'b> ImportResolver<'a, 'b> { PathResult::Indeterminate | PathResult::NonModule(..) => unreachable!(), }; - let (ident, target, source_bindings, target_bindings, type_ns_only) = match directive - .subclass - { - SingleImport { + let (ident, target, source_bindings, target_bindings, type_ns_only) = match import.kind { + ImportKind::Single { source, target, ref source_bindings, @@ -968,25 +961,25 @@ impl<'a, 'b> ImportResolver<'a, 'b> { type_ns_only, .. } => (source, target, source_bindings, target_bindings, type_ns_only), - GlobImport { is_prelude, ref max_vis } => { - if directive.module_path.len() <= 1 { + ImportKind::Glob { is_prelude, ref max_vis } => { + if import.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 = directive.module_path.clone(); + let mut full_path = import.module_path.clone(); full_path.push(Segment::from_ident(Ident::invalid())); self.r.lint_if_path_starts_with_module( - directive.crate_lint(), + import.crate_lint(), &full_path, - directive.span, + import.span, None, ); } if let ModuleOrUniformRoot::Module(module) = module { - if module.def_id() == directive.parent_scope.module.def_id() { + if module.def_id() == import.parent_scope.module.def_id() { // Importing a module into itself is not allowed. return Some(UnresolvedImportError { - span: directive.span, + span: import.span, label: Some(String::from("cannot glob-import a module into itself")), note: Vec::new(), suggestion: None, @@ -995,15 +988,10 @@ impl<'a, 'b> ImportResolver<'a, 'b> { } if !is_prelude && max_vis.get() != ty::Visibility::Invisible && // Allow empty globs. - !max_vis.get().is_at_least(directive.vis.get(), &*self) + !max_vis.get().is_at_least(import.vis.get(), &*self) { let msg = "glob import doesn't reexport anything because no candidate is public enough"; - self.r.lint_buffer.buffer_lint( - UNUSED_IMPORTS, - directive.id, - directive.span, - msg, - ); + self.r.lint_buffer.buffer_lint(UNUSED_IMPORTS, import.id, import.span, msg); } return None; } @@ -1013,7 +1001,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { let mut all_ns_err = true; self.r.per_ns(|this, ns| { if !type_ns_only || ns == TypeNS { - let orig_vis = directive.vis.replace(ty::Visibility::Invisible); + let orig_vis = import.vis.replace(ty::Visibility::Invisible); let orig_blacklisted_binding = mem::replace(&mut this.blacklisted_binding, target_bindings[ns].get()); let orig_last_import_segment = mem::replace(&mut this.last_import_segment, true); @@ -1021,13 +1009,13 @@ impl<'a, 'b> ImportResolver<'a, 'b> { module, ident, ns, - &directive.parent_scope, + &import.parent_scope, true, - directive.span, + import.span, ); this.last_import_segment = orig_last_import_segment; this.blacklisted_binding = orig_blacklisted_binding; - directive.vis.set(orig_vis); + import.vis.set(orig_vis); match binding { Ok(binding) => { @@ -1044,7 +1032,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { ident, ns, target_binding, - directive.module_path.is_empty(), + import.module_path.is_empty(), ); } } @@ -1053,7 +1041,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { let res = binding.res(); if let Ok(initial_res) = initial_res { if res != initial_res && this.ambiguity_errors.is_empty() { - span_bug!(directive.span, "inconsistent resolution for an import"); + span_bug!(import.span, "inconsistent resolution for an import"); } } else { if res != Res::Err @@ -1064,7 +1052,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { let msg_note = "import resolution is stuck, try simplifying other imports"; this.session - .struct_span_err(directive.span, msg) + .struct_span_err(import.span, msg) .note(msg_note) .emit(); } @@ -1090,9 +1078,9 @@ impl<'a, 'b> ImportResolver<'a, 'b> { module, ident, ns, - &directive.parent_scope, + &import.parent_scope, true, - directive.span, + import.span, ); if binding.is_ok() { all_ns_failed = false; @@ -1143,7 +1131,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { }); let (suggestion, note) = - match self.check_for_module_export_macro(directive, module, ident) { + match self.check_for_module_export_macro(import, module, ident) { Some((suggestion, note)) => (suggestion.or(lev_suggestion), note), _ => (lev_suggestion, Vec::new()), }; @@ -1169,14 +1157,14 @@ impl<'a, 'b> ImportResolver<'a, 'b> { }; Some(UnresolvedImportError { - span: directive.span, + span: import.span, label: Some(label), note, suggestion, }) } else { // `resolve_ident_in_module` reported a privacy error. - self.r.import_dummy_binding(directive); + self.r.import_dummy_binding(import); None }; } @@ -1185,7 +1173,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { let mut any_successful_reexport = false; self.r.per_ns(|this, ns| { if let Ok(binding) = source_bindings[ns].get() { - let vis = directive.vis.get(); + let vis = import.vis.get(); if !binding.pseudo_vis().is_at_least(vis, &*this) { reexport_error = Some((ns, binding)); } else { @@ -1206,42 +1194,42 @@ impl<'a, 'b> ImportResolver<'a, 'b> { ); self.r.lint_buffer.buffer_lint( PUB_USE_OF_PRIVATE_EXTERN_CRATE, - directive.id, - directive.span, + import.id, + import.span, &msg, ); } else if ns == TypeNS { struct_span_err!( self.r.session, - directive.span, + import.span, E0365, "`{}` is private, and cannot be re-exported", ident ) - .span_label(directive.span, format!("re-export of private `{}`", ident)) + .span_label(import.span, format!("re-export of private `{}`", ident)) .note(&format!("consider declaring type or module `{}` with `pub`", ident)) .emit(); } else { let msg = format!("`{}` is private, and cannot be re-exported", ident); let note_msg = format!("consider marking `{}` as `pub` in the imported module", ident,); - struct_span_err!(self.r.session, directive.span, E0364, "{}", &msg) - .span_note(directive.span, ¬e_msg) + struct_span_err!(self.r.session, import.span, E0364, "{}", &msg) + .span_note(import.span, ¬e_msg) .emit(); } } - if directive.module_path.len() <= 1 { + if import.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 = directive.module_path.clone(); + let mut full_path = import.module_path.clone(); full_path.push(Segment::from_ident(ident)); self.r.per_ns(|this, ns| { if let Ok(binding) = source_bindings[ns].get() { this.lint_if_path_starts_with_module( - directive.crate_lint(), + import.crate_lint(), &full_path, - directive.span, + import.span, Some(binding), ); } @@ -1253,17 +1241,11 @@ impl<'a, 'b> ImportResolver<'a, 'b> { // purposes it's good enough to just favor one over the other. self.r.per_ns(|this, ns| { if let Ok(binding) = source_bindings[ns].get() { - this.import_res_map.entry(directive.id).or_default()[ns] = Some(binding.res()); + this.import_res_map.entry(import.id).or_default()[ns] = Some(binding.res()); } }); - self.check_for_redundant_imports( - ident, - directive, - source_bindings, - target_bindings, - target, - ); + self.check_for_redundant_imports(ident, import, source_bindings, target_bindings, target); debug!("(resolving single import) successfully resolved import"); None @@ -1272,19 +1254,19 @@ impl<'a, 'b> ImportResolver<'a, 'b> { fn check_for_redundant_imports( &mut self, ident: Ident, - directive: &'b ImportDirective<'b>, + import: &'b Import<'b>, source_bindings: &PerNS, Determinacy>>>, target_bindings: &PerNS>>>, target: Ident, ) { // Skip if the import was produced by a macro. - if directive.parent_scope.expansion != ExpnId::root() { + if import.parent_scope.expansion != ExpnId::root() { return; } // Skip if we are inside a named module (in contrast to an anonymous // module defined by a block). - if let ModuleKind::Def(..) = directive.parent_scope.module.kind { + if let ModuleKind::Def(..) = import.parent_scope.module.kind { return; } @@ -1304,10 +1286,10 @@ impl<'a, 'b> ImportResolver<'a, 'b> { match this.early_resolve_ident_in_lexical_scope( target, ScopeSet::All(ns, false), - &directive.parent_scope, + &import.parent_scope, false, false, - directive.span, + import.span, ) { Ok(other_binding) => { is_redundant[ns] = Some( @@ -1329,35 +1311,35 @@ impl<'a, 'b> ImportResolver<'a, 'b> { redundant_spans.dedup(); self.r.lint_buffer.buffer_lint_with_diagnostic( UNUSED_IMPORTS, - directive.id, - directive.span, + import.id, + import.span, &format!("the item `{}` is imported redundantly", ident), BuiltinLintDiagnostics::RedundantImport(redundant_spans, ident), ); } } - fn resolve_glob_import(&mut self, directive: &'b ImportDirective<'b>) { - let module = match directive.imported_module.get().unwrap() { + fn resolve_glob_import(&mut self, import: &'b Import<'b>) { + let module = match import.imported_module.get().unwrap() { ModuleOrUniformRoot::Module(module) => module, _ => { - self.r.session.span_err(directive.span, "cannot glob-import all possible crates"); + self.r.session.span_err(import.span, "cannot glob-import all possible crates"); return; } }; if module.is_trait() { - self.r.session.span_err(directive.span, "items in traits are not importable."); + self.r.session.span_err(import.span, "items in traits are not importable."); return; - } else if module.def_id() == directive.parent_scope.module.def_id() { + } else if module.def_id() == import.parent_scope.module.def_id() { return; - } else if let GlobImport { is_prelude: true, .. } = directive.subclass { + } else if let ImportKind::Glob { is_prelude: true, .. } = import.kind { self.r.prelude = Some(module); return; } // Add to module's glob_importers - module.glob_importers.borrow_mut().push(directive); + module.glob_importers.borrow_mut().push(import); // Ensure that `resolutions` isn't borrowed during `try_define`, // since it might get updated via a glob cycle. @@ -1371,19 +1353,19 @@ impl<'a, 'b> ImportResolver<'a, 'b> { }) .collect::>(); for (mut key, binding) in bindings { - let scope = match key.ident.span.reverse_glob_adjust(module.expansion, directive.span) { + let scope = match key.ident.span.reverse_glob_adjust(module.expansion, import.span) { Some(Some(def)) => self.r.macro_def_scope(def), - Some(None) => directive.parent_scope.module, + Some(None) => import.parent_scope.module, None => continue, }; if self.r.is_accessible_from(binding.pseudo_vis(), scope) { - let imported_binding = self.r.import(binding, directive); - let _ = self.r.try_define(directive.parent_scope.module, key, imported_binding); + let imported_binding = self.r.import(binding, import); + let _ = self.r.try_define(import.parent_scope.module, key, imported_binding); } } // Record the destination of this import - self.r.record_partial_res(directive.id, PartialRes::new(module.res().unwrap())); + self.r.record_partial_res(import.id, PartialRes::new(module.res().unwrap())); } // Miscellaneous post-processing, including recording re-exports, @@ -1407,16 +1389,16 @@ impl<'a, 'b> ImportResolver<'a, 'b> { } } - if let NameBindingKind::Import { binding: orig_binding, directive, .. } = binding.kind { + if let NameBindingKind::Import { binding: orig_binding, import, .. } = binding.kind { if ns == TypeNS && orig_binding.is_variant() && !orig_binding.vis.is_at_least(binding.vis, &*this) { - let msg = match directive.subclass { - ImportDirectiveSubclass::SingleImport { .. } => { + let msg = match import.kind { + ImportKind::Single { .. } => { format!("variant `{}` is private and cannot be re-exported", ident) } - ImportDirectiveSubclass::GlobImport { .. } => { + ImportKind::Glob { .. } => { let msg = "enum is private and its variants \ cannot be re-exported" .to_owned(); @@ -1432,18 +1414,18 @@ impl<'a, 'b> ImportResolver<'a, 'b> { } msg } - ref s => bug!("unexpected import subclass {:?}", s), + ref s => bug!("unexpected import kind {:?}", s), }; let mut err = this.session.struct_span_err(binding.span, &msg); - let imported_module = match directive.imported_module.get() { + let imported_module = match import.imported_module.get() { Some(ModuleOrUniformRoot::Module(module)) => module, _ => bug!("module should exist"), }; let parent_module = imported_module.parent.expect("parent should exist"); let resolutions = this.resolutions(parent_module).borrow(); - let enum_path_segment_index = directive.module_path.len() - 1; - let enum_ident = directive.module_path[enum_path_segment_index].ident; + let enum_path_segment_index = import.module_path.len() - 1; + let enum_ident = import.module_path[enum_path_segment_index].ident; let key = this.new_key(enum_ident, TypeNS); let enum_resolution = resolutions.get(&key).expect("resolution should exist"); @@ -1481,11 +1463,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { } } -fn import_path_to_string( - names: &[Ident], - subclass: &ImportDirectiveSubclass<'_>, - span: Span, -) -> String { +fn import_path_to_string(names: &[Ident], import_kind: &ImportKind<'_>, span: Span) -> String { let pos = names.iter().position(|p| span == p.span && p.name != kw::PathRoot); let global = !names.is_empty() && names[0].name == kw::PathRoot; if let Some(pos) = pos { @@ -1494,22 +1472,22 @@ fn import_path_to_string( } else { let names = if global { &names[1..] } else { names }; if names.is_empty() { - import_directive_subclass_to_string(subclass) + import_kind_to_string(import_kind) } else { format!( "{}::{}", names_to_string(&names.iter().map(|ident| ident.name).collect::>()), - import_directive_subclass_to_string(subclass), + import_kind_to_string(import_kind), ) } } } -fn import_directive_subclass_to_string(subclass: &ImportDirectiveSubclass<'_>) -> String { - match *subclass { - SingleImport { source, .. } => source.to_string(), - GlobImport { .. } => "*".to_string(), - ExternCrate { .. } => "".to_string(), - MacroUse => "#[macro_use]".to_string(), +fn import_kind_to_string(import_kind: &ImportKind<'_>) -> String { + match import_kind { + ImportKind::Single { source, .. } => source.to_string(), + ImportKind::Glob { .. } => "*".to_string(), + ImportKind::ExternCrate { .. } => "".to_string(), + ImportKind::MacroUse => "#[macro_use]".to_string(), } } diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index 3481beec42a84..97d60e1a23d8d 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -2189,10 +2189,10 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { trait_name: Ident, ) -> SmallVec<[NodeId; 1]> { let mut import_ids = smallvec![]; - while let NameBindingKind::Import { directive, binding, .. } = kind { - self.r.maybe_unused_trait_imports.insert(directive.id); - self.r.add_to_glob_map(&directive, trait_name); - import_ids.push(directive.id); + while let NameBindingKind::Import { import, binding, .. } = kind { + self.r.maybe_unused_trait_imports.insert(import.id); + self.r.add_to_glob_map(&import, trait_name); + import_ids.push(import.id); kind = &binding.kind; } import_ids diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 44eba0d533d3a..492ac6ed83977 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -56,7 +56,7 @@ use std::{cmp, fmt, iter, ptr}; use diagnostics::{extend_span_to_previous_binding, find_span_of_binding_until_next_binding}; use diagnostics::{ImportSuggestion, Suggestion}; -use imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver, NameResolution}; +use imports::{Import, ImportKind, ImportResolver, NameResolution}; use late::{HasGenericParams, PathSource, Rib, RibKind::*}; use macros::{LegacyBinding, LegacyScope}; @@ -456,8 +456,8 @@ pub struct ModuleData<'a> { no_implicit_prelude: bool, - glob_importers: RefCell>>, - globs: RefCell>>, + glob_importers: RefCell>>, + globs: RefCell>>, // Used to memoize the traits in this module for faster searches through all traits in scope. traits: RefCell)]>>>, @@ -584,7 +584,7 @@ impl<'a> ToNameBinding<'a> for &'a NameBinding<'a> { enum NameBindingKind<'a> { Res(Res, /* is_macro_export */ bool), Module(Module<'a>), - Import { binding: &'a NameBinding<'a>, directive: &'a ImportDirective<'a>, used: Cell }, + Import { binding: &'a NameBinding<'a>, import: &'a Import<'a>, used: Cell }, } impl<'a> NameBindingKind<'a> { @@ -713,8 +713,7 @@ impl<'a> NameBinding<'a> { fn is_extern_crate(&self) -> bool { match self.kind { NameBindingKind::Import { - directive: - &ImportDirective { subclass: ImportDirectiveSubclass::ExternCrate { .. }, .. }, + import: &Import { kind: ImportKind::ExternCrate { .. }, .. }, .. } => true, NameBindingKind::Module(&ModuleData { @@ -734,7 +733,7 @@ impl<'a> NameBinding<'a> { fn is_glob_import(&self) -> bool { match self.kind { - NameBindingKind::Import { directive, .. } => directive.is_glob(), + NameBindingKind::Import { import, .. } => import.is_glob(), _ => false, } } @@ -839,10 +838,10 @@ pub struct Resolver<'a> { field_names: FxHashMap>>, /// All imports known to succeed or fail. - determined_imports: Vec<&'a ImportDirective<'a>>, + determined_imports: Vec<&'a Import<'a>>, /// All non-determined imports. - indeterminate_imports: Vec<&'a ImportDirective<'a>>, + indeterminate_imports: Vec<&'a Import<'a>>, /// FIXME: Refactor things so that these fields are passed through arguments and not resolver. /// We are resolving a last import segment during import validation. @@ -947,7 +946,7 @@ pub struct Resolver<'a> { /// Avoid duplicated errors for "name already defined". name_already_seen: FxHashMap, - potentially_unused_imports: Vec<&'a ImportDirective<'a>>, + potentially_unused_imports: Vec<&'a Import<'a>>, /// Table for mapping struct IDs into struct constructor IDs, /// it's not used during normal resolution, only for better error reporting. @@ -971,7 +970,7 @@ pub struct ResolverArenas<'a> { modules: arena::TypedArena>, local_modules: RefCell>>, name_bindings: arena::TypedArena>, - import_directives: arena::TypedArena>, + imports: arena::TypedArena>, name_resolutions: arena::TypedArena>>, legacy_bindings: arena::TypedArena>, ast_paths: arena::TypedArena, @@ -991,11 +990,8 @@ impl<'a> ResolverArenas<'a> { fn alloc_name_binding(&'a self, name_binding: NameBinding<'a>) -> &'a NameBinding<'a> { self.name_bindings.alloc(name_binding) } - fn alloc_import_directive( - &'a self, - import_directive: ImportDirective<'a>, - ) -> &'a ImportDirective<'_> { - self.import_directives.alloc(import_directive) + fn alloc_import(&'a self, import: Import<'a>) -> &'a Import<'_> { + self.imports.alloc(import) } fn alloc_name_resolution(&'a self) -> &'a RefCell> { self.name_resolutions.alloc(Default::default()) @@ -1410,7 +1406,7 @@ impl<'a> Resolver<'a> { misc2: AmbiguityErrorMisc::None, }); } - if let NameBindingKind::Import { directive, binding, ref used } = used_binding.kind { + if let NameBindingKind::Import { import, binding, ref used } = used_binding.kind { // 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 { @@ -1423,17 +1419,17 @@ impl<'a> Resolver<'a> { } } used.set(true); - directive.used.set(true); - self.used_imports.insert((directive.id, ns)); - self.add_to_glob_map(&directive, ident); + import.used.set(true); + self.used_imports.insert((import.id, ns)); + self.add_to_glob_map(&import, ident); self.record_use(ident, ns, binding, false); } } #[inline] - fn add_to_glob_map(&mut self, directive: &ImportDirective<'_>, ident: Ident) { - if directive.is_glob() { - self.glob_map.entry(directive.id).or_default().insert(ident.name); + fn add_to_glob_map(&mut self, import: &Import<'_>, ident: Ident) { + if import.is_glob() { + self.glob_map.entry(import.id).or_default().insert(ident.name); } } @@ -2258,10 +2254,9 @@ impl<'a> Resolver<'a> { // `ExternCrate` (also used for `crate::...`) then no need to issue a // warning, this looks all good! if let Some(binding) = second_binding { - if let NameBindingKind::Import { directive: d, .. } = binding.kind { - // Careful: we still want to rewrite paths from - // renamed extern crates. - if let ImportDirectiveSubclass::ExternCrate { source: None, .. } = d.subclass { + if let NameBindingKind::Import { import, .. } = binding.kind { + // Careful: we still want to rewrite paths from renamed extern crates. + if let ImportKind::ExternCrate { source: None, .. } = import.kind { return; } } @@ -2564,10 +2559,10 @@ impl<'a> Resolver<'a> { // See https://github.com/rust-lang/rust/issues/32354 use NameBindingKind::Import; - let directive = match (&new_binding.kind, &old_binding.kind) { + let import = match (&new_binding.kind, &old_binding.kind) { // If there are two imports where one or both have attributes then prefer removing the // import without attributes. - (Import { directive: new, .. }, Import { directive: old, .. }) + (Import { import: new, .. }, Import { import: old, .. }) if { !new_binding.span.is_dummy() && !old_binding.span.is_dummy() @@ -2581,11 +2576,11 @@ impl<'a> Resolver<'a> { } } // Otherwise prioritize the new binding. - (Import { directive, .. }, other) if !new_binding.span.is_dummy() => { - Some((directive, new_binding.span, other.is_import())) + (Import { import, .. }, other) if !new_binding.span.is_dummy() => { + Some((import, new_binding.span, other.is_import())) } - (other, Import { directive, .. }) if !old_binding.span.is_dummy() => { - Some((directive, old_binding.span, other.is_import())) + (other, Import { import, .. }) if !old_binding.span.is_dummy() => { + Some((import, old_binding.span, other.is_import())) } _ => None, }; @@ -2602,22 +2597,22 @@ impl<'a> Resolver<'a> { && !has_dummy_span && ((new_binding.is_extern_crate() || old_binding.is_extern_crate()) || from_item); - match directive { - Some((directive, span, true)) if should_remove_import && directive.is_nested() => { - self.add_suggestion_for_duplicate_nested_use(&mut err, directive, span) + match import { + Some((import, span, true)) if should_remove_import && import.is_nested() => { + self.add_suggestion_for_duplicate_nested_use(&mut err, import, span) } - Some((directive, _, true)) if should_remove_import && !directive.is_glob() => { + Some((import, _, true)) if should_remove_import && !import.is_glob() => { // Simple case - remove the entire import. Due to the above match arm, this can // only be a single use so just remove it entirely. err.tool_only_span_suggestion( - directive.use_span_with_attributes, + import.use_span_with_attributes, "remove unnecessary import", String::new(), Applicability::MaybeIncorrect, ); } - Some((directive, span, _)) => { - self.add_suggestion_for_rename_of_use(&mut err, name, directive, span) + Some((import, span, _)) => { + self.add_suggestion_for_rename_of_use(&mut err, name, import, span) } _ => {} } @@ -2639,7 +2634,7 @@ impl<'a> Resolver<'a> { &self, err: &mut DiagnosticBuilder<'_>, name: Name, - directive: &ImportDirective<'_>, + import: &Import<'_>, binding_span: Span, ) { let suggested_name = if name.as_str().chars().next().unwrap().is_uppercase() { @@ -2649,11 +2644,11 @@ impl<'a> Resolver<'a> { }; let mut suggestion = None; - match directive.subclass { - ImportDirectiveSubclass::SingleImport { type_ns_only: true, .. } => { + match import.kind { + ImportKind::Single { type_ns_only: true, .. } => { suggestion = Some(format!("self as {}", suggested_name)) } - ImportDirectiveSubclass::SingleImport { source, .. } => { + ImportKind::Single { source, .. } => { if let Some(pos) = source.span.hi().0.checked_sub(binding_span.lo().0).map(|pos| pos as usize) { @@ -2669,7 +2664,7 @@ impl<'a> Resolver<'a> { } } } - ImportDirectiveSubclass::ExternCrate { source, target, .. } => { + ImportKind::ExternCrate { source, target, .. } => { suggestion = Some(format!( "extern crate {} as {};", source.unwrap_or(target.name), @@ -2711,27 +2706,27 @@ impl<'a> Resolver<'a> { /// If the nested use contains only one import then the suggestion will remove the entire /// line. /// - /// It is expected that the directive provided is a nested import - this isn't checked by the + /// It is expected that the provided import is nested - this isn't checked by the /// function. If this invariant is not upheld, this function's behaviour will be unexpected /// as characters expected by span manipulations won't be present. fn add_suggestion_for_duplicate_nested_use( &self, err: &mut DiagnosticBuilder<'_>, - directive: &ImportDirective<'_>, + import: &Import<'_>, binding_span: Span, ) { - assert!(directive.is_nested()); + assert!(import.is_nested()); let message = "remove unnecessary import"; // Two examples will be used to illustrate the span manipulations we're doing: // // - Given `use issue_52891::{d, a, e};` where `a` is a duplicate then `binding_span` is - // `a` and `directive.use_span` is `issue_52891::{d, a, e};`. + // `a` and `import.use_span` is `issue_52891::{d, a, e};`. // - Given `use issue_52891::{d, e, a};` where `a` is a duplicate then `binding_span` is - // `a` and `directive.use_span` is `issue_52891::{d, e, a};`. + // `a` and `import.use_span` is `issue_52891::{d, e, a};`. let (found_closing_brace, span) = - find_span_of_binding_until_next_binding(self.session, binding_span, directive.use_span); + find_span_of_binding_until_next_binding(self.session, binding_span, import.use_span); // If there was a closing brace then identify the span to remove any trailing commas from // previous imports. @@ -2747,7 +2742,7 @@ impl<'a> Resolver<'a> { // Remove the entire line if we cannot extend the span back, this indicates a // `issue_52891::{self}` case. err.span_suggestion( - directive.use_span_with_attributes, + import.use_span_with_attributes, message, String::new(), Applicability::MaybeIncorrect, diff --git a/src/test/ui/rust-2018/macro-use-warned-against.rs b/src/test/ui/rust-2018/macro-use-warned-against.rs index 6cd54aa68aedd..65400163ddd86 100644 --- a/src/test/ui/rust-2018/macro-use-warned-against.rs +++ b/src/test/ui/rust-2018/macro-use-warned-against.rs @@ -4,7 +4,7 @@ #![warn(macro_use_extern_crate, unused)] -#[macro_use] //~ WARN should be replaced at use sites with a `use` statement +#[macro_use] //~ WARN should be replaced at use sites with a `use` item extern crate macro_use_warned_against; #[macro_use] //~ WARN unused `#[macro_use]` extern crate macro_use_warned_against2; diff --git a/src/test/ui/rust-2018/macro-use-warned-against.stderr b/src/test/ui/rust-2018/macro-use-warned-against.stderr index 611b9d5dac9fd..ef00b865815c0 100644 --- a/src/test/ui/rust-2018/macro-use-warned-against.stderr +++ b/src/test/ui/rust-2018/macro-use-warned-against.stderr @@ -1,4 +1,4 @@ -warning: deprecated `#[macro_use]` directive used to import macros should be replaced at use sites with a `use` statement to import the macro instead +warning: deprecated `#[macro_use]` attribute used to import macros should be replaced at use sites with a `use` item to import the macro instead --> $DIR/macro-use-warned-against.rs:7:1 | LL | #[macro_use]