Repository: astral-sh/ruff
File: crates/ty_python_semantic/src/semantic_index/builder.rs (Rust)

Code before:
                                        unpack,
                                        iterable: &node.iter,
                                        target: expr,
                                        first,
                                        is_async: node.is_async,
                                    },
                                );
                            }
                            Some(CurrentAssignment::WithItem {
                                item,
                                is_async,
                                unpack,
                            }) => {
                                self.add_definition(
                                    place_id,
                                    WithItemDefinitionNodeRef {
                                        unpack,
                                        context_expr: &item.context_expr,
                                        target: expr,
                                        is_async,
                                    },
                                );
                            }
                            None => {}
                        }
                    }

                    if let Some(unpack_position) = self
                        .current_assignment_mut()
                        .and_then(CurrentAssignment::unpack_position_mut)
                    {
                        *unpack_position = UnpackPosition::Other;
                    }
                }

                // Track reachability of attribute expressions to silence `unresolved-attribute`
                // diagnostics in unreachable code.
                if expr.is_attribute_expr() {
                    self.current_use_def_map_mut()
                        .record_node_reachability(node_key);
                }

                walk_expr(self, expr);
            }
            ast::Expr::Named(node) => {
                // TODO walrus in comprehensions is implicitly nonlocal
                self.visit_expr(&node.value);

                // See https://peps.python.org/pep-0572/#differences-between-assignment-expressions-and-assignment-statements
                if node.target.is_name_expr() {
                    self.push_assignment(node.into());

Review comment (suggestion):
Note that during semantic indexing, we don't have a way of distinguishing between an annotated or unannotated assignment, e.g., `x: dict[str, Any]; x = {}`, so we perform the narrowing in both cases. We also perform the narrowing on `TypedDict` assignments for the same reason.

Code after:
                            .record_use(place_id, use_id, node_key);
                    }

                    if is_definition {
                        match self.current_assignment() {
                            Some(CurrentAssignment::Assign { node, unpack }) => {
                                let assignment = self.add_definition(
                                    place_id,
                                    AssignmentDefinitionNodeRef {
                                        unpack,
                                        value: &node.value,
                                        target: expr,
                                    },
                                );

                                if let ast::Expr::Dict(dict) = &*node.value {
                                    self.add_dict_key_assignment_definitions(
                                        &node.targets,
                                        dict,
                                        assignment,
                                    );
                                }
                            }
                            Some(CurrentAssignment::AnnAssign(ann_assign)) => {
                                self.add_standalone_type_expression(&ann_assign.annotation);
                                let assignment = self.add_definition(
                                    place_id,
                                    AnnotatedAssignmentDefinitionNodeRef {
                                        node: ann_assign,
                                        annotation: &ann_assign.annotation,
                                        value: ann_assign.value.as_deref(),
                                        target: expr,
                                    },
                                );

                                if let Some(ast::Expr::Dict(dict)) = ann_assign.value.as_deref() {
                                    self.add_dict_key_assignment_definitions(
                                        [&*ann_assign.target],
                                        dict,
                                        assignment,
                                    );
                                }
                            }
                            Some(CurrentAssignment::AugAssign(aug_assign)) => {
                                self.add_definition(place_id, aug_assign);
                            }
                            Some(CurrentAssignment::For { node, unpack }) => {
                                self.add_definition(
                                    place_id,
                                    ForStmtDefinitionNodeRef {
                                        unpack,