Skip to content

Commit

Permalink
resolve: Future-proof against imports referring to local variables an…
Browse files Browse the repository at this point in the history
…d generic parameters
  • Loading branch information
petrochenkov committed Nov 17, 2018
1 parent 696fbc0 commit 22a13ef
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 1 deletion.
36 changes: 35 additions & 1 deletion src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2305,6 +2305,36 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
});
}

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);
Expand Down Expand Up @@ -2398,7 +2428,11 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
});
}

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
}
Expand Down
49 changes: 49 additions & 0 deletions src/test/ui/rust-2018/future-proofing-locals.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 50 additions & 0 deletions src/test/ui/rust-2018/future-proofing-locals.stderr
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 22a13ef

Please sign in to comment.