Skip to content

Commit a5f9bd0

Browse files
committed
resolve: Future-proof against imports referring to local variables and generic parameters
1 parent 4fc3c13 commit a5f9bd0

File tree

3 files changed

+134
-1
lines changed

3 files changed

+134
-1
lines changed

src/librustc_resolve/lib.rs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2364,6 +2364,36 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
23642364
});
23652365
}
23662366

2367+
fn future_proof_import(&mut self, use_tree: &ast::UseTree) {
2368+
if !self.session.rust_2018() {
2369+
return;
2370+
}
2371+
2372+
let segments = &use_tree.prefix.segments;
2373+
if !segments.is_empty() {
2374+
let ident = segments[0].ident;
2375+
if ident.is_path_segment_keyword() {
2376+
return;
2377+
}
2378+
2379+
let nss = match use_tree.kind {
2380+
ast::UseTreeKind::Simple(..) if segments.len() == 1 => &[TypeNS, ValueNS][..],
2381+
_ => &[TypeNS],
2382+
};
2383+
for &ns in nss {
2384+
if let Some(LexicalScopeBinding::Def(..)) =
2385+
self.resolve_ident_in_lexical_scope(ident, ns, None, use_tree.prefix.span) {
2386+
let what = if ns == TypeNS { "type parameters" } else { "local variables" };
2387+
self.session.span_err(ident.span, &format!("imports cannot refer to {}", what));
2388+
}
2389+
}
2390+
} else if let ast::UseTreeKind::Nested(use_trees) = &use_tree.kind {
2391+
for (use_tree, _) in use_trees {
2392+
self.future_proof_import(use_tree);
2393+
}
2394+
}
2395+
}
2396+
23672397
fn resolve_item(&mut self, item: &Item) {
23682398
let name = item.ident.name;
23692399
debug!("(resolving item) resolving {}", name);
@@ -2457,7 +2487,11 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
24572487
});
24582488
}
24592489

2460-
ItemKind::Use(..) | ItemKind::ExternCrate(..) |
2490+
ItemKind::Use(ref use_tree) => {
2491+
self.future_proof_import(use_tree);
2492+
}
2493+
2494+
ItemKind::ExternCrate(..) |
24612495
ItemKind::MacroDef(..) | ItemKind::GlobalAsm(..) => {
24622496
// do nothing, these are just around to be encoded
24632497
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// edition:2018
2+
3+
#![feature(uniform_paths, underscore_imports)]
4+
5+
mod T {
6+
pub struct U;
7+
}
8+
mod x {
9+
pub struct y;
10+
}
11+
12+
fn type_param<T>() {
13+
use T as _; //~ ERROR imports cannot refer to type parameters
14+
use T::U; //~ ERROR imports cannot refer to type parameters
15+
use T::*; //~ ERROR imports cannot refer to type parameters
16+
}
17+
18+
fn self_import<T>() {
19+
use T; // FIXME Should be an error, but future-proofing fails due to `T` being "self-shadowed"
20+
}
21+
22+
fn let_binding() {
23+
let x = 10;
24+
25+
use x as _; //~ ERROR imports cannot refer to local variables
26+
use x::y; // OK
27+
use x::*; // OK
28+
}
29+
30+
fn param_binding(x: u8) {
31+
use x; //~ ERROR imports cannot refer to local variables
32+
}
33+
34+
fn match_binding() {
35+
match 0 {
36+
x => {
37+
use x; //~ ERROR imports cannot refer to local variables
38+
}
39+
}
40+
}
41+
42+
fn nested<T>() {
43+
let x = 10;
44+
45+
use {T as _, x}; //~ ERROR imports cannot refer to type parameters
46+
//~| ERROR imports cannot refer to local variables
47+
}
48+
49+
fn main() {}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
error: imports cannot refer to type parameters
2+
--> $DIR/future-proofing-locals.rs:13:9
3+
|
4+
LL | use T as _; //~ ERROR imports cannot refer to type parameters
5+
| ^
6+
7+
error: imports cannot refer to type parameters
8+
--> $DIR/future-proofing-locals.rs:14:9
9+
|
10+
LL | use T::U; //~ ERROR imports cannot refer to type parameters
11+
| ^
12+
13+
error: imports cannot refer to type parameters
14+
--> $DIR/future-proofing-locals.rs:15:9
15+
|
16+
LL | use T::*; //~ ERROR imports cannot refer to type parameters
17+
| ^
18+
19+
error: imports cannot refer to local variables
20+
--> $DIR/future-proofing-locals.rs:25:9
21+
|
22+
LL | use x as _; //~ ERROR imports cannot refer to local variables
23+
| ^
24+
25+
error: imports cannot refer to local variables
26+
--> $DIR/future-proofing-locals.rs:31:9
27+
|
28+
LL | use x; //~ ERROR imports cannot refer to local variables
29+
| ^
30+
31+
error: imports cannot refer to local variables
32+
--> $DIR/future-proofing-locals.rs:37:17
33+
|
34+
LL | use x; //~ ERROR imports cannot refer to local variables
35+
| ^
36+
37+
error: imports cannot refer to type parameters
38+
--> $DIR/future-proofing-locals.rs:45:10
39+
|
40+
LL | use {T as _, x}; //~ ERROR imports cannot refer to type parameters
41+
| ^
42+
43+
error: imports cannot refer to local variables
44+
--> $DIR/future-proofing-locals.rs:45:18
45+
|
46+
LL | use {T as _, x}; //~ ERROR imports cannot refer to type parameters
47+
| ^
48+
49+
error: aborting due to 8 previous errors
50+

0 commit comments

Comments
 (0)