Compare commits
1 Commits
dcreager/h
...
dhruv/cont
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d3db7cb04d |
@@ -205,7 +205,11 @@ impl<'db> SemanticIndexBuilder<'db> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn flow_merge(&mut self, state: FlowSnapshot) {
|
fn flow_merge(&mut self, state: FlowSnapshot) {
|
||||||
self.current_use_def_map_mut().merge(state);
|
self.current_use_def_map_mut().merge(state, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flow_merge_no_declarations(&mut self, state: FlowSnapshot) {
|
||||||
|
self.current_use_def_map_mut().merge(state, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_symbol(&mut self, name: Name) -> ScopedSymbolId {
|
fn add_symbol(&mut self, name: Name) -> ScopedSymbolId {
|
||||||
@@ -1002,7 +1006,7 @@ where
|
|||||||
// Prepare for visiting the `except` block(s)
|
// Prepare for visiting the `except` block(s)
|
||||||
self.flow_restore(pre_try_block_state);
|
self.flow_restore(pre_try_block_state);
|
||||||
for state in try_block_snapshots {
|
for state in try_block_snapshots {
|
||||||
self.flow_merge(state);
|
self.flow_merge_no_declarations(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
let pre_except_state = self.flow_snapshot();
|
let pre_except_state = self.flow_snapshot();
|
||||||
|
|||||||
@@ -544,7 +544,7 @@ impl<'db> UseDefMapBuilder<'db> {
|
|||||||
/// Merge the given snapshot into the current state, reflecting that we might have taken either
|
/// Merge the given snapshot into the current state, reflecting that we might have taken either
|
||||||
/// path to get here. The new state for each symbol should include definitions from both the
|
/// path to get here. The new state for each symbol should include definitions from both the
|
||||||
/// prior state and the snapshot.
|
/// prior state and the snapshot.
|
||||||
pub(super) fn merge(&mut self, snapshot: FlowSnapshot) {
|
pub(super) fn merge(&mut self, snapshot: FlowSnapshot, exclude_declarations: bool) {
|
||||||
// We never remove symbols from `symbol_states` (it's an IndexVec, and the symbol
|
// We never remove symbols from `symbol_states` (it's an IndexVec, and the symbol
|
||||||
// IDs must line up), so the current number of known symbols must always be equal to or
|
// IDs must line up), so the current number of known symbols must always be equal to or
|
||||||
// greater than the number of known symbols in a previously-taken snapshot.
|
// greater than the number of known symbols in a previously-taken snapshot.
|
||||||
@@ -553,7 +553,7 @@ impl<'db> UseDefMapBuilder<'db> {
|
|||||||
let mut snapshot_definitions_iter = snapshot.symbol_states.into_iter();
|
let mut snapshot_definitions_iter = snapshot.symbol_states.into_iter();
|
||||||
for current in &mut self.symbol_states {
|
for current in &mut self.symbol_states {
|
||||||
if let Some(snapshot) = snapshot_definitions_iter.next() {
|
if let Some(snapshot) = snapshot_definitions_iter.next() {
|
||||||
current.merge(snapshot);
|
current.merge(snapshot, exclude_declarations);
|
||||||
} else {
|
} else {
|
||||||
// Symbol not present in snapshot, so it's unbound/undeclared from that path.
|
// Symbol not present in snapshot, so it's unbound/undeclared from that path.
|
||||||
current.set_may_be_unbound();
|
current.set_may_be_unbound();
|
||||||
|
|||||||
@@ -227,24 +227,32 @@ impl SymbolState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Merge another [`SymbolState`] into this one.
|
/// Merge another [`SymbolState`] into this one.
|
||||||
pub(super) fn merge(&mut self, b: SymbolState) {
|
pub(super) fn merge(&mut self, b: SymbolState, exclude_declarations: bool) {
|
||||||
let mut a = Self {
|
let mut a = Self {
|
||||||
bindings: SymbolBindings {
|
bindings: SymbolBindings {
|
||||||
live_bindings: Bindings::default(),
|
live_bindings: Bindings::default(),
|
||||||
constraints: Constraints::default(),
|
constraints: Constraints::default(),
|
||||||
may_be_unbound: self.bindings.may_be_unbound || b.bindings.may_be_unbound,
|
may_be_unbound: self.bindings.may_be_unbound || b.bindings.may_be_unbound,
|
||||||
},
|
},
|
||||||
declarations: SymbolDeclarations {
|
declarations: {
|
||||||
live_declarations: self.declarations.live_declarations.clone(),
|
if exclude_declarations {
|
||||||
may_be_undeclared: self.declarations.may_be_undeclared
|
self.declarations.clone()
|
||||||
|| b.declarations.may_be_undeclared,
|
} else {
|
||||||
|
SymbolDeclarations {
|
||||||
|
live_declarations: self.declarations.live_declarations.clone(),
|
||||||
|
may_be_undeclared: self.declarations.may_be_undeclared
|
||||||
|
|| b.declarations.may_be_undeclared,
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
std::mem::swap(&mut a, self);
|
std::mem::swap(&mut a, self);
|
||||||
self.declarations
|
if !exclude_declarations {
|
||||||
.live_declarations
|
self.declarations
|
||||||
.union(&b.declarations.live_declarations);
|
.live_declarations
|
||||||
|
.union(&b.declarations.live_declarations);
|
||||||
|
}
|
||||||
|
|
||||||
let mut a_defs_iter = a.bindings.live_bindings.iter();
|
let mut a_defs_iter = a.bindings.live_bindings.iter();
|
||||||
let mut b_defs_iter = b.bindings.live_bindings.iter();
|
let mut b_defs_iter = b.bindings.live_bindings.iter();
|
||||||
@@ -494,7 +502,7 @@ mod tests {
|
|||||||
sym0b.record_binding(ScopedDefinitionId::from_u32(0));
|
sym0b.record_binding(ScopedDefinitionId::from_u32(0));
|
||||||
sym0b.record_constraint(ScopedConstraintId::from_u32(0));
|
sym0b.record_constraint(ScopedConstraintId::from_u32(0));
|
||||||
|
|
||||||
sym0a.merge(sym0b);
|
sym0a.merge(sym0b, false);
|
||||||
let mut sym0 = sym0a;
|
let mut sym0 = sym0a;
|
||||||
assert_bindings(&sym0, false, &["0<0>"]);
|
assert_bindings(&sym0, false, &["0<0>"]);
|
||||||
|
|
||||||
@@ -507,7 +515,7 @@ mod tests {
|
|||||||
sym1b.record_binding(ScopedDefinitionId::from_u32(1));
|
sym1b.record_binding(ScopedDefinitionId::from_u32(1));
|
||||||
sym1b.record_constraint(ScopedConstraintId::from_u32(2));
|
sym1b.record_constraint(ScopedConstraintId::from_u32(2));
|
||||||
|
|
||||||
sym1a.merge(sym1b);
|
sym1a.merge(sym1b, false);
|
||||||
let sym1 = sym1a;
|
let sym1 = sym1a;
|
||||||
assert_bindings(&sym1, false, &["1<>"]);
|
assert_bindings(&sym1, false, &["1<>"]);
|
||||||
|
|
||||||
@@ -518,12 +526,12 @@ mod tests {
|
|||||||
|
|
||||||
let sym2b = SymbolState::undefined();
|
let sym2b = SymbolState::undefined();
|
||||||
|
|
||||||
sym2a.merge(sym2b);
|
sym2a.merge(sym2b, false);
|
||||||
let sym2 = sym2a;
|
let sym2 = sym2a;
|
||||||
assert_bindings(&sym2, true, &["2<3>"]);
|
assert_bindings(&sym2, true, &["2<3>"]);
|
||||||
|
|
||||||
// merging different definitions keeps them each with their existing constraints
|
// merging different definitions keeps them each with their existing constraints
|
||||||
sym0.merge(sym2);
|
sym0.merge(sym2, false);
|
||||||
let sym = sym0;
|
let sym = sym0;
|
||||||
assert_bindings(&sym, true, &["0<0>", "2<3>"]);
|
assert_bindings(&sym, true, &["0<0>", "2<3>"]);
|
||||||
}
|
}
|
||||||
@@ -560,7 +568,7 @@ mod tests {
|
|||||||
let mut sym2 = SymbolState::undefined();
|
let mut sym2 = SymbolState::undefined();
|
||||||
sym2.record_declaration(ScopedDefinitionId::from_u32(2));
|
sym2.record_declaration(ScopedDefinitionId::from_u32(2));
|
||||||
|
|
||||||
sym.merge(sym2);
|
sym.merge(sym2, false);
|
||||||
|
|
||||||
assert_declarations(&sym, false, &[1, 2]);
|
assert_declarations(&sym, false, &[1, 2]);
|
||||||
}
|
}
|
||||||
@@ -572,7 +580,7 @@ mod tests {
|
|||||||
|
|
||||||
let sym2 = SymbolState::undefined();
|
let sym2 = SymbolState::undefined();
|
||||||
|
|
||||||
sym.merge(sym2);
|
sym.merge(sym2, false);
|
||||||
|
|
||||||
assert_declarations(&sym, true, &[1]);
|
assert_declarations(&sym, true, &[1]);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user