Skip to content

Commit d19c16a

Browse files
committed
Fix cross-crate resolution of half-items created by export shadowing
1 parent da7b1c9 commit d19c16a

File tree

15 files changed

+558
-46
lines changed

15 files changed

+558
-46
lines changed

src/librustc/hir/def.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ pub type ExportMap = NodeMap<Vec<Export>>;
100100

101101
#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
102102
pub struct Export {
103-
pub name: ast::Name, // The name of the target.
104-
pub def_id: DefId, // The definition of the target.
103+
pub name: ast::Name, // The name of the target.
104+
pub def: Def, // The definition of the target.
105105
}
106106

107107
impl CtorKind {

src/librustc_metadata/csearch.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
149149
self.dep_graph.read(DepNode::MetaData(def_id));
150150
let mut result = vec![];
151151
self.get_crate_data(def_id.krate)
152-
.each_child_of_item(def_id.index, |child| result.push(child.def_id));
152+
.each_child_of_item(def_id.index, |child| result.push(child.def.def_id()));
153153
result
154154
}
155155

@@ -566,7 +566,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
566566

567567
let mut bfs_queue = &mut VecDeque::new();
568568
let mut add_child = |bfs_queue: &mut VecDeque<_>, child: def::Export, parent: DefId| {
569-
let child = child.def_id;
569+
let child = child.def.def_id();
570570

571571
if self.visibility(child) != ty::Visibility::Public {
572572
return;

src/librustc_metadata/decoder.rs

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -670,10 +670,12 @@ impl<'a, 'tcx> CrateMetadata {
670670
// FIXME(eddyb) Don't encode these in children.
671671
EntryKind::ForeignMod => {
672672
for child_index in child.children.decode(self) {
673-
callback(def::Export {
674-
def_id: self.local_def_id(child_index),
675-
name: self.item_name(&self.entry(child_index))
676-
});
673+
if let Some(def) = self.get_def(child_index) {
674+
callback(def::Export {
675+
def: def,
676+
name: self.item_name(&self.entry(child_index))
677+
});
678+
}
677679
}
678680
continue;
679681
}
@@ -683,11 +685,26 @@ impl<'a, 'tcx> CrateMetadata {
683685
}
684686

685687
let def_key = child.def_key.decode(self);
686-
if let Some(name) = def_key.disambiguated_data.data.get_opt_name() {
687-
callback(def::Export {
688-
def_id: self.local_def_id(child_index),
689-
name: name
690-
});
688+
if let (Some(def), Some(name)) = (self.get_def(child_index),
689+
def_key.disambiguated_data.data.get_opt_name()) {
690+
callback(def::Export { def: def, name: name });
691+
// For non-reexport structs and variants add their constructors to children.
692+
// Reexport lists automatically contain constructors when necessary.
693+
match def {
694+
Def::Struct(..) => {
695+
if let Some(ctor_def_id) = self.get_struct_ctor_def_id(child_index) {
696+
let vkind = self.get_variant_kind(child_index).unwrap();
697+
let ctor_def = Def::StructCtor(ctor_def_id, vkind.ctor_kind());
698+
callback(def::Export { def: ctor_def, name: name });
699+
}
700+
}
701+
Def::Variant(def_id) => {
702+
let vkind = self.get_variant_kind(child_index).unwrap();
703+
let ctor_def = Def::VariantCtor(def_id, vkind.ctor_kind());
704+
callback(def::Export { def: ctor_def, name: name });
705+
}
706+
_ => {}
707+
}
691708
}
692709
}
693710
}

src/librustc_metadata/encoder.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -406,17 +406,21 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
406406

407407
fn encode_struct_ctor(&mut self, (adt_def_id, def_id): (DefId, DefId))
408408
-> Entry<'tcx> {
409-
let variant = self.tcx.lookup_adt_def(adt_def_id).struct_variant();
409+
let tcx = self.tcx;
410+
let variant = tcx.lookup_adt_def(adt_def_id).struct_variant();
410411

411412
let data = VariantData {
412413
kind: variant.kind,
413414
disr: variant.disr_val.to_u64_unchecked(),
414415
struct_ctor: Some(def_id.index)
415416
};
416417

418+
let struct_id = tcx.map.as_local_node_id(adt_def_id).unwrap();
419+
let struct_vis = &tcx.map.expect_item(struct_id).vis;
420+
417421
Entry {
418422
kind: EntryKind::Struct(self.lazy(&data)),
419-
visibility: ty::Visibility::Public,
423+
visibility: struct_vis.simplify(),
420424
def_key: self.encode_def_key(def_id),
421425
attributes: LazySeq::empty(),
422426
children: LazySeq::empty(),

src/librustc_privacy/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
286286
if self.prev_level.is_some() {
287287
if let Some(exports) = self.export_map.get(&id) {
288288
for export in exports {
289-
if let Some(node_id) = self.tcx.map.as_local_node_id(export.def_id) {
289+
if let Some(node_id) = self.tcx.map.as_local_node_id(export.def.def_id()) {
290290
self.update(node_id, Some(AccessLevel::Exported));
291291
}
292292
}

src/librustc_resolve/build_reduced_graph.rs

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ use {resolve_error, resolve_struct_error, ResolutionError};
2424
use rustc::middle::cstore::LoadedMacroKind;
2525
use rustc::hir::def::*;
2626
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
27-
use rustc::hir::map::DefPathData;
2827
use rustc::ty;
2928

3029
use std::cell::Cell;
@@ -398,15 +397,9 @@ impl<'b> Resolver<'b> {
398397
/// Builds the reduced graph for a single item in an external crate.
399398
fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>,
400399
child: Export) {
401-
let def_id = child.def_id;
402400
let name = child.name;
403-
404-
let def = if let Some(def) = self.session.cstore.describe_def(def_id) {
405-
def
406-
} else {
407-
return;
408-
};
409-
401+
let def = child.def;
402+
let def_id = def.def_id();
410403
let vis = if parent.is_trait() {
411404
ty::Visibility::Public
412405
} else {
@@ -424,14 +417,15 @@ impl<'b> Resolver<'b> {
424417
debug!("(building reduced graph for external crate) building variant {}", name);
425418
// All variants are defined in both type and value namespaces as future-proofing.
426419
let vkind = self.session.cstore.variant_kind(def_id).unwrap();
427-
let ctor_def = Def::VariantCtor(def_id, vkind.ctor_kind());
428420
let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
429-
let _ = self.try_define(parent, name, ValueNS, (ctor_def, DUMMY_SP, vis));
430421
if vkind == ty::VariantKind::Struct {
431422
// Not adding fields for variants as they are not accessed with a self receiver
432423
self.structs.insert(def_id, Vec::new());
433424
}
434425
}
426+
Def::VariantCtor(..) => {
427+
let _ = self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis));
428+
}
435429
Def::Fn(..) |
436430
Def::Static(..) |
437431
Def::Const(..) |
@@ -468,33 +462,25 @@ impl<'b> Resolver<'b> {
468462
debug!("(building reduced graph for external crate) building type {}", name);
469463
let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
470464
}
471-
Def::Struct(..)
472-
if self.session.cstore.def_key(def_id).disambiguated_data.data !=
473-
DefPathData::StructCtor
474-
=> {
465+
Def::Struct(..) => {
475466
debug!("(building reduced graph for external crate) building type and value for {}",
476467
name);
477468
let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
478-
if let Some(ctor_def_id) = self.session.cstore.struct_ctor_def_id(def_id) {
479-
let vkind = self.session.cstore.variant_kind(def_id).unwrap();
480-
let ctor_def = Def::StructCtor(ctor_def_id, vkind.ctor_kind());
481-
let _ = self.try_define(parent, name, ValueNS, (ctor_def, DUMMY_SP, vis));
482-
}
483469

484470
// Record the def ID and fields of this struct.
485471
let fields = self.session.cstore.struct_field_names(def_id);
486472
self.structs.insert(def_id, fields);
487473
}
474+
Def::StructCtor(..) => {
475+
let _ = self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis));
476+
}
488477
Def::Union(_) => {
489478
let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
490479

491480
// Record the def ID and fields of this union.
492481
let fields = self.session.cstore.struct_field_names(def_id);
493482
self.structs.insert(def_id, fields);
494483
}
495-
Def::Struct(..) => {}
496-
Def::VariantCtor(..) |
497-
Def::StructCtor(..) |
498484
Def::Local(..) |
499485
Def::PrimTy(..) |
500486
Def::TyParam(..) |

src/librustc_resolve/resolve_imports.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -797,7 +797,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
797797
(binding.is_import() || binding.is_extern_crate()) {
798798
let def = binding.def();
799799
if def != Def::Err {
800-
reexports.push(Export { name: name, def_id: def.def_id() });
800+
reexports.push(Export { name: name, def: def });
801801
}
802802
}
803803

src/librustc_typeck/check/method/suggest.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> {
461461
return;
462462
}
463463
for child in ccx.tcx.sess.cstore.item_children(def_id) {
464-
handle_external_def(ccx, traits, external_mods, child.def_id)
464+
handle_external_def(ccx, traits, external_mods, child.def.def_id())
465465
}
466466
}
467467
_ => {}

src/librustdoc/clean/inline.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -498,9 +498,10 @@ fn build_module<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
498498
// visit each node at most once.
499499
let mut visited = FnvHashSet();
500500
for item in tcx.sess.cstore.item_children(did) {
501-
if tcx.sess.cstore.visibility(item.def_id) == ty::Visibility::Public {
502-
if !visited.insert(item.def_id) { continue }
503-
if let Some(def) = tcx.sess.cstore.describe_def(item.def_id) {
501+
let def_id = item.def.def_id();
502+
if tcx.sess.cstore.visibility(def_id) == ty::Visibility::Public {
503+
if !visited.insert(def_id) { continue }
504+
if let Some(def) = tcx.sess.cstore.describe_def(def_id) {
504505
if let Some(i) = try_inline_def(cx, tcx, def) {
505506
items.extend(i)
506507
}

src/librustdoc/clean/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ impl Clean<ExternalCrate> for CrateNum {
237237
let root = DefId { krate: self.0, index: CRATE_DEF_INDEX };
238238
cx.tcx_opt().map(|tcx| {
239239
for item in tcx.sess.cstore.item_children(root) {
240-
let attrs = inline::load_attrs(cx, tcx, item.def_id);
240+
let attrs = inline::load_attrs(cx, tcx, item.def.def_id());
241241
PrimitiveType::find(&attrs).map(|prim| primitives.push(prim));
242242
}
243243
});

src/librustdoc/visit_lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ impl<'a, 'b, 'tcx> LibEmbargoVisitor<'a, 'b, 'tcx> {
6666

6767
pub fn visit_mod(&mut self, def_id: DefId) {
6868
for item in self.cstore.item_children(def_id) {
69-
self.visit_item(item.def_id);
69+
self.visit_item(item.def.def_id());
7070
}
7171
}
7272

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(item_like_imports, relaxed_adts)]
12+
13+
pub mod c {
14+
pub struct S {}
15+
pub struct TS();
16+
pub struct US;
17+
pub enum E {
18+
V {},
19+
TV(),
20+
UV,
21+
}
22+
23+
pub struct Item;
24+
}
25+
26+
pub mod xm1 {
27+
pub use ::c::*;
28+
pub type S = ::c::Item;
29+
}
30+
pub mod xm2 {
31+
pub use ::c::*;
32+
pub const S: ::c::Item = ::c::Item;
33+
}
34+
35+
pub mod xm3 {
36+
pub use ::c::*;
37+
pub type TS = ::c::Item;
38+
}
39+
pub mod xm4 {
40+
pub use ::c::*;
41+
pub const TS: ::c::Item = ::c::Item;
42+
}
43+
44+
pub mod xm5 {
45+
pub use ::c::*;
46+
pub type US = ::c::Item;
47+
}
48+
pub mod xm6 {
49+
pub use ::c::*;
50+
pub const US: ::c::Item = ::c::Item;
51+
}
52+
53+
pub mod xm7 {
54+
pub use ::c::E::*;
55+
pub type V = ::c::Item;
56+
}
57+
pub mod xm8 {
58+
pub use ::c::E::*;
59+
pub const V: ::c::Item = ::c::Item;
60+
}
61+
62+
pub mod xm9 {
63+
pub use ::c::E::*;
64+
pub type TV = ::c::Item;
65+
}
66+
pub mod xmA {
67+
pub use ::c::E::*;
68+
pub const TV: ::c::Item = ::c::Item;
69+
}
70+
71+
pub mod xmB {
72+
pub use ::c::E::*;
73+
pub type UV = ::c::Item;
74+
}
75+
pub mod xmC {
76+
pub use ::c::E::*;
77+
pub const UV: ::c::Item = ::c::Item;
78+
}

0 commit comments

Comments
 (0)