Skip to content

Commit d0d3a9d

Browse files
committed
WIP: rewrite build_reduced_graph_for_use_tree
1 parent ce6daf3 commit d0d3a9d

File tree

7 files changed

+104
-1
lines changed

7 files changed

+104
-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: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,8 +594,29 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
594594
}
595595
}
596596
} else {
597+
if matches!(source.ident.name, kw::Crate | kw::Super) {
598+
// Disallow `use foo::crate;` and `use crate::crate;`
599+
if !module_path.is_empty() {
600+
// FIXME: use other errors
601+
self.r
602+
.dcx()
603+
.emit_err(errors::UnnamedImports { span: ident.span, ident });
604+
return;
605+
}
606+
607+
// Disallow `use crate;` and `use super;`
608+
if rename.is_none() {
609+
self.r
610+
.dcx()
611+
.emit_err(errors::UnnamedImports { span: ident.span, ident });
612+
return;
613+
}
614+
615+
// Allow `use super as name;`
616+
type_ns_only = true;
617+
}
597618
// Disallow `self`
598-
if source.ident.name == kw::SelfLower {
619+
else if source.ident.name == kw::SelfLower {
599620
let parent = module_path.last();
600621

601622
let span = match parent {
@@ -706,6 +727,12 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
706727
}
707728

708729
e.emit();
730+
} else if let &[self_span] = &self_spans[..]
731+
&& prefix.len() == 1
732+
&& prefix[0].ident.name == kw::DollarCrate
733+
{
734+
// Disallow `use $crate::{self};`
735+
self.r.dcx().emit_err(errors::CrateImported { span: self_span });
709736
}
710737

711738
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
@@ -861,6 +861,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
861861
// FIXME: Implement these with renaming requirements so that e.g.
862862
// `use super;` doesn't work, but `use super as name;` does.
863863
// Fall through here to get an error from `early_resolve_...`.
864+
865+
if ident.name == kw::Super {
866+
if let Some(parent) = parent_scope.module.parent {
867+
return Ok(parent.self_binding.unwrap());
868+
}
869+
} else {
870+
return Ok(parent_scope.module.self_binding.unwrap());
871+
}
864872
}
865873
}
866874

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: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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+
9+
// mod y;
10+
// use y::crate; // bad
11+
// use crate::crate; // bad
12+
13+
// // use $crate; // bad
14+
// // use $crate as name; // good
15+
16+
// // use super::{self}; // bad
17+
// // use super::{self as name}; // good
18+
// // use crate::{self}; // bad
19+
// // use crate::{self as name}; // good
20+
// // use $crate::{self}; // bad
21+
// // use $crate::{self as name}; // good
22+
// }
23+
24+
mod foo {
25+
pub mod foobar {
26+
pub use super as x;
27+
}
28+
pub fn bar() {
29+
println!("hello");
30+
}
31+
}
32+
33+
fn main() {
34+
foo::foobar::x::bar();
35+
}

0 commit comments

Comments
 (0)