diff options
| author | bors <bors@rust-lang.org> | 2018-04-25 04:19:06 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-04-25 04:19:06 +0000 |
| commit | 432fe0cefc76045a98a38ba6c7a74b018aae1b7d (patch) | |
| tree | 92e4e30e507b840bff4200b9728b803912410055 /src/librustc_resolve | |
| parent | 0c5740feb24bff4f13b68b565288dd8a42ab93f6 (diff) | |
| parent | 2a5ce10dfb20e794d324cb1621e5ac892b7e421a (diff) | |
| download | rust-432fe0cefc76045a98a38ba6c7a74b018aae1b7d.tar.gz rust-432fe0cefc76045a98a38ba6c7a74b018aae1b7d.zip | |
Auto merge of #50100 - Manishearth:edition-path-lint, r=nikomatsakis
Edition breakage lint for absolute paths starting with modules We plan to enable `extern_absolute_paths` in the 2018 edition. To allow for that, folks must transition their paths in a previous edition to the new one. This makes paths which import module contents via `use module::` or `::module::` obsolete, and we must edition-lint these. https://internals.rust-lang.org/t/the-great-module-adventure-continues/6678/205?u=manishearth is the current plan for paths. r? @nikomatsakis Fixes #48722
Diffstat (limited to 'src/librustc_resolve')
| -rw-r--r-- | src/librustc_resolve/lib.rs | 50 | ||||
| -rw-r--r-- | src/librustc_resolve/macros.rs | 4 | ||||
| -rw-r--r-- | src/librustc_resolve/resolve_imports.rs | 8 |
3 files changed, 49 insertions, 13 deletions
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 671856c4e54..7a87a72afc2 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1654,11 +1654,12 @@ impl<'a> Resolver<'a> { let path: Vec<Ident> = segments.iter() .map(|seg| Ident::new(seg.name, span)) .collect(); - match self.resolve_path(&path, Some(namespace), true, span) { + // FIXME (Manishearth): Intra doc links won't get warned of epoch changes + match self.resolve_path(&path, Some(namespace), true, span, None) { 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) { + PathResult::NonModule(..) => match self.resolve_path(&path, None, true, span, None) { PathResult::Failed(span, msg, _) => { error_callback(self, span, ResolutionError::FailedToResolve(&msg)); } @@ -2360,7 +2361,8 @@ 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) { + if let PathResult::Module(module) = self.resolve_path(&path, None, false, span, + Some(trait_ref.ref_id)) { new_val = Some((module, trait_ref.clone())); } } @@ -2819,7 +2821,8 @@ impl<'a> Resolver<'a> { (format!(""), format!("the crate root")) } else { let mod_path = &path[..path.len() - 1]; - let mod_prefix = match this.resolve_path(mod_path, Some(TypeNS), false, span) { + let mod_prefix = match this.resolve_path(mod_path, Some(TypeNS), + false, span, None) { PathResult::Module(module) => module.def(), _ => None, }.map_or(format!(""), |def| format!("{} ", def.kind_name())); @@ -3149,7 +3152,7 @@ impl<'a> Resolver<'a> { )); } - let result = match self.resolve_path(&path, Some(ns), true, span) { + let result = match self.resolve_path(&path, Some(ns), true, span, Some(id)) { PathResult::NonModule(path_res) => path_res, PathResult::Module(module) if !module.is_normal() => { PathResolution::new(module.def().unwrap()) @@ -3186,7 +3189,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) { + match self.resolve_path(&[*path.last().unwrap()], Some(ns), false, span, None) { PathResult::NonModule(path_res) => path_res.base_def(), PathResult::Module(module) => module.def().unwrap(), _ => return Some(result), @@ -3205,7 +3208,9 @@ impl<'a> Resolver<'a> { path: &[Ident], opt_ns: Option<Namespace>, // `None` indicates a module path record_used: bool, - path_span: Span) + path_span: Span, + node_id: Option<NodeId>) // None indicates that we don't care about linting + // `::module` paths -> PathResult<'a> { let mut module = None; let mut allow_super = true; @@ -3253,6 +3258,8 @@ impl<'a> Resolver<'a> { let prev_name = path[0].name; if prev_name == keywords::Extern.name() || prev_name == keywords::CrateRoot.name() && + // Note: When this feature stabilizes, this should + // be gated on sess.rust_2018() self.session.features_untracked().extern_absolute_paths { // `::extern_crate::a::b` let crate_id = self.crate_loader.process_path_extern(name, ident.span); @@ -3324,6 +3331,33 @@ impl<'a> Resolver<'a> { format!("Not a module `{}`", ident), is_last); } + + if let Some(id) = node_id { + if i == 1 && self.session.features_untracked().crate_in_paths + && !self.session.rust_2018() { + let prev_name = path[0].name; + if prev_name == keywords::Extern.name() || + prev_name == keywords::CrateRoot.name() { + let mut is_crate = false; + if let NameBindingKind::Import { directive: d, .. } = binding.kind { + if let ImportDirectiveSubclass::ExternCrate(..) = d.subclass { + is_crate = true; + } + } + + if !is_crate { + let diag = lint::builtin::BuiltinLintDiagnostics + ::AbsPathWithModule(path_span); + self.session.buffer_lint_with_diagnostic( + lint::builtin::ABSOLUTE_PATH_STARTING_WITH_MODULE, + id, path_span, + "Absolute paths must start with `self`, `super`, \ + `crate`, or an external crate name in the 2018 edition", + diag); + } + } + } + } } Err(Undetermined) => return PathResult::Indeterminate, Err(Determined) => { @@ -3571,7 +3605,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) { + false, span, None) { add_module_candidates(module, &mut names); } } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 3a859c02c16..af1e17cd89c 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -438,7 +438,7 @@ impl<'a> Resolver<'a> { return Err(Determinacy::Determined); } - let def = match self.resolve_path(&path, Some(MacroNS), false, span) { + let def = match self.resolve_path(&path, Some(MacroNS), false, span, None) { PathResult::NonModule(path_res) => match path_res.base_def() { Def::Err => Err(Determinacy::Determined), def @ _ => { @@ -616,7 +616,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) { + match self.resolve_path(&path, Some(MacroNS), true, span, None) { 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 37c62a7b0b4..e2a7f5668d2 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -535,7 +535,8 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { // For better failure detection, pretend that the import will not define any names // while resolving its module path. directive.vis.set(ty::Visibility::Invisible); - let result = self.resolve_path(&directive.module_path[..], None, false, directive.span); + let result = self.resolve_path(&directive.module_path[..], None, false, + directive.span, Some(directive.id)); directive.vis.set(vis); match result { @@ -663,7 +664,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { } } - let module_result = self.resolve_path(&module_path, None, true, span); + let module_result = self.resolve_path(&module_path, None, true, span, Some(directive.id)); let module = match module_result { PathResult::Module(module) => module, PathResult::Failed(span, msg, false) => { @@ -677,7 +678,8 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { if !self_path.is_empty() && !is_special(self_path[0]) && !(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)); + self_result = Some(self.resolve_path(&self_path, None, false, + span, None)); } return if let Some(PathResult::Module(..)) = self_result { Some((span, format!("Did you mean `{}`?", names_to_string(&self_path[..])))) |
