Skip to content

[red-knot] Stack overflow in Type::bool #15672

Closed
@sharkdp

Description

Description

We have an existing code path in Type::bool that tries to prevent infinite recursion:

// Check if the class has `__bool__ = bool` and avoid infinite recursion, since
// `Type::call` on `bool` will call `Type::bool` on the argument.
if bool_method
.into_class_literal()
.is_some_and(|ClassLiteralType { class }| {
class.is_known(db, KnownClass::Bool)
})
{
return Truthiness::Ambiguous;
}

and a test for it here:

# We don't get into a cycle if someone sets their `__bool__` method to the `bool` builtin:
class BoolIsBool:
__bool__ = bool
# revealed: bool
reveal_type(not BoolIsBool())

But this only checks the case where __bool__ has the exact type Literal[bool]. It fails if the type is a union that contains Literal[bool], for example:

def flag() -> bool: return True

class Boom:
    if flag():
        __bool__ = bool
    else:
        __bool__ = int

bool(Boom())
> cargo run --bin red_knot -- --project /path/to/folder/with/example
thread '<unknown>' has overflowed its stack
fatal runtime error: stack overflow

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghelp wantedContributions especially welcomered-knotMulti-file analysis & type inference

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions