Skip to content

Commit 808e22a

Browse files
committed
docs(erased-cast-argument): note the reified-cell case
the cast now shares the parametric `is` engine, so a value typed by a reified type parameter verifies its argument exactly (`T == int`) and no longer warns. document that alongside the `__orig_class__` and protocol cases, and regenerate rules.md / ty.schema.json.
1 parent 684d364 commit 808e22a

2 files changed

Lines changed: 14 additions & 8 deletions

File tree

crates/ty_python_semantic/src/types/diagnostic.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1372,13 +1372,16 @@ declare_lint! {
13721372
/// `list[int]`, but nothing verifies the `int` claim at runtime, which is
13731373
/// exactly the assumption a checked cast exists to rule out.
13741374
///
1375-
/// A *user* generic does not have this problem: its instances carry
1376-
/// `__orig_class__`, so `A[int]` is checked in full. A *protocol* is checked
1377-
/// structurally against the value's reified annotations — data members
1378-
/// against class annotations, method members against parameter/return
1379-
/// annotations. Only a protocol member whose specialized type has no runtime
1380-
/// spelling (a callable attribute) leaves the cast with no runtime residue,
1381-
/// so the whole cast — not just its arguments — is left unchecked.
1375+
/// This only fires where the claim really is assumed. A *user* generic
1376+
/// carries `__orig_class__`, so `A[int]` is checked in full. A value typed by
1377+
/// a *reified* type parameter carries the answer in a runtime cell, so
1378+
/// casting `list[T]` to `list[int]` compares `T == int` exactly. A *protocol*
1379+
/// is checked structurally against the value's reified annotations — data
1380+
/// members against class annotations, method members against
1381+
/// parameter/return annotations. Only a protocol member whose specialized
1382+
/// type has no runtime spelling (a callable attribute) leaves the cast with
1383+
/// no runtime residue, so the whole cast — not just its arguments — is left
1384+
/// unchecked.
13821385
///
13831386
/// ## Example
13841387
///
@@ -1396,6 +1399,9 @@ declare_lint! {
13961399
/// def g(x: object):
13971400
/// a = x cast A[int] # ok — checked in full via `__orig_class__`
13981401
///
1402+
/// def r[T](data: list[T]):
1403+
/// a = data cast list[int] # ok — the reified `T` cell decides it
1404+
///
13991405
/// class HasCb[T](Protocol):
14001406
/// cb: Callable[[T], T]
14011407
///

ty.schema.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)