Skip to content

Commit b1b06b8

Browse files
authored
Unrolled build for #155137
Rollup merge of #155137 - mu001999-contrib:self-at-end, r=petrochenkov Allow trailing `self` in more contexts Reference PR: - rust-lang/reference#2237 As a follow-up PR to #152996, after this PR: 1. Trailing `self` can appear in paths 2. [E0429](https://doc.rust-lang.org/stable/error_codes/E0429.html#error-code-e0429) will be no longer emitted, `use ...::self [as target];` will be equivalent to `use ...::{self [as target]};` r? petrochenkov
2 parents 52b6e2c + d93395c commit b1b06b8

30 files changed

Lines changed: 742 additions & 1720 deletions

compiler/rustc_error_codes/src/error_codes/E0429.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
#### Note: this error code is no longer emitted by the compiler.
2+
13
The `self` keyword cannot appear alone as the last segment in a `use`
24
declaration.
35

46
Erroneous code example:
57

6-
```compile_fail,E0429
8+
```ignore (error is no longer emitted)
79
use std::fmt::self; // error: `self` imports are only allowed within a { } list
810
```
911

compiler/rustc_resolve/src/build_reduced_graph.rs

Lines changed: 27 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use crate::ref_mut::CmCell;
3737
use crate::{
3838
BindingKey, Decl, DeclData, DeclKind, ExternModule, ExternPreludeEntry, Finalize, IdentKey,
3939
LocalModule, MacroData, Module, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, Res,
40-
ResolutionError, Resolver, Segment, Used, VisResolutionError, errors,
40+
Resolver, Segment, Used, VisResolutionError, errors,
4141
};
4242

4343
impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
@@ -531,18 +531,16 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
531531

532532
self.r.indeterminate_imports.push(import);
533533
match import.kind {
534-
ImportKind::Single { target, type_ns_only, .. } => {
534+
ImportKind::Single { target, .. } => {
535535
// Don't add underscore imports to `single_imports`
536536
// because they cannot define any usable names.
537537
if target.name != kw::Underscore {
538538
self.r.per_ns(|this, ns| {
539-
if !type_ns_only || ns == TypeNS {
540-
let key = BindingKey::new(IdentKey::new(target), ns);
541-
this.resolution_or_default(current_module, key, target.span)
542-
.borrow_mut(this)
543-
.single_imports
544-
.insert(import);
545-
}
539+
let key = BindingKey::new(IdentKey::new(target), ns);
540+
this.resolution_or_default(current_module, key, target.span)
541+
.borrow_mut(this)
542+
.single_imports
543+
.insert(import);
546544
});
547545
}
548546
}
@@ -612,30 +610,8 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
612610
let mut module_path = prefix;
613611
let source = module_path.pop().unwrap();
614612

615-
// `true` for `...::{self [as target]}` imports, `false` otherwise.
616-
let type_ns_only = nested && source.ident.name == kw::SelfLower;
617-
618-
// Suggest `use prefix::{self};` for `use prefix::self;`
619-
if source.ident.name == kw::SelfLower
620-
&& let Some(parent) = module_path.last()
621-
&& !type_ns_only
622-
&& (parent.ident.name != kw::PathRoot
623-
|| self.r.path_root_is_crate_root(parent.ident))
624-
{
625-
let span_with_rename = match rename {
626-
Some(rename) => source.ident.span.to(rename.span),
627-
None => source.ident.span,
628-
};
629-
630-
self.r.report_error(
631-
parent.ident.span.shrink_to_hi().to(source.ident.span),
632-
ResolutionError::SelfImportsOnlyAllowedWithin {
633-
root: parent.ident.name == kw::PathRoot,
634-
span_with_rename,
635-
},
636-
);
637-
}
638-
613+
// If the identifier is `self` without a rename,
614+
// then it is replaced with the parent identifier.
639615
let ident = if source.ident.name == kw::SelfLower
640616
&& rename.is_none()
641617
&& let Some(parent) = module_path.last()
@@ -689,30 +665,36 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
689665
self.r.dcx().span_err(use_tree.span(), "extern prelude cannot be imported");
690666
return;
691667
}
692-
_ => {}
668+
_ => (),
669+
}
670+
671+
// Deny `use ...::self::source [as target];` or `use ...::self::self [as target];`,
672+
// but allow `use self::source [as target];` and `use self::self as target;`.
673+
if let Some(parent) = module_path.last()
674+
&& parent.ident.name == kw::SelfLower
675+
&& module_path.len() > 1
676+
{
677+
self.r.dcx().span_err(
678+
parent.ident.span,
679+
"`self` in paths can only be used in start position or last position",
680+
);
681+
return;
693682
}
694683

695684
// Deny importing path-kw without renaming
696685
if rename.is_none() && ident.is_path_segment_keyword() {
697686
let ident = use_tree.ident();
698-
699-
// Don't suggest `use xx::self as name;` for `use xx::self;`
700-
// But it's OK to suggest `use xx::{self as name};` for `use xx::{self};`
701-
let sugg = if !type_ns_only && ident.name == kw::SelfLower {
702-
None
703-
} else {
704-
Some(errors::UnnamedImportSugg { span: ident.span, ident })
705-
};
706-
707-
self.r.dcx().emit_err(errors::UnnamedImport { span: ident.span, sugg });
687+
self.r.dcx().emit_err(errors::UnnamedImport {
688+
span: ident.span,
689+
sugg: errors::UnnamedImportSugg { span: ident.span, ident },
690+
});
708691
return;
709692
}
710693

711694
let kind = ImportKind::Single {
712695
source: source.ident,
713696
target: ident,
714697
decls: Default::default(),
715-
type_ns_only,
716698
nested,
717699
id,
718700
};

compiler/rustc_resolve/src/diagnostics.rs

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -386,9 +386,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
386386
let mut suggestion = None;
387387
let mut span = binding_span;
388388
match import.kind {
389-
ImportKind::Single { type_ns_only: true, .. } => {
390-
suggestion = Some(format!("self as {suggested_name}"))
391-
}
392389
ImportKind::Single { source, .. } => {
393390
if let Some(pos) = source.span.hi().0.checked_sub(binding_span.lo().0)
394391
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(binding_span)
@@ -913,29 +910,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
913910
sub_unreachable,
914911
})
915912
}
916-
ResolutionError::SelfImportsOnlyAllowedWithin { root, span_with_rename } => {
917-
// None of the suggestions below would help with a case like `use self`.
918-
let (suggestion, mpart_suggestion) = if root {
919-
(None, None)
920-
} else {
921-
// use foo::bar::self -> foo::bar
922-
// use foo::bar::self as abc -> foo::bar as abc
923-
let suggestion = errs::SelfImportsOnlyAllowedWithinSuggestion { span };
924-
925-
// use foo::bar::self -> foo::bar::{self}
926-
// use foo::bar::self as abc -> foo::bar::{self as abc}
927-
let mpart_suggestion = errs::SelfImportsOnlyAllowedWithinMultipartSuggestion {
928-
multipart_start: span_with_rename.shrink_to_lo(),
929-
multipart_end: span_with_rename.shrink_to_hi(),
930-
};
931-
(Some(suggestion), Some(mpart_suggestion))
932-
};
933-
self.dcx().create_err(errs::SelfImportsOnlyAllowedWithin {
934-
span,
935-
suggestion,
936-
mpart_suggestion,
937-
})
938-
}
939913
ResolutionError::FailedToResolve { segment, label, suggestion, module, message } => {
940914
let mut err = struct_span_code_err!(self.dcx(), span, E0433, "{message}");
941915
err.span_label(span, label);

compiler/rustc_resolve/src/errors.rs

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -301,40 +301,6 @@ pub(crate) struct AttemptToUseNonConstantValueInConstantWithoutSuggestion<'a> {
301301
pub(crate) suggestion: &'a str,
302302
}
303303

304-
#[derive(Diagnostic)]
305-
#[diag("`self` imports are only allowed within a {\"{\"} {\"}\"} list", code = E0429)]
306-
pub(crate) struct SelfImportsOnlyAllowedWithin {
307-
#[primary_span]
308-
pub(crate) span: Span,
309-
#[subdiagnostic]
310-
pub(crate) suggestion: Option<SelfImportsOnlyAllowedWithinSuggestion>,
311-
#[subdiagnostic]
312-
pub(crate) mpart_suggestion: Option<SelfImportsOnlyAllowedWithinMultipartSuggestion>,
313-
}
314-
315-
#[derive(Subdiagnostic)]
316-
#[suggestion(
317-
"consider importing the module directly",
318-
code = "",
319-
applicability = "machine-applicable"
320-
)]
321-
pub(crate) struct SelfImportsOnlyAllowedWithinSuggestion {
322-
#[primary_span]
323-
pub(crate) span: Span,
324-
}
325-
326-
#[derive(Subdiagnostic)]
327-
#[multipart_suggestion(
328-
"alternatively, use the multi-path `use` syntax to import `self`",
329-
applicability = "machine-applicable"
330-
)]
331-
pub(crate) struct SelfImportsOnlyAllowedWithinMultipartSuggestion {
332-
#[suggestion_part(code = "{{")]
333-
pub(crate) multipart_start: Span,
334-
#[suggestion_part(code = "}}")]
335-
pub(crate) multipart_end: Span,
336-
}
337-
338304
#[derive(Diagnostic)]
339305
#[diag("{$shadowing_binding}s cannot shadow {$shadowed_binding}s", code = E0530)]
340306
pub(crate) struct BindingShadowsSomethingUnacceptable<'a> {
@@ -998,7 +964,7 @@ pub(crate) struct UnnamedImport {
998964
#[primary_span]
999965
pub(crate) span: Span,
1000966
#[subdiagnostic]
1001-
pub(crate) sugg: Option<UnnamedImportSugg>,
967+
pub(crate) sugg: UnnamedImportSugg,
1002968
}
1003969

1004970
#[derive(Diagnostic)]

compiler/rustc_resolve/src/ident.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1837,8 +1837,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
18371837
}
18381838
}
18391839

1840+
let allow_trailing_self = is_last && name == kw::SelfLower;
1841+
18401842
// Report special messages for path segment keywords in wrong positions.
1841-
if ident.is_path_segment_keyword() && segment_idx != 0 {
1843+
if ident.is_path_segment_keyword() && segment_idx != 0 && !allow_trailing_self {
18421844
return PathResult::failed(
18431845
ident,
18441846
false,
@@ -1858,6 +1860,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
18581860
format!("global paths cannot start with {name_str}"),
18591861
"cannot start with this".to_string(),
18601862
)
1863+
} else if name == kw::SelfLower {
1864+
(
1865+
format!(
1866+
"`self` in paths can only be used in start position or last position"
1867+
),
1868+
"can only be used in path start position or last position"
1869+
.to_string(),
1870+
)
18611871
} else {
18621872
(
18631873
format!("{name_str} in paths can only be used in start position"),

0 commit comments

Comments
 (0)