add Self from implicit type[Self] to gc too

This commit is contained in:
Douglas Creager 2025-12-11 09:35:45 -05:00
parent 826e2f331b
commit c25fc5923c
2 changed files with 68 additions and 2 deletions

View File

@ -282,8 +282,10 @@ reveal_type(C().method()) # revealed: C
## Class Methods
### Explicit
```py
from typing import Self, TypeVar
from typing import Self
class Shape:
def foo(self: Self) -> Self:
@ -298,6 +300,64 @@ class Circle(Shape): ...
reveal_type(Shape().foo()) # revealed: Shape
reveal_type(Shape.bar()) # revealed: Shape
reveal_type(Circle().foo()) # revealed: Circle
reveal_type(Circle.bar()) # revealed: Circle
```
### Implicit
```py
from typing import Self
class Shape:
def foo(self) -> Self:
return self
@classmethod
def bar(cls) -> Self:
reveal_type(cls) # revealed: type[Self@bar]
return cls()
class Circle(Shape): ...
reveal_type(Shape().foo()) # revealed: Shape
reveal_type(Shape.bar()) # revealed: Shape
reveal_type(Circle().foo()) # revealed: Circle
reveal_type(Circle.bar()) # revealed: Circle
```
### Implicit in generic class
```py
from typing import Self
class GenericShape[T]:
def foo(self) -> Self:
return self
@classmethod
def bar(cls) -> Self:
reveal_type(cls) # revealed: type[Self@bar]
return cls()
@classmethod
def baz[U](cls, u: U) -> "GenericShape[U]":
reveal_type(cls) # revealed: type[Self@baz]
return cls()
class GenericCircle[T](GenericShape[T]): ...
reveal_type(GenericShape().foo()) # revealed: GenericShape[Unknown]
reveal_type(GenericShape.bar()) # revealed: GenericShape[Unknown]
reveal_type(GenericShape[int].bar()) # revealed: GenericShape[int]
reveal_type(GenericShape.baz(1)) # revealed: GenericShape[Literal[1]]
reveal_type(GenericCircle().foo()) # revealed: GenericCircle[Unknown]
reveal_type(GenericCircle.bar()) # revealed: GenericCircle[Unknown]
reveal_type(GenericCircle[int].bar()) # revealed: GenericCircle[int]
reveal_type(GenericCircle.baz(1)) # revealed: GenericShape[Literal[1]]
```
## Attributes

View File

@ -732,7 +732,13 @@ impl<'db> Signature<'db> {
// signature's generic context, too. (The generic context should include any synthetic
// typevars created for `typing.Self`, even if the `typing.Self` annotation was added
// implicitly.)
if let Type::TypeVar(self_typevar) = self_type {
let self_typevar = match self_type {
Type::TypeVar(self_typevar) => Some(self_typevar),
Type::SubclassOf(subclass_of) => subclass_of.into_type_var(),
_ => None,
};
if let Some(self_typevar) = self_typevar {
match self.generic_context.as_mut() {
Some(generic_context)
if generic_context