mirror of https://github.com/astral-sh/ruff
avoid promoting invariant generics during literal promotion
This commit is contained in:
parent
8ca2b5555d
commit
e73d73b0f7
|
|
@ -38,6 +38,21 @@ reveal_type(x[0].__name__) # revealed: Unknown | str
|
|||
reveal_type([1, (1, 2), (1, 2, 3)])
|
||||
```
|
||||
|
||||
## Invariant generic elements
|
||||
|
||||
We take care not to promote invariant generics:
|
||||
|
||||
```py
|
||||
from typing import Literal
|
||||
|
||||
def _(a: list[Literal[1]], b: Literal[2]):
|
||||
c = [a]
|
||||
reveal_type(c) # revealed: list[Unknown | list[Literal[1]]]
|
||||
|
||||
d = [(a, b)]
|
||||
reveal_type(d) # revealed: list[Unknown | tuple[list[Literal[1]], int]]
|
||||
```
|
||||
|
||||
## List comprehensions
|
||||
|
||||
```py
|
||||
|
|
|
|||
|
|
@ -6648,7 +6648,7 @@ impl<'db> Type<'db> {
|
|||
tcx: TypeContext<'db>,
|
||||
visitor: &ApplyTypeMappingVisitor<'db>,
|
||||
) -> Type<'db> {
|
||||
match self {
|
||||
let ty = match self {
|
||||
Type::TypeVar(bound_typevar) => match type_mapping {
|
||||
TypeMapping::Specialization(specialization) => {
|
||||
specialization.get(db, bound_typevar).unwrap_or(self)
|
||||
|
|
@ -6837,6 +6837,15 @@ impl<'db> Type<'db> {
|
|||
| Type::BoundSuper(_)
|
||||
| Type::SpecialForm(_)
|
||||
| Type::KnownInstance(_) => self,
|
||||
};
|
||||
|
||||
match type_mapping {
|
||||
TypeMapping::PromoteLiterals => {
|
||||
// It is only sound to promote to a supertype (i.e. it is unsound to promote
|
||||
// invariant generics).
|
||||
if self.is_subtype_of(db, ty) { ty } else { self }
|
||||
}
|
||||
_ => ty,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue