mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-30 21:01:10 +00:00
chore: fix type variance bug
This commit is contained in:
parent
ccb54e0115
commit
6b5af0ffb4
3 changed files with 56 additions and 2 deletions
|
@ -902,7 +902,7 @@ impl Context {
|
||||||
},
|
},
|
||||||
(TyParam::Array(sup), TyParam::Array(sub))
|
(TyParam::Array(sup), TyParam::Array(sub))
|
||||||
| (TyParam::Tuple(sup), TyParam::Tuple(sub)) => {
|
| (TyParam::Tuple(sup), TyParam::Tuple(sub)) => {
|
||||||
if sup.len() > sub.len() {
|
if sup.len() > sub.len() || (variance.is_invariant() && sup.len() != sub.len()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (sup_p, sub_p) in sup.iter().zip(sub.iter()) {
|
for (sup_p, sub_p) in sup.iter().zip(sub.iter()) {
|
||||||
|
@ -914,7 +914,9 @@ impl Context {
|
||||||
}
|
}
|
||||||
// {Int: Str} :> {Int: Str, Bool: Int}
|
// {Int: Str} :> {Int: Str, Bool: Int}
|
||||||
(TyParam::Dict(sup_d), TyParam::Dict(sub_d)) => {
|
(TyParam::Dict(sup_d), TyParam::Dict(sub_d)) => {
|
||||||
if sup_d.len() > sub_d.len() {
|
if sup_d.len() > sub_d.len()
|
||||||
|
|| (variance.is_invariant() && sup_d.len() != sub_d.len())
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (sub_k, sub_v) in sub_d.iter() {
|
for (sub_k, sub_v) in sub_d.iter() {
|
||||||
|
@ -931,6 +933,26 @@ impl Context {
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
(TyParam::Record(sup_r), TyParam::Record(sub_r)) => {
|
||||||
|
if sup_r.len() > sub_r.len()
|
||||||
|
|| (variance.is_invariant() && sup_r.len() != sub_r.len())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (sub_k, sub_v) in sub_r.iter() {
|
||||||
|
if let Some(sup_v) = sup_r.get(sub_k) {
|
||||||
|
if !self.supertype_of_tp(sup_v, sub_v, variance) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
(TyParam::UnsizedArray(sup), TyParam::UnsizedArray(sub)) => {
|
||||||
|
self.supertype_of_tp(sup, sub, variance)
|
||||||
|
}
|
||||||
(TyParam::Type(sup), TyParam::Type(sub)) => match variance {
|
(TyParam::Type(sup), TyParam::Type(sub)) => match variance {
|
||||||
Variance::Contravariant => self.subtype_of(sup, sub),
|
Variance::Contravariant => self.subtype_of(sup, sub),
|
||||||
Variance::Covariant => self.supertype_of(sup, sub),
|
Variance::Covariant => self.supertype_of(sup, sub),
|
||||||
|
|
|
@ -286,6 +286,12 @@ impl std::ops::Mul for Variance {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Variance {
|
||||||
|
pub const fn is_invariant(&self) -> bool {
|
||||||
|
matches!(self, Variance::Invariant)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct ParamSpec {
|
pub struct ParamSpec {
|
||||||
pub(crate) name: Option<Str>,
|
pub(crate) name: Option<Str>,
|
||||||
|
|
|
@ -24,6 +24,27 @@
|
||||||
.NDArray(T, S)|<: Add .NDArray(T, S)|.
|
.NDArray(T, S)|<: Add .NDArray(T, S)|.
|
||||||
Output: {.NDArray(T, S)}
|
Output: {.NDArray(T, S)}
|
||||||
__add__: (self: .NDArray(T, S), other: .NDArray(T, S)) -> .NDArray(T, S)
|
__add__: (self: .NDArray(T, S), other: .NDArray(T, S)) -> .NDArray(T, S)
|
||||||
|
.NDArray(T, S)|<: Add T|.
|
||||||
|
Output: {.NDArray(T, S)}
|
||||||
|
__add__: (self: .NDArray(T, S), other: T) -> .NDArray(T, S)
|
||||||
|
.NDArray(T, S)|<: Sub .NDArray(T, S)|.
|
||||||
|
Output: {.NDArray(T, S)}
|
||||||
|
__sub__: (self: .NDArray(T, S), other: .NDArray(T, S)) -> .NDArray(T, S)
|
||||||
|
.NDArray(T, S)|<: Sub T|.
|
||||||
|
Output: {.NDArray(T, S)}
|
||||||
|
__sub__: (self: .NDArray(T, S), other: T) -> .NDArray(T, S)
|
||||||
|
.NDArray(T, S)|<: Mul .NDArray(T, S)|.
|
||||||
|
Output: {.NDArray(T, S)}
|
||||||
|
__mul__: (self: .NDArray(T, S), other: .NDArray(T, S)) -> .NDArray(T, S)
|
||||||
|
.NDArray(T, S)|<: Mul T|.
|
||||||
|
Output: {.NDArray(T, S)}
|
||||||
|
__mul__: (self: .NDArray(T, S), other: T) -> .NDArray(T, S)
|
||||||
|
.NDArray(T, S)|<: Div .NDArray(T, S)|.
|
||||||
|
Output: {.NDArray(T, S)}
|
||||||
|
__div__: (self: .NDArray(T, S), other: .NDArray(T, S)) -> .NDArray(T, S)
|
||||||
|
.NDArray(T, S)|<: Div T|.
|
||||||
|
Output: {.NDArray(T, S)}
|
||||||
|
__div__: (self: .NDArray(T, S), other: T) -> .NDArray(T, S)
|
||||||
.NDArray.
|
.NDArray.
|
||||||
shape: [Nat; _]
|
shape: [Nat; _]
|
||||||
ndim: Nat
|
ndim: Nat
|
||||||
|
@ -61,3 +82,8 @@
|
||||||
.transpose: |T|(object: .NDArray(T), axes := [Nat; _]) -> .NDArray(T)
|
.transpose: |T|(object: .NDArray(T), axes := [Nat; _]) -> .NDArray(T)
|
||||||
.zeros: (|N: Nat|(shape: {N}, dtype := Type) -> .NDArray(Nat, [N])) \
|
.zeros: (|N: Nat|(shape: {N}, dtype := Type) -> .NDArray(Nat, [N])) \
|
||||||
and (|S: [Nat; _]|(shape: {S}, dtype := Type) -> .NDArray(Nat, S))
|
and (|S: [Nat; _]|(shape: {S}, dtype := Type) -> .NDArray(Nat, S))
|
||||||
|
.empty: (|N: Nat|(shape: {N}, dtype := Type) -> .NDArray(Nat, [N])) \
|
||||||
|
and (|S: [Nat; _]|(shape: {S}, dtype := Type) -> .NDArray(Nat, S))
|
||||||
|
.dot: (|T, I: Nat, J: Nat, K: Nat|(l: .NDArray(T, [I, J]), r: .NDArray(T, [J, K])) -> .NDArray(T, [I, K])) \
|
||||||
|
and (|T, I: Nat, J: Nat|(l: .NDArray(T, [I]), r: .NDArray(T, [I, J])) -> .NDArray(T, [J])) \
|
||||||
|
and (|T, I: Nat|(l: .NDArray(T, [I]), r: .NDArray(T, [I])) -> T)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue