Skip to content

Commit

Permalink
Rollup merge of rust-lang#59296 - petrochenkov:stdup, r=estebank
Browse files Browse the repository at this point in the history
Do not encode gensymed imports in metadata

(Unless they are underscore `_` imports which are re-gensymed on crate loading, see rust-lang#56392.)

We cannot encode gensymed imports properly in metadata and if we encode them improperly, we can get erroneous name conflicts downstream.
Gensymed imports are produced by the compiler, so we control their set, and can be sure that none of them needs being encoded for use from other crates.

A workaround that fixes rust-lang#59243.
  • Loading branch information
Centril authored Mar 19, 2019
2 parents 3ff78d4 + 30d5dc9 commit 080332b
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 4 deletions.
4 changes: 2 additions & 2 deletions src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ impl<'a> Resolver<'a> {
}

// Empty groups `a::b::{}` are turned into synthetic `self` imports
// `a::b::c::{self as _}`, so that their prefixes are correctly
// `a::b::c::{self as __dummy}`, so that their prefixes are correctly
// resolved and checked for privacy/stability/etc.
if items.is_empty() && !empty_for_self(&prefix) {
let new_span = prefix[prefix.len() - 1].ident.span;
Expand All @@ -312,7 +312,7 @@ impl<'a> Resolver<'a> {
Ident::new(keywords::SelfLower.name(), new_span)
),
kind: ast::UseTreeKind::Simple(
Some(Ident::new(keywords::Underscore.name().gensymed(), new_span)),
Some(Ident::new(Name::gensym("__dummy"), new_span)),
ast::DUMMY_NODE_ID,
ast::DUMMY_NODE_ID,
),
Expand Down
6 changes: 4 additions & 2 deletions src/librustc_resolve/resolve_imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1295,9 +1295,11 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
None => continue,
};

// Filter away "empty import canaries" and ambiguous imports.
// Filter away ambiguous and gensymed imports. Gensymed imports
// (e.g. implicitly injected `std`) cannot be properly encoded in metadata,
// so they can cause name conflict errors downstream.
let is_good_import = binding.is_import() && !binding.is_ambiguity() &&
binding.vis != ty::Visibility::Invisible;
!(ident.name.is_gensymed() && ident.name != "_");
if is_good_import || binding.is_macro_def() {
let def = binding.def();
if def != Def::Err {
Expand Down
4 changes: 4 additions & 0 deletions src/libsyntax_pos/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,10 @@ impl Symbol {
with_interner(|interner| interner.gensymed(self))
}

pub fn is_gensymed(self) -> bool {
with_interner(|interner| interner.is_gensymed(self))
}

pub fn as_str(self) -> LocalInternedString {
with_interner(|interner| unsafe {
LocalInternedString {
Expand Down
3 changes: 3 additions & 0 deletions src/test/ui/imports/auxiliary/gensymed.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// edition:2018

mod std {}
7 changes: 7 additions & 0 deletions src/test/ui/imports/gensymed.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// compile-pass
// edition:2018
// aux-build:gensymed.rs

extern crate gensymed;

fn main() {}

0 comments on commit 080332b

Please sign in to comment.