Skip to content

Commit

Permalink
Auto merge of #54005 - eddyb:uniform-paths-self-resolve, r=petrochenkov
Browse files Browse the repository at this point in the history
rustc_resolve: allow `use crate_name;` under `uniform_paths`.

Specifically, `use crate_name;` and `use crate_name::{self, ...};` are now allowed, whereas previously there would produce a (false positive) ambiguity error, as the ambiguity detection code was seeing the `crate_name` import as a locally-available definition to conflict with the crate.

r? @petrochenkov cc @aturon @joshtriplett @Centril
  • Loading branch information
bors committed Sep 6, 2018
2 parents a8c11d2 + 31fce91 commit ad7b22e
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 32 deletions.
19 changes: 18 additions & 1 deletion src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,23 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
self.session.features_untracked().uniform_paths);

let source = module_path[0];

// HACK(eddyb) For `use x::{self, ...};`, use the ID of the
// `self` nested import for the canary. This allows the
// ambiguity reporting scope to ignore false positives
// in the same way it does for `use x;` (by comparing IDs).
let mut canary_id = id;
if let ast::UseTreeKind::Nested(ref items) = use_tree.kind {
for &(ref use_tree, id) in items {
if let ast::UseTreeKind::Simple(..) = use_tree.kind {
if use_tree.ident().name == keywords::SelfValue.name() {
canary_id = id;
break;
}
}
}
}

// Helper closure to emit a canary with the given base path.
let emit = |this: &mut Self, base: Option<Ident>| {
let subclass = SingleImport {
Expand All @@ -200,7 +217,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
base.into_iter().collect(),
subclass.clone(),
source.span,
id,
canary_id,
root_use_tree.span,
root_id,
ty::Visibility::Invisible,
Expand Down
24 changes: 8 additions & 16 deletions src/librustc_resolve/resolve_imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,14 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {

self.per_ns(|_, ns| {
if let Some(result) = result[ns].get().ok() {
if let NameBindingKind::Import { directive, .. } = result.kind {
// Skip canaries that resolve to the import itself.
// These come from `use crate_name;`, which isn't really
// ambiguous, as the import can't actually shadow itself.
if directive.id == import.id {
return;
}
}
if has_explicit_self {
// There should only be one `self::x` (module-scoped) canary.
assert_eq!(canary_results[ns].module_scope, None);
Expand Down Expand Up @@ -718,22 +726,6 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {

errors = true;

// Special-case the error when `self::x` finds its own `use x;`.
if has_external_crate &&
results.module_scope == Some(span) &&
results.block_scopes.is_empty() {
let msg = format!("`{}` import is redundant", name);
this.session.struct_span_err(span, &msg)
.span_label(span,
format!("refers to external crate `::{}`", name))
.span_label(span,
format!("defines `self::{}`, shadowing itself", name))
.help(&format!("remove or write `::{}` explicitly instead", name))
.note("relative `use` paths enabled by `#![feature(uniform_paths)]`")
.emit();
return;
}

let msg = format!("`{}` import is ambiguous", name);
let mut err = this.session.struct_span_err(span, &msg);
let mut suggestion_choices = String::new();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,16 @@

use std;

fn main() {}
mod foo {
pub use std as my_std;
}

mod bar {
pub use std::{self};
}

fn main() {
self::std::io::stdout();
foo::my_std::io::stdout();
bar::std::io::stdout();
}
14 changes: 0 additions & 14 deletions src/test/ui/rust-2018/uniform-paths/redundant.stderr

This file was deleted.

0 comments on commit ad7b22e

Please sign in to comment.