Skip to content

Commit bd4a554

Browse files
committed
resolve: Fallback to extern crates in absolute paths on 2015 edition
1 parent f613dc1 commit bd4a554

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+102
-199
lines changed

src/librustc_resolve/build_reduced_graph.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,7 @@ impl<'a> Resolver<'a> {
129129
// get crate root prepended, but get special treatment during in-scope resolution instead.
130130
let is_glob = if let ast::UseTreeKind::Glob = use_tree.kind { true } else { false };
131131
let crate_root = match prefix_iter.peek() {
132-
Some(seg) if !seg.ident.is_path_segment_keyword() &&
133-
seg.ident.span.rust_2015() && self.session.rust_2015() => {
132+
Some(seg) if !seg.ident.is_path_segment_keyword() && seg.ident.span.rust_2015() => {
134133
Some(seg.ident.span.ctxt())
135134
}
136135
None if is_glob && use_tree.span.rust_2015() => {

src/librustc_resolve/lib.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,7 +1243,7 @@ struct UseError<'a> {
12431243
#[derive(Clone, Copy, PartialEq, Debug)]
12441244
enum AmbiguityKind {
12451245
Import,
1246-
AbsolutePath,
1246+
// AbsolutePath,
12471247
BuiltinAttr,
12481248
DeriveHelper,
12491249
LegacyHelperVsPrelude,
@@ -1259,8 +1259,8 @@ impl AmbiguityKind {
12591259
match self {
12601260
AmbiguityKind::Import =>
12611261
"name vs any other name during import resolution",
1262-
AmbiguityKind::AbsolutePath =>
1263-
"name in the crate root vs extern crate during absolute path resolution",
1262+
// AmbiguityKind::AbsolutePath =>
1263+
// "name in the crate root vs extern crate during absolute path resolution",
12641264
AmbiguityKind::BuiltinAttr =>
12651265
"built-in attribute vs any other name",
12661266
AmbiguityKind::DeriveHelper =>
@@ -1513,6 +1513,8 @@ pub struct Resolver<'a> {
15131513
/// FIXME: Refactor things so that these fields are passed through arguments and not resolver.
15141514
/// We are resolving a last import segment during import validation.
15151515
last_import_segment: bool,
1516+
/// We are resolving a prefix for `use *` or `use ::*` on 2015 edition.
1517+
root_glob_import: bool,
15161518
/// This binding should be ignored during in-module resolution, so that we don't get
15171519
/// "self-confirming" import resolutions during import validation.
15181520
blacklisted_binding: Option<&'a NameBinding<'a>>,
@@ -1861,6 +1863,7 @@ impl<'a> Resolver<'a> {
18611863
current_self_type: None,
18621864
current_self_item: None,
18631865
last_import_segment: false,
1866+
root_glob_import: false,
18641867
blacklisted_binding: None,
18651868

18661869
primitive_type_table: PrimitiveTypeTable::new(),
@@ -3833,19 +3836,17 @@ impl<'a> Resolver<'a> {
38333836
self.resolve_self(&mut ctxt, self.current_module)));
38343837
continue;
38353838
}
3836-
if name == keywords::PathRoot.name() && ident.span.rust_2018() {
3837-
module = Some(ModuleOrUniformRoot::ExternPrelude);
3838-
continue;
3839-
}
3840-
if name == keywords::PathRoot.name() &&
3841-
ident.span.rust_2015() && self.session.rust_2018() {
3842-
// `::a::b` from 2015 macro on 2018 global edition
3843-
module = Some(ModuleOrUniformRoot::CrateRootAndExternPrelude);
3839+
if name == keywords::PathRoot.name() {
3840+
module = Some(if ident.span.rust_2018() {
3841+
ModuleOrUniformRoot::ExternPrelude
3842+
} else if !self.root_glob_import {
3843+
ModuleOrUniformRoot::CrateRootAndExternPrelude
3844+
} else {
3845+
ModuleOrUniformRoot::Module(self.resolve_crate_root(ident))
3846+
});
38443847
continue;
38453848
}
3846-
if name == keywords::PathRoot.name() ||
3847-
name == keywords::Crate.name() ||
3848-
name == keywords::DollarCrate.name() {
3849+
if name == keywords::Crate.name() || name == keywords::DollarCrate.name() {
38493850
// `::a::b`, `crate::a::b` or `$crate::a::b`
38503851
module = Some(ModuleOrUniformRoot::Module(
38513852
self.resolve_crate_root(ident)));

src/librustc_resolve/macros.rs

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -709,8 +709,6 @@ impl<'a> Resolver<'a> {
709709

710710
let ambiguity_error_kind = if is_import {
711711
Some(AmbiguityKind::Import)
712-
} else if is_absolute_path {
713-
Some(AmbiguityKind::AbsolutePath)
714712
} else if innermost_def == builtin || def == builtin {
715713
Some(AmbiguityKind::BuiltinAttr)
716714
} else if innermost_def == derive_helper || def == derive_helper {
@@ -824,44 +822,7 @@ impl<'a> Resolver<'a> {
824822
}
825823

826824
// The first found solution was the only one, return it.
827-
if let Some((binding, flags)) = innermost_result {
828-
// We get to here only if there's no ambiguity, in ambiguous cases an error will
829-
// be reported anyway, so there's no reason to report an additional feature error.
830-
// The `binding` can actually be introduced by something other than `--extern`,
831-
// but its `Def` should coincide with a crate passed with `--extern`
832-
// (otherwise there would be ambiguity) and we can skip feature error in this case.
833-
'ok: {
834-
if !is_import || !rust_2015 {
835-
break 'ok;
836-
}
837-
if ns == TypeNS && use_prelude && self.extern_prelude_get(ident, true).is_some() {
838-
break 'ok;
839-
}
840-
let root_ident = Ident::new(keywords::PathRoot.name(), orig_ident.span);
841-
let root_module = self.resolve_crate_root(root_ident);
842-
if self.resolve_ident_in_module_ext(ModuleOrUniformRoot::Module(root_module),
843-
orig_ident, ns, None, false, path_span)
844-
.is_ok() {
845-
break 'ok;
846-
}
847-
848-
let msg = "imports can only refer to extern crate names passed with \
849-
`--extern` in macros originating from 2015 edition";
850-
let mut err = self.session.struct_span_err(ident.span, msg);
851-
let what = self.binding_description(binding, ident,
852-
flags.contains(Flags::MISC_FROM_PRELUDE));
853-
let note_msg = format!("this import refers to {what}", what = what);
854-
let label_span = if binding.span.is_dummy() {
855-
err.note(&note_msg);
856-
ident.span
857-
} else {
858-
err.span_note(binding.span, &note_msg);
859-
binding.span
860-
};
861-
err.span_label(label_span, "not an extern crate passed with `--extern`");
862-
err.emit();
863-
}
864-
825+
if let Some((binding, _)) = innermost_result {
865826
return Ok(binding);
866827
}
867828

src/librustc_resolve/resolve_imports.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,9 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
765765
} else {
766766
// For better failure detection, pretend that the import will
767767
// not define any names while resolving its module path.
768+
let orig_root_glob_import = mem::replace(
769+
&mut self.root_glob_import, directive.is_glob() && directive.module_path.len() == 1
770+
);
768771
let orig_vis = directive.vis.replace(ty::Visibility::Invisible);
769772
let path_res = self.resolve_path(
770773
&directive.module_path,
@@ -775,6 +778,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
775778
directive.crate_lint(),
776779
);
777780
directive.vis.set(orig_vis);
781+
self.root_glob_import = orig_root_glob_import;
778782

779783
match path_res {
780784
PathResult::Module(module) => module,
@@ -850,12 +854,16 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
850854
) -> Option<(Span, String, Option<String>)> {
851855
self.current_module = directive.parent_scope.module;
852856

857+
let orig_root_glob_import = mem::replace(
858+
&mut self.root_glob_import, directive.is_glob() && directive.module_path.len() == 1
859+
);
853860
let orig_vis = directive.vis.replace(ty::Visibility::Invisible);
854861
let prev_ambiguity_errors_len = self.ambiguity_errors.len();
855862
let path_res = self.resolve_path(&directive.module_path, None, &directive.parent_scope,
856863
true, directive.span, directive.crate_lint());
857864
let no_ambiguity = self.ambiguity_errors.len() == prev_ambiguity_errors_len;
858865
directive.vis.set(orig_vis);
866+
self.root_glob_import = orig_root_glob_import;
859867
let module = match path_res {
860868
PathResult::Module(module) => {
861869
// Consistency checks, analogous to `finalize_current_module_macro_resolutions`.

src/test/run-make-fulldeps/extern-prelude/Makefile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,4 @@ all:
77
$(RUSTC) basic.rs --extern ep_lib=$(TMPDIR)/libep_lib.rlib
88
$(RUSTC) shadow-mod.rs --extern ep_lib=$(TMPDIR)/libep_lib.rlib
99
$(RUSTC) shadow-prelude.rs --extern Vec=$(TMPDIR)/libep_vec.rlib
10-
$(RUSTC) relative-only.rs --extern ep_lib=$(TMPDIR)/libep_lib.rlib 2>&1 | $(CGREP) "unresolved import"
11-
$(RUSTC) relative-only.rs --extern ep_lib=$(TMPDIR)/libep_lib.rlib 2>&1 | $(CGREP) "failed to resolve"
10+
$(RUSTC) relative-only.rs --extern ep_lib=$(TMPDIR)/libep_lib.rlib

src/test/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ error[E0432]: unresolved import `Foo`
22
--> $DIR/issue-38054-do-not-show-unresolved-names.rs:1:5
33
|
44
LL | use Foo; //~ ERROR unresolved
5-
| ^^^ no `Foo` in the root
5+
| ^^^ no `Foo` external crate
66

77
error[E0432]: unresolved import `Foo1`
88
--> $DIR/issue-38054-do-not-show-unresolved-names.rs:3:5
99
|
1010
LL | use Foo1; //~ ERROR unresolved
11-
| ^^^^ no `Foo1` in the root
11+
| ^^^^ no `Foo1` external crate
1212

1313
error: aborting due to 2 previous errors
1414

src/test/ui/editions/edition-imports-2018.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// compile-pass
12
// edition:2018
23
// aux-build:edition-imports-2015.rs
34

@@ -21,7 +22,7 @@ mod check {
2122
}
2223

2324
mod check_glob {
24-
gen_glob!(); //~ ERROR cannot glob-import all possible crates
25+
gen_glob!(); // OK
2526
}
2627

2728
fn main() {}

src/test/ui/editions/edition-imports-2018.stderr

Lines changed: 0 additions & 10 deletions
This file was deleted.

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

Lines changed: 2 additions & 2 deletions
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!();
1717
}
1818
}
1919

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

Lines changed: 0 additions & 40 deletions
This file was deleted.

0 commit comments

Comments
 (0)