Add a field pub_outstanding_references
to NameResolution
.
Add an argument `allow_private_imports` to some methods.
This commit is contained in:
parent
45f0ce71c1
commit
61f1f4d21e
@ -681,8 +681,8 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
|
|||||||
|
|
||||||
match subclass {
|
match subclass {
|
||||||
SingleImport { target, .. } => {
|
SingleImport { target, .. } => {
|
||||||
module_.increment_outstanding_references_for(target, ValueNS);
|
module_.increment_outstanding_references_for(target, ValueNS, is_public);
|
||||||
module_.increment_outstanding_references_for(target, TypeNS);
|
module_.increment_outstanding_references_for(target, TypeNS, is_public);
|
||||||
}
|
}
|
||||||
GlobImport => {
|
GlobImport => {
|
||||||
// Set the glob flag. This tells us that we don't know the
|
// Set the glob flag. This tells us that we don't know the
|
||||||
|
@ -125,7 +125,8 @@ impl ImportDirective {
|
|||||||
/// Records information about the resolution of a name in a module.
|
/// Records information about the resolution of a name in a module.
|
||||||
pub struct NameResolution<'a> {
|
pub struct NameResolution<'a> {
|
||||||
/// The number of unresolved single imports that could define the name.
|
/// The number of unresolved single imports that could define the name.
|
||||||
outstanding_references: usize,
|
outstanding_references: u32,
|
||||||
|
pub_outstanding_references: u32,
|
||||||
/// The least shadowable known binding for this name, or None if there are no known bindings.
|
/// The least shadowable known binding for this name, or None if there are no known bindings.
|
||||||
pub binding: Option<&'a NameBinding<'a>>,
|
pub binding: Option<&'a NameBinding<'a>>,
|
||||||
duplicate_globs: Vec<&'a NameBinding<'a>>,
|
duplicate_globs: Vec<&'a NameBinding<'a>>,
|
||||||
@ -151,7 +152,7 @@ impl<'a> NameResolution<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns the resolution of the name assuming no more globs will define it.
|
// Returns the resolution of the name assuming no more globs will define it.
|
||||||
fn result(&self) -> ResolveResult<&'a NameBinding<'a>> {
|
fn result(&self, allow_private_imports: bool) -> ResolveResult<&'a NameBinding<'a>> {
|
||||||
match self.binding {
|
match self.binding {
|
||||||
Some(binding) if !binding.defined_with(DefModifiers::GLOB_IMPORTED) => Success(binding),
|
Some(binding) if !binding.defined_with(DefModifiers::GLOB_IMPORTED) => Success(binding),
|
||||||
_ if self.outstanding_references > 0 => Indeterminate,
|
_ if self.outstanding_references > 0 => Indeterminate,
|
||||||
@ -162,8 +163,9 @@ impl<'a> NameResolution<'a> {
|
|||||||
|
|
||||||
// Returns Some(the resolution of the name), or None if the resolution depends
|
// Returns Some(the resolution of the name), or None if the resolution depends
|
||||||
// on whether more globs can define the name.
|
// on whether more globs can define the name.
|
||||||
fn try_result(&self) -> Option<ResolveResult<&'a NameBinding<'a>>> {
|
fn try_result(&self, allow_private_imports: bool)
|
||||||
match self.result() {
|
-> Option<ResolveResult<&'a NameBinding<'a>>> {
|
||||||
|
match self.result(allow_private_imports) {
|
||||||
Success(binding) if binding.defined_with(DefModifiers::PRELUDE) => None,
|
Success(binding) if binding.defined_with(DefModifiers::PRELUDE) => None,
|
||||||
Failed(_) => None,
|
Failed(_) => None,
|
||||||
result @ _ => Some(result),
|
result @ _ => Some(result),
|
||||||
@ -200,7 +202,7 @@ impl<'a> ::ModuleS<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let resolution = resolutions.get(&(name, ns)).cloned().unwrap_or_default();
|
let resolution = resolutions.get(&(name, ns)).cloned().unwrap_or_default();
|
||||||
if let Some(result) = resolution.try_result() {
|
if let Some(result) = resolution.try_result(allow_private_imports) {
|
||||||
// If the resolution doesn't depend on glob definability, check privacy and return.
|
// If the resolution doesn't depend on glob definability, check privacy and return.
|
||||||
return result.and_then(|binding| {
|
return result.and_then(|binding| {
|
||||||
let allowed = allow_private_imports || !binding.is_import() || binding.is_public();
|
let allowed = allow_private_imports || !binding.is_import() || binding.is_public();
|
||||||
@ -234,7 +236,7 @@ impl<'a> ::ModuleS<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resolution.result()
|
resolution.result(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.
|
||||||
@ -246,15 +248,26 @@ impl<'a> ::ModuleS<'a> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn increment_outstanding_references_for(&self, name: Name, ns: Namespace) {
|
pub fn increment_outstanding_references_for(&self, name: Name, ns: Namespace, is_public: bool) {
|
||||||
let mut resolutions = self.resolutions.borrow_mut();
|
let mut resolutions = self.resolutions.borrow_mut();
|
||||||
resolutions.entry((name, ns)).or_insert_with(Default::default).outstanding_references += 1;
|
let resolution = resolutions.entry((name, ns)).or_insert_with(Default::default);
|
||||||
|
resolution.outstanding_references += 1;
|
||||||
|
if is_public {
|
||||||
|
resolution.pub_outstanding_references += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decrement_outstanding_references_for(&self, name: Name, ns: Namespace) {
|
fn decrement_outstanding_references_for(&self, name: Name, ns: Namespace, is_public: bool) {
|
||||||
self.update_resolution(name, ns, |resolution| match resolution.outstanding_references {
|
let decrement_references = |count: &mut _| {
|
||||||
0 => panic!("No more outstanding references!"),
|
assert!(*count > 0);
|
||||||
ref mut outstanding_references => *outstanding_references -= 1,
|
*count -= 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.update_resolution(name, ns, |resolution| {
|
||||||
|
decrement_references(&mut resolution.outstanding_references);
|
||||||
|
if is_public {
|
||||||
|
decrement_references(&mut resolution.pub_outstanding_references);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,11 +278,11 @@ impl<'a> ::ModuleS<'a> {
|
|||||||
{
|
{
|
||||||
let mut resolutions = self.resolutions.borrow_mut();
|
let mut resolutions = self.resolutions.borrow_mut();
|
||||||
let resolution = resolutions.entry((name, ns)).or_insert_with(Default::default);
|
let resolution = resolutions.entry((name, ns)).or_insert_with(Default::default);
|
||||||
let was_success = resolution.try_result().and_then(ResolveResult::success).is_some();
|
let was_success = resolution.try_result(false).and_then(ResolveResult::success).is_some();
|
||||||
|
|
||||||
let t = update(resolution);
|
let t = update(resolution);
|
||||||
if !was_success {
|
if !was_success {
|
||||||
if let Some(Success(binding)) = resolution.try_result() {
|
if let Some(Success(binding)) = resolution.try_result(false) {
|
||||||
self.define_in_glob_importers(name, ns, binding);
|
self.define_in_glob_importers(name, ns, binding);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -460,10 +473,14 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
|
|||||||
let mut resolve_in_ns = |ns, determined: bool| {
|
let mut resolve_in_ns = |ns, determined: bool| {
|
||||||
// Temporarily count the directive as determined so that the resolution fails
|
// Temporarily count the directive as determined so that the resolution fails
|
||||||
// (as opposed to being indeterminate) when it can only be defined by the directive.
|
// (as opposed to being indeterminate) when it can only be defined by the directive.
|
||||||
if !determined { module_.decrement_outstanding_references_for(target, ns) }
|
if !determined {
|
||||||
|
module_.decrement_outstanding_references_for(target, ns, directive.is_public)
|
||||||
|
}
|
||||||
let result =
|
let result =
|
||||||
self.resolver.resolve_name_in_module(target_module, source, ns, false, true);
|
self.resolver.resolve_name_in_module(target_module, source, ns, false, true);
|
||||||
if !determined { module_.increment_outstanding_references_for(target, ns) }
|
if !determined {
|
||||||
|
module_.increment_outstanding_references_for(target, ns, directive.is_public)
|
||||||
|
}
|
||||||
result
|
result
|
||||||
};
|
};
|
||||||
(resolve_in_ns(ValueNS, value_determined.get()),
|
(resolve_in_ns(ValueNS, value_determined.get()),
|
||||||
@ -494,7 +511,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
|
|||||||
self.report_conflict(target, ns, &directive.import(binding, None), old_binding);
|
self.report_conflict(target, ns, &directive.import(binding, None), old_binding);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
module_.decrement_outstanding_references_for(target, ns);
|
module_.decrement_outstanding_references_for(target, ns, directive.is_public);
|
||||||
}
|
}
|
||||||
|
|
||||||
match (&value_result, &type_result) {
|
match (&value_result, &type_result) {
|
||||||
@ -601,7 +618,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (&(name, ns), resolution) in target_module.resolutions.borrow().iter() {
|
for (&(name, ns), resolution) in target_module.resolutions.borrow().iter() {
|
||||||
if let Some(Success(binding)) = resolution.try_result() {
|
if let Some(Success(binding)) = resolution.try_result(false) {
|
||||||
if binding.defined_with(DefModifiers::IMPORTABLE | DefModifiers::PUBLIC) {
|
if binding.defined_with(DefModifiers::IMPORTABLE | DefModifiers::PUBLIC) {
|
||||||
let _ = module_.try_define_child(name, ns, directive.import(binding, None));
|
let _ = module_.try_define_child(name, ns, directive.import(binding, None));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user