Skip to content

Commit db9bb42

Browse files
committed
WIP: rewrite build_reduced_graph_for_use_tree
1 parent 956f47c commit db9bb42

File tree

8 files changed

+277
-1
lines changed

8 files changed

+277
-1
lines changed

compiler/rustc_resolve/messages.ftl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,9 @@ resolve_unexpected_res_use_at_op_in_slice_pat_with_range_sugg =
463463
resolve_unnamed_crate_root_import =
464464
crate root imports need to be explicitly named: `use crate as name;`
465465
466+
resolve_unnamed_imports =
467+
imports need to be explicitly named: `use {$ident} as name;`
468+
466469
resolve_unreachable_label =
467470
use of unreachable label `{$name}`
468471
.label = unreachable label `{$name}`

compiler/rustc_resolve/src/build_reduced_graph.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,47 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
595595
}
596596
}
597597
} else {
598-
// Disallow `self`
598+
match source.ident.name {
599+
// Only allow `use crate as name;`
600+
kw::Crate => {
601+
if !module_path.is_empty() {
602+
self.r.dcx().span_err(
603+
ident.span,
604+
"`crate` in paths can only be used in start position",
605+
);
606+
return;
607+
}
608+
609+
if rename.is_none() {
610+
self.r
611+
.dcx()
612+
.emit_err(errors::UnnamedCrateRootImport { span: ident.span });
613+
return;
614+
}
615+
}
616+
kw::Super => {
617+
if !module_path.is_empty() {
618+
self.r.dcx().span_err(
619+
ident.span,
620+
"`super` in paths can only be used in start position",
621+
);
622+
return;
623+
}
624+
625+
if rename.is_none() {
626+
self.r
627+
.dcx()
628+
.emit_err(errors::UnnamedImports { span: ident.span, ident });
629+
return;
630+
}
631+
632+
type_ns_only = true;
633+
}
634+
kw::SelfLower => {}
635+
kw::DollarCrate => {}
636+
_ => {}
637+
}
638+
599639
if source.ident.name == kw::SelfLower {
600640
let parent = module_path.last();
601641

@@ -707,6 +747,12 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
707747
}
708748

709749
e.emit();
750+
} else if let &[self_span] = &self_spans[..]
751+
&& prefix.len() == 1
752+
&& prefix[0].ident.name == kw::DollarCrate
753+
{
754+
// Disallow `use $crate::{self};`
755+
self.r.dcx().emit_err(errors::CrateImported { span: self_span });
710756
}
711757

712758
for &(ref tree, id) in items {

compiler/rustc_resolve/src/errors.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,14 @@ pub(crate) struct UnnamedCrateRootImport {
898898
pub(crate) span: Span,
899899
}
900900

901+
#[derive(Diagnostic)]
902+
#[diag(resolve_unnamed_imports)]
903+
pub(crate) struct UnnamedImports {
904+
#[primary_span]
905+
pub(crate) span: Span,
906+
pub(crate) ident: Ident,
907+
}
908+
901909
#[derive(Diagnostic)]
902910
#[diag(resolve_macro_expanded_extern_crate_cannot_shadow_extern_arguments)]
903911
pub(crate) struct MacroExpandedExternCrateCannotShadowExternArguments {

compiler/rustc_resolve/src/ident.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
869869
// FIXME: Implement these with renaming requirements so that e.g.
870870
// `use super;` doesn't work, but `use super as name;` does.
871871
// Fall through here to get an error from `early_resolve_...`.
872+
873+
if ident.name == kw::Super {
874+
if let Some(parent) = parent_scope.module.parent {
875+
return Ok(parent.self_binding.unwrap());
876+
}
877+
} else {
878+
return Ok(parent_scope.module.self_binding.unwrap());
879+
}
872880
}
873881
}
874882

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
macro_rules! foo {
2+
() => {
3+
use $crate::{self}; //~ ERROR `$crate` may not be imported
4+
};
5+
}
6+
7+
foo!();
8+
9+
fn main() {}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error: `$crate` may not be imported
2+
--> $DIR/use-dollar-crate-self.rs:3:22
3+
|
4+
LL | use $crate::{self};
5+
| ^^^^
6+
...
7+
LL | foo!();
8+
| ------ in this macro invocation
9+
|
10+
= note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
11+
12+
error: aborting due to 1 previous error
13+
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// mod x {
2+
// use super; // bad
3+
// use super as name; // good
4+
// use self; // bad
5+
// use self as name; // good
6+
// use crate; // bad
7+
// use crate as name; // good
8+
// use $crate; // bad
9+
// use $crate as name; // good
10+
11+
// mod foo;
12+
// use foo::crate; // bad
13+
// use crate::crate; // bad
14+
// use foo::super; // bad
15+
// use super::super; // bad
16+
// use foo::self; // good
17+
// use self::self; // bad
18+
// use self::self as name; // good
19+
// }
20+
21+
fn bar() {}
22+
23+
mod foo {
24+
mod bar {}
25+
26+
use crate as _crate; // good
27+
use crate; // bad
28+
use ::crate; // bad
29+
use bar::crate; // bad
30+
use crate::crate; // bad
31+
use super::crate; // bad
32+
use self::crate; // bad
33+
use ::crate as _crate2; // bad
34+
use bar::crate as _crate3; // bad
35+
use crate::crate as _crate4; // bad
36+
use super::crate as _crate5; // bad
37+
use self::crate as _crate6; // bad
38+
39+
pub use super as _super; // good
40+
use super; // bad
41+
use ::super; // bad
42+
use bar::super; // bad
43+
use crate::super; // bad
44+
use super::super; // bad
45+
use self::super; // bad
46+
use ::super as _super2; // bad
47+
use bar::super as _super3; // bad
48+
use crate::super as _super4; // bad
49+
use super::super as _super5; // bad
50+
use bar::super as _super6; // bad
51+
}
52+
53+
fn main() {
54+
foo::_super::bar();
55+
}
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
error: crate root imports need to be explicitly named: `use crate as name;`
2+
--> $DIR/use-path-segment-kw.rs:27:9
3+
|
4+
LL | use crate; // bad
5+
| ^^^^^
6+
7+
error: `crate` in paths can only be used in start position
8+
--> $DIR/use-path-segment-kw.rs:28:11
9+
|
10+
LL | use ::crate; // bad
11+
| ^^^^^
12+
13+
error: `crate` in paths can only be used in start position
14+
--> $DIR/use-path-segment-kw.rs:29:14
15+
|
16+
LL | use bar::crate; // bad
17+
| ^^^^^
18+
19+
error: `crate` in paths can only be used in start position
20+
--> $DIR/use-path-segment-kw.rs:30:16
21+
|
22+
LL | use crate::crate; // bad
23+
| ^^^^^
24+
25+
error: `crate` in paths can only be used in start position
26+
--> $DIR/use-path-segment-kw.rs:31:16
27+
|
28+
LL | use super::crate; // bad
29+
| ^^^^^
30+
31+
error: `crate` in paths can only be used in start position
32+
--> $DIR/use-path-segment-kw.rs:32:15
33+
|
34+
LL | use self::crate; // bad
35+
| ^^^^^
36+
37+
error: `crate` in paths can only be used in start position
38+
--> $DIR/use-path-segment-kw.rs:33:20
39+
|
40+
LL | use ::crate as _crate2; // bad
41+
| ^^^^^^^
42+
43+
error: `crate` in paths can only be used in start position
44+
--> $DIR/use-path-segment-kw.rs:34:23
45+
|
46+
LL | use bar::crate as _crate3; // bad
47+
| ^^^^^^^
48+
49+
error: `crate` in paths can only be used in start position
50+
--> $DIR/use-path-segment-kw.rs:35:25
51+
|
52+
LL | use crate::crate as _crate4; // bad
53+
| ^^^^^^^
54+
55+
error: `crate` in paths can only be used in start position
56+
--> $DIR/use-path-segment-kw.rs:36:25
57+
|
58+
LL | use super::crate as _crate5; // bad
59+
| ^^^^^^^
60+
61+
error: `crate` in paths can only be used in start position
62+
--> $DIR/use-path-segment-kw.rs:37:24
63+
|
64+
LL | use self::crate as _crate6; // bad
65+
| ^^^^^^^
66+
67+
error: imports need to be explicitly named: `use super as name;`
68+
--> $DIR/use-path-segment-kw.rs:40:9
69+
|
70+
LL | use super; // bad
71+
| ^^^^^
72+
73+
error: `super` in paths can only be used in start position
74+
--> $DIR/use-path-segment-kw.rs:41:11
75+
|
76+
LL | use ::super; // bad
77+
| ^^^^^
78+
79+
error: `super` in paths can only be used in start position
80+
--> $DIR/use-path-segment-kw.rs:42:14
81+
|
82+
LL | use bar::super; // bad
83+
| ^^^^^
84+
85+
error: `super` in paths can only be used in start position
86+
--> $DIR/use-path-segment-kw.rs:43:16
87+
|
88+
LL | use crate::super; // bad
89+
| ^^^^^
90+
91+
error: `super` in paths can only be used in start position
92+
--> $DIR/use-path-segment-kw.rs:44:16
93+
|
94+
LL | use super::super; // bad
95+
| ^^^^^
96+
97+
error: `super` in paths can only be used in start position
98+
--> $DIR/use-path-segment-kw.rs:45:15
99+
|
100+
LL | use self::super; // bad
101+
| ^^^^^
102+
103+
error: `super` in paths can only be used in start position
104+
--> $DIR/use-path-segment-kw.rs:46:20
105+
|
106+
LL | use ::super as _super2; // bad
107+
| ^^^^^^^
108+
109+
error: `super` in paths can only be used in start position
110+
--> $DIR/use-path-segment-kw.rs:47:23
111+
|
112+
LL | use bar::super as _super3; // bad
113+
| ^^^^^^^
114+
115+
error: `super` in paths can only be used in start position
116+
--> $DIR/use-path-segment-kw.rs:48:25
117+
|
118+
LL | use crate::super as _super4; // bad
119+
| ^^^^^^^
120+
121+
error: `super` in paths can only be used in start position
122+
--> $DIR/use-path-segment-kw.rs:49:25
123+
|
124+
LL | use super::super as _super5; // bad
125+
| ^^^^^^^
126+
127+
error: `super` in paths can only be used in start position
128+
--> $DIR/use-path-segment-kw.rs:50:23
129+
|
130+
LL | use bar::super as _super6; // bad
131+
| ^^^^^^^
132+
133+
error: aborting due to 22 previous errors
134+

0 commit comments

Comments
 (0)