Auto merge of #37361 - jseyfried:fix_crate_var_regressions, r=nrc
Fix `$crate`-related regressions Fixes #37345, fixes #37357, fixes #37352, and improves the `unused_extern_crates` lint. r? @nrc
This commit is contained in:
commit
a7557e758d
|
@ -130,14 +130,27 @@ impl<'b> Resolver<'b> {
|
||||||
|
|
||||||
match view_path.node {
|
match view_path.node {
|
||||||
ViewPathSimple(binding, ref full_path) => {
|
ViewPathSimple(binding, ref full_path) => {
|
||||||
let source_name = full_path.segments.last().unwrap().identifier.name;
|
let mut source = full_path.segments.last().unwrap().identifier;
|
||||||
if source_name.as_str() == "mod" || source_name.as_str() == "self" {
|
let source_name = source.name.as_str();
|
||||||
|
if source_name == "mod" || source_name == "self" {
|
||||||
resolve_error(self,
|
resolve_error(self,
|
||||||
view_path.span,
|
view_path.span,
|
||||||
ResolutionError::SelfImportsOnlyAllowedWithin);
|
ResolutionError::SelfImportsOnlyAllowedWithin);
|
||||||
|
} else if source_name == "$crate" && full_path.segments.len() == 1 {
|
||||||
|
let crate_root = self.resolve_crate_var(source.ctxt);
|
||||||
|
let crate_name = match crate_root.kind {
|
||||||
|
ModuleKind::Def(_, name) => name,
|
||||||
|
ModuleKind::Block(..) => unreachable!(),
|
||||||
|
};
|
||||||
|
source.name = crate_name;
|
||||||
|
|
||||||
|
self.session.struct_span_warn(item.span, "`$crate` may not be imported")
|
||||||
|
.note("`use $crate;` was erroneously allowed and \
|
||||||
|
will become a hard error in a future release")
|
||||||
|
.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
let subclass = ImportDirectiveSubclass::single(binding.name, source_name);
|
let subclass = ImportDirectiveSubclass::single(binding.name, source.name);
|
||||||
let span = view_path.span;
|
let span = view_path.span;
|
||||||
self.add_import_directive(module_path, subclass, span, item.id, vis);
|
self.add_import_directive(module_path, subclass, span, item.id, vis);
|
||||||
}
|
}
|
||||||
|
@ -500,6 +513,7 @@ impl<'b> Resolver<'b> {
|
||||||
legacy_imports: LegacyMacroImports,
|
legacy_imports: LegacyMacroImports,
|
||||||
allow_shadowing: bool) {
|
allow_shadowing: bool) {
|
||||||
let import_macro = |this: &mut Self, name, ext: Rc<_>, span| {
|
let import_macro = |this: &mut Self, name, ext: Rc<_>, span| {
|
||||||
|
this.used_crates.insert(module.def_id().unwrap().krate);
|
||||||
if let SyntaxExtension::NormalTT(..) = *ext {
|
if let SyntaxExtension::NormalTT(..) = *ext {
|
||||||
this.macro_names.insert(name);
|
this.macro_names.insert(name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -845,6 +845,10 @@ impl<'a> ModuleS<'a> {
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_local(&self) -> bool {
|
||||||
|
self.normal_ancestor_id.is_some()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> fmt::Debug for ModuleS<'a> {
|
impl<'a> fmt::Debug for ModuleS<'a> {
|
||||||
|
@ -1580,14 +1584,7 @@ impl<'a> Resolver<'a> {
|
||||||
fn resolve_module_prefix(&mut self, module_path: &[Ident], span: Option<Span>)
|
fn resolve_module_prefix(&mut self, module_path: &[Ident], span: Option<Span>)
|
||||||
-> ResolveResult<ModulePrefixResult<'a>> {
|
-> ResolveResult<ModulePrefixResult<'a>> {
|
||||||
if &*module_path[0].name.as_str() == "$crate" {
|
if &*module_path[0].name.as_str() == "$crate" {
|
||||||
let mut ctxt = module_path[0].ctxt;
|
return Success(PrefixFound(self.resolve_crate_var(module_path[0].ctxt), 1));
|
||||||
while ctxt.source().0 != SyntaxContext::empty() {
|
|
||||||
ctxt = ctxt.source().0;
|
|
||||||
}
|
|
||||||
let module = self.invocations[&ctxt.source().1].module.get();
|
|
||||||
let crate_root =
|
|
||||||
if module.def_id().unwrap().is_local() { self.graph_root } else { module };
|
|
||||||
return Success(PrefixFound(crate_root, 1))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start at the current module if we see `self` or `super`, or at the
|
// Start at the current module if we see `self` or `super`, or at the
|
||||||
|
@ -1620,6 +1617,14 @@ impl<'a> Resolver<'a> {
|
||||||
return Success(PrefixFound(containing_module, i));
|
return Success(PrefixFound(containing_module, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn resolve_crate_var(&mut self, mut crate_var_ctxt: SyntaxContext) -> Module<'a> {
|
||||||
|
while crate_var_ctxt.source().0 != SyntaxContext::empty() {
|
||||||
|
crate_var_ctxt = crate_var_ctxt.source().0;
|
||||||
|
}
|
||||||
|
let module = self.invocations[&crate_var_ctxt.source().1].module.get();
|
||||||
|
if module.is_local() { self.graph_root } else { module }
|
||||||
|
}
|
||||||
|
|
||||||
// AST resolution
|
// AST resolution
|
||||||
//
|
//
|
||||||
// We maintain a list of value ribs and type ribs.
|
// We maintain a list of value ribs and type ribs.
|
||||||
|
@ -2569,7 +2574,8 @@ impl<'a> Resolver<'a> {
|
||||||
let unqualified_def = resolve_identifier_with_fallback(self, None);
|
let unqualified_def = resolve_identifier_with_fallback(self, None);
|
||||||
let qualified_binding = self.resolve_module_relative_path(span, segments, namespace);
|
let qualified_binding = self.resolve_module_relative_path(span, segments, namespace);
|
||||||
match (qualified_binding, unqualified_def) {
|
match (qualified_binding, unqualified_def) {
|
||||||
(Ok(binding), Some(ref ud)) if binding.def() == ud.def => {
|
(Ok(binding), Some(ref ud)) if binding.def() == ud.def &&
|
||||||
|
segments[0].identifier.name.as_str() != "$crate" => {
|
||||||
self.session
|
self.session
|
||||||
.add_lint(lint::builtin::UNUSED_QUALIFICATIONS,
|
.add_lint(lint::builtin::UNUSED_QUALIFICATIONS,
|
||||||
id,
|
id,
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! m { () => { use $crate; } }
|
|
@ -0,0 +1,21 @@
|
||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// aux-build:import_crate_var.rs
|
||||||
|
// error-pattern: `$crate` may not be imported
|
||||||
|
// error-pattern: `use $crate;` was erroneously allowed and will become a hard error
|
||||||
|
|
||||||
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
|
#[macro_use] extern crate import_crate_var;
|
||||||
|
m!();
|
||||||
|
|
||||||
|
#[rustc_error]
|
||||||
|
fn main() {}
|
|
@ -18,4 +18,11 @@ fn main() {
|
||||||
use foo::bar;
|
use foo::bar;
|
||||||
foo::bar(); //~ ERROR: unnecessary qualification
|
foo::bar(); //~ ERROR: unnecessary qualification
|
||||||
bar();
|
bar();
|
||||||
|
|
||||||
|
let _ = || -> Result<(), ()> { try!(Ok(())); Ok(()) }; // issue #37345
|
||||||
|
|
||||||
|
macro_rules! m {
|
||||||
|
() => { $crate::foo::bar(); }
|
||||||
|
}
|
||||||
|
m!(); // issue #37357
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,8 @@ extern crate rand; // no error, the use marks it as used
|
||||||
|
|
||||||
extern crate lint_unused_extern_crate as other; // no error, the use * marks it as used
|
extern crate lint_unused_extern_crate as other; // no error, the use * marks it as used
|
||||||
|
|
||||||
|
#[macro_use] extern crate core; // no error, the `#[macro_use]` marks it as used
|
||||||
|
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use rand::isaac::IsaacRng;
|
use rand::isaac::IsaacRng;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue