Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 10 pull requests #50847

Merged
merged 26 commits into from
May 18, 2018
Merged
Changes from 2 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
4f2cfb5
Remove leftover tab in libtest outputs
phansch May 2, 2018
3f6b3bb
Improve format string errors
estebank May 10, 2018
a91f6f7
Tweak `nearest_common_ancestor()`.
nnethercote May 11, 2018
8ab2d15
Add Option::xor method
clarfonthey May 9, 2018
ce0b7cc
Fix grammar documentation wrt Unicode identifiers
bstrie May 16, 2018
ab4735e
Null exclusions in grammar docs
bstrie May 16, 2018
f778bde
Avoid repeated HashMap lookups in `opt_normalize_projection_type`.
nnethercote May 16, 2018
47bc774
Avoid allocations in `opt_normalize_projection_type`.
nnethercote May 16, 2018
37dee69
Add `bless` x.py subcommand for easy ui test replacement
oli-obk May 16, 2018
ceed8eb
Make `bless` a flag instead of a subcommand
oli-obk May 16, 2018
0356a61
Fix selftests
oli-obk May 17, 2018
74bfd94
`bless` also produces `.nll` files now
oli-obk May 17, 2018
0ac2fd1
Update docs and diagnostics
oli-obk May 17, 2018
ec0d946
Make sure people know the book is free oline
glassresistor May 17, 2018
eac94d1
Revert #49767
steveklabnik May 17, 2018
cfa26da
Update tutorial.md
glassresistor May 17, 2018
6e95b87
Rollup merge of #50387 - phansch:remove_leftover_tab, r=alexcrichton
Mark-Simulacrum May 17, 2018
0c0bb18
Rollup merge of #50553 - clarcharr:option_xor, r=sfackler
Mark-Simulacrum May 17, 2018
b3734bd
Rollup merge of #50610 - estebank:fmt-str, r=Kimundi
Mark-Simulacrum May 17, 2018
e1848df
Rollup merge of #50649 - nnethercote:tweak-nearest_common_ancestor, r…
Mark-Simulacrum May 17, 2018
77a4296
Rollup merge of #50790 - bstrie:grammar, r=steveklabnik
Mark-Simulacrum May 17, 2018
c95267e
Rollup merge of #50791 - bstrie:null, r=QuietMisdreavus
Mark-Simulacrum May 17, 2018
f83e4d7
Rollup merge of #50806 - oli-obk:gesundheit, r=ehuss
Mark-Simulacrum May 17, 2018
54df1bf
Rollup merge of #50818 - nnethercote:faster-normalize, r=nikomatsakis
Mark-Simulacrum May 17, 2018
53ea73a
Rollup merge of #50837 - steveklabnik:revert-49767, r=QuietMisdreavus
Mark-Simulacrum May 17, 2018
faa1f21
Rollup merge of #50839 - glassresistor:master, r=steveklabnik
Mark-Simulacrum May 17, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 19 additions & 59 deletions src/librustc/middle/region.rs
Original file line number Diff line number Diff line change
@@ -542,18 +542,6 @@ impl<'tcx> ScopeTree {
assert!(previous.is_none());
}

fn closure_is_enclosed_by(&self,
mut sub_closure: hir::ItemLocalId,
sup_closure: hir::ItemLocalId) -> bool {
loop {
if sub_closure == sup_closure { return true; }
match self.closure_tree.get(&sub_closure) {
Some(&s) => { sub_closure = s; }
None => { return false; }
}
}
}

fn record_var_scope(&mut self, var: hir::ItemLocalId, lifetime: Scope) {
debug!("record_var_scope(sub={:?}, sup={:?})", var, lifetime);
assert!(var != lifetime.item_local_id());
@@ -688,65 +676,37 @@ impl<'tcx> ScopeTree {
// requires a hash table lookup, and we often have very long scope
// chains (10s or 100s of scopes) that only differ by a few elements at
// the start. So this algorithm is faster.
let mut ma = Some(scope_a);
let mut mb = Some(scope_b);
let mut seen_a: SmallVec<[Scope; 32]> = SmallVec::new();
let mut seen_b: SmallVec<[Scope; 32]> = SmallVec::new();

let mut ma = Some(&scope_a);
let mut mb = Some(&scope_b);

// A HashSet<Scope> is a more obvious choice for these, but SmallVec is
// faster because the set size is normally small so linear search is
// as good or better than a hash table lookup, plus the size is usually
// small enough to avoid a heap allocation.
let mut seen_a: SmallVec<[&Scope; 32]> = SmallVec::new();
let mut seen_b: SmallVec<[&Scope; 32]> = SmallVec::new();

loop {
if let Some(a) = ma {
if seen_b.iter().position(|s| *s == a).is_some() {
return a;
if seen_b.iter().any(|s| *s == a) {
return *a;
}
seen_a.push(a);
ma = self.parent_map.get(&a).map(|s| *s);
ma = self.parent_map.get(&a);
}

if let Some(b) = mb {
if seen_a.iter().position(|s| *s == b).is_some() {
return b;
if seen_a.iter().any(|s| *s == b) {
return *b;
}
seen_b.push(b);
mb = self.parent_map.get(&b).map(|s| *s);
mb = self.parent_map.get(&b);
}

if ma.is_none() && mb.is_none() {
break;
}
};

fn outermost_scope(parent_map: &FxHashMap<Scope, Scope>, scope: Scope) -> Scope {
let mut scope = scope;
loop {
match parent_map.get(&scope) {
Some(&superscope) => scope = superscope,
None => break scope,
}
}
}

// In this (rare) case, the two regions belong to completely different
// functions. Compare those fn for lexical nesting. The reasoning
// behind this is subtle. See the "Modeling closures" section of the
// README in infer::region_constraints for more details.
let a_root_scope = outermost_scope(&self.parent_map, scope_a);
let b_root_scope = outermost_scope(&self.parent_map, scope_b);
match (a_root_scope.data(), b_root_scope.data()) {
(ScopeData::Destruction(a_root_id),
ScopeData::Destruction(b_root_id)) => {
if self.closure_is_enclosed_by(a_root_id, b_root_id) {
// `a` is enclosed by `b`, hence `b` is the ancestor of everything in `a`
scope_b
} else if self.closure_is_enclosed_by(b_root_id, a_root_id) {
// `b` is enclosed by `a`, hence `a` is the ancestor of everything in `b`
scope_a
} else {
// neither fn encloses the other
bug!()
}
}
_ => {
// root ids are always Node right now
bug!()
// No nearest common ancestor found.
bug!();
}
}
}