Skip to content

Commit 8bf1f1c

Browse files
committed
Auto merge of #58349 - petrochenkov:uni201x, r=pnkfelix
resolve: Simplify import resolution for mixed 2015/2018 edition mode Non-controversial part of #57745. Before: | Local edition (per-span) | Global edition (--edition) | Imports (`use foo;`) | Absolute paths (`::foo`) | | ------------- |----------------|-----------------------------------------|------------------------------------------------| | 2018 | Any | Uniform | Extern prelude | | 2015 | 2015 | Crate-relative | Crate-relative | | 2015 | 2018 | Crate-relative with fallback to Uniform (future-proofed to error if the result is not Crate-relative or from Extern prelude) | Crate-relative with fallback to Extern prelude | After: | Local edition (per-span) | Global edition (--edition) | Imports (`use foo;`) | Absolute paths (`::foo`) | | ------------- |----------------|-----------------------------------------|------------------------------------------------| | 2018 | Any | Uniform | Extern prelude | | 2015 | 2015 | Crate-relative | Crate-relative | | 2015 | 2018 | Crate-relative with fallback to Extern prelude | Crate-relative with fallback to Extern prelude | I.e. only the behavior of the mixed local-2015-global-2018 mode is changed. This mixed mode has two goals: - Address regressions from #56053 (comment). Both "before" and "after" variants address those regressions. - Be retrofit-able to "full 2015" edition (#57745). Any more complex fallback scheme (with more candidates) than "Crate-relative with fallback to Extern prelude" will give more regressions than #57745 (comment) and is therefore less retrofit-able while also being, well, more complex. So, we can settle on "Crate-relative with fallback to Extern prelude". (I'll hopefully proceed with #57745 after mid-February.) r? @Centril
2 parents cf6d881 + 1d6f4d6 commit 8bf1f1c

7 files changed

+11
-111
lines changed

src/librustc_resolve/build_reduced_graph.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,9 @@ impl<'a> Resolver<'a> {
131131
// so prefixes are prepended with crate root segment if necessary.
132132
// The root is prepended lazily, when the first non-empty prefix or terminating glob
133133
// appears, so imports in braced groups can have roots prepended independently.
134-
// 2015 identifiers used on global 2018 edition enter special "virtual 2015 mode", don't
135-
// get crate root prepended, but get special treatment during in-scope resolution instead.
136134
let is_glob = if let ast::UseTreeKind::Glob = use_tree.kind { true } else { false };
137135
let crate_root = match prefix_iter.peek() {
138-
Some(seg) if !seg.ident.is_path_segment_keyword() &&
139-
seg.ident.span.rust_2015() && self.session.rust_2015() => {
136+
Some(seg) if !seg.ident.is_path_segment_keyword() && seg.ident.span.rust_2015() => {
140137
Some(seg.ident.span.ctxt())
141138
}
142139
None if is_glob && use_tree.span.rust_2015() => {

src/librustc_resolve/lib.rs

-3
Original file line numberDiff line numberDiff line change
@@ -1273,7 +1273,6 @@ struct UseError<'a> {
12731273
#[derive(Clone, Copy, PartialEq, Debug)]
12741274
enum AmbiguityKind {
12751275
Import,
1276-
AbsolutePath,
12771276
BuiltinAttr,
12781277
DeriveHelper,
12791278
LegacyHelperVsPrelude,
@@ -1289,8 +1288,6 @@ impl AmbiguityKind {
12891288
match self {
12901289
AmbiguityKind::Import =>
12911290
"name vs any other name during import resolution",
1292-
AmbiguityKind::AbsolutePath =>
1293-
"name in the crate root vs extern crate during absolute path resolution",
12941291
AmbiguityKind::BuiltinAttr =>
12951292
"built-in attribute vs any other name",
12961293
AmbiguityKind::DeriveHelper =>

src/librustc_resolve/macros.rs

+3-47
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ impl<'a> Resolver<'a> {
572572
ScopeSet::Module => (TypeNS, None, false, false),
573573
};
574574
let mut where_to_resolve = match ns {
575-
_ if is_absolute_path || is_import && rust_2015 => WhereToResolve::CrateRoot,
575+
_ if is_absolute_path => WhereToResolve::CrateRoot,
576576
TypeNS | ValueNS => WhereToResolve::Module(parent_scope.module),
577577
MacroNS => WhereToResolve::DeriveHelpers,
578578
};
@@ -770,8 +770,6 @@ impl<'a> Resolver<'a> {
770770

771771
let ambiguity_error_kind = if is_import {
772772
Some(AmbiguityKind::Import)
773-
} else if is_absolute_path {
774-
Some(AmbiguityKind::AbsolutePath)
775773
} else if innermost_def == builtin || def == builtin {
776774
Some(AmbiguityKind::BuiltinAttr)
777775
} else if innermost_def == derive_helper || def == derive_helper {
@@ -841,18 +839,13 @@ impl<'a> Resolver<'a> {
841839
LegacyScope::Empty => WhereToResolve::Module(parent_scope.module),
842840
LegacyScope::Uninitialized => unreachable!(),
843841
}
844-
WhereToResolve::CrateRoot if is_import => match ns {
845-
TypeNS | ValueNS => WhereToResolve::Module(parent_scope.module),
846-
MacroNS => WhereToResolve::DeriveHelpers,
847-
}
848-
WhereToResolve::CrateRoot if is_absolute_path => match ns {
842+
WhereToResolve::CrateRoot => match ns {
849843
TypeNS => {
850844
ident.span.adjust(Mark::root());
851845
WhereToResolve::ExternPrelude
852846
}
853847
ValueNS | MacroNS => break,
854848
}
855-
WhereToResolve::CrateRoot => unreachable!(),
856849
WhereToResolve::Module(module) => {
857850
match self.hygienic_lexical_parent(module, &mut ident.span) {
858851
Some(parent_module) => WhereToResolve::Module(parent_module),
@@ -885,44 +878,7 @@ impl<'a> Resolver<'a> {
885878
}
886879

887880
// The first found solution was the only one, return it.
888-
if let Some((binding, flags)) = innermost_result {
889-
// We get to here only if there's no ambiguity, in ambiguous cases an error will
890-
// be reported anyway, so there's no reason to report an additional feature error.
891-
// The `binding` can actually be introduced by something other than `--extern`,
892-
// but its `Def` should coincide with a crate passed with `--extern`
893-
// (otherwise there would be ambiguity) and we can skip feature error in this case.
894-
'ok: {
895-
if !is_import || !rust_2015 {
896-
break 'ok;
897-
}
898-
if ns == TypeNS && use_prelude && self.extern_prelude_get(ident, true).is_some() {
899-
break 'ok;
900-
}
901-
let root_ident = Ident::new(keywords::PathRoot.name(), orig_ident.span);
902-
let root_module = self.resolve_crate_root(root_ident);
903-
if self.resolve_ident_in_module_ext(ModuleOrUniformRoot::Module(root_module),
904-
orig_ident, ns, None, false, path_span)
905-
.is_ok() {
906-
break 'ok;
907-
}
908-
909-
let msg = "imports can only refer to extern crate names passed with \
910-
`--extern` in macros originating from 2015 edition";
911-
let mut err = self.session.struct_span_err(ident.span, msg);
912-
let what = self.binding_description(binding, ident,
913-
flags.contains(Flags::MISC_FROM_PRELUDE));
914-
let note_msg = format!("this import refers to {what}", what = what);
915-
let label_span = if binding.span.is_dummy() {
916-
err.note(&note_msg);
917-
ident.span
918-
} else {
919-
err.span_note(binding.span, &note_msg);
920-
binding.span
921-
};
922-
err.span_label(label_span, "not an extern crate passed with `--extern`");
923-
err.emit();
924-
}
925-
881+
if let Some((binding, _)) = innermost_result {
926882
return Ok(binding);
927883
}
928884

src/test/ui/editions/edition-imports-virtual-2015-ambiguity.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// compile-pass
12
// edition:2018
23
// compile-flags:--extern edition_imports_2015
34
// aux-build:edition-imports-2015.rs
@@ -12,8 +13,7 @@ mod check {
1213
pub struct Ambiguous {}
1314

1415
fn check() {
15-
edition_imports_2015::gen_ambiguous!(); //~ ERROR `Ambiguous` is ambiguous
16-
//~| ERROR `edition_imports_2015` is ambiguous
16+
edition_imports_2015::gen_ambiguous!(); // OK
1717
}
1818
}
1919

src/test/ui/editions/edition-imports-virtual-2015-ambiguity.stderr

-40
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
// edition:2018
22
// aux-build:edition-imports-2015.rs
3-
// error-pattern: imports can only refer to extern crate names passed with `--extern`
43

54
#[macro_use]
65
extern crate edition_imports_2015;
76

87
mod check {
9-
gen_gated!();
8+
gen_gated!(); //~ ERROR unresolved import `E`
109
}
1110

1211
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,11 @@
1-
error: imports can only refer to extern crate names passed with `--extern` in macros originating from 2015 edition
2-
--> <::edition_imports_2015::gen_gated macros>:1:50
3-
|
4-
LL | ( ) => { fn check_gated ( ) { enum E { A } use E :: * ; } }
5-
| ^
6-
|
7-
::: $DIR/edition-imports-virtual-2015-gated.rs:9:5
1+
error[E0432]: unresolved import `E`
2+
--> $DIR/edition-imports-virtual-2015-gated.rs:8:5
83
|
94
LL | gen_gated!();
10-
| ------------- not an extern crate passed with `--extern`
11-
|
12-
note: this import refers to the enum defined here
13-
--> $DIR/edition-imports-virtual-2015-gated.rs:9:5
5+
| ^^^^^^^^^^^^^ could not find `E` in `{{root}}`
146
|
15-
LL | gen_gated!();
16-
| ^^^^^^^^^^^^^
177
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
188

199
error: aborting due to previous error
2010

11+
For more information about this error, try `rustc --explain E0432`.

0 commit comments

Comments
 (0)