De-genericize `try_define`.

This commit is contained in:
Jeffrey Seyfried 2016-11-29 02:53:00 +00:00
parent 59de7f8f04
commit aa19274b72
3 changed files with 30 additions and 28 deletions

View File

@ -16,7 +16,8 @@
use macros::{InvocationData, LegacyScope}; use macros::{InvocationData, LegacyScope};
use resolve_imports::ImportDirective; use resolve_imports::ImportDirective;
use resolve_imports::ImportDirectiveSubclass::{self, GlobImport, SingleImport}; use resolve_imports::ImportDirectiveSubclass::{self, GlobImport, SingleImport};
use {Resolver, Module, ModuleS, ModuleKind, NameBinding, NameBindingKind, ToNameBinding}; use {Module, ModuleS, ModuleKind, NameBinding, NameBindingKind, ToNameBinding};
use {Resolver, ResolverArenas};
use Namespace::{self, TypeNS, ValueNS, MacroNS}; use Namespace::{self, TypeNS, ValueNS, MacroNS};
use {resolve_error, resolve_struct_error, ResolutionError}; use {resolve_error, resolve_struct_error, ResolutionError};
@ -45,24 +46,24 @@ use syntax::visit::{self, Visitor};
use syntax_pos::{Span, DUMMY_SP}; use syntax_pos::{Span, DUMMY_SP};
impl<'a> ToNameBinding<'a> for (Module<'a>, ty::Visibility, Span, Mark) { impl<'a> ToNameBinding<'a> for (Module<'a>, ty::Visibility, Span, Mark) {
fn to_name_binding(self) -> NameBinding<'a> { fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> {
NameBinding { arenas.alloc_name_binding(NameBinding {
kind: NameBindingKind::Module(self.0), kind: NameBindingKind::Module(self.0),
vis: self.1, vis: self.1,
span: self.2, span: self.2,
expansion: self.3, expansion: self.3,
} })
} }
} }
impl<'a> ToNameBinding<'a> for (Def, ty::Visibility, Span, Mark) { impl<'a> ToNameBinding<'a> for (Def, ty::Visibility, Span, Mark) {
fn to_name_binding(self) -> NameBinding<'a> { fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> {
NameBinding { arenas.alloc_name_binding(NameBinding {
kind: NameBindingKind::Def(self.0), kind: NameBindingKind::Def(self.0),
vis: self.1, vis: self.1,
span: self.2, span: self.2,
expansion: self.3, expansion: self.3,
} })
} }
} }
@ -79,8 +80,8 @@ impl<'b> Resolver<'b> {
fn define<T>(&mut self, parent: Module<'b>, ident: Ident, ns: Namespace, def: T) fn define<T>(&mut self, parent: Module<'b>, ident: Ident, ns: Namespace, def: T)
where T: ToNameBinding<'b>, where T: ToNameBinding<'b>,
{ {
let binding = def.to_name_binding(); let binding = def.to_name_binding(self.arenas);
if let Err(old_binding) = self.try_define(parent, ident, ns, binding.clone()) { if let Err(old_binding) = self.try_define(parent, ident, ns, binding) {
self.report_conflict(parent, ident, ns, old_binding, &binding); self.report_conflict(parent, ident, ns, old_binding, &binding);
} }
} }
@ -238,8 +239,8 @@ impl<'b> Resolver<'b> {
// n.b. we don't need to look at the path option here, because cstore already did // n.b. we don't need to look at the path option here, because cstore already did
let crate_id = self.session.cstore.extern_mod_stmt_cnum(item.id).unwrap(); let crate_id = self.session.cstore.extern_mod_stmt_cnum(item.id).unwrap();
let module = self.get_extern_crate_root(crate_id); let module = self.get_extern_crate_root(crate_id);
let binding = (module, ty::Visibility::Public, sp, expansion).to_name_binding(); let binding =
let binding = self.arenas.alloc_name_binding(binding); (module, ty::Visibility::Public, sp, expansion).to_name_binding(self.arenas);
let directive = self.arenas.alloc_import_directive(ImportDirective { let directive = self.arenas.alloc_import_directive(ImportDirective {
id: item.id, id: item.id,
parent: parent, parent: parent,

View File

@ -875,11 +875,11 @@ pub struct NameBinding<'a> {
} }
pub trait ToNameBinding<'a> { pub trait ToNameBinding<'a> {
fn to_name_binding(self) -> NameBinding<'a>; fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a>;
} }
impl<'a> ToNameBinding<'a> for NameBinding<'a> { impl<'a> ToNameBinding<'a> for &'a NameBinding<'a> {
fn to_name_binding(self) -> NameBinding<'a> { fn to_name_binding(self, _: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> {
self self
} }
} }

View File

@ -12,7 +12,7 @@ use self::ImportDirectiveSubclass::*;
use {AmbiguityError, Module, PerNS}; use {AmbiguityError, Module, PerNS};
use Namespace::{self, TypeNS, MacroNS}; use Namespace::{self, TypeNS, MacroNS};
use {NameBinding, NameBindingKind, PathResult, PathScope, PrivacyError, ToNameBinding}; use {NameBinding, NameBindingKind, PathResult, PathScope, PrivacyError};
use Resolver; use Resolver;
use {names_to_string, module_to_string}; use {names_to_string, module_to_string};
use {resolve_error, ResolutionError}; use {resolve_error, ResolutionError};
@ -273,7 +273,7 @@ impl<'a> Resolver<'a> {
// Given a binding and an import directive that resolves to it, // Given a binding and an import directive that resolves to it,
// return the corresponding binding defined by the import directive. // return the corresponding binding defined by the import directive.
pub fn import(&mut self, binding: &'a NameBinding<'a>, directive: &'a ImportDirective<'a>) pub fn import(&mut self, binding: &'a NameBinding<'a>, directive: &'a ImportDirective<'a>)
-> NameBinding<'a> { -> &'a NameBinding<'a> {
let vis = if binding.pseudo_vis().is_at_least(directive.vis.get(), self) || let vis = if binding.pseudo_vis().is_at_least(directive.vis.get(), self) ||
!directive.is_glob() && binding.is_extern_crate() { // c.f. `PRIVATE_IN_PUBLIC` !directive.is_glob() && binding.is_extern_crate() { // c.f. `PRIVATE_IN_PUBLIC`
directive.vis.get() directive.vis.get()
@ -287,7 +287,7 @@ impl<'a> Resolver<'a> {
} }
} }
NameBinding { self.arenas.alloc_name_binding(NameBinding {
kind: NameBindingKind::Import { kind: NameBindingKind::Import {
binding: binding, binding: binding,
directive: directive, directive: directive,
@ -296,16 +296,17 @@ impl<'a> Resolver<'a> {
span: directive.span, span: directive.span,
vis: vis, vis: vis,
expansion: directive.expansion, expansion: directive.expansion,
} })
} }
// Define the name or return the existing binding if there is a collision. // Define the name or return the existing binding if there is a collision.
pub fn try_define<T>(&mut self, module: Module<'a>, ident: Ident, ns: Namespace, binding: T) pub fn try_define(&mut self,
-> Result<(), &'a NameBinding<'a>> module: Module<'a>,
where T: ToNameBinding<'a> ident: Ident,
{ ns: Namespace,
binding: &'a NameBinding<'a>)
-> Result<(), &'a NameBinding<'a>> {
let ident = ident.unhygienize(); let ident = ident.unhygienize();
let binding = self.arenas.alloc_name_binding(binding.to_name_binding());
self.update_resolution(module, ident, ns, |this, resolution| { self.update_resolution(module, ident, ns, |this, resolution| {
if let Some(old_binding) = resolution.binding { if let Some(old_binding) = resolution.binding {
if binding.is_glob_import() { if binding.is_glob_import() {
@ -389,7 +390,7 @@ impl<'a> Resolver<'a> {
let dummy_binding = self.dummy_binding; let dummy_binding = self.dummy_binding;
let dummy_binding = self.import(dummy_binding, directive); let dummy_binding = self.import(dummy_binding, directive);
self.per_ns(|this, ns| { self.per_ns(|this, ns| {
let _ = this.try_define(directive.parent, target, ns, dummy_binding.clone()); let _ = this.try_define(directive.parent, target, ns, dummy_binding);
}); });
} }
} }
@ -516,10 +517,11 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
return return
}; };
let parent = directive.parent;
match result[ns].get() { match result[ns].get() {
Err(Undetermined) => indeterminate = true, Err(Undetermined) => indeterminate = true,
Err(Determined) => { Err(Determined) => {
this.update_resolution(directive.parent, target, ns, |_, resolution| { this.update_resolution(parent, target, ns, |_, resolution| {
resolution.single_imports.directive_failed() resolution.single_imports.directive_failed()
}); });
} }
@ -534,10 +536,9 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
} }
Ok(binding) => { Ok(binding) => {
let imported_binding = this.import(binding, directive); let imported_binding = this.import(binding, directive);
let conflict = this.try_define(directive.parent, target, ns, imported_binding); let conflict = this.try_define(parent, target, ns, imported_binding);
if let Err(old_binding) = conflict { if let Err(old_binding) = conflict {
let binding = &this.import(binding, directive); this.report_conflict(parent, target, ns, imported_binding, old_binding);
this.report_conflict(directive.parent, target, ns, binding, old_binding);
} }
} }
} }