resolve: Future-proof against imports referring to local variables and generic parameters

This commit is contained in:
Vadim Petrochenkov 2018-11-17 20:00:00 +03:00
parent 4fc3c13e32
commit a5f9bd02b1
3 changed files with 134 additions and 1 deletions

View File

@ -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
}

View 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() {}

View 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