Skip to content

aliases_implicit: is_assignable_to_bound accepts every TypeVar bound outside int/float/complex #410

Description

@MelbourneDeveloper

Split out of #408. Confirmed live on main @ da74283 and on the bidirectionaltype-inference branch.

The code

crates/basilisk-checker/src/rules/aliases_implicit.rs:757

fn is_assignable_to_bound(
    subtyping: &crate::subtyping::SubtypingContext,
    arg: &str,
    bound: &str,
) -> bool {
    match bound {
        "int" | "float" | "complex" => subtyping.is_subtype(arg, bound),
        _ => true,
    }
}

Every TypeVar bound that is not int, float, or complex returns true — accept. Bound checking on type-alias parameterization exists only for the numeric tower.

Why that is exactly the numeric tower

aliases_implicit.py declares exactly one bounded TypeVar:

TFloat = TypeVar("TFloat", bound=float)   # line 10
GoodTypeAlias12 = list[TFloat]            # line 41
...
p6: GoodTypeAlias12[str],  # E: type argument doesn't match bound   (line 81)

float is the only bound the suite exercises. The implemented set is int | float | complex — that one bound plus its two numeric-tower neighbours. Nothing else in the language is checked.

Failing case

from typing import TypeVar

T = TypeVar("T", bound=str)
Alias = list[T]

def f(x: Alias[int]) -> None: ...   # should error: int does not satisfy bound str

bound is "str", so the _ => true arm accepts. No diagnostic. The same holds for every user-defined class bound, every protocol bound, and every constrained TypeVar (TypeVar("T", str, bytes) — constraints are not consulted here at all; AliasInfo::typevar_bounds only carries bound_type_name).

Note also that arg and bound are compared as strings (bound_type_name is a name, arg is annotation text), so even within the numeric tower this cannot see through an alias, a qualified name, or a subscripted generic.

Fix

Route all bounds — not a hardcoded three — through the real subtyping context, resolving both the argument and the bound to types rather than comparing names. Carry TypeVar constraints alongside bounds and check membership for constrained TypeVars. _ => true must not be the default answer for the rest of the type system.

Needs off-suite regression tests: a bound=str case cannot fail in the conformance suite, because the suite has no such case.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    spec-violationCode functionality/logic does not match its spec (see SPEC-CONFORMANCE-AUDIT-PLAN.md)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions