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

Code before:
        places
    }

    /// Compare expressions can narrow places on either side of the comparison,
    /// and can also narrow subscript bases (for `TypedDict` and tuple narrowing).
    fn expr_compare(&self, expr_compare: &ast::ExprCompare) -> PossiblyNarrowedPlaces {
        let mut places = PossiblyNarrowedPlaces::default();

        // The left side can be narrowed
        self.add_narrowing_target(&expr_compare.left, &mut places);

        // Each comparator can also be narrowed
        for comparator in &expr_compare.comparators {
            self.add_narrowing_target(comparator, &mut places);
        }

        // For subscript expressions on either side, the subscript base can also be narrowed.
        // (TypedDict and tuple discriminated union narrowing.)
        for expr in std::iter::once(&*expr_compare.left).chain(&expr_compare.comparators) {
            if let ast::Expr::Subscript(subscript) = expr {
                if let Some(place_expr) = PlaceExpr::try_from_expr(&subscript.value) {
                    if let Some(place) = self.places.place_id((&place_expr).into()) {
                        places.insert(place);
                    }
                }
            }
        }

        places
    }

    /// Call expressions can narrow their first argument (isinstance, issubclass, hasattr, len)
    /// or narrow based on TypeGuard/TypeIs return types.
    fn expr_call(&self, expr_call: &ast::ExprCall) -> PossiblyNarrowedPlaces {
        let mut places = PossiblyNarrowedPlaces::default();

        // Most narrowing calls narrow their first argument
        if let Some(first_arg) = expr_call.arguments.args.first() {
            if let Some(place_expr) = PlaceExpr::try_from_expr(first_arg) {
                if let Some(place) = self.places.place_id((&place_expr).into()) {
                    places.insert(place);
                }
            }
        }

        // `bool(expr)` can delegate to narrowing `expr` itself, e.g. `bool(x is not None)`
        if let Some(first_arg) = expr_call.arguments.args.first() {
            if expr_call.arguments.args.len() == 1 && expr_call.arguments.keywords.is_empty() {
                places.extend(self.expression_node(first_arg));
            }
        }

Review comment (suggestion):
what do I have to do to get Claude to use `let` chains

```suggestion
            if let ast::Expr::Subscript(subscript) = expr
                && let Some(place_expr) = PlaceExpr::try_from_expr(&subscript.value)
                && let Some(place) = self.places.place_id((&place_expr).into())
            {
                places.insert(place);
            }
```

Code after:
        places
    }

    /// Call expressions can narrow their first argument (isinstance, issubclass, hasattr, len)
    /// or narrow based on TypeGuard/TypeIs return types.
    fn expr_call(&self, expr_call: &ast::ExprCall) -> PossiblyNarrowedPlaces {
        let mut places = PossiblyNarrowedPlaces::default();

        // Most narrowing calls narrow their first argument
        if let Some(first_arg) = expr_call.arguments.args.first() {
            if let Some(place_expr) = PlaceExpr::try_from_expr(first_arg) {
                if let Some(place) = self.places.place_id((&place_expr).into()) {
                    places.insert(place);
                }
            }
        }

        // `bool(expr)` can delegate to narrowing `expr` itself, e.g. `bool(x is not None)`
        if let Some(first_arg) = expr_call.arguments.args.first() {
            if expr_call.arguments.args.len() == 1 && expr_call.arguments.keywords.is_empty() {
                places.extend(self.expression_node(first_arg));
            }
        }

        places
    }

    /// Boolean operations combine places from all sub-expressions.
    fn expr_bool_op(&self, bool_op: &ast::ExprBoolOp) -> PossiblyNarrowedPlaces {
        let mut places = PossiblyNarrowedPlaces::default();
        for value in &bool_op.values {
            places.extend(self.expression_node(value));
        }
        places
    }

    /// Helper to add a potential narrowing target expression to the set.
    fn add_narrowing_target(&self, expr: &ast::Expr, places: &mut PossiblyNarrowedPlaces) {
        match expr {
            ast::Expr::Name(_)
            | ast::Expr::Attribute(_)
            | ast::Expr::Subscript(_)
            | ast::Expr::Named(_) => {
                if let Some(place_expr) = PlaceExpr::try_from_expr(expr) {
                    if let Some(place) = self.places.place_id((&place_expr).into()) {
                        places.insert(place);
                    }
                }
            }
            // type(x) is Y can narrow x
            ast::Expr::Call(call) if call.arguments.args.len() == 1 => {