Skip to content

Commit aca5e4e

Browse files
committed
WIP: rewrite build_reduced_graph_for_use_tree
1 parent 11d2046 commit aca5e4e

File tree

10 files changed

+355
-93
lines changed

10 files changed

+355
-93
lines changed

compiler/rustc_resolve/messages.ftl

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -381,15 +381,6 @@ resolve_self_import_only_in_import_list_with_non_empty_prefix =
381381
`self` import can only appear in an import list with a non-empty prefix
382382
.label = can only appear in an import list with a non-empty prefix
383383
384-
resolve_self_imports_only_allowed_within =
385-
`self` imports are only allowed within a {"{"} {"}"} list
386-
387-
resolve_self_imports_only_allowed_within_multipart_suggestion =
388-
alternatively, use the multi-path `use` syntax to import `self`
389-
390-
resolve_self_imports_only_allowed_within_suggestion =
391-
consider importing the module directly
392-
393384
resolve_self_in_const_generic_ty =
394385
cannot use `Self` in const parameter type
395386
@@ -463,6 +454,9 @@ resolve_unexpected_res_use_at_op_in_slice_pat_with_range_sugg =
463454
resolve_unnamed_crate_root_import =
464455
crate root imports need to be explicitly named: `use crate as name;`
465456
457+
resolve_unnamed_imports =
458+
imports need to be explicitly named: `use {$ident} as name;`
459+
466460
resolve_unreachable_label =
467461
use of unreachable label `{$name}`
468462
.label = unreachable label `{$name}`

compiler/rustc_resolve/src/build_reduced_graph.rs

Lines changed: 55 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -596,35 +596,59 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
596596
}
597597
}
598598
} else {
599-
// Disallow `self`
600-
if source.ident.name == kw::SelfLower {
601-
let parent = module_path.last();
599+
match source.ident.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+
}
602608

603-
let span = match parent {
604-
// only `::self` from `use foo::self as bar`
605-
Some(seg) => seg.ident.span.shrink_to_hi().to(source.ident.span),
606-
None => source.ident.span,
607-
};
608-
let span_with_rename = match rename {
609-
// only `self as bar` from `use foo::self as bar`
610-
Some(rename) => source.ident.span.to(rename.span),
611-
None => source.ident.span,
612-
};
613-
self.r.report_error(
614-
span,
615-
ResolutionError::SelfImportsOnlyAllowedWithin {
616-
root: parent.is_none(),
617-
span_with_rename,
618-
},
619-
);
620-
621-
// Error recovery: replace `use foo::self;` with `use foo;`
622-
if let Some(parent) = module_path.pop() {
623-
source = parent;
624609
if rename.is_none() {
625-
ident = source.ident;
610+
self.r
611+
.dcx()
612+
.emit_err(errors::UnnamedCrateRootImport { span: ident.span });
613+
return;
626614
}
627615
}
616+
kw::Super => {
617+
if rename.is_none() {
618+
self.r
619+
.dcx()
620+
.emit_err(errors::UnnamedImports { span: ident.span, ident });
621+
return;
622+
}
623+
624+
type_ns_only = true;
625+
}
626+
kw::SelfLower => {
627+
if let Some(parent) = module_path.pop() {
628+
if parent.ident.name.is_path_segment_keyword() && rename.is_none() {
629+
self.r.dcx().emit_err(errors::UnnamedImports {
630+
span: ident.span,
631+
ident,
632+
});
633+
return;
634+
}
635+
636+
let self_span = source.ident.span;
637+
source = parent;
638+
if rename.is_none() {
639+
ident = Ident::new(source.ident.name, self_span);
640+
}
641+
} else if rename.is_none() {
642+
self.r
643+
.dcx()
644+
.emit_err(errors::UnnamedImports { span: ident.span, ident });
645+
return;
646+
}
647+
648+
type_ns_only = true;
649+
}
650+
kw::DollarCrate => {}
651+
_ => {}
628652
}
629653

630654
// Disallow `use $crate;`
@@ -708,6 +732,12 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
708732
}
709733

710734
e.emit();
735+
} else if let &[self_span] = &self_spans[..]
736+
&& prefix.len() == 1
737+
&& prefix[0].ident.name == kw::DollarCrate
738+
{
739+
// Disallow `use $crate::{self};`
740+
self.r.dcx().emit_err(errors::CrateImported { span: self_span });
711741
}
712742

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

compiler/rustc_resolve/src/diagnostics.rs

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -867,29 +867,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
867867
sub_unreachable,
868868
})
869869
}
870-
ResolutionError::SelfImportsOnlyAllowedWithin { root, span_with_rename } => {
871-
// None of the suggestions below would help with a case like `use self`.
872-
let (suggestion, mpart_suggestion) = if root {
873-
(None, None)
874-
} else {
875-
// use foo::bar::self -> foo::bar
876-
// use foo::bar::self as abc -> foo::bar as abc
877-
let suggestion = errs::SelfImportsOnlyAllowedWithinSuggestion { span };
878-
879-
// use foo::bar::self -> foo::bar::{self}
880-
// use foo::bar::self as abc -> foo::bar::{self as abc}
881-
let mpart_suggestion = errs::SelfImportsOnlyAllowedWithinMultipartSuggestion {
882-
multipart_start: span_with_rename.shrink_to_lo(),
883-
multipart_end: span_with_rename.shrink_to_hi(),
884-
};
885-
(Some(suggestion), Some(mpart_suggestion))
886-
};
887-
self.dcx().create_err(errs::SelfImportsOnlyAllowedWithin {
888-
span,
889-
suggestion,
890-
mpart_suggestion,
891-
})
892-
}
893870
ResolutionError::SelfImportCanOnlyAppearOnceInTheList => {
894871
self.dcx().create_err(errs::SelfImportCanOnlyAppearOnceInTheList { span })
895872
}

compiler/rustc_resolve/src/errors.rs

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -272,40 +272,6 @@ pub(crate) struct AttemptToUseNonConstantValueInConstantWithoutSuggestion<'a> {
272272
pub(crate) suggestion: &'a str,
273273
}
274274

275-
#[derive(Diagnostic)]
276-
#[diag(resolve_self_imports_only_allowed_within, code = E0429)]
277-
pub(crate) struct SelfImportsOnlyAllowedWithin {
278-
#[primary_span]
279-
pub(crate) span: Span,
280-
#[subdiagnostic]
281-
pub(crate) suggestion: Option<SelfImportsOnlyAllowedWithinSuggestion>,
282-
#[subdiagnostic]
283-
pub(crate) mpart_suggestion: Option<SelfImportsOnlyAllowedWithinMultipartSuggestion>,
284-
}
285-
286-
#[derive(Subdiagnostic)]
287-
#[suggestion(
288-
resolve_self_imports_only_allowed_within_suggestion,
289-
code = "",
290-
applicability = "machine-applicable"
291-
)]
292-
pub(crate) struct SelfImportsOnlyAllowedWithinSuggestion {
293-
#[primary_span]
294-
pub(crate) span: Span,
295-
}
296-
297-
#[derive(Subdiagnostic)]
298-
#[multipart_suggestion(
299-
resolve_self_imports_only_allowed_within_multipart_suggestion,
300-
applicability = "machine-applicable"
301-
)]
302-
pub(crate) struct SelfImportsOnlyAllowedWithinMultipartSuggestion {
303-
#[suggestion_part(code = "{{")]
304-
pub(crate) multipart_start: Span,
305-
#[suggestion_part(code = "}}")]
306-
pub(crate) multipart_end: Span,
307-
}
308-
309275
#[derive(Diagnostic)]
310276
#[diag(resolve_binding_shadows_something_unacceptable, code = E0530)]
311277
pub(crate) struct BindingShadowsSomethingUnacceptable<'a> {
@@ -898,6 +864,14 @@ pub(crate) struct UnnamedCrateRootImport {
898864
pub(crate) span: Span,
899865
}
900866

867+
#[derive(Diagnostic)]
868+
#[diag(resolve_unnamed_imports)]
869+
pub(crate) struct UnnamedImports {
870+
#[primary_span]
871+
pub(crate) span: Span,
872+
pub(crate) ident: Ident,
873+
}
874+
901875
#[derive(Diagnostic)]
902876
#[diag(resolve_macro_expanded_extern_crate_cannot_shadow_extern_arguments)]
903877
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

compiler/rustc_resolve/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,8 +261,6 @@ enum ResolutionError<'ra> {
261261
IdentifierBoundMoreThanOnceInSamePattern(Ident),
262262
/// Error E0426: use of undeclared label.
263263
UndeclaredLabel { name: Symbol, suggestion: Option<LabelSuggestion> },
264-
/// Error E0429: `self` imports are only allowed within a `{ }` list.
265-
SelfImportsOnlyAllowedWithin { root: bool, span_with_rename: Span },
266264
/// Error E0430: `self` import can only appear once in the list.
267265
SelfImportCanOnlyAppearOnceInTheList,
268266
/// Error E0431: `self` import can only appear in an import list with a non-empty prefix.
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: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
//@ edition: 2021
2+
3+
// mod x {
4+
// use super; // bad
5+
// use super as name; // good
6+
// use self; // bad
7+
// use self as name; // good
8+
// use crate; // bad
9+
// use crate as name; // good
10+
// use $crate; // bad
11+
// use $crate as name; // good
12+
13+
// mod foo;
14+
// use foo::crate; // bad
15+
// use crate::crate; // bad
16+
// use foo::super; // bad
17+
// use super::super; // bad
18+
// use foo::self; // good
19+
// use self::self; // bad
20+
// use self::self as name; // good
21+
// }
22+
23+
fn outer() {}
24+
25+
mod foo {
26+
pub mod bar {
27+
pub mod foobar {
28+
pub mod qux {
29+
pub use super::inner;
30+
}
31+
32+
pub fn inner() {}
33+
}
34+
35+
pub use crate as _crate; // Good
36+
use crate; //~ ERROR crate root imports need to be explicitly named: `use crate as name;`
37+
use ::crate; //~ ERROR `crate` in paths can only be used in start position
38+
use foobar::crate; //~ ERROR `crate` in paths can only be used in start position
39+
use crate::crate; //~ ERROR `crate` in paths can only be used in start position
40+
use super::crate; //~ ERROR `crate` in paths can only be used in start position
41+
use self::crate; //~ ERROR `crate` in paths can only be used in start position
42+
use ::crate as _crate2; //~ ERROR `crate` in paths can only be used in start position
43+
use foobar::crate as _crate3; //~ ERROR `crate` in paths can only be used in start position
44+
use crate::crate as _crate4; //~ ERROR `crate` in paths can only be used in start position
45+
use super::crate as _crate5; //~ ERROR `crate` in paths can only be used in start position
46+
use self::crate as _crate6; //~ ERROR `crate` in paths can only be used in start position
47+
48+
pub use super as _super; // Good
49+
use super; //~ ERROR imports need to be explicitly named: `use super as name;`
50+
use ::super; //~ ERROR imports need to be explicitly named: `use super as name;`
51+
use foobar::super; //~ ERROR imports need to be explicitly named: `use super as name;`
52+
use crate::super; //~ ERROR imports need to be explicitly named: `use super as name;`
53+
use super::super; //~ ERROR imports need to be explicitly named: `use super as name;`
54+
use self::super; //~ ERROR imports need to be explicitly named: `use super as name;`
55+
use ::super as _super2; //~ ERROR unresolved import `super`
56+
use foobar::super as _super3; //~ ERROR unresolved import `foobar::super`
57+
use crate::super as _super4; //~ ERROR unresolved import `crate::super`
58+
use super::super as _super5; //~ ERROR unresolved import `super::super`
59+
use foobar::super as _super6; //~ ERROR unresolved import `foobar::super`
60+
61+
pub use self as _self; // Good
62+
pub use foobar::qux::self; // Good
63+
pub use foobar::self as _self3; // Good
64+
use self; //~ ERROR imports need to be explicitly named: `use self as name;`
65+
use ::self; //~ ERROR imports need to be explicitly named: `use self as name;`
66+
use crate::self; //~ ERROR imports need to be explicitly named: `use self as name;`
67+
use super::self; //~ ERROR imports need to be explicitly named: `use self as name;`
68+
use self::self; //~ ERROR imports need to be explicitly named: `use self as name;`
69+
use ::self as _self2; //~ ERROR unresolved import `{{root}}`
70+
pub use crate::self as _self4;
71+
pub use super::self as _self5;
72+
pub use self::self as _self6;
73+
}
74+
}
75+
76+
fn main() {
77+
foo::bar::_crate::outer();
78+
foo::bar::_crate::foo::bar::foobar::inner();
79+
80+
foo::bar::_super::bar::foobar::inner();
81+
82+
foo::bar::_self::foobar::inner();
83+
foo::bar::qux::inner();
84+
foo::bar::_self3::inner();
85+
foo::bar::_self4::outer();
86+
foo::bar::_self5::bar::foobar::inner();
87+
foo::bar::_self6::foobar::inner();
88+
}

0 commit comments

Comments
 (0)