diff --git a/crates/red_knot_python_semantic/src/node_key.rs b/crates/red_knot_python_semantic/src/node_key.rs index 0935a1f839..4c2ade0b7e 100644 --- a/crates/red_knot_python_semantic/src/node_key.rs +++ b/crates/red_knot_python_semantic/src/node_key.rs @@ -1,14 +1,14 @@ -use ruff_python_ast::{AnyNodeRef, NodeKind}; -use ruff_text_size::{Ranged, TextRange}; +use ruff_python_ast::AnyNodeRef; /// Compact key for a node for use in a hash map. /// -/// Compares two nodes by their kind and text range. +/// Stores the memory address of the node, because using the range and the kind +/// of the node is not enough to uniquely identify them in ASTs resulting from +/// invalid syntax. For example, parsing the input `for` results in a `StmtFor` +/// AST node where both the `target` and the `iter` field are `ExprName` nodes +/// with the same (empty) range `3..3`. #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] -pub(super) struct NodeKey { - kind: NodeKind, - range: TextRange, -} +pub(super) struct NodeKey(usize); impl NodeKey { pub(super) fn from_node<'a, N>(node: N) -> Self @@ -16,9 +16,6 @@ impl NodeKey { N: Into>, { let node = node.into(); - NodeKey { - kind: node.kind(), - range: node.range(), - } + NodeKey(node.as_ptr().as_ptr() as usize) } } diff --git a/crates/red_knot_workspace/resources/test/corpus/10_if_invalid.py b/crates/red_knot_workspace/resources/test/corpus/10_if_invalid.py new file mode 100644 index 0000000000..fc8fca6026 --- /dev/null +++ b/crates/red_knot_workspace/resources/test/corpus/10_if_invalid.py @@ -0,0 +1 @@ +x if $z diff --git a/crates/red_knot_workspace/resources/test/corpus/16_for_invalid.py b/crates/red_knot_workspace/resources/test/corpus/16_for_invalid.py new file mode 100644 index 0000000000..54578ea3b3 --- /dev/null +++ b/crates/red_knot_workspace/resources/test/corpus/16_for_invalid.py @@ -0,0 +1 @@ +for