diff options
Diffstat (limited to 'src/librustc_resolve/resolve_imports.rs')
| -rw-r--r-- | src/librustc_resolve/resolve_imports.rs | 331 |
1 files changed, 183 insertions, 148 deletions
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 48f312ce9f2..a3694cd73ad 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -13,15 +13,16 @@ use self::ImportDirectiveSubclass::*; use {AmbiguityError, CrateLint, Module, ModuleOrUniformRoot, PerNS}; use Namespace::{self, TypeNS, MacroNS}; use {NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError}; -use Resolver; +use {Resolver, Segment}; use {names_to_string, module_to_string}; use {resolve_error, ResolutionError}; +use macros::ParentScope; 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::{CRATE_DEF_INDEX, DefId}; +use rustc::hir::def_id::DefId; use rustc::hir::def::*; use rustc::session::DiagnosticMessageId; use rustc::util::nodemap::FxHashSet; @@ -35,7 +36,6 @@ use syntax_pos::{MultiSpan, Span}; use std::cell::{Cell, RefCell}; use std::collections::BTreeMap; -use std::fmt::Write; use std::{mem, ptr}; /// Contains data for specific types of import directives. @@ -52,7 +52,10 @@ pub enum ImportDirectiveSubclass<'a> { max_vis: Cell<ty::Visibility>, // The visibility of the greatest re-export. // n.b. `max_vis` is only used in `finalize_import` to check for re-export errors. }, - ExternCrate(Option<Name>), + ExternCrate { + source: Option<Name>, + target: Ident, + }, MacroUse, } @@ -85,13 +88,12 @@ pub struct ImportDirective<'a> { /// Span of the *root* use tree (see `root_id`). pub root_span: Span, - pub parent: Module<'a>, - pub module_path: Vec<Ident>, + pub parent_scope: ParentScope<'a>, + pub module_path: Vec<Segment>, /// The resolution of `module_path`. pub imported_module: Cell<Option<ModuleOrUniformRoot<'a>>>, pub subclass: ImportDirectiveSubclass<'a>, pub vis: Cell<ty::Visibility>, - pub expansion: Mark, pub used: Cell<bool>, /// Whether this import is a "canary" for the `uniform_paths` feature, @@ -199,7 +201,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { if !( ns == TypeNS && !ident.is_path_segment_keyword() && - self.extern_prelude.contains(&ident.name) + self.extern_prelude.contains_key(&ident.modern()) ) { // ... unless the crate name is not in the `extern_prelude`. return binding; @@ -217,12 +219,18 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { self.resolve_crate_root(ident) } else if ns == TypeNS && - !ident.is_path_segment_keyword() && - self.extern_prelude.contains(&ident.name) + !ident.is_path_segment_keyword() { - let crate_id = - self.crate_loader.process_path_extern(ident.name, ident.span); - self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX }) + if let Some(binding) = self.extern_prelude_get(ident, !record_used, false) { + let module = self.get_module(binding.def().def_id()); + self.populate_module_if_necessary(module); + return Ok(binding); + } else if !self.graph_root.unresolved_invocations.borrow().is_empty() { + // Macro-expanded `extern crate`items still can add names to extern prelude. + return Err(Undetermined); + } else { + return Err(Determined); + } } else { return Err(Determined); }; @@ -266,7 +274,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { return Ok(self.dummy_binding); } if !self.is_accessible(binding.vis) { - self.privacy_errors.push(PrivacyError(path_span, ident.name, binding)); + self.privacy_errors.push(PrivacyError(path_span, ident, binding)); } } @@ -301,8 +309,9 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { }; match self.resolve_ident_in_module(module, ident, ns, false, path_span) { Err(Determined) => continue, - Ok(binding) - if !self.is_accessible_from(binding.vis, single_import.parent) => continue, + Ok(binding) if !self.is_accessible_from( + binding.vis, single_import.parent_scope.module + ) => continue, Ok(_) | Err(Undetermined) => return Err(Undetermined), } } @@ -375,8 +384,9 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { match result { Err(Determined) => continue, - Ok(binding) - if !self.is_accessible_from(binding.vis, glob_import.parent) => continue, + Ok(binding) if !self.is_accessible_from( + binding.vis, glob_import.parent_scope.module + ) => continue, Ok(_) | Err(Undetermined) => return Err(Undetermined), } } @@ -387,18 +397,18 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { // Add an import directive to the current module. pub fn add_import_directive(&mut self, - module_path: Vec<Ident>, + module_path: Vec<Segment>, subclass: ImportDirectiveSubclass<'a>, span: Span, id: NodeId, root_span: Span, root_id: NodeId, vis: ty::Visibility, - expansion: Mark, + parent_scope: ParentScope<'a>, is_uniform_paths_canary: bool) { - let current_module = self.current_module; + let current_module = parent_scope.module; let directive = self.arenas.alloc_import_directive(ImportDirective { - parent: current_module, + parent_scope, module_path, imported_module: Cell::new(None), subclass, @@ -407,7 +417,6 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { root_span, root_id, vis: Cell::new(vis), - expansion, used: Cell::new(false), is_uniform_paths_canary, }); @@ -425,7 +434,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { // 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 { .. } => self.current_module.globs.borrow_mut().push(directive), + GlobImport { .. } => current_module.globs.borrow_mut().push(directive), _ => unreachable!(), } } @@ -456,7 +465,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { }, span: directive.span, vis, - expansion: directive.expansion, + expansion: directive.parent_scope.expansion, }) } @@ -562,12 +571,12 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { let scope = match ident.span.reverse_glob_adjust(module.expansion, directive.span.ctxt().modern()) { Some(Some(def)) => self.macro_def_scope(def), - Some(None) => directive.parent, + Some(None) => directive.parent_scope.module, None => continue, }; if self.is_accessible_from(binding.vis, scope) { let imported_binding = self.import(binding, directive); - let _ = self.try_define(directive.parent, ident, ns, imported_binding); + let _ = self.try_define(directive.parent_scope.module, ident, ns, imported_binding); } } @@ -581,7 +590,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { let dummy_binding = self.dummy_binding; let dummy_binding = self.import(dummy_binding, directive); self.per_ns(|this, ns| { - let _ = this.try_define(directive.parent, target, ns, dummy_binding); + let _ = this.try_define(directive.parent_scope.module, target, ns, dummy_binding); }); } } @@ -652,7 +661,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { > = BTreeMap::new(); let mut errors = false; - let mut seen_spans = FxHashSet(); + let mut seen_spans = FxHashSet::default(); let mut error_vec = Vec::new(); let mut prev_root_id: NodeId = NodeId::new(0); for i in 0 .. self.determined_imports.len() { @@ -672,8 +681,8 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { }; let has_explicit_self = - import.module_path.len() > 0 && - import.module_path[0].name == keywords::SelfValue.name(); + !import.module_path.is_empty() && + import.module_path[0].ident.name == keywords::SelfValue.name(); self.per_ns(|_, ns| { if let Some(result) = result[ns].get().ok() { @@ -697,15 +706,14 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { } } }); - } else if let Some((span, err)) = error { + } else if let Some((span, err, note)) = error { errors = true; if let SingleImport { source, ref result, .. } = import.subclass { if source.name == "self" { // Silence `unresolved import` error if E0429 is already emitted - match result.value_ns.get() { - Err(Determined) => continue, - _ => {}, + if let Err(Determined) = result.value_ns.get() { + continue; } } } @@ -723,10 +731,12 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { self.throw_unresolved_import_error(empty_vec, None); } if !seen_spans.contains(&span) { - let path = import_path_to_string(&import.module_path[..], - &import.subclass, - span); - error_vec.push((span, path, err)); + let path = import_path_to_string( + &import.module_path.iter().map(|seg| seg.ident).collect::<Vec<_>>(), + &import.subclass, + span, + ); + error_vec.push((span, path, err, note)); seen_spans.insert(span); prev_root_id = import.root_id; } @@ -736,10 +746,9 @@ 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.contains(&name) { - let crate_id = - self.crate_loader.process_path_extern(name, span); - Some(Def::Mod(DefId { krate: crate_id, index: CRATE_DEF_INDEX })) + let external_crate = if ns == TypeNS { + self.extern_prelude_get(Ident::with_empty_ctxt(name), true, false) + .map(|binding| binding.def()) } else { None }; @@ -770,17 +779,14 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { let msg = format!("`{}` import is ambiguous", name); let mut err = self.session.struct_span_err(span, &msg); - let mut suggestion_choices = String::new(); + let mut suggestion_choices = vec![]; if external_crate.is_some() { - write!(suggestion_choices, "`::{}`", name); + suggestion_choices.push(format!("`::{}`", name)); err.span_label(span, format!("can refer to external crate `::{}`", name)); } if let Some(result) = results.module_scope { - if !suggestion_choices.is_empty() { - suggestion_choices.push_str(" or "); - } - write!(suggestion_choices, "`self::{}`", name); + suggestion_choices.push(format!("`self::{}`", name)); if uniform_paths_feature { err.span_label(result.span, format!("can refer to `self::{}`", name)); @@ -793,7 +799,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { err.span_label(result.span, format!("shadowed by block-scoped `{}`", name)); } - err.help(&format!("write {} explicitly instead", suggestion_choices)); + 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 { @@ -819,28 +825,45 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { } } - fn throw_unresolved_import_error(&self, error_vec: Vec<(Span, String, String)>, - span: Option<MultiSpan>) { + fn throw_unresolved_import_error( + &self, + error_vec: Vec<(Span, String, String, Option<String>)>, + span: Option<MultiSpan>, + ) { let max_span_label_msg_count = 10; // upper limit on number of span_label message. - let (span,msg) = match error_vec.is_empty() { - true => (span.unwrap(), "unresolved import".to_string()), - false => { - let span = MultiSpan::from_spans(error_vec.clone().into_iter() - .map(|elem: (Span, String, String)| { elem.0 } - ).collect()); - let path_vec: Vec<String> = error_vec.clone().into_iter() - .map(|elem: (Span, String, String)| { format!("`{}`", elem.1) } - ).collect(); - let path = path_vec.join(", "); - let msg = format!("unresolved import{} {}", - if path_vec.len() > 1 { "s" } else { "" }, path); - (span, msg) - } + let (span, msg, note) = if error_vec.is_empty() { + (span.unwrap(), "unresolved import".to_string(), None) + } else { + let span = MultiSpan::from_spans( + error_vec.clone().into_iter() + .map(|elem: (Span, String, String, Option<String>)| elem.0) + .collect() + ); + + let note: Option<String> = error_vec.clone().into_iter() + .filter_map(|elem: (Span, String, String, Option<String>)| elem.3) + .last(); + + let path_vec: Vec<String> = error_vec.clone().into_iter() + .map(|elem: (Span, String, String, Option<String>)| format!("`{}`", elem.1)) + .collect(); + let path = path_vec.join(", "); + let msg = format!( + "unresolved import{} {}", + if path_vec.len() > 1 { "s" } else { "" }, + path + ); + + (span, msg, note) }; + let mut err = struct_span_err!(self.resolver.session, span, E0432, "{}", &msg); for span_error in error_vec.into_iter().take(max_span_label_msg_count) { err.span_label(span_error.0, span_error.2); } + if let Some(note) = note { + err.note(¬e); + } err.emit(); } @@ -848,10 +871,10 @@ 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[..]), - module_to_string(self.current_module).unwrap_or("???".to_string())); + Segment::names_to_string(&directive.module_path[..]), + module_to_string(self.current_module).unwrap_or_else(|| "???".to_string())); - self.current_module = directive.parent; + self.current_module = directive.parent_scope.module; let module = if let Some(module) = directive.imported_module.get() { module @@ -862,12 +885,13 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { directive.vis.set(ty::Visibility::Invisible); let result = self.resolve_path( Some(if directive.is_uniform_paths_canary { - ModuleOrUniformRoot::Module(directive.parent) + ModuleOrUniformRoot::Module(directive.parent_scope.module) } else { ModuleOrUniformRoot::UniformRoot(keywords::Invalid.name()) }), &directive.module_path[..], None, + &directive.parent_scope, false, directive.span, directive.crate_lint(), @@ -904,7 +928,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { return }; - let parent = directive.parent; + let parent = directive.parent_scope.module; match result[ns].get() { Err(Undetermined) => indeterminate = true, Err(Determined) => { @@ -935,18 +959,22 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { } // If appropriate, returns an error to report. - fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<(Span, String)> { - self.current_module = directive.parent; + fn finalize_import( + &mut self, + directive: &'b ImportDirective<'b> + ) -> Option<(Span, String, Option<String>)> { + self.current_module = directive.parent_scope.module; let ImportDirective { ref module_path, span, .. } = *directive; let module_result = self.resolve_path( Some(if directive.is_uniform_paths_canary { - ModuleOrUniformRoot::Module(directive.parent) + ModuleOrUniformRoot::Module(directive.parent_scope.module) } else { ModuleOrUniformRoot::UniformRoot(keywords::Invalid.name()) }), &module_path, None, + &directive.parent_scope, true, span, directive.crate_lint(), @@ -958,15 +986,16 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { return None; } PathResult::Failed(span, msg, true) => { - return if let Some(suggested_path) = self.make_path_suggestion( - span, module_path.clone() + return if let Some((suggested_path, note)) = self.make_path_suggestion( + span, module_path.clone(), &directive.parent_scope ) { Some(( span, - format!("Did you mean `{}`?", names_to_string(&suggested_path[..])) + format!("Did you mean `{}`?", Segment::names_to_string(&suggested_path)), + note, )) } else { - Some((span, msg)) + Some((span, msg, None)) }; }, _ => return None, @@ -979,7 +1008,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { // 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(); - full_path.push(keywords::Invalid.ident()); + full_path.push(Segment::from_ident(keywords::Invalid.ident())); self.lint_if_path_starts_with_module( directive.crate_lint(), &full_path, @@ -989,10 +1018,13 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { } if let ModuleOrUniformRoot::Module(module) = module { - if module.def_id() == directive.parent.def_id() { + if module.def_id() == directive.parent_scope.module.def_id() { // Importing a module into itself is not allowed. - return Some((directive.span, - "Cannot glob-import a module into itself.".to_string())); + return Some(( + directive.span, + "Cannot glob-import a module into itself.".to_string(), + None, + )); } } if !is_prelude && @@ -1020,15 +1052,21 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { Some(this.dummy_binding); } } + if record_used && ns == TypeNS { + if let ModuleOrUniformRoot::UniformRoot(..) = module { + // Make sure single-segment import is resolved non-speculatively + // at least once to report the feature error. + this.extern_prelude_get(ident, false, false); + } + } } }); if all_ns_err { let mut all_ns_failed = true; self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS { - match this.resolve_ident_in_module(module, ident, ns, record_used, span) { - Ok(_) => all_ns_failed = false, - _ => {} + if this.resolve_ident_in_module(module, ident, ns, record_used, span).is_ok() { + all_ns_failed = false; } }); @@ -1084,7 +1122,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { } } }; - Some((span, msg)) + Some((span, msg, None)) } else { // `resolve_ident_in_module` reported a privacy error. self.import_dummy_binding(directive); @@ -1137,7 +1175,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { // 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(); - full_path.push(ident); + full_path.push(Segment::from_ident(ident)); self.per_ns(|this, ns| { if let Ok(binding) = result[ns].get() { this.lint_if_path_starts_with_module( @@ -1177,7 +1215,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { if let Some(Def::Trait(_)) = module.def() { self.session.span_err(directive.span, "items in traits are not importable."); return; - } else if module.def_id() == directive.parent.def_id() { + } else if module.def_id() == directive.parent_scope.module.def_id() { return; } else if let GlobImport { is_prelude: true, .. } = directive.subclass { self.prelude = Some(module); @@ -1201,7 +1239,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { }; if self.is_accessible_from(binding.pseudo_vis(), scope) { let imported_binding = self.import(binding, directive); - let _ = self.try_define(directive.parent, ident, ns, imported_binding); + let _ = self.try_define(directive.parent_scope.module, ident, ns, imported_binding); } } @@ -1247,65 +1285,62 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { } } - match binding.kind { - NameBindingKind::Import { binding: orig_binding, directive, .. } => { - if ns == TypeNS && orig_binding.is_variant() && - !orig_binding.vis.is_at_least(binding.vis, &*self) { - let msg = match directive.subclass { - ImportDirectiveSubclass::SingleImport { .. } => { - format!("variant `{}` is private and cannot be re-exported", - ident) - }, - ImportDirectiveSubclass::GlobImport { .. } => { - let msg = "enum is private and its variants \ - cannot be re-exported".to_owned(); - let error_id = (DiagnosticMessageId::ErrorId(0), // no code?! - Some(binding.span), - msg.clone()); - let fresh = self.session.one_time_diagnostics - .borrow_mut().insert(error_id); - if !fresh { - continue; - } - msg - }, - ref s @ _ => bug!("unexpected import subclass {:?}", s) - }; - let mut err = self.session.struct_span_err(binding.span, &msg); - - let imported_module = match directive.imported_module.get() { - Some(ModuleOrUniformRoot::Module(module)) => module, - _ => bug!("module should exist"), - }; - let resolutions = imported_module.parent.expect("parent should exist") - .resolutions.borrow(); - let enum_path_segment_index = directive.module_path.len() - 1; - let enum_ident = directive.module_path[enum_path_segment_index]; - - let enum_resolution = resolutions.get(&(enum_ident, TypeNS)) - .expect("resolution should exist"); - let enum_span = enum_resolution.borrow() - .binding.expect("binding should exist") - .span; - let enum_def_span = self.session.source_map().def_span(enum_span); - let enum_def_snippet = self.session.source_map() - .span_to_snippet(enum_def_span).expect("snippet should exist"); - // potentially need to strip extant `crate`/`pub(path)` for suggestion - let after_vis_index = enum_def_snippet.find("enum") - .expect("`enum` keyword should exist in snippet"); - let suggestion = format!("pub {}", - &enum_def_snippet[after_vis_index..]); - - self.session - .diag_span_suggestion_once(&mut err, - DiagnosticMessageId::ErrorId(0), - enum_def_span, - "consider making the enum public", - suggestion); - err.emit(); - } + if let NameBindingKind::Import { binding: orig_binding, directive, .. } = binding.kind { + if ns == TypeNS && orig_binding.is_variant() && + !orig_binding.vis.is_at_least(binding.vis, &*self) { + let msg = match directive.subclass { + ImportDirectiveSubclass::SingleImport { .. } => { + format!("variant `{}` is private and cannot be re-exported", + ident) + }, + ImportDirectiveSubclass::GlobImport { .. } => { + let msg = "enum is private and its variants \ + cannot be re-exported".to_owned(); + let error_id = (DiagnosticMessageId::ErrorId(0), // no code?! + Some(binding.span), + msg.clone()); + let fresh = self.session.one_time_diagnostics + .borrow_mut().insert(error_id); + if !fresh { + continue; + } + msg + }, + ref s @ _ => bug!("unexpected import subclass {:?}", s) + }; + let mut err = self.session.struct_span_err(binding.span, &msg); + + let imported_module = match directive.imported_module.get() { + Some(ModuleOrUniformRoot::Module(module)) => module, + _ => bug!("module should exist"), + }; + let resolutions = imported_module.parent.expect("parent should exist") + .resolutions.borrow(); + let enum_path_segment_index = directive.module_path.len() - 1; + let enum_ident = directive.module_path[enum_path_segment_index].ident; + + let enum_resolution = resolutions.get(&(enum_ident, TypeNS)) + .expect("resolution should exist"); + let enum_span = enum_resolution.borrow() + .binding.expect("binding should exist") + .span; + let enum_def_span = self.session.source_map().def_span(enum_span); + let enum_def_snippet = self.session.source_map() + .span_to_snippet(enum_def_span).expect("snippet should exist"); + // potentially need to strip extant `crate`/`pub(path)` for suggestion + let after_vis_index = enum_def_snippet.find("enum") + .expect("`enum` keyword should exist in snippet"); + let suggestion = format!("pub {}", + &enum_def_snippet[after_vis_index..]); + + self.session + .diag_span_suggestion_once(&mut err, + DiagnosticMessageId::ErrorId(0), + enum_def_span, + "consider making the enum public", + suggestion); + err.emit(); } - _ => {} } } @@ -1342,7 +1377,7 @@ fn import_directive_subclass_to_string(subclass: &ImportDirectiveSubclass) -> St match *subclass { SingleImport { source, .. } => source.to_string(), GlobImport { .. } => "*".to_string(), - ExternCrate(_) => "<extern crate>".to_string(), + ExternCrate { .. } => "<extern crate>".to_string(), MacroUse => "#[macro_use]".to_string(), } } |
