Skip to content

Commit 2f308cb

Browse files
committed
---
yaml --- r: 276811 b: refs/heads/try c: bfb832e h: refs/heads/master i: 276809: 7bc7fd9 276807: 69ed8e8
1 parent 50ebc13 commit 2f308cb

File tree

3 files changed

+115
-105
lines changed

3 files changed

+115
-105
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: 6dbb0e86aec11050480beb76eade6fb805010ba7
33
refs/heads/snap-stage3: 235d77457d80b549dad3ac36d94f235208a1eafb
4-
refs/heads/try: 5ff21f138a1a807205180caf7921256e6dc16790
4+
refs/heads/try: bfb832e7c886a720e0aa847ffd8500621a3152d5
55
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
66
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
77
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try/src/librustc_resolve/build_reduced_graph.rs

Lines changed: 8 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@
1414
//! any imports resolved.
1515
1616
use DefModifiers;
17-
use resolve_imports::ImportDirective;
18-
use resolve_imports::ImportDirectiveSubclass::{self, SingleImport, GlobImport};
17+
use resolve_imports::ImportDirectiveSubclass::{self, GlobImport};
1918
use Module;
2019
use Namespace::{self, TypeNS, ValueNS};
2120
use {NameBinding, NameBindingKind};
@@ -28,7 +27,7 @@ use rustc::middle::def::*;
2827
use rustc::middle::def_id::{CRATE_DEF_INDEX, DefId};
2928
use rustc::ty::VariantKind;
3029

31-
use syntax::ast::{Name, NodeId};
30+
use syntax::ast::Name;
3231
use syntax::attr::AttrMetaMethods;
3332
use syntax::parse::token::special_idents;
3433
use syntax::codemap::{Span, DUMMY_SP};
@@ -152,8 +151,8 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> {
152151
}
153152

154153
let subclass = ImportDirectiveSubclass::single(binding, source_name);
155-
self.build_import_directive(parent,
156-
module_path,
154+
self.unresolved_imports += 1;
155+
parent.add_import_directive(module_path,
157156
subclass,
158157
view_path.span,
159158
item.id,
@@ -203,8 +202,8 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> {
203202
}
204203
};
205204
let subclass = ImportDirectiveSubclass::single(rename, name);
206-
self.build_import_directive(parent,
207-
module_path,
205+
self.unresolved_imports += 1;
206+
parent.add_import_directive(module_path,
208207
subclass,
209208
source_item.span,
210209
source_item.node.id(),
@@ -213,8 +212,8 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> {
213212
}
214213
}
215214
ViewPathGlob(_) => {
216-
self.build_import_directive(parent,
217-
module_path,
215+
self.unresolved_imports += 1;
216+
parent.add_import_directive(module_path,
218217
GlobImport,
219218
view_path.span,
220219
item.id,
@@ -521,32 +520,6 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> {
521520
}
522521
}
523522

524-
/// Creates and adds an import directive to the given module.
525-
fn build_import_directive(&mut self,
526-
module_: Module<'b>,
527-
module_path: Vec<Name>,
528-
subclass: ImportDirectiveSubclass,
529-
span: Span,
530-
id: NodeId,
531-
is_public: bool,
532-
is_prelude: bool) {
533-
// Bump the reference count on the name. Or, if this is a glob, set
534-
// the appropriate flag.
535-
536-
match subclass {
537-
SingleImport { target, .. } => {
538-
module_.increment_outstanding_references_for(target, ValueNS, is_public);
539-
module_.increment_outstanding_references_for(target, TypeNS, is_public);
540-
}
541-
GlobImport => {}
542-
}
543-
544-
let directive =
545-
ImportDirective::new(module_path, subclass, span, id, is_public, is_prelude);
546-
module_.add_import_directive(directive);
547-
self.unresolved_imports += 1;
548-
}
549-
550523
/// Ensures that the reduced graph rooted at the given external module
551524
/// is built, building it if it is not.
552525
pub fn populate_module_if_necessary(&mut self, module: Module<'b>) {

branches/try/src/librustc_resolve/resolve_imports.rs

Lines changed: 106 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -68,24 +68,6 @@ pub struct ImportDirective<'a> {
6868
}
6969

7070
impl<'a> ImportDirective<'a> {
71-
pub fn new(module_path: Vec<Name>,
72-
subclass: ImportDirectiveSubclass,
73-
span: Span,
74-
id: NodeId,
75-
is_public: bool,
76-
is_prelude: bool)
77-
-> Self {
78-
ImportDirective {
79-
module_path: module_path,
80-
target_module: Cell::new(None),
81-
subclass: subclass,
82-
span: span,
83-
id: id,
84-
is_public: is_public,
85-
is_prelude: is_prelude,
86-
}
87-
}
88-
8971
// Given the binding to which this directive resolves in a particular namespace,
9072
// this returns the binding for the name this directive defines in that namespace.
9173
fn import(&self, binding: &'a NameBinding<'a>, privacy_error: Option<Box<PrivacyError<'a>>>)
@@ -111,17 +93,52 @@ impl<'a> ImportDirective<'a> {
11193
}
11294

11395
#[derive(Clone, Default)]
114-
/// Records information about the resolution of a name in a module.
96+
/// Records information about the resolution of a name in a namespace of a module.
11597
pub struct NameResolution<'a> {
116-
/// The number of unresolved single imports of any visibility that could define the name.
117-
outstanding_references: u32,
118-
/// The number of unresolved `pub` single imports that could define the name.
119-
pub_outstanding_references: u32,
98+
/// The single imports that define the name in the namespace.
99+
single_imports: SingleImports<'a>,
120100
/// The least shadowable known binding for this name, or None if there are no known bindings.
121101
pub binding: Option<&'a NameBinding<'a>>,
122102
duplicate_globs: Vec<&'a NameBinding<'a>>,
123103
}
124104

105+
#[derive(Clone, Debug)]
106+
enum SingleImports<'a> {
107+
/// No single imports can define the name in the namespace.
108+
None,
109+
/// Only the given single import can define the name in the namespace.
110+
MaybeOne(&'a ImportDirective<'a>),
111+
/// At least one single import will define the name in the namespace.
112+
AtLeastOne,
113+
}
114+
115+
impl<'a> Default for SingleImports<'a> {
116+
fn default() -> Self {
117+
SingleImports::None
118+
}
119+
}
120+
121+
impl<'a> SingleImports<'a> {
122+
fn add_directive(&mut self, directive: &'a ImportDirective<'a>) {
123+
match *self {
124+
SingleImports::None => *self = SingleImports::MaybeOne(directive),
125+
// If two single imports can define the name in the namespace, we can assume that at
126+
// least one of them will define it since otherwise both would have to define only one
127+
// namespace, leading to a duplicate error.
128+
SingleImports::MaybeOne(_) => *self = SingleImports::AtLeastOne,
129+
SingleImports::AtLeastOne => {}
130+
};
131+
}
132+
133+
fn directive_failed(&mut self) {
134+
match *self {
135+
SingleImports::None => unreachable!(),
136+
SingleImports::MaybeOne(_) => *self = SingleImports::None,
137+
SingleImports::AtLeastOne => {}
138+
}
139+
}
140+
}
141+
125142
impl<'a> NameResolution<'a> {
126143
fn try_define(&mut self, binding: &'a NameBinding<'a>) -> Result<(), &'a NameBinding<'a>> {
127144
if let Some(old_binding) = self.binding {
@@ -140,40 +157,43 @@ impl<'a> NameResolution<'a> {
140157
Ok(())
141158
}
142159

160+
// Returns the binding for the name if it is known or None if it not known.
161+
fn binding(&self) -> Option<&'a NameBinding<'a>> {
162+
self.binding.and_then(|binding| match self.single_imports {
163+
SingleImports::None => Some(binding),
164+
_ if !binding.defined_with(DefModifiers::GLOB_IMPORTED) => Some(binding),
165+
_ => None, // The binding could be shadowed by a single import, so it is not known.
166+
})
167+
}
168+
143169
// Returns Some(the resolution of the name), or None if the resolution depends
144170
// on whether more globs can define the name.
145171
fn try_result(&self, allow_private_imports: bool)
146172
-> Option<ResolveResult<&'a NameBinding<'a>>> {
147173
match self.binding {
148174
Some(binding) if !binding.defined_with(DefModifiers::GLOB_IMPORTED) =>
149-
Some(Success(binding)),
150-
// If (1) we don't allow private imports, (2) no public single import can define the
151-
// name, and (3) no public glob has defined the name, the resolution depends on globs.
152-
_ if !allow_private_imports && self.pub_outstanding_references == 0 &&
153-
!self.binding.map(NameBinding::is_public).unwrap_or(false) => None,
154-
_ if self.outstanding_references > 0 => Some(Indeterminate),
155-
Some(binding) => Some(Success(binding)),
156-
None => None,
157-
}
158-
}
159-
160-
fn increment_outstanding_references(&mut self, is_public: bool) {
161-
self.outstanding_references += 1;
162-
if is_public {
163-
self.pub_outstanding_references += 1;
164-
}
165-
}
166-
167-
fn decrement_outstanding_references(&mut self, is_public: bool) {
168-
let decrement_references = |count: &mut _| {
169-
assert!(*count > 0);
170-
*count -= 1;
175+
return Some(Success(binding)),
176+
_ => {} // Items and single imports are not shadowable
171177
};
172178

173-
decrement_references(&mut self.outstanding_references);
174-
if is_public {
175-
decrement_references(&mut self.pub_outstanding_references);
179+
// Check if a single import can still define the name.
180+
match self.single_imports {
181+
SingleImports::None => {},
182+
SingleImports::AtLeastOne => return Some(Indeterminate),
183+
SingleImports::MaybeOne(directive) => {
184+
// If (1) we don't allow private imports, (2) no public single import can define
185+
// the name, and (3) no public glob has defined the name, the resolution depends
186+
// on whether more globs can define the name.
187+
if !allow_private_imports && !directive.is_public &&
188+
!self.binding.map(NameBinding::is_public).unwrap_or(false) {
189+
return None;
190+
}
191+
192+
return Indeterminate;
193+
}
176194
}
195+
196+
self.binding.map(Success)
177197
}
178198

179199
fn report_conflicts<F: FnMut(&NameBinding, &NameBinding)>(&self, mut report: F) {
@@ -245,35 +265,51 @@ impl<'a> ::ModuleS<'a> {
245265
})
246266
}
247267

248-
pub fn add_import_directive(&self, directive: ImportDirective<'a>) {
249-
let directive = self.arenas.alloc_import_directive(directive);
268+
pub fn add_import_directive(&self,
269+
module_path: Vec<Name>,
270+
subclass: ImportDirectiveSubclass,
271+
span: Span,
272+
id: NodeId,
273+
is_public: bool,
274+
is_prelude: bool) {
275+
let directive = self.arenas.alloc_import_directive(ImportDirective {
276+
module_path: module_path,
277+
target_module: Cell::new(None),
278+
subclass: subclass,
279+
span: span,
280+
id: id,
281+
is_public: is_public,
282+
is_prelude: is_prelude,
283+
});
284+
250285
self.unresolved_imports.borrow_mut().push(directive);
251-
if let GlobImport = directive.subclass {
286+
match directive.subclass {
287+
SingleImport { target, .. } => {
288+
let mut resolutions = self.resolutions.borrow_mut();
289+
for &ns in &[ValueNS, TypeNS] {
290+
resolutions.entry((target, ns)).or_insert_with(Default::default)
291+
.single_imports.add_directive(directive);
292+
}
293+
}
252294
// We don't add prelude imports to the globs since they only affect lexical scopes,
253295
// which are not relevant to import resolution.
254-
if !directive.is_prelude {
255-
self.globs.borrow_mut().push(directive);
256-
}
296+
GlobImport if directive.is_prelude => {}
297+
GlobImport => self.globs.borrow_mut().push(directive),
257298
}
258299
}
259300

260-
pub fn increment_outstanding_references_for(&self, name: Name, ns: Namespace, is_public: bool) {
261-
self.resolutions.borrow_mut().entry((name, ns)).or_insert_with(Default::default)
262-
.increment_outstanding_references(is_public);
263-
}
264-
265301
// Use `update` to mutate the resolution for the name.
266302
// If the resolution becomes a success, define it in the module's glob importers.
267303
fn update_resolution<T, F>(&self, name: Name, ns: Namespace, update: F) -> T
268304
where F: FnOnce(&mut NameResolution<'a>) -> T
269305
{
270306
let mut resolutions = self.resolutions.borrow_mut();
271307
let resolution = resolutions.entry((name, ns)).or_insert_with(Default::default);
272-
let was_success = resolution.try_result(false).and_then(ResolveResult::success).is_some();
308+
let was_known = resolution.binding().is_some();
273309

274310
let t = update(resolution);
275-
if !was_success {
276-
if let Some(Success(binding)) = resolution.try_result(false) {
311+
if !was_known {
312+
if let Some(binding) = resolution.binding() {
277313
self.define_in_glob_importers(name, ns, binding);
278314
}
279315
}
@@ -454,12 +490,13 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
454490
// (as opposed to being indeterminate) when it can only be defined by the directive.
455491
if !determined {
456492
module_.resolutions.borrow_mut().get_mut(&(target, ns)).unwrap()
457-
.decrement_outstanding_references(directive.is_public);
493+
.single_imports.directive_failed();
458494
}
459495
let result =
460496
self.resolver.resolve_name_in_module(target_module, source, ns, false, true);
461497
if !determined {
462-
module_.increment_outstanding_references_for(target, ns, directive.is_public)
498+
module_.resolutions.borrow_mut().get_mut(&(target, ns)).unwrap()
499+
.single_imports.add_directive(directive);
463500
}
464501
result
465502
};
@@ -491,11 +528,11 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
491528
let binding = &directive.import(binding, None);
492529
self.resolver.report_conflict(module_, target, ns, binding, old_binding);
493530
}
531+
} else {
532+
module_.update_resolution(target, ns, |resolution| {
533+
resolution.single_imports.directive_failed();
534+
});
494535
}
495-
496-
module_.update_resolution(target, ns, |resolution| {
497-
resolution.decrement_outstanding_references(directive.is_public);
498-
})
499536
}
500537

501538
match (&value_result, &type_result) {
@@ -605,7 +642,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
605642
target_module.glob_importers.borrow_mut().push((module_, directive));
606643

607644
for (&(name, ns), resolution) in target_module.resolutions.borrow().iter() {
608-
if let Some(Success(binding)) = resolution.try_result(false) {
645+
if let Some(binding) = resolution.binding() {
609646
if binding.defined_with(DefModifiers::IMPORTABLE | DefModifiers::PUBLIC) {
610647
let _ = module_.try_define_child(name, ns, directive.import(binding, None));
611648
}

0 commit comments

Comments
 (0)