resolve: Future-proof against imports referring to local variables and generic parameters
This commit is contained in:
parent
4fc3c13e32
commit
a5f9bd02b1
@ -2364,6 +2364,36 @@ fn resolve_adt(&mut self, item: &Item, generics: &Generics) {
|
||||
});
|
||||
}
|
||||
|
||||
fn future_proof_import(&mut self, use_tree: &ast::UseTree) {
|
||||
if !self.session.rust_2018() {
|
||||
return;
|
||||
}
|
||||
|
||||
let segments = &use_tree.prefix.segments;
|
||||
if !segments.is_empty() {
|
||||
let ident = segments[0].ident;
|
||||
if ident.is_path_segment_keyword() {
|
||||
return;
|
||||
}
|
||||
|
||||
let nss = match use_tree.kind {
|
||||
ast::UseTreeKind::Simple(..) if segments.len() == 1 => &[TypeNS, ValueNS][..],
|
||||
_ => &[TypeNS],
|
||||
};
|
||||
for &ns in nss {
|
||||
if let Some(LexicalScopeBinding::Def(..)) =
|
||||
self.resolve_ident_in_lexical_scope(ident, ns, None, use_tree.prefix.span) {
|
||||
let what = if ns == TypeNS { "type parameters" } else { "local variables" };
|
||||
self.session.span_err(ident.span, &format!("imports cannot refer to {}", what));
|
||||
}
|
||||
}
|
||||
} else if let ast::UseTreeKind::Nested(use_trees) = &use_tree.kind {
|
||||
for (use_tree, _) in use_trees {
|
||||
self.future_proof_import(use_tree);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_item(&mut self, item: &Item) {
|
||||
let name = item.ident.name;
|
||||
debug!("(resolving item) resolving {}", name);
|
||||
@ -2457,7 +2487,11 @@ fn resolve_item(&mut self, item: &Item) {
|
||||
});
|
||||
}
|
||||
|
||||
ItemKind::Use(..) | ItemKind::ExternCrate(..) |
|
||||
ItemKind::Use(ref use_tree) => {
|
||||
self.future_proof_import(use_tree);
|
||||
}
|
||||
|
||||
ItemKind::ExternCrate(..) |
|
||||
ItemKind::MacroDef(..) | ItemKind::GlobalAsm(..) => {
|
||||
// do nothing, these are just around to be encoded
|
||||
}
|
||||
|
49
src/test/ui/rust-2018/future-proofing-locals.rs
Normal file
49
src/test/ui/rust-2018/future-proofing-locals.rs
Normal file
@ -0,0 +1,49 @@
|
||||
// edition:2018
|
||||
|
||||
#![feature(uniform_paths, underscore_imports)]
|
||||
|
||||
mod T {
|
||||
pub struct U;
|
||||
}
|
||||
mod x {
|
||||
pub struct y;
|
||||
}
|
||||
|
||||
fn type_param<T>() {
|
||||
use T as _; //~ ERROR imports cannot refer to type parameters
|
||||
use T::U; //~ ERROR imports cannot refer to type parameters
|
||||
use T::*; //~ ERROR imports cannot refer to type parameters
|
||||
}
|
||||
|
||||
fn self_import<T>() {
|
||||
use T; // FIXME Should be an error, but future-proofing fails due to `T` being "self-shadowed"
|
||||
}
|
||||
|
||||
fn let_binding() {
|
||||
let x = 10;
|
||||
|
||||
use x as _; //~ ERROR imports cannot refer to local variables
|
||||
use x::y; // OK
|
||||
use x::*; // OK
|
||||
}
|
||||
|
||||
fn param_binding(x: u8) {
|
||||
use x; //~ ERROR imports cannot refer to local variables
|
||||
}
|
||||
|
||||
fn match_binding() {
|
||||
match 0 {
|
||||
x => {
|
||||
use x; //~ ERROR imports cannot refer to local variables
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn nested<T>() {
|
||||
let x = 10;
|
||||
|
||||
use {T as _, x}; //~ ERROR imports cannot refer to type parameters
|
||||
//~| ERROR imports cannot refer to local variables
|
||||
}
|
||||
|
||||
fn main() {}
|
50
src/test/ui/rust-2018/future-proofing-locals.stderr
Normal file
50
src/test/ui/rust-2018/future-proofing-locals.stderr
Normal file
@ -0,0 +1,50 @@
|
||||
error: imports cannot refer to type parameters
|
||||
--> $DIR/future-proofing-locals.rs:13:9
|
||||
|
|
||||
LL | use T as _; //~ ERROR imports cannot refer to type parameters
|
||||
| ^
|
||||
|
||||
error: imports cannot refer to type parameters
|
||||
--> $DIR/future-proofing-locals.rs:14:9
|
||||
|
|
||||
LL | use T::U; //~ ERROR imports cannot refer to type parameters
|
||||
| ^
|
||||
|
||||
error: imports cannot refer to type parameters
|
||||
--> $DIR/future-proofing-locals.rs:15:9
|
||||
|
|
||||
LL | use T::*; //~ ERROR imports cannot refer to type parameters
|
||||
| ^
|
||||
|
||||
error: imports cannot refer to local variables
|
||||
--> $DIR/future-proofing-locals.rs:25:9
|
||||
|
|
||||
LL | use x as _; //~ ERROR imports cannot refer to local variables
|
||||
| ^
|
||||
|
||||
error: imports cannot refer to local variables
|
||||
--> $DIR/future-proofing-locals.rs:31:9
|
||||
|
|
||||
LL | use x; //~ ERROR imports cannot refer to local variables
|
||||
| ^
|
||||
|
||||
error: imports cannot refer to local variables
|
||||
--> $DIR/future-proofing-locals.rs:37:17
|
||||
|
|
||||
LL | use x; //~ ERROR imports cannot refer to local variables
|
||||
| ^
|
||||
|
||||
error: imports cannot refer to type parameters
|
||||
--> $DIR/future-proofing-locals.rs:45:10
|
||||
|
|
||||
LL | use {T as _, x}; //~ ERROR imports cannot refer to type parameters
|
||||
| ^
|
||||
|
||||
error: imports cannot refer to local variables
|
||||
--> $DIR/future-proofing-locals.rs:45:18
|
||||
|
|
||||
LL | use {T as _, x}; //~ ERROR imports cannot refer to type parameters
|
||||
| ^
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
Loading…
Reference in New Issue
Block a user