Fix cross-crate resolution of half-items created by export shadowing

This commit is contained in:
Vadim Petrochenkov 2016-09-15 00:51:46 +03:00
parent da7b1c984c
commit d19c16acfb
15 changed files with 558 additions and 46 deletions

View File

@ -100,8 +100,8 @@ pub type ExportMap = NodeMap<Vec<Export>>;
#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
pub struct Export {
pub name: ast::Name, // The name of the target.
pub def_id: DefId, // The definition of the target.
pub name: ast::Name, // The name of the target.
pub def: Def, // The definition of the target.
}
impl CtorKind {

View File

@ -149,7 +149,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
self.dep_graph.read(DepNode::MetaData(def_id));
let mut result = vec![];
self.get_crate_data(def_id.krate)
.each_child_of_item(def_id.index, |child| result.push(child.def_id));
.each_child_of_item(def_id.index, |child| result.push(child.def.def_id()));
result
}
@ -566,7 +566,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
let mut bfs_queue = &mut VecDeque::new();
let mut add_child = |bfs_queue: &mut VecDeque<_>, child: def::Export, parent: DefId| {
let child = child.def_id;
let child = child.def.def_id();
if self.visibility(child) != ty::Visibility::Public {
return;

View File

@ -670,10 +670,12 @@ impl<'a, 'tcx> CrateMetadata {
// FIXME(eddyb) Don't encode these in children.
EntryKind::ForeignMod => {
for child_index in child.children.decode(self) {
callback(def::Export {
def_id: self.local_def_id(child_index),
name: self.item_name(&self.entry(child_index))
});
if let Some(def) = self.get_def(child_index) {
callback(def::Export {
def: def,
name: self.item_name(&self.entry(child_index))
});
}
}
continue;
}
@ -683,11 +685,26 @@ impl<'a, 'tcx> CrateMetadata {
}
let def_key = child.def_key.decode(self);
if let Some(name) = def_key.disambiguated_data.data.get_opt_name() {
callback(def::Export {
def_id: self.local_def_id(child_index),
name: name
});
if let (Some(def), Some(name)) = (self.get_def(child_index),
def_key.disambiguated_data.data.get_opt_name()) {
callback(def::Export { def: def, name: name });
// For non-reexport structs and variants add their constructors to children.
// Reexport lists automatically contain constructors when necessary.
match def {
Def::Struct(..) => {
if let Some(ctor_def_id) = self.get_struct_ctor_def_id(child_index) {
let vkind = self.get_variant_kind(child_index).unwrap();
let ctor_def = Def::StructCtor(ctor_def_id, vkind.ctor_kind());
callback(def::Export { def: ctor_def, name: name });
}
}
Def::Variant(def_id) => {
let vkind = self.get_variant_kind(child_index).unwrap();
let ctor_def = Def::VariantCtor(def_id, vkind.ctor_kind());
callback(def::Export { def: ctor_def, name: name });
}
_ => {}
}
}
}
}

View File

@ -406,7 +406,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
fn encode_struct_ctor(&mut self, (adt_def_id, def_id): (DefId, DefId))
-> Entry<'tcx> {
let variant = self.tcx.lookup_adt_def(adt_def_id).struct_variant();
let tcx = self.tcx;
let variant = tcx.lookup_adt_def(adt_def_id).struct_variant();
let data = VariantData {
kind: variant.kind,
@ -414,9 +415,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
struct_ctor: Some(def_id.index)
};
let struct_id = tcx.map.as_local_node_id(adt_def_id).unwrap();
let struct_vis = &tcx.map.expect_item(struct_id).vis;
Entry {
kind: EntryKind::Struct(self.lazy(&data)),
visibility: ty::Visibility::Public,
visibility: struct_vis.simplify(),
def_key: self.encode_def_key(def_id),
attributes: LazySeq::empty(),
children: LazySeq::empty(),

View File

@ -286,7 +286,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
if self.prev_level.is_some() {
if let Some(exports) = self.export_map.get(&id) {
for export in exports {
if let Some(node_id) = self.tcx.map.as_local_node_id(export.def_id) {
if let Some(node_id) = self.tcx.map.as_local_node_id(export.def.def_id()) {
self.update(node_id, Some(AccessLevel::Exported));
}
}

View File

@ -24,7 +24,6 @@ use {resolve_error, resolve_struct_error, ResolutionError};
use rustc::middle::cstore::LoadedMacroKind;
use rustc::hir::def::*;
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
use rustc::hir::map::DefPathData;
use rustc::ty;
use std::cell::Cell;
@ -398,15 +397,9 @@ impl<'b> Resolver<'b> {
/// Builds the reduced graph for a single item in an external crate.
fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>,
child: Export) {
let def_id = child.def_id;
let name = child.name;
let def = if let Some(def) = self.session.cstore.describe_def(def_id) {
def
} else {
return;
};
let def = child.def;
let def_id = def.def_id();
let vis = if parent.is_trait() {
ty::Visibility::Public
} else {
@ -424,14 +417,15 @@ impl<'b> Resolver<'b> {
debug!("(building reduced graph for external crate) building variant {}", name);
// All variants are defined in both type and value namespaces as future-proofing.
let vkind = self.session.cstore.variant_kind(def_id).unwrap();
let ctor_def = Def::VariantCtor(def_id, vkind.ctor_kind());
let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
let _ = self.try_define(parent, name, ValueNS, (ctor_def, DUMMY_SP, vis));
if vkind == ty::VariantKind::Struct {
// Not adding fields for variants as they are not accessed with a self receiver
self.structs.insert(def_id, Vec::new());
}
}
Def::VariantCtor(..) => {
let _ = self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis));
}
Def::Fn(..) |
Def::Static(..) |
Def::Const(..) |
@ -468,23 +462,18 @@ impl<'b> Resolver<'b> {
debug!("(building reduced graph for external crate) building type {}", name);
let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
}
Def::Struct(..)
if self.session.cstore.def_key(def_id).disambiguated_data.data !=
DefPathData::StructCtor
=> {
Def::Struct(..) => {
debug!("(building reduced graph for external crate) building type and value for {}",
name);
let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
if let Some(ctor_def_id) = self.session.cstore.struct_ctor_def_id(def_id) {
let vkind = self.session.cstore.variant_kind(def_id).unwrap();
let ctor_def = Def::StructCtor(ctor_def_id, vkind.ctor_kind());
let _ = self.try_define(parent, name, ValueNS, (ctor_def, DUMMY_SP, vis));
}
// Record the def ID and fields of this struct.
let fields = self.session.cstore.struct_field_names(def_id);
self.structs.insert(def_id, fields);
}
Def::StructCtor(..) => {
let _ = self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis));
}
Def::Union(_) => {
let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
@ -492,9 +481,6 @@ impl<'b> Resolver<'b> {
let fields = self.session.cstore.struct_field_names(def_id);
self.structs.insert(def_id, fields);
}
Def::Struct(..) => {}
Def::VariantCtor(..) |
Def::StructCtor(..) |
Def::Local(..) |
Def::PrimTy(..) |
Def::TyParam(..) |

View File

@ -797,7 +797,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
(binding.is_import() || binding.is_extern_crate()) {
let def = binding.def();
if def != Def::Err {
reexports.push(Export { name: name, def_id: def.def_id() });
reexports.push(Export { name: name, def: def });
}
}

View File

@ -461,7 +461,7 @@ pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> {
return;
}
for child in ccx.tcx.sess.cstore.item_children(def_id) {
handle_external_def(ccx, traits, external_mods, child.def_id)
handle_external_def(ccx, traits, external_mods, child.def.def_id())
}
}
_ => {}

View File

@ -498,9 +498,10 @@ fn build_module<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
// visit each node at most once.
let mut visited = FnvHashSet();
for item in tcx.sess.cstore.item_children(did) {
if tcx.sess.cstore.visibility(item.def_id) == ty::Visibility::Public {
if !visited.insert(item.def_id) { continue }
if let Some(def) = tcx.sess.cstore.describe_def(item.def_id) {
let def_id = item.def.def_id();
if tcx.sess.cstore.visibility(def_id) == ty::Visibility::Public {
if !visited.insert(def_id) { continue }
if let Some(def) = tcx.sess.cstore.describe_def(def_id) {
if let Some(i) = try_inline_def(cx, tcx, def) {
items.extend(i)
}

View File

@ -237,7 +237,7 @@ impl Clean<ExternalCrate> for CrateNum {
let root = DefId { krate: self.0, index: CRATE_DEF_INDEX };
cx.tcx_opt().map(|tcx| {
for item in tcx.sess.cstore.item_children(root) {
let attrs = inline::load_attrs(cx, tcx, item.def_id);
let attrs = inline::load_attrs(cx, tcx, item.def.def_id());
PrimitiveType::find(&attrs).map(|prim| primitives.push(prim));
}
});

View File

@ -66,7 +66,7 @@ impl<'a, 'b, 'tcx> LibEmbargoVisitor<'a, 'b, 'tcx> {
pub fn visit_mod(&mut self, def_id: DefId) {
for item in self.cstore.item_children(def_id) {
self.visit_item(item.def_id);
self.visit_item(item.def.def_id());
}
}

View File

@ -0,0 +1,78 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(item_like_imports, relaxed_adts)]
pub mod c {
pub struct S {}
pub struct TS();
pub struct US;
pub enum E {
V {},
TV(),
UV,
}
pub struct Item;
}
pub mod xm1 {
pub use ::c::*;
pub type S = ::c::Item;
}
pub mod xm2 {
pub use ::c::*;
pub const S: ::c::Item = ::c::Item;
}
pub mod xm3 {
pub use ::c::*;
pub type TS = ::c::Item;
}
pub mod xm4 {
pub use ::c::*;
pub const TS: ::c::Item = ::c::Item;
}
pub mod xm5 {
pub use ::c::*;
pub type US = ::c::Item;
}
pub mod xm6 {
pub use ::c::*;
pub const US: ::c::Item = ::c::Item;
}
pub mod xm7 {
pub use ::c::E::*;
pub type V = ::c::Item;
}
pub mod xm8 {
pub use ::c::E::*;
pub const V: ::c::Item = ::c::Item;
}
pub mod xm9 {
pub use ::c::E::*;
pub type TV = ::c::Item;
}
pub mod xmA {
pub use ::c::E::*;
pub const TV: ::c::Item = ::c::Item;
}
pub mod xmB {
pub use ::c::E::*;
pub type UV = ::c::Item;
}
pub mod xmC {
pub use ::c::E::*;
pub const UV: ::c::Item = ::c::Item;
}

View File

@ -0,0 +1,85 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// FIXME: Remove when `item_like_imports` is stabilized.
#![feature(relaxed_adts)]
pub mod c {
pub struct S {}
pub struct TS();
pub struct US;
pub enum E {
V {},
TV(),
UV,
}
pub struct Item;
}
pub mod proxy {
pub use c::*;
pub use c::E::*;
}
pub mod xm1 {
pub use ::proxy::*;
pub type S = ::c::Item;
}
pub mod xm2 {
pub use ::proxy::*;
pub const S: ::c::Item = ::c::Item;
}
pub mod xm3 {
pub use ::proxy::*;
pub type TS = ::c::Item;
}
pub mod xm4 {
pub use ::proxy::*;
pub const TS: ::c::Item = ::c::Item;
}
pub mod xm5 {
pub use ::proxy::*;
pub type US = ::c::Item;
}
pub mod xm6 {
pub use ::proxy::*;
pub const US: ::c::Item = ::c::Item;
}
pub mod xm7 {
pub use ::proxy::*;
pub type V = ::c::Item;
}
pub mod xm8 {
pub use ::proxy::*;
pub const V: ::c::Item = ::c::Item;
}
pub mod xm9 {
pub use ::proxy::*;
pub type TV = ::c::Item;
}
pub mod xmA {
pub use ::proxy::*;
pub const TV: ::c::Item = ::c::Item;
}
pub mod xmB {
pub use ::proxy::*;
pub type UV = ::c::Item;
}
pub mod xmC {
pub use ::proxy::*;
pub const UV: ::c::Item = ::c::Item;
}

View File

@ -0,0 +1,167 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// aux-build:namespace-mix-new.rs
#![feature(item_like_imports, relaxed_adts)]
extern crate namespace_mix_new;
use namespace_mix_new::*;
mod c {
pub struct S {}
pub struct TS();
pub struct US;
pub enum E {
V {},
TV(),
UV,
}
pub struct Item;
}
// Use something emitting the type argument name, e.g. unsatisfied bound.
trait Impossible {}
fn check<T: Impossible>(_: T) {}
mod m1 {
pub use ::c::*;
pub type S = ::c::Item;
}
mod m2 {
pub use ::c::*;
pub const S: ::c::Item = ::c::Item;
}
fn f12() {
check(m1::S{}); //~ ERROR c::Item
check(m1::S); //~ ERROR unresolved name
check(m2::S{}); //~ ERROR c::S
check(m2::S); //~ ERROR c::Item
}
fn xf12() {
check(xm1::S{}); //~ ERROR c::Item
check(xm1::S); //~ ERROR unresolved name
check(xm2::S{}); //~ ERROR c::S
check(xm2::S); //~ ERROR c::Item
}
mod m3 {
pub use ::c::*;
pub type TS = ::c::Item;
}
mod m4 {
pub use ::c::*;
pub const TS: ::c::Item = ::c::Item;
}
fn f34() {
check(m3::TS{}); //~ ERROR c::Item
check(m3::TS); //~ ERROR c::TS
check(m4::TS{}); //~ ERROR c::TS
check(m4::TS); //~ ERROR c::Item
}
fn xf34() {
check(xm3::TS{}); //~ ERROR c::Item
check(xm3::TS); //~ ERROR c::TS
check(xm4::TS{}); //~ ERROR c::TS
check(xm4::TS); //~ ERROR c::Item
}
mod m5 {
pub use ::c::*;
pub type US = ::c::Item;
}
mod m6 {
pub use ::c::*;
pub const US: ::c::Item = ::c::Item;
}
fn f56() {
check(m5::US{}); //~ ERROR c::Item
check(m5::US); //~ ERROR c::US
check(m6::US{}); //~ ERROR c::US
check(m6::US); //~ ERROR c::Item
}
fn xf56() {
check(xm5::US{}); //~ ERROR c::Item
check(xm5::US); //~ ERROR c::US
check(xm6::US{}); //~ ERROR c::US
check(xm6::US); //~ ERROR c::Item
}
mod m7 {
pub use ::c::E::*;
pub type V = ::c::Item;
}
mod m8 {
pub use ::c::E::*;
pub const V: ::c::Item = ::c::Item;
}
fn f78() {
check(m7::V{}); //~ ERROR c::Item
check(m7::V); //~ ERROR name of a struct or struct variant
check(m8::V{}); //~ ERROR c::E
check(m8::V); //~ ERROR c::Item
}
fn xf78() {
check(xm7::V{}); //~ ERROR c::Item
check(xm7::V); //~ ERROR name of a struct or struct variant
check(xm8::V{}); //~ ERROR c::E
check(xm8::V); //~ ERROR c::Item
}
mod m9 {
pub use ::c::E::*;
pub type TV = ::c::Item;
}
mod mA {
pub use ::c::E::*;
pub const TV: ::c::Item = ::c::Item;
}
fn f9A() {
check(m9::TV{}); //~ ERROR c::Item
check(m9::TV); //~ ERROR c::E
check(mA::TV{}); //~ ERROR c::E
check(mA::TV); //~ ERROR c::Item
}
fn xf9A() {
check(xm9::TV{}); //~ ERROR c::Item
check(xm9::TV); //~ ERROR c::E
check(xmA::TV{}); //~ ERROR c::E
check(xmA::TV); //~ ERROR c::Item
}
mod mB {
pub use ::c::E::*;
pub type UV = ::c::Item;
}
mod mC {
pub use ::c::E::*;
pub const UV: ::c::Item = ::c::Item;
}
fn fBC() {
check(mB::UV{}); //~ ERROR c::Item
check(mB::UV); //~ ERROR c::E
check(mC::UV{}); //~ ERROR c::E
check(mC::UV); //~ ERROR c::Item
}
fn xfBC() {
check(xmB::UV{}); //~ ERROR c::Item
check(xmB::UV); //~ ERROR c::E
check(xmC::UV{}); //~ ERROR c::E
check(xmC::UV); //~ ERROR c::Item
}
fn main() {}

View File

@ -0,0 +1,174 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// FIXME: Remove when `item_like_imports` is stabilized.
// aux-build:namespace-mix-old.rs
#![feature(relaxed_adts)]
extern crate namespace_mix_old;
use namespace_mix_old::{xm1, xm2, xm3, xm4, xm5, xm6, xm7, xm8, xm9, xmA, xmB, xmC};
mod c {
pub struct S {}
pub struct TS();
pub struct US;
pub enum E {
V {},
TV(),
UV,
}
pub struct Item;
}
mod proxy {
pub use c::*;
pub use c::E::*;
}
// Use something emitting the type argument name, e.g. unsatisfied bound.
trait Impossible {}
fn check<T: Impossible>(_: T) {}
mod m1 {
pub use ::proxy::*;
pub type S = ::c::Item;
}
mod m2 {
pub use ::proxy::*;
pub const S: ::c::Item = ::c::Item;
}
fn f12() {
check(m1::S{}); //~ ERROR c::Item
check(m1::S); //~ ERROR unresolved name
check(m2::S{}); //~ ERROR c::S
check(m2::S); //~ ERROR c::Item
}
fn xf12() {
check(xm1::S{}); //~ ERROR c::Item
check(xm1::S); //~ ERROR unresolved name
check(xm2::S{}); //~ ERROR c::S
check(xm2::S); //~ ERROR c::Item
}
mod m3 {
pub use ::proxy::*;
pub type TS = ::c::Item;
}
mod m4 {
pub use ::proxy::*;
pub const TS: ::c::Item = ::c::Item;
}
fn f34() {
check(m3::TS{}); //~ ERROR c::Item
check(m3::TS); //~ ERROR c::TS
check(m4::TS{}); //~ ERROR c::TS
check(m4::TS); //~ ERROR c::Item
}
fn xf34() {
check(xm3::TS{}); //~ ERROR c::Item
check(xm3::TS); //~ ERROR c::TS
check(xm4::TS{}); //~ ERROR c::TS
check(xm4::TS); //~ ERROR c::Item
}
mod m5 {
pub use ::proxy::*;
pub type US = ::c::Item;
}
mod m6 {
pub use ::proxy::*;
pub const US: ::c::Item = ::c::Item;
}
fn f56() {
check(m5::US{}); //~ ERROR c::Item
check(m5::US); //~ ERROR c::US
check(m6::US{}); //~ ERROR c::US
check(m6::US); //~ ERROR c::Item
}
fn xf56() {
check(xm5::US{}); //~ ERROR c::Item
check(xm5::US); //~ ERROR c::US
check(xm6::US{}); //~ ERROR c::US
check(xm6::US); //~ ERROR c::Item
}
mod m7 {
pub use ::proxy::*;
pub type V = ::c::Item;
}
mod m8 {
pub use ::proxy::*;
pub const V: ::c::Item = ::c::Item;
}
fn f78() {
check(m7::V{}); //~ ERROR c::Item
check(m7::V); //~ ERROR name of a struct or struct variant
check(m8::V{}); //~ ERROR c::E
check(m8::V); //~ ERROR c::Item
}
fn xf78() {
check(xm7::V{}); //~ ERROR c::Item
check(xm7::V); //~ ERROR name of a struct or struct variant
check(xm8::V{}); //~ ERROR c::E
check(xm8::V); //~ ERROR c::Item
}
mod m9 {
pub use ::proxy::*;
pub type TV = ::c::Item;
}
mod mA {
pub use ::proxy::*;
pub const TV: ::c::Item = ::c::Item;
}
fn f9A() {
check(m9::TV{}); //~ ERROR c::Item
check(m9::TV); //~ ERROR c::E
check(mA::TV{}); //~ ERROR c::E
check(mA::TV); //~ ERROR c::Item
}
fn xf9A() {
check(xm9::TV{}); //~ ERROR c::Item
check(xm9::TV); //~ ERROR c::E
check(xmA::TV{}); //~ ERROR c::E
check(xmA::TV); //~ ERROR c::Item
}
mod mB {
pub use ::proxy::*;
pub type UV = ::c::Item;
}
mod mC {
pub use ::proxy::*;
pub const UV: ::c::Item = ::c::Item;
}
fn fBC() {
check(mB::UV{}); //~ ERROR c::Item
check(mB::UV); //~ ERROR c::E
check(mC::UV{}); //~ ERROR c::E
check(mC::UV); //~ ERROR c::Item
}
fn xfBC() {
check(xmB::UV{}); //~ ERROR c::Item
check(xmB::UV); //~ ERROR c::E
check(xmC::UV{}); //~ ERROR c::E
check(xmC::UV); //~ ERROR c::Item
}
fn main() {}