Skip to content

Commit d383152

Browse files
committed
Use record_place_load
1 parent 7bbb41a commit d383152

File tree

2 files changed

+68
-105
lines changed

2 files changed

+68
-105
lines changed

crates/ty_python_semantic/src/semantic_index/reachability_constraints.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,9 @@
195195
196196
use std::cmp::Ordering;
197197

198+
use ruff_db::parsed::parsed_module;
198199
use ruff_index::{Idx, IndexVec};
200+
use ruff_python_ast::HasNodeIndex;
199201
use rustc_hash::FxHashMap;
200202

201203
use crate::Db;
@@ -792,8 +794,14 @@ impl ReachabilityConstraints {
792794
fn analyze_single(db: &dyn Db, predicate: &Predicate) -> Truthiness {
793795
match predicate.node {
794796
PredicateNode::Expression(test_expr) => {
797+
let expression = &test_expr;
798+
let file = expression.file(db);
799+
let module = parsed_module(db, file).load(db);
800+
let node = expression.node_ref(db, &module);
795801
let ty = infer_expression_if_definitely_bound(db, test_expr);
796-
ty.bool(db).negate_if(!predicate.is_positive)
802+
let t = ty.bool(db).negate_if(!predicate.is_positive);
803+
804+
t
797805
}
798806
PredicateNode::ReturnsNever(CallableAndCallExpr {
799807
callable,

crates/ty_python_semantic/src/types/infer.rs

Lines changed: 59 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -344,14 +344,13 @@ pub(crate) fn infer_expression_if_definitely_bound<'db>(
344344
db: &'db dyn Db,
345345
expression: Expression<'db>,
346346
) -> Type<'db> {
347+
let inference = infer_expression_types(db, expression);
347348
let file = expression.file(db);
348349
let module = parsed_module(db, file).load(db);
349-
eprintln!("inferring types");
350-
let inference = infer_expression_types(db, expression);
351-
eprintln!("type inferred");
352350
let node = expression.node_ref(db, &module);
353351
let b = inference.definitely_bound();
354-
eprintln!("{node:?} is definitely bound: {b}");
352+
353+
eprintln!("node {:?} is fully bound: {}", node, b);
355354

356355
if b {
357356
inference.expression_type(node)
@@ -684,7 +683,7 @@ impl<'db> ExpressionInference<'db> {
684683
Self {
685684
extra: Some(Box::new(ExpressionInferenceExtra {
686685
cycle_fallback: true,
687-
all_definitely_bound: false,
686+
all_definitely_bound: true,
688687
..ExpressionInferenceExtra::default()
689688
})),
690689
expressions: FxHashMap::default(),
@@ -720,7 +719,6 @@ impl<'db> ExpressionInference<'db> {
720719
}
721720

722721
pub(crate) fn definitely_bound(&self) -> bool {
723-
// If there was a cycle fallback or there is no extra field then returns false.
724722
match self.extra.as_ref() {
725723
Some(e) => e.all_definitely_bound,
726724
None => true,
@@ -6400,6 +6398,31 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
64006398
}
64016399
}
64026400

6401+
// TODO: Not needed
6402+
fn is_in_method(&self) -> bool {
6403+
let current_scope_id = self.scope().file_scope_id(self.db());
6404+
let current_scope = self.index.scope(current_scope_id);
6405+
let module = &parsed_module(self.db(), self.scope().file(self.db())).load(self.db());
6406+
let Some(method) = current_scope.node().as_function(module) else {
6407+
return false;
6408+
};
6409+
6410+
let Some(parent_scope_id) = current_scope.parent() else {
6411+
return false;
6412+
};
6413+
let parent_scope = self.index.scope(parent_scope_id);
6414+
let Some(_) = parent_scope.node().as_class(module) else {
6415+
return false;
6416+
};
6417+
6418+
let definition = self.index.expect_single_definition(method);
6419+
if let DefinitionKind::Function(_) = definition.kind(self.db()) {
6420+
return true;
6421+
} else {
6422+
return false;
6423+
}
6424+
}
6425+
64036426
/// NOTE: first way, if any of places are not definitely bound then set the value
64046427
/// Calls infer_place_load and records if the expression is definitely bound.
64056428
fn record_place_load(
@@ -6410,6 +6433,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
64106433
let place = self.infer_place_load(place_expr, expr_ref);
64116434
if !place.0.place.is_definitely_bound() {
64126435
self.all_definitely_bound = false;
6436+
eprintln!("expr_ref: {:?} was not bound", expr_ref);
64136437
}
64146438

64156439
place
@@ -8932,20 +8956,20 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
89328956
pub(super) fn finish_expression(mut self) -> ExpressionInference<'db> {
89338957
self.infer_region();
89348958

8935-
let all_definitely_bound = match self.region {
8936-
InferenceRegion::Expression(expression) => {
8937-
let mut visitor = BoundSymbolsVisitor {
8938-
builder: &self,
8939-
all_definitely_bound: false,
8940-
};
8941-
let node = expression.node_ref(self.db(), self.module());
8942-
visitor.visit_expr(node);
8943-
let b = visitor.all_definitely_bound;
8944-
eprintln!("{node:?}\n is bound: {b}");
8945-
b
8946-
}
8947-
_ => false,
8948-
};
8959+
// TODO: Remove because record_place_load is used instead
8960+
// let all_definitely_bound = match self.region {
8961+
// InferenceRegion::Expression(expression) => {
8962+
// let mut visitor = BoundSymbolsVisitor {
8963+
// builder: &self,
8964+
// all_definitely_bound: true,
8965+
// };
8966+
// let node = expression.node_ref(self.db(), self.module());
8967+
// visitor.visit_expr(node);
8968+
// let b = visitor.all_definitely_bound;
8969+
// b
8970+
// }
8971+
// _ => false,
8972+
// };
89498973

89508974
let Self {
89518975
context,
@@ -8955,9 +8979,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
89558979
declarations,
89568980
deferred,
89578981
cycle_fallback,
8958-
8959-
// ignored
8960-
all_definitely_bound: _,
8982+
all_definitely_bound,
89618983

89628984
// builder only state
89638985
deferred_state: _,
@@ -8980,7 +9002,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
89809002
);
89819003

89829004
let extra =
8983-
(cycle_fallback || !bindings.is_empty() || !diagnostics.is_empty()).then(|| {
9005+
(cycle_fallback || !bindings.is_empty() || !diagnostics.is_empty() || !all_definitely_bound).then(|| {
89849006
if bindings.len() > 20 {
89859007
tracing::debug!(
89869008
"Inferred expression region `{:?}` contains {} bindings. Lookups by linear scan might be slow.",
@@ -8999,6 +9021,11 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
89999021

90009022
expressions.shrink_to_fit();
90019023

9024+
// eprintln!(
9025+
// "finished inference id {:?} and definitely bound {:?}",
9026+
// scope, all_definitely_bound
9027+
// );
9028+
90029029
ExpressionInference {
90039030
expressions,
90049031
extra,
@@ -10797,18 +10824,18 @@ impl<'a, 'db, 'ast> Visitor<'ast> for BoundSymbolsVisitor<'a, 'db, 'ast> {
1079710824
}
1079810825

1079910826
match expr {
10800-
ast::Expr::Attribute(attr) if attr.ctx == ast::ExprContext::Load => {}
10827+
ast::Expr::Attribute(attr) if attr.ctx == ast::ExprContext::Load => {
10828+
if attr.attr.id().as_str() == "version_info" {
10829+
return walk_expr(self, expr);
10830+
}
10831+
}
1080110832
ast::Expr::Name(name) if name.ctx == ast::ExprContext::Load => {}
1080210833
_ => return walk_expr(self, expr),
1080310834
};
1080410835

1080510836
let place_expr = match PlaceExpr::try_from_expr(expr) {
1080610837
Some(place_expr) => place_expr,
1080710838
None => {
10808-
debug_assert!(
10809-
false,
10810-
"ast::Expr::Name, ast::Expr::Attribute should be a valid PlaceExpr"
10811-
);
1081210839
return walk_expr(self, expr);
1081310840
}
1081410841
};
@@ -10820,6 +10847,8 @@ impl<'a, 'db, 'ast> Visitor<'ast> for BoundSymbolsVisitor<'a, 'db, 'ast> {
1082010847
.place;
1082110848

1082210849
if !matches!(place, Place::Type(_, Boundness::Bound)) {
10850+
dbg!(place);
10851+
eprintln!("{expr:?} was not bound");
1082310852
self.all_definitely_bound = false;
1082410853
return;
1082510854
}
@@ -11222,80 +11251,6 @@ mod tests {
1122211251
assert_diagnostic_messages(&diagnostics, expected);
1122311252
}
1122411253

11225-
#[test]
11226-
fn analyze_cycles_gridout() {
11227-
let mut db = setup_db();
11228-
let filename = "src/gridout.py";
11229-
db.write_dedented(
11230-
filename,
11231-
r#"
11232-
EMPTY = b""
11233-
11234-
11235-
class GridOut:
11236-
def __init__(self: "GridOut") -> None:
11237-
self._buffer_pos = 0
11238-
self._buffer = b""
11239-
11240-
def readchunk(self: "GridOut") -> bytes:
11241-
if not len(self._buffer) - self._buffer_pos:
11242-
raise Exception("truncated chunk")
11243-
self._buffer_pos = 0
11244-
return EMPTY
11245-
11246-
def _read_size_or_line(self: "GridOut", size: int = -1) -> bytes:
11247-
if size > self._position:
11248-
size = self._position
11249-
if size == 0:
11250-
return bytes()
11251-
11252-
received = 0
11253-
needed = size - received
11254-
while received < size:
11255-
if self._buffer:
11256-
buf = self._buffer
11257-
chunk_start = self._buffer_pos
11258-
chunk_data = buf[self._buffer_pos :]
11259-
self._buffer = EMPTY
11260-
else:
11261-
buf = self.readchunk()
11262-
chunk_start = 0
11263-
chunk_data = buf
11264-
11265-
needed = buf.find(EMPTY, chunk_start, chunk_start + needed)
11266-
if len(chunk_data) > needed:
11267-
self._buffer = buf
11268-
self._buffer_pos = chunk_start + needed
11269-
self._position -= len(self._buffer) - self._buffer_pos
11270-
11271-
return b""
11272-
"#,
11273-
)
11274-
.unwrap();
11275-
11276-
db.clear_salsa_events();
11277-
assert_file_diagnostics(&db, filename, &[]);
11278-
let events = db.take_salsa_events();
11279-
let cycles = salsa::attach(&db, || {
11280-
events
11281-
.iter()
11282-
.filter_map(|event| {
11283-
if let salsa::EventKind::WillIterateCycle {
11284-
database_key,
11285-
iteration_count,
11286-
fell_back: _,
11287-
} = event.kind
11288-
{
11289-
Some(format!("{database_key:?}, {iteration_count:?}"))
11290-
} else {
11291-
None
11292-
}
11293-
})
11294-
.collect::<Vec<_>>()
11295-
});
11296-
assert_eq!(cycles.len(), 2414);
11297-
}
11298-
1129911254
#[test]
1130011255
fn cyclic_dependant_attributes() {
1130111256
let mut db = setup_db();
@@ -11333,7 +11288,7 @@ mod tests {
1133311288
})
1133411289
.collect::<Vec<_>>()
1133511290
});
11336-
assert_eq!(cycles.len(), 0);
11291+
assert_eq!(cycles.len(), 1);
1133711292
}
1133811293

1133911294
#[test]

0 commit comments

Comments
 (0)