diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2018-05-22 11:10:17 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2018-05-22 11:10:17 -0400 |
| commit | 068c4364c7f793e12d998f5b9b212e723dafa210 (patch) | |
| tree | 2b99c8214a3cc615cd6e1f63fafe27ca7e2b386b | |
| parent | cce913278041031bce87563fa985b0718f8ad939 (diff) | |
| download | rust-068c4364c7f793e12d998f5b9b212e723dafa210.tar.gz rust-068c4364c7f793e12d998f5b9b212e723dafa210.zip | |
pass down information about the root tree and use that to guide lint
| -rw-r--r-- | src/librustc_resolve/lib.rs | 78 | ||||
| -rw-r--r-- | src/librustc_resolve/macros.rs | 6 | ||||
| -rw-r--r-- | src/librustc_resolve/resolve_imports.rs | 12 |
3 files changed, 62 insertions, 34 deletions
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index e13e6bc6b74..939e6202257 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -12,6 +12,7 @@ html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] +#![feature(crate_visibility_modifier)] #![feature(rustc_diagnostic_macros)] #![feature(slice_sort_by_cached_key)] @@ -1655,11 +1656,11 @@ impl<'a> Resolver<'a> { .map(|seg| Ident::new(seg.name, span)) .collect(); // FIXME (Manishearth): Intra doc links won't get warned of epoch changes - match self.resolve_path(&path, Some(namespace), true, span, None) { + match self.resolve_path(&path, Some(namespace), true, span, CrateLint::No) { PathResult::Module(module) => *def = module.def().unwrap(), PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => *def = path_res.base_def(), - PathResult::NonModule(..) => match self.resolve_path(&path, None, true, span, None) { + PathResult::NonModule(..) => match self.resolve_path(&path, None, true, span, CrateLint::No) { PathResult::Failed(span, msg, _) => { error_callback(self, span, ResolutionError::FailedToResolve(&msg)); } @@ -2378,8 +2379,13 @@ impl<'a> Resolver<'a> { if def != Def::Err { new_id = Some(def.def_id()); let span = trait_ref.path.span; - if let PathResult::Module(module) = self.resolve_path(&path, None, false, span, - Some(trait_ref.ref_id)) { + if let PathResult::Module(module) = self.resolve_path( + &path, + None, + false, + span, + CrateLint::SimplePath(trait_ref.ref_id), + ) { new_val = Some((module, trait_ref.clone())); } } @@ -2839,7 +2845,7 @@ impl<'a> Resolver<'a> { } else { let mod_path = &path[..path.len() - 1]; let mod_prefix = match this.resolve_path(mod_path, Some(TypeNS), - false, span, None) { + false, span, CrateLint::No) { PathResult::Module(module) => module.def(), _ => None, }.map_or(format!(""), |def| format!("{} ", def.kind_name())); @@ -3169,7 +3175,7 @@ impl<'a> Resolver<'a> { )); } - let result = match self.resolve_path(&path, Some(ns), true, span, Some(id)) { + let result = match self.resolve_path(&path, Some(ns), true, span, CrateLint::SimplePath(id)) { PathResult::NonModule(path_res) => path_res, PathResult::Module(module) if !module.is_normal() => { PathResolution::new(module.def().unwrap()) @@ -3206,7 +3212,7 @@ impl<'a> Resolver<'a> { path[0].name != keywords::CrateRoot.name() && path[0].name != keywords::DollarCrate.name() { let unqualified_result = { - match self.resolve_path(&[*path.last().unwrap()], Some(ns), false, span, None) { + match self.resolve_path(&[*path.last().unwrap()], Some(ns), false, span, CrateLint::No) { PathResult::NonModule(path_res) => path_res.base_def(), PathResult::Module(module) => module.def().unwrap(), _ => return Some(result), @@ -3221,14 +3227,14 @@ impl<'a> Resolver<'a> { Some(result) } - fn resolve_path(&mut self, - path: &[Ident], - opt_ns: Option<Namespace>, // `None` indicates a module path - record_used: bool, - path_span: Span, - node_id: Option<NodeId>) // None indicates that we don't care about linting - // `::module` paths - -> PathResult<'a> { + fn resolve_path( + &mut self, + path: &[Ident], + opt_ns: Option<Namespace>, // `None` indicates a module path + record_used: bool, + path_span: Span, + crate_lint: CrateLint, + ) -> PathResult<'a> { let mut module = None; let mut allow_super = true; let mut second_binding = None; @@ -3347,7 +3353,7 @@ impl<'a> Resolver<'a> { return PathResult::NonModule(err_path_resolution()); } else if opt_ns.is_some() && (is_last || maybe_assoc) { self.lint_if_path_starts_with_module( - node_id, + crate_lint, path, path_span, second_binding, @@ -3392,19 +3398,22 @@ impl<'a> Resolver<'a> { } } - self.lint_if_path_starts_with_module(node_id, path, path_span, second_binding); + self.lint_if_path_starts_with_module(crate_lint, path, path_span, second_binding); PathResult::Module(module.unwrap_or(self.graph_root)) } - fn lint_if_path_starts_with_module(&self, - id: Option<NodeId>, - path: &[Ident], - path_span: Span, - second_binding: Option<&NameBinding>) { - let id = match id { - Some(id) => id, - None => return, + fn lint_if_path_starts_with_module( + &self, + crate_lint: CrateLint, + path: &[Ident], + path_span: Span, + second_binding: Option<&NameBinding>, + ) { + let (diag_id, diag_span) = match crate_lint { + CrateLint::No => return, + CrateLint::SimplePath(id) => (id, path_span), + CrateLint::UsePath { root_id, root_span } => (root_id, root_span), }; let first_name = match path.get(0) { @@ -3440,7 +3449,7 @@ impl<'a> Resolver<'a> { } } - self.lint_path_starts_with_module(id, path_span); + self.lint_path_starts_with_module(diag_id, diag_span); } fn lint_path_starts_with_module(&self, id: NodeId, span: Span) { @@ -3676,7 +3685,7 @@ impl<'a> Resolver<'a> { // Search in module. let mod_path = &path[..path.len() - 1]; if let PathResult::Module(module) = self.resolve_path(mod_path, Some(TypeNS), - false, span, None) { + false, span, CrateLint::No) { add_module_candidates(module, &mut names); } } @@ -4475,4 +4484,19 @@ pub enum MakeGlobMap { No, } +enum CrateLint { + /// Do not issue the lint + No, + + /// This lint applies to some random path like `impl ::foo::Bar` + /// or whatever. In this case, we can take the span of that path. + SimplePath(NodeId), + + /// This lint comes from a `use` statement. In this case, what we + /// care about really is the *root* `use` statement; e.g., if we + /// have nested things like `use a::{b, c}`, we care about the + /// `use a` part. + UsePath { root_id: NodeId, root_span: Span }, +} + __build_diagnostic_array! { librustc_resolve, DIAGNOSTICS } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 0fc963a1367..c5d04293d03 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use {AmbiguityError, Resolver, ResolutionError, resolve_error}; +use {AmbiguityError, CrateLint, Resolver, ResolutionError, resolve_error}; use {Module, ModuleKind, NameBinding, NameBindingKind, PathResult}; use Namespace::{self, MacroNS}; use build_reduced_graph::BuildReducedGraphVisitor; @@ -441,7 +441,7 @@ impl<'a> Resolver<'a> { return Err(Determinacy::Determined); } - let def = match self.resolve_path(&path, Some(MacroNS), false, span, None) { + let def = match self.resolve_path(&path, Some(MacroNS), false, span, CrateLint::No) { PathResult::NonModule(path_res) => match path_res.base_def() { Def::Err => Err(Determinacy::Determined), def @ _ => { @@ -619,7 +619,7 @@ impl<'a> Resolver<'a> { pub fn finalize_current_module_macro_resolutions(&mut self) { let module = self.current_module; for &(ref path, span) in module.macro_resolutions.borrow().iter() { - match self.resolve_path(&path, Some(MacroNS), true, span, None) { + match self.resolve_path(&path, Some(MacroNS), true, span, CrateLint::No) { PathResult::NonModule(_) => {}, PathResult::Failed(span, msg, _) => { resolve_error(self, span, ResolutionError::FailedToResolve(&msg)); diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index fd657cbf805..2661cd7bb67 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -10,7 +10,7 @@ use self::ImportDirectiveSubclass::*; -use {AmbiguityError, Module, PerNS}; +use {AmbiguityError, CrateLint, Module, PerNS}; use Namespace::{self, TypeNS, MacroNS}; use {NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError}; use Resolver; @@ -94,6 +94,10 @@ impl<'a> ImportDirective<'a> { pub fn is_glob(&self) -> bool { match self.subclass { ImportDirectiveSubclass::GlobImport { .. } => true, _ => false } } + + crate fn crate_lint(&self) -> CrateLint { + CrateLint::UsePath { root_id: self.root_id, root_span: self.root_span } + } } #[derive(Clone, Default, Debug)] @@ -599,7 +603,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { // while resolving its module path. directive.vis.set(ty::Visibility::Invisible); let result = self.resolve_path(&directive.module_path[..], None, false, - directive.span, Some(directive.id)); + directive.span, directive.crate_lint()); directive.vis.set(vis); match result { @@ -733,7 +737,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { } } - let module_result = self.resolve_path(&module_path, None, true, span, Some(directive.id)); + let module_result = self.resolve_path(&module_path, None, true, span, directive.crate_lint()); let module = match module_result { PathResult::Module(module) => module, PathResult::Failed(span, msg, false) => { @@ -748,7 +752,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { !(self_path.len() > 1 && is_special(self_path[1])) { self_path[0].name = keywords::SelfValue.name(); self_result = Some(self.resolve_path(&self_path, None, false, - span, None)); + span, CrateLint::No)); } return if let Some(PathResult::Module(..)) = self_result { Some((span, format!("Did you mean `{}`?", names_to_string(&self_path[..])))) |
