resolve: Remove record_exports, fixes #4953

This commit is contained in:
Jeffrey Seyfried 2016-01-12 04:55:21 +00:00
parent c12c42de0a
commit a353490e6f
4 changed files with 22 additions and 161 deletions

View File

@ -329,9 +329,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
// This code is here instead of in visit_item so that the
// crate module gets processed as well.
if self.prev_level.is_some() {
for export in self.export_map.get(&id).expect("module isn't found in export map") {
if let Some(node_id) = self.tcx.map.as_local_node_id(export.def_id) {
self.update(node_id, Some(AccessLevel::Exported));
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) {
self.update(node_id, Some(AccessLevel::Exported));
}
}
}
}

View File

@ -101,7 +101,6 @@ use resolve_imports::Shadowable;
pub mod diagnostics;
mod check_unused;
mod record_exports;
mod build_reduced_graph;
mod resolve_imports;
@ -4014,9 +4013,6 @@ pub fn create_resolver<'a, 'tcx>(session: &'a Session,
resolve_imports::resolve_imports(&mut resolver);
session.abort_if_errors();
record_exports::record(&mut resolver);
session.abort_if_errors();
resolver
}

View File

@ -1,154 +0,0 @@
// Copyright 2012-2014 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.
// Export recording
//
// This pass simply determines what all "export" keywords refer to and
// writes the results into the export map.
//
// FIXME #4953 This pass will be removed once exports change to per-item.
// Then this operation can simply be performed as part of item (or import)
// processing.
use {Module, NameBinding, Resolver};
use Namespace::{TypeNS, ValueNS};
use build_reduced_graph;
use module_to_string;
use rustc::middle::def::Export;
use syntax::ast;
use std::ops::{Deref, DerefMut};
struct ExportRecorder<'a, 'b: 'a, 'tcx: 'b> {
resolver: &'a mut Resolver<'b, 'tcx>,
}
// Deref and DerefMut impls allow treating ExportRecorder as Resolver.
impl<'a, 'b, 'tcx:'b> Deref for ExportRecorder<'a, 'b, 'tcx> {
type Target = Resolver<'b, 'tcx>;
fn deref<'c>(&'c self) -> &'c Resolver<'b, 'tcx> {
&*self.resolver
}
}
impl<'a, 'b, 'tcx:'b> DerefMut for ExportRecorder<'a, 'b, 'tcx> {
fn deref_mut<'c>(&'c mut self) -> &'c mut Resolver<'b, 'tcx> {
&mut *self.resolver
}
}
impl<'a, 'b, 'tcx> ExportRecorder<'a, 'b, 'tcx> {
fn record_exports_for_module_subtree(&mut self, module_: Module<'b>) {
// If this isn't a local krate, then bail out. We don't need to record
// exports for nonlocal crates.
match module_.def_id() {
Some(def_id) if def_id.is_local() => {
// OK. Continue.
debug!("(recording exports for module subtree) recording exports for local \
module `{}`",
module_to_string(module_));
}
None => {
// Record exports for the root module.
debug!("(recording exports for module subtree) recording exports for root module \
`{}`",
module_to_string(module_));
}
Some(_) => {
// Bail out.
debug!("(recording exports for module subtree) not recording exports for `{}`",
module_to_string(module_));
return;
}
}
self.record_exports_for_module(module_);
build_reduced_graph::populate_module_if_necessary(self.resolver, &module_);
for (_, child_name_bindings) in module_.children.borrow().iter() {
match child_name_bindings.type_ns.module() {
None => {
// Nothing to do.
}
Some(child_module) => {
self.record_exports_for_module_subtree(child_module);
}
}
}
for (_, child_module) in module_.anonymous_children.borrow().iter() {
self.record_exports_for_module_subtree(child_module);
}
}
fn record_exports_for_module(&mut self, module_: Module<'b>) {
let mut exports = Vec::new();
self.add_exports_for_module(&mut exports, module_);
match module_.def_id() {
Some(def_id) => {
let node_id = self.ast_map.as_local_node_id(def_id).unwrap();
self.export_map.insert(node_id, exports);
debug!("(computing exports) writing exports for {} (some)", node_id);
}
None => {}
}
}
fn add_export_of_namebinding(&mut self,
exports: &mut Vec<Export>,
name: ast::Name,
namebinding: &NameBinding) {
match namebinding.def() {
Some(d) => {
debug!("(computing exports) YES: export '{}' => {:?}",
name,
d.def_id());
exports.push(Export {
name: name,
def_id: d.def_id(),
});
}
d_opt => {
debug!("(computing exports) NO: {:?}", d_opt);
}
}
}
fn add_exports_for_module(&mut self, exports: &mut Vec<Export>, module_: Module<'b>) {
for (name, import_resolution) in module_.import_resolutions.borrow().iter() {
let xs = [TypeNS, ValueNS];
for &ns in &xs {
if !import_resolution[ns].is_public {
continue;
}
match import_resolution[ns].target {
Some(ref target) => {
debug!("(computing exports) maybe export '{}'", name);
self.add_export_of_namebinding(exports, *name, &target.binding)
}
_ => (),
}
}
}
}
}
pub fn record(resolver: &mut Resolver) {
let mut recorder = ExportRecorder { resolver: resolver };
let root_module = recorder.graph_root;
recorder.record_exports_for_module_subtree(root_module);
}

View File

@ -688,6 +688,8 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
id: directive.id,
is_public: directive.is_public
};
self.add_export(module_, target, &import_resolution[namespace]);
*used_public = name_binding.is_public();
}
UnboundResult => {
@ -827,6 +829,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
dest_import_resolution[ns] = ImportResolution {
id: id, is_public: is_public, target: Some(target.clone())
};
self.add_export(module_, *name, &dest_import_resolution[ns]);
}
_ => {}
}
@ -919,6 +922,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
id: id,
is_public: is_public
};
self.add_export(module_, name, &dest_import_resolution[namespace]);
}
} else {
// FIXME #30159: This is required for backwards compatability.
@ -935,6 +939,19 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
name);
}
fn add_export(&mut self, module: Module<'b>, name: Name, resolution: &ImportResolution<'b>) {
if !resolution.is_public { return }
let node_id = match module.def_id() {
Some(def_id) => self.resolver.ast_map.as_local_node_id(def_id).unwrap(),
None => return,
};
let export = match resolution.target.as_ref().unwrap().binding.def() {
Some(def) => Export { name: name, def_id: def.def_id() },
None => return,
};
self.resolver.export_map.entry(node_id).or_insert(Vec::new()).push(export);
}
/// Checks that imported names and items don't have the same name.
fn check_for_conflicting_import(&mut self,
import_resolution: &ImportResolutionPerNamespace,