Skip to content

Commit 4dd146c

Browse files
make DefMap account for namespaces
1 parent 4122885 commit 4dd146c

File tree

3 files changed

+77
-56
lines changed

3 files changed

+77
-56
lines changed

src/librustc/hir/def.rs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ use syntax_pos::Span;
1616
use hir;
1717
use ty;
1818

19+
use self::Namespace::*;
20+
1921
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
2022
pub enum CtorKind {
2123
/// Constructor function automatically created by a tuple struct/variant.
@@ -116,8 +118,47 @@ impl PathResolution {
116118
}
117119
}
118120

121+
/// Different kinds of symbols don't influence each other.
122+
///
123+
/// Therefore, they have a separate universe (namespace).
124+
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
125+
pub enum Namespace {
126+
TypeNS,
127+
ValueNS,
128+
MacroNS,
129+
}
130+
131+
/// Just a helper ‒ separate structure for each namespace.
132+
#[derive(Clone, Default, Debug)]
133+
pub struct PerNS<T> {
134+
pub value_ns: T,
135+
pub type_ns: T,
136+
pub macro_ns: T,
137+
}
138+
139+
impl<T> ::std::ops::Index<Namespace> for PerNS<T> {
140+
type Output = T;
141+
fn index(&self, ns: Namespace) -> &T {
142+
match ns {
143+
ValueNS => &self.value_ns,
144+
TypeNS => &self.type_ns,
145+
MacroNS => &self.macro_ns,
146+
}
147+
}
148+
}
149+
150+
impl<T> ::std::ops::IndexMut<Namespace> for PerNS<T> {
151+
fn index_mut(&mut self, ns: Namespace) -> &mut T {
152+
match ns {
153+
ValueNS => &mut self.value_ns,
154+
TypeNS => &mut self.type_ns,
155+
MacroNS => &mut self.macro_ns,
156+
}
157+
}
158+
}
159+
119160
/// Definition mapping
120-
pub type DefMap = NodeMap<PathResolution>;
161+
pub type DefMap = NodeMap<PerNS<Option<PathResolution>>>;
121162

122163
/// This is the replacement export map. It maps a module to all of the exports
123164
/// within.

src/librustc_resolve/lib.rs

Lines changed: 29 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#![feature(crate_visibility_modifier)]
1616
#![feature(rustc_diagnostic_macros)]
1717
#![feature(slice_sort_by_cached_key)]
18+
#![feature(entry_or_default)]
1819

1920
#[macro_use]
2021
extern crate log;
@@ -27,7 +28,8 @@ extern crate arena;
2728
extern crate rustc;
2829
extern crate rustc_data_structures;
2930

30-
use self::Namespace::*;
31+
pub use rustc::hir::def::{Namespace, PerNS};
32+
3133
use self::TypeParameters::*;
3234
use self::RibKind::*;
3335

@@ -37,7 +39,9 @@ use rustc::middle::cstore::{CrateStore, CrateLoader};
3739
use rustc::session::Session;
3840
use rustc::lint;
3941
use rustc::hir::def::*;
42+
use rustc::hir::def::Namespace::*;
4043
use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
44+
use rustc::hir::lowering::Resolver as ResolverTrait;
4145
use rustc::ty;
4246
use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap};
4347
use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet, DefIdMap};
@@ -614,45 +618,6 @@ impl<'a> PathSource<'a> {
614618
}
615619
}
616620

617-
/// Different kinds of symbols don't influence each other.
618-
///
619-
/// Therefore, they have a separate universe (namespace).
620-
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
621-
pub enum Namespace {
622-
TypeNS,
623-
ValueNS,
624-
MacroNS,
625-
}
626-
627-
/// Just a helper ‒ separate structure for each namespace.
628-
#[derive(Clone, Default, Debug)]
629-
pub struct PerNS<T> {
630-
value_ns: T,
631-
type_ns: T,
632-
macro_ns: T,
633-
}
634-
635-
impl<T> ::std::ops::Index<Namespace> for PerNS<T> {
636-
type Output = T;
637-
fn index(&self, ns: Namespace) -> &T {
638-
match ns {
639-
ValueNS => &self.value_ns,
640-
TypeNS => &self.type_ns,
641-
MacroNS => &self.macro_ns,
642-
}
643-
}
644-
}
645-
646-
impl<T> ::std::ops::IndexMut<Namespace> for PerNS<T> {
647-
fn index_mut(&mut self, ns: Namespace) -> &mut T {
648-
match ns {
649-
ValueNS => &mut self.value_ns,
650-
TypeNS => &mut self.type_ns,
651-
MacroNS => &mut self.macro_ns,
652-
}
653-
}
654-
}
655-
656621
struct UsePlacementFinder {
657622
target_module: NodeId,
658623
span: Option<Span>,
@@ -752,7 +717,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
752717
let self_ty = keywords::SelfType.ident();
753718
let def = self.resolve_ident_in_lexical_scope(self_ty, TypeNS, true, ty.span)
754719
.map_or(Def::Err, |d| d.def());
755-
self.record_def(ty.id, PathResolution::new(def));
720+
self.record_def(ty.id, TypeNS, PathResolution::new(def));
756721
}
757722
_ => (),
758723
}
@@ -1512,7 +1477,17 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> {
15121477
}
15131478

15141479
fn get_resolution(&mut self, id: NodeId) -> Option<PathResolution> {
1515-
self.def_map.get(&id).cloned()
1480+
//for people calling this one, they don't necessarily care which namespace it's in, so just
1481+
//have a preference but check all of them
1482+
if let Some(def) = self.def_map.get(&id) {
1483+
for ns in [TypeNS, ValueNS, MacroNS].iter().cloned() {
1484+
if let Some(res) = def[ns] {
1485+
return Some(res);
1486+
}
1487+
}
1488+
}
1489+
1490+
None
15161491
}
15171492

15181493
fn definitions(&mut self) -> &mut Definitions {
@@ -2241,7 +2216,7 @@ impl<'a> Resolver<'a> {
22412216
let def_id = self.definitions.local_def_id(type_parameter.id);
22422217
let def = Def::TyParam(def_id);
22432218
function_type_rib.bindings.insert(ident, def);
2244-
self.record_def(type_parameter.id, PathResolution::new(def));
2219+
self.record_def(type_parameter.id, TypeNS, PathResolution::new(def));
22452220
}
22462221
}
22472222
self.ribs[TypeNS].push(function_type_rib);
@@ -2454,7 +2429,9 @@ impl<'a> Resolver<'a> {
24542429

24552430
pat.walk(&mut |pat| {
24562431
if let PatKind::Ident(binding_mode, ident, ref sub_pat) = pat.node {
2457-
if sub_pat.is_some() || match self.def_map.get(&pat.id).map(|res| res.base_def()) {
2432+
//FIXME(misdreavus): `get_resolution` is the "i don't care what namespace" version,
2433+
//is that valid?
2434+
if sub_pat.is_some() || match self.get_resolution(pat.id).map(|res| res.base_def()) {
24582435
Some(Def::Local(..)) => true,
24592436
_ => false,
24602437
} {
@@ -2710,7 +2687,7 @@ impl<'a> Resolver<'a> {
27102687
self.fresh_binding(ident, pat.id, outer_pat_id, pat_src, bindings)
27112688
});
27122689

2713-
self.record_def(pat.id, resolution);
2690+
self.record_def(pat.id, ValueNS, resolution);
27142691
}
27152692

27162693
PatKind::TupleStruct(ref path, ..) => {
@@ -3026,7 +3003,7 @@ impl<'a> Resolver<'a> {
30263003

30273004
if let PathSource::TraitItem(..) = source {} else {
30283005
// Avoid recording definition of `A::B` in `<T as A>::B::C`.
3029-
self.record_def(id, resolution);
3006+
self.record_def(id, ns, resolution);
30303007
}
30313008
resolution
30323009
}
@@ -3624,7 +3601,7 @@ impl<'a> Resolver<'a> {
36243601
if filter_fn(Def::Local(ast::DUMMY_NODE_ID)) {
36253602
if let Some(node_id) = self.current_self_type.as_ref().and_then(extract_node_id) {
36263603
// Look for a field with the same name in the current self_type.
3627-
if let Some(resolution) = self.def_map.get(&node_id) {
3604+
if let Some(resolution) = self.get_resolution(node_id) {
36283605
match resolution.base_def() {
36293606
Def::Struct(did) | Def::Union(did)
36303607
if resolution.unresolved_segments() == 0 => {
@@ -3777,15 +3754,15 @@ impl<'a> Resolver<'a> {
37773754
let names = rib.bindings.iter().map(|(id, _)| &id.name);
37783755
find_best_match_for_name(names, &*ident.as_str(), None)
37793756
});
3780-
self.record_def(expr.id, err_path_resolution());
3757+
self.record_def(expr.id, ValueNS, err_path_resolution());
37813758
resolve_error(self,
37823759
label.ident.span,
37833760
ResolutionError::UndeclaredLabel(&label.ident.as_str(),
37843761
close_match));
37853762
}
37863763
Some(Def::Label(id)) => {
37873764
// Since this def is a label, it is never read.
3788-
self.record_def(expr.id, PathResolution::new(Def::Label(id)));
3765+
self.record_def(expr.id, ValueNS, PathResolution::new(Def::Label(id)));
37893766
self.unused_labels.remove(&id);
37903767
}
37913768
Some(_) => {
@@ -4111,9 +4088,10 @@ impl<'a> Resolver<'a> {
41114088
})
41124089
}
41134090

4114-
fn record_def(&mut self, node_id: NodeId, resolution: PathResolution) {
4091+
fn record_def(&mut self, node_id: NodeId, ns: Namespace, resolution: PathResolution) {
41154092
debug!("(recording def) recording {:?} for {}", resolution, node_id);
4116-
if let Some(prev_res) = self.def_map.insert(node_id, resolution) {
4093+
let record = self.def_map.entry(node_id).or_default();
4094+
if let Some(prev_res) = replace(&mut record[ns], Some(resolution)) {
41174095
panic!("path resolved multiple times ({:?} before, {:?} now)", prev_res, resolution);
41184096
}
41194097
}

src/librustc_resolve/resolve_imports.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010

1111
use self::ImportDirectiveSubclass::*;
1212

13-
use {AmbiguityError, CrateLint, Module, PerNS};
14-
use Namespace::{self, TypeNS, MacroNS};
13+
use {AmbiguityError, CrateLint, Module, PerNS, Namespace};
14+
use Namespace::*;
1515
use {NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError};
1616
use Resolver;
1717
use {names_to_string, module_to_string};
@@ -917,7 +917,8 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
917917
// this may resolve to either a value or a type, but for documentation
918918
// purposes it's good enough to just favor one over the other.
919919
self.per_ns(|this, ns| if let Some(binding) = result[ns].get().ok() {
920-
this.def_map.entry(directive.id).or_insert(PathResolution::new(binding.def()));
920+
let def = this.def_map.entry(directive.id).or_default();
921+
def[ns] = Some(PathResolution::new(binding.def()));
921922
});
922923

923924
debug!("(resolving single import) successfully resolved import");
@@ -960,7 +961,8 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
960961
}
961962

962963
// Record the destination of this import
963-
self.record_def(directive.id, PathResolution::new(module.def().unwrap()));
964+
// FIXME(misdreavus): this was a guess based on the fact that it's recording a module
965+
self.record_def(directive.id, TypeNS, PathResolution::new(module.def().unwrap()));
964966
}
965967

966968
// Miscellaneous post-processing, including recording re-exports,

0 commit comments

Comments
 (0)