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

Code before:
        if let ast::Expr::Subscript(subscript) = &*expr_compare.left {
            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(x) can delegate to narrowing x itself
        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(_) => {

Review comment (suggestion):
Took me a second to see how this is different from the above. Maybe add an example?
```suggestion
        // `bool(expr)` can delegate to narrowing `expr` itself, e.g. `bool(x is not None)`
```

Code after:
        if let ast::Expr::Subscript(subscript) = &*expr_compare.left {
            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));
            }
        }

        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(_) => {