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

[red-knot] Combine terminal statement support with statically known branches #15817

Merged
merged 36 commits into from
Feb 5, 2025
Merged
Changes from 1 commit
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
02c4798
Add ALWAYS_FALSE
dcreager Jan 29, 2025
2c0d577
Mark return states
dcreager Jan 29, 2025
e198806
Mark live bindings as non-visible when flow is unreachable
dcreager Jan 29, 2025
23b366d
Revert "Mark return states"
dcreager Jan 30, 2025
38f3d99
Handle final return statement specially
dcreager Jan 30, 2025
5c1918a
Customizable binding visibility
dcreager Jan 30, 2025
7504fb7
Reachability is now a vis constraint, not a bool
dcreager Jan 30, 2025
ee6f253
Fix ternary AND logic
dcreager Jan 30, 2025
6b53554
These are now unresolved I guess?
dcreager Jan 30, 2025
bb11cf8
clippy
dcreager Jan 30, 2025
a2ef702
Normalize negations of ALWAYS_{TRUE,FALSE}
dcreager Jan 30, 2025
1c42a2b
scope_start_visibility _is_ reachability
dcreager Jan 30, 2025
289c0c6
No, bindings are always visible
dcreager Jan 30, 2025
8b0899f
TODO for `raise`/`else` unreachability
dcreager Jan 30, 2025
9cd8e68
Fix test failure
dcreager Jan 30, 2025
1a80f81
Expected test case change
dcreager Jan 30, 2025
f71325c
Try to skip simplification by checking scope_start_visibility
dcreager Jan 30, 2025
0e06012
And try via a separate `always_reachable` boolean
dcreager Jan 30, 2025
b3b4577
Add AlwaysFalse as its own constraint variant
dcreager Jan 30, 2025
46b1ec2
Update always_reachable on merge correctly
dcreager Jan 30, 2025
999188a
Try checking if reachability contains AlwaysFalse in syntax tree
dcreager Jan 30, 2025
0f278da
But that doesn't work either
dcreager Jan 30, 2025
0fb6a74
Merge branch 'main' into dcreager/static-terminal
dcreager Feb 4, 2025
c882a95
This is working again
dcreager Feb 4, 2025
33db6f1
Remove static bool
dcreager Feb 4, 2025
b49916d
Remove moot comment
dcreager Feb 4, 2025
c80f27e
And another
dcreager Feb 4, 2025
0d50385
New bindings are visible only if control flow is reachable
dcreager Feb 4, 2025
c42490c
Add xfail for RET503
dcreager Feb 4, 2025
26f842b
Update terminal statement comment
dcreager Feb 5, 2025
e5b6c4a
Add shorter example for bindings after terminal statement
dcreager Feb 5, 2025
00e236f
Add back debug derive
dcreager Feb 5, 2025
1d93650
Add TODO to function symbol comment
dcreager Feb 5, 2025
ae83741
Wrap try examples in functions to bound reachability
dcreager Feb 5, 2025
f13a6a6
Spelling typo
dcreager Feb 5, 2025
7423de2
Add TODO for unreachable code example
dcreager Feb 5, 2025
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
Prev Previous commit
Next Next commit
scope_start_visibility _is_ reachability
dcreager committed Jan 30, 2025
commit 1c42a2b598a35372cf0205093948b8c6dbeffe9a
21 changes: 4 additions & 17 deletions crates/red_knot_python_semantic/src/semantic_index/use_def.rs
Original file line number Diff line number Diff line change
@@ -477,7 +477,6 @@ impl std::iter::FusedIterator for DeclarationsIterator<'_, '_> {}
pub(super) struct FlowSnapshot {
symbol_states: IndexVec<ScopedSymbolId, SymbolState>,
scope_start_visibility: ScopedVisibilityConstraintId,
reachability: ScopedVisibilityConstraintId,
}

pub(super) struct UseDefMapBuilder<'db> {
@@ -506,8 +505,6 @@ pub(super) struct UseDefMapBuilder<'db> {

/// Currently live bindings and declarations for each symbol.
symbol_states: IndexVec<ScopedSymbolId, SymbolState>,

reachability: ScopedVisibilityConstraintId,
}

impl<'db> UseDefMapBuilder<'db> {
@@ -521,12 +518,10 @@ impl<'db> UseDefMapBuilder<'db> {
bindings_by_use: IndexVec::new(),
definitions_by_definition: FxHashMap::default(),
symbol_states: IndexVec::new(),
reachability: ScopedVisibilityConstraintId::ALWAYS_TRUE,
}
}

pub(super) fn mark_unreachable(&mut self) {
self.reachability = ScopedVisibilityConstraintId::ALWAYS_FALSE;
self.record_visibility_constraint_id(ScopedVisibilityConstraintId::ALWAYS_FALSE);
}

@@ -544,7 +539,7 @@ impl<'db> UseDefMapBuilder<'db> {
binding,
SymbolDefinitions::Declarations(symbol_state.declarations().clone()),
);
symbol_state.record_binding(def_id, self.reachability);
symbol_state.record_binding(def_id, self.scope_start_visibility);
}

pub(super) fn add_constraint(&mut self, constraint: Constraint<'db>) -> ScopedConstraintId {
@@ -658,7 +653,7 @@ impl<'db> UseDefMapBuilder<'db> {
let def_id = self.all_definitions.push(Some(definition));
let symbol_state = &mut self.symbol_states[symbol];
symbol_state.record_declaration(def_id);
symbol_state.record_binding(def_id, self.reachability);
symbol_state.record_binding(def_id, self.scope_start_visibility);
}

pub(super) fn record_use(&mut self, symbol: ScopedSymbolId, use_id: ScopedUseId) {
@@ -675,7 +670,6 @@ impl<'db> UseDefMapBuilder<'db> {
FlowSnapshot {
symbol_states: self.symbol_states.clone(),
scope_start_visibility: self.scope_start_visibility,
reachability: self.reachability,
}
}

@@ -698,8 +692,6 @@ impl<'db> UseDefMapBuilder<'db> {
num_symbols,
SymbolState::undefined(self.scope_start_visibility),
);

self.reachability = snapshot.reachability;
}

/// Merge the given snapshot into the current state, reflecting that we might have taken either
@@ -715,14 +707,14 @@ impl<'db> UseDefMapBuilder<'db> {
// we can determine whether any particular binding is non-visible due to unreachability.
if self
.visibility_constraints
.evaluate_without_inference(self.db, snapshot.reachability)
.evaluate_without_inference(self.db, snapshot.scope_start_visibility)
.is_always_false()
{
return;
}
if self
.visibility_constraints
.evaluate_without_inference(self.db, self.reachability)
.evaluate_without_inference(self.db, self.scope_start_visibility)
.is_always_false()
{
self.restore(snapshot);
@@ -750,11 +742,6 @@ impl<'db> UseDefMapBuilder<'db> {
self.scope_start_visibility = self
.visibility_constraints
.add_or_constraint(self.scope_start_visibility, snapshot.scope_start_visibility);

// The merged result is reachability when either of the merged flows is.
self.reachability = self
.visibility_constraints
.add_or_constraint(self.reachability, snapshot.reachability);
}

pub(super) fn finish(mut self) -> UseDefMap<'db> {