Skip to content

Commit 22e189e

Browse files
committed
Add and use an arena for NameBindings
1 parent 7366d10 commit 22e189e

File tree

3 files changed

+48
-40
lines changed

3 files changed

+48
-40
lines changed

src/librustc_resolve/build_reduced_graph.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,14 +101,14 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
101101
fn try_define<T>(&self, parent: Module<'b>, name: Name, ns: Namespace, def: T)
102102
where T: ToNameBinding<'b>
103103
{
104-
parent.try_define_child(name, ns, def.to_name_binding());
104+
parent.try_define_child(name, ns, self.new_name_binding(def.to_name_binding()));
105105
}
106106

107107
/// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined;
108108
/// otherwise, reports an error.
109109
fn define<T: ToNameBinding<'b>>(&self, parent: Module<'b>, name: Name, ns: Namespace, def: T) {
110-
let binding = def.to_name_binding();
111-
let old_binding = match parent.try_define_child(name, ns, binding.clone()) {
110+
let binding = self.new_name_binding(def.to_name_binding());
111+
let old_binding = match parent.try_define_child(name, ns, binding) {
112112
Some(old_binding) => old_binding,
113113
None => return,
114114
};

src/librustc_resolve/lib.rs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,7 @@ pub struct ModuleS<'a> {
794794
is_public: bool,
795795
is_extern_crate: bool,
796796

797-
children: RefCell<HashMap<(Name, Namespace), NameBinding<'a>>>,
797+
children: RefCell<HashMap<(Name, Namespace), &'a NameBinding<'a>>>,
798798
imports: RefCell<Vec<ImportDirective>>,
799799

800800
// The anonymous children of this node. Anonymous children are pseudo-
@@ -855,21 +855,21 @@ impl<'a> ModuleS<'a> {
855855
}
856856
}
857857

858-
fn get_child(&self, name: Name, ns: Namespace) -> Option<NameBinding<'a>> {
858+
fn get_child(&self, name: Name, ns: Namespace) -> Option<&'a NameBinding<'a>> {
859859
self.children.borrow().get(&(name, ns)).cloned()
860860
}
861861

862862
// If the name is not yet defined, define the name and return None.
863863
// Otherwise, return the existing definition.
864-
fn try_define_child(&self, name: Name, ns: Namespace, binding: NameBinding<'a>)
865-
-> Option<NameBinding<'a>> {
864+
fn try_define_child(&self, name: Name, ns: Namespace, binding: &'a NameBinding<'a>)
865+
-> Option<&'a NameBinding<'a>> {
866866
match self.children.borrow_mut().entry((name, ns)) {
867867
hash_map::Entry::Vacant(entry) => { entry.insert(binding); None }
868-
hash_map::Entry::Occupied(entry) => { Some(entry.get().clone()) },
868+
hash_map::Entry::Occupied(entry) => { Some(entry.get()) },
869869
}
870870
}
871871

872-
fn for_each_local_child<F: FnMut(Name, Namespace, &NameBinding<'a>)>(&self, mut f: F) {
872+
fn for_each_local_child<F: FnMut(Name, Namespace, &'a NameBinding<'a>)>(&self, mut f: F) {
873873
for (&(name, ns), name_binding) in self.children.borrow().iter() {
874874
if !name_binding.is_extern_crate() {
875875
f(name, ns, name_binding)
@@ -1112,6 +1112,7 @@ pub struct Resolver<'a, 'tcx: 'a> {
11121112

11131113
pub struct ResolverArenas<'a> {
11141114
modules: arena::TypedArena<ModuleS<'a>>,
1115+
name_bindings: arena::TypedArena<NameBinding<'a>>,
11151116
}
11161117

11171118
#[derive(PartialEq)]
@@ -1177,6 +1178,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
11771178
fn arenas() -> ResolverArenas<'a> {
11781179
ResolverArenas {
11791180
modules: arena::TypedArena::new(),
1181+
name_bindings: arena::TypedArena::new(),
11801182
}
11811183
}
11821184

@@ -1188,6 +1190,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
11881190
self.arenas.modules.alloc(ModuleS::new(parent_link, def, external, is_public))
11891191
}
11901192

1193+
fn new_name_binding(&self, name_binding: NameBinding<'a>) -> &'a NameBinding<'a> {
1194+
self.arenas.name_bindings.alloc(name_binding)
1195+
}
1196+
11911197
fn new_extern_crate_module(&self, parent_link: ParentLink<'a>, def: Def) -> Module<'a> {
11921198
let mut module = ModuleS::new(parent_link, Some(def), false, true);
11931199
module.is_extern_crate = true;
@@ -1234,7 +1240,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
12341240
-> ResolveResult<(Module<'a>, LastPrivate)> {
12351241
fn search_parent_externals<'a>(needle: Name, module: Module<'a>) -> Option<Module<'a>> {
12361242
match module.get_child(needle, TypeNS) {
1237-
Some(ref binding) if binding.is_extern_crate() => Some(module),
1243+
Some(binding) if binding.is_extern_crate() => Some(module),
12381244
_ => match module.parent_link {
12391245
ModuleParentLink(ref parent, _) => {
12401246
search_parent_externals(needle, parent)
@@ -1424,7 +1430,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
14241430
name: Name,
14251431
namespace: Namespace,
14261432
record_used: bool)
1427-
-> ResolveResult<(NameBinding<'a>, bool)> {
1433+
-> ResolveResult<(&'a NameBinding<'a>, bool)> {
14281434
debug!("(resolving item in lexical scope) resolving `{}` in namespace {:?} in `{}`",
14291435
name,
14301436
namespace,
@@ -1554,7 +1560,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
15541560
namespace: Namespace,
15551561
allow_private_imports: bool,
15561562
record_used: bool)
1557-
-> ResolveResult<(NameBinding<'a>, bool)> {
1563+
-> ResolveResult<(&'a NameBinding<'a>, bool)> {
15581564
debug!("(resolving name in module) resolving `{}` in `{}`",
15591565
name,
15601566
module_to_string(&*module_));
@@ -1580,7 +1586,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
15801586
debug!("(resolving name in module) import unresolved; bailing out");
15811587
return Indeterminate;
15821588
}
1583-
if let Some(binding) = import_resolution.binding.clone() {
1589+
if let Some(binding) = import_resolution.binding {
15841590
debug!("(resolving name in module) resolved to import");
15851591
if record_used {
15861592
self.record_import_use(name, namespace, &import_resolution);
@@ -2619,7 +2625,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
26192625
Success((binding, _)) => {
26202626
debug!("(resolve bare identifier pattern) succeeded in finding {} at {:?}",
26212627
name,
2622-
&binding);
2628+
binding);
26232629
match binding.def() {
26242630
None => {
26252631
panic!("resolved name in the value namespace to a set of name bindings \
@@ -3058,7 +3064,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
30583064
match this.primitive_type_table.primitive_types.get(last_name) {
30593065
Some(_) => None,
30603066
None => this.current_module.get_child(*last_name, TypeNS)
3061-
.as_ref()
30623067
.and_then(NameBinding::module)
30633068
}
30643069
} else {
@@ -3456,7 +3461,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
34563461
for (&(_, ns), import) in search_module.import_resolutions.borrow().iter() {
34573462
if ns != TypeNS { continue }
34583463
let binding = match import.binding {
3459-
Some(ref binding) => binding,
3464+
Some(binding) => binding,
34603465
None => continue,
34613466
};
34623467
let did = match binding.def() {

src/librustc_resolve/resolve_imports.rs

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ impl ImportDirective {
8181

8282
// Given the binding to which this directive resolves in a particular namespace,
8383
// this returns the binding for the name this directive defines in that namespace.
84-
fn import<'a>(&self, mut binding: NameBinding<'a>) -> NameBinding<'a> {
84+
fn import<'a>(&self, binding: &'a NameBinding<'a>) -> NameBinding<'a> {
85+
let mut binding = binding.clone();
8586
if self.shadowable == Shadowable::Always {
8687
binding.modifiers = binding.modifiers | DefModifiers::PRELUDE;
8788
}
@@ -107,7 +108,7 @@ pub struct ImportResolution<'a> {
107108
pub is_public: bool,
108109

109110
/// Resolution of the name in the namespace
110-
pub binding: Option<NameBinding<'a>>,
111+
pub binding: Option<&'a NameBinding<'a>>,
111112

112113
/// The source node of the `use` directive
113114
pub id: NodeId,
@@ -125,7 +126,7 @@ impl<'a> ImportResolution<'a> {
125126

126127
pub fn shadowable(&self) -> Shadowable {
127128
match self.binding {
128-
Some(ref binding) if binding.defined_with(DefModifiers::PRELUDE) =>
129+
Some(binding) if binding.defined_with(DefModifiers::PRELUDE) =>
129130
Shadowable::Always,
130131
Some(_) => Shadowable::Never,
131132
None => Shadowable::Always,
@@ -195,7 +196,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
195196

196197
/// Resolves an `ImportResolvingError` into the correct enum discriminant
197198
/// and passes that on to `resolve_error`.
198-
fn import_resolving_error(&self, e: ImportResolvingError) {
199+
fn import_resolving_error(&self, e: ImportResolvingError<'b>) {
199200
// If it's a single failed import then create a "fake" import
200201
// resolution for it so that later resolve stages won't complain.
201202
if let SingleImport(target, _) = e.import_directive.subclass {
@@ -213,11 +214,11 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
213214
debug!("(resolving import error) adding fake target to import resolution of `{}`",
214215
target);
215216

216-
let dummy_binding = NameBinding {
217+
let dummy_binding = self.resolver.new_name_binding(NameBinding {
217218
modifiers: DefModifiers::IMPORTABLE,
218219
def_or_module: DefOrModule::Def(Def::Err),
219220
span: None,
220-
};
221+
});
221222

222223
resolution.binding = Some(dummy_binding);
223224
}
@@ -367,7 +368,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
367368
name: Name,
368369
ns: Namespace,
369370
importing_module: Module<'b>) // Module importing the name
370-
-> (ResolveResult<NameBinding<'b>>, bool) {
371+
-> (ResolveResult<&'b NameBinding<'b>>, bool) {
371372
build_reduced_graph::populate_module_if_necessary(self.resolver, module);
372373
if let Some(name_binding) = module.get_child(name, ns) {
373374
if name_binding.is_extern_crate() {
@@ -397,7 +398,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
397398
return (Failed(None), false);
398399
}
399400

400-
if let Some(binding) = resolution.binding.clone() {
401+
if let Some(binding) = resolution.binding {
401402
self.resolver.record_import_use(name, ns, &resolution);
402403
(Success(binding), true)
403404
} else {
@@ -455,9 +456,9 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
455456
self.resolve_name_in_module(target_module, source, TypeNS, module_);
456457

457458
match (&value_result, &type_result) {
458-
(&Success(ref name_binding), _) if !value_used_reexport &&
459-
directive.is_public &&
460-
!name_binding.is_public() => {
459+
(&Success(name_binding), _) if !value_used_reexport &&
460+
directive.is_public &&
461+
!name_binding.is_public() => {
461462
let msg = format!("`{}` is private, and cannot be reexported", source);
462463
let note_msg = format!("Consider marking `{}` as `pub` in the imported module",
463464
source);
@@ -466,8 +467,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
466467
.emit();
467468
}
468469

469-
(_, &Success(ref name_binding)) if !type_used_reexport &&
470-
directive.is_public => {
470+
(_, &Success(name_binding)) if !type_used_reexport && directive.is_public => {
471471
if !name_binding.is_public() {
472472
let msg = format!("`{}` is private, and cannot be reexported", source);
473473
let note_msg =
@@ -519,7 +519,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
519519

520520
{
521521
let mut check_and_write_import = |namespace, result, used_public: &mut bool| {
522-
let result: &ResolveResult<NameBinding> = result;
522+
let result: &ResolveResult<&NameBinding> = result;
523523

524524
let import_resolution = import_resolutions.get_mut(&(target, namespace)).unwrap();
525525
let namespace_name = match namespace {
@@ -528,7 +528,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
528528
};
529529

530530
match *result {
531-
Success(ref name_binding) => {
531+
Success(name_binding) => {
532532
debug!("(resolving single import) found {:?} target: {:?}",
533533
namespace_name,
534534
name_binding.def());
@@ -541,7 +541,8 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
541541
directive.span,
542542
target);
543543

544-
import_resolution.binding = Some(directive.import(name_binding.clone()));
544+
import_resolution.binding =
545+
Some(self.resolver.new_name_binding(directive.import(name_binding)));
545546
import_resolution.id = directive.id;
546547
import_resolution.is_public = directive.is_public;
547548

@@ -679,14 +680,15 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
679680
.or_insert_with(|| ImportResolution::new(id, is_public));
680681

681682
match target_import_resolution.binding {
682-
Some(ref binding) if target_import_resolution.is_public => {
683+
Some(binding) if target_import_resolution.is_public => {
683684
self.check_for_conflicting_import(&dest_import_resolution,
684685
import_directive.span,
685686
name,
686687
ns);
687688
dest_import_resolution.id = id;
688689
dest_import_resolution.is_public = is_public;
689-
dest_import_resolution.binding = Some(import_directive.import(binding.clone()));
690+
dest_import_resolution.binding =
691+
Some(self.resolver.new_name_binding(import_directive.import(binding)));
690692
self.add_export(module_, name, &dest_import_resolution);
691693
}
692694
_ => {}
@@ -701,7 +703,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
701703
target_module,
702704
import_directive,
703705
(name, ns),
704-
name_binding.clone());
706+
name_binding);
705707
});
706708

707709
// Record the destination of this import
@@ -723,7 +725,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
723725
containing_module: Module<'b>,
724726
import_directive: &ImportDirective,
725727
(name, ns): (Name, Namespace),
726-
name_binding: NameBinding<'b>) {
728+
name_binding: &'b NameBinding<'b>) {
727729
let id = import_directive.id;
728730
let is_public = import_directive.is_public;
729731

@@ -761,7 +763,8 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
761763
name);
762764
span_err!(self.resolver.session, import_directive.span, E0251, "{}", msg);
763765
} else {
764-
dest_import_resolution.binding = Some(import_directive.import(name_binding.clone()));
766+
dest_import_resolution.binding =
767+
Some(self.resolver.new_name_binding(import_directive.import(name_binding)));
765768
dest_import_resolution.id = id;
766769
dest_import_resolution.is_public = is_public;
767770
self.add_export(module_, name, &dest_import_resolution);
@@ -799,7 +802,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
799802
binding.is_some());
800803

801804
match *binding {
802-
Some(ref binding) if !binding.defined_with(DefModifiers::PRELUDE) => {
805+
Some(binding) if !binding.defined_with(DefModifiers::PRELUDE) => {
803806
let ns_word = match namespace {
804807
TypeNS => {
805808
match binding.module() {
@@ -857,7 +860,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
857860

858861
if ns == ValueNS {
859862
match import.binding {
860-
Some(ref binding) if !binding.defined_with(DefModifiers::PRELUDE) => {
863+
Some(binding) if !binding.defined_with(DefModifiers::PRELUDE) => {
861864
let mut err = struct_span_err!(self.resolver.session,
862865
import_span,
863866
E0255,
@@ -873,7 +876,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
873876
}
874877
} else {
875878
match import.binding {
876-
Some(ref binding) if !binding.defined_with(DefModifiers::PRELUDE) => {
879+
Some(binding) if !binding.defined_with(DefModifiers::PRELUDE) => {
877880
if name_binding.is_extern_crate() {
878881
let msg = format!("import `{0}` conflicts with imported crate \
879882
in this module (maybe you meant `use {0}::*`?)",

0 commit comments

Comments
 (0)