mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-28 20:14:45 +00:00
fix: minor bugs
This commit is contained in:
parent
5365c87cb4
commit
a8c1113df7
6 changed files with 166 additions and 83 deletions
|
@ -4,7 +4,7 @@ use std::mem;
|
||||||
use erg_common::dict::Dict;
|
use erg_common::dict::Dict;
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use erg_common::log;
|
use erg_common::log;
|
||||||
use erg_common::{dict, enum_unwrap, set};
|
use erg_common::{dict, set};
|
||||||
|
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::feature_error;
|
use crate::feature_error;
|
||||||
|
@ -186,14 +186,19 @@ pub(crate) fn __array_getitem__(mut args: ValueArgs, ctx: &Context) -> EvalValue
|
||||||
let slf = args
|
let slf = args
|
||||||
.remove_left_or_key("Self")
|
.remove_left_or_key("Self")
|
||||||
.ok_or_else(|| not_passed("Self"))?;
|
.ok_or_else(|| not_passed("Self"))?;
|
||||||
let slf = ctx
|
let slf = match ctx.convert_value_into_array(slf) {
|
||||||
.convert_value_into_array(slf)
|
Ok(slf) => slf,
|
||||||
.unwrap_or_else(|err| panic!("{err}, {args}"));
|
Err(val) => {
|
||||||
|
return Err(type_mismatch("Array", val, "Self"));
|
||||||
|
}
|
||||||
|
};
|
||||||
let index = args
|
let index = args
|
||||||
.remove_left_or_key("Index")
|
.remove_left_or_key("Index")
|
||||||
.ok_or_else(|| not_passed("Index"))?;
|
.ok_or_else(|| not_passed("Index"))?;
|
||||||
let index = enum_unwrap!(index, ValueObj::Nat);
|
let Ok(index) = usize::try_from(&index) else {
|
||||||
if let Some(v) = slf.get(index as usize) {
|
return Err(type_mismatch("Nat", index, "Index"));
|
||||||
|
};
|
||||||
|
if let Some(v) = slf.get(index) {
|
||||||
Ok(v.clone().into())
|
Ok(v.clone().into())
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorCore::new(
|
Err(ErrorCore::new(
|
||||||
|
@ -280,7 +285,9 @@ pub(crate) fn __dict_getitem__(mut args: ValueArgs, ctx: &Context) -> EvalValueR
|
||||||
let slf = args
|
let slf = args
|
||||||
.remove_left_or_key("Self")
|
.remove_left_or_key("Self")
|
||||||
.ok_or_else(|| not_passed("Self"))?;
|
.ok_or_else(|| not_passed("Self"))?;
|
||||||
let slf = enum_unwrap!(slf, ValueObj::Dict);
|
let ValueObj::Dict(slf) = slf else {
|
||||||
|
return Err(type_mismatch("Dict", slf, "Self"));
|
||||||
|
};
|
||||||
let index = args
|
let index = args
|
||||||
.remove_left_or_key("Index")
|
.remove_left_or_key("Index")
|
||||||
.ok_or_else(|| not_passed("Index"))?;
|
.ok_or_else(|| not_passed("Index"))?;
|
||||||
|
@ -302,7 +309,9 @@ pub(crate) fn dict_keys(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<T
|
||||||
let slf = args
|
let slf = args
|
||||||
.remove_left_or_key("Self")
|
.remove_left_or_key("Self")
|
||||||
.ok_or_else(|| not_passed("Self"))?;
|
.ok_or_else(|| not_passed("Self"))?;
|
||||||
let slf = enum_unwrap!(slf, ValueObj::Dict);
|
let ValueObj::Dict(slf) = slf else {
|
||||||
|
return Err(type_mismatch("Dict", slf, "Self"));
|
||||||
|
};
|
||||||
let slf = slf
|
let slf = slf
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(k, v)| {
|
.map(|(k, v)| {
|
||||||
|
@ -324,7 +333,9 @@ pub(crate) fn dict_values(mut args: ValueArgs, ctx: &Context) -> EvalValueResult
|
||||||
let slf = args
|
let slf = args
|
||||||
.remove_left_or_key("Self")
|
.remove_left_or_key("Self")
|
||||||
.ok_or_else(|| not_passed("Self"))?;
|
.ok_or_else(|| not_passed("Self"))?;
|
||||||
let slf = enum_unwrap!(slf, ValueObj::Dict);
|
let ValueObj::Dict(slf) = slf else {
|
||||||
|
return Err(type_mismatch("Dict", slf, "Self"));
|
||||||
|
};
|
||||||
let slf = slf
|
let slf = slf
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(k, v)| {
|
.map(|(k, v)| {
|
||||||
|
@ -346,7 +357,9 @@ pub(crate) fn dict_items(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<
|
||||||
let slf = args
|
let slf = args
|
||||||
.remove_left_or_key("Self")
|
.remove_left_or_key("Self")
|
||||||
.ok_or_else(|| not_passed("Self"))?;
|
.ok_or_else(|| not_passed("Self"))?;
|
||||||
let slf = enum_unwrap!(slf, ValueObj::Dict);
|
let ValueObj::Dict(slf) = slf else {
|
||||||
|
return Err(type_mismatch("Dict", slf, "Self"));
|
||||||
|
};
|
||||||
let slf = slf
|
let slf = slf
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(k, v)| {
|
.map(|(k, v)| {
|
||||||
|
@ -369,11 +382,15 @@ pub(crate) fn dict_concat(mut args: ValueArgs, _ctx: &Context) -> EvalValueResul
|
||||||
let slf = args
|
let slf = args
|
||||||
.remove_left_or_key("Self")
|
.remove_left_or_key("Self")
|
||||||
.ok_or_else(|| not_passed("Self"))?;
|
.ok_or_else(|| not_passed("Self"))?;
|
||||||
let slf = enum_unwrap!(slf, ValueObj::Dict);
|
let ValueObj::Dict(slf) = slf else {
|
||||||
|
return Err(type_mismatch("Dict", slf, "Self"));
|
||||||
|
};
|
||||||
let other = args
|
let other = args
|
||||||
.remove_left_or_key("Other")
|
.remove_left_or_key("Other")
|
||||||
.ok_or_else(|| not_passed("Other"))?;
|
.ok_or_else(|| not_passed("Other"))?;
|
||||||
let other = enum_unwrap!(other, ValueObj::Dict);
|
let ValueObj::Dict(other) = other else {
|
||||||
|
return Err(type_mismatch("Dict", other, "Other"));
|
||||||
|
};
|
||||||
Ok(ValueObj::Dict(slf.concat(other)).into())
|
Ok(ValueObj::Dict(slf.concat(other)).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,11 +398,15 @@ pub(crate) fn dict_diff(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<
|
||||||
let slf = args
|
let slf = args
|
||||||
.remove_left_or_key("Self")
|
.remove_left_or_key("Self")
|
||||||
.ok_or_else(|| not_passed("Self"))?;
|
.ok_or_else(|| not_passed("Self"))?;
|
||||||
let slf = enum_unwrap!(slf, ValueObj::Dict);
|
let ValueObj::Dict(slf) = slf else {
|
||||||
|
return Err(type_mismatch("Dict", slf, "Self"));
|
||||||
|
};
|
||||||
let other = args
|
let other = args
|
||||||
.remove_left_or_key("Other")
|
.remove_left_or_key("Other")
|
||||||
.ok_or_else(|| not_passed("Other"))?;
|
.ok_or_else(|| not_passed("Other"))?;
|
||||||
let other = enum_unwrap!(other, ValueObj::Dict);
|
let ValueObj::Dict(other) = other else {
|
||||||
|
return Err(type_mismatch("Dict", other, "Other"));
|
||||||
|
};
|
||||||
Ok(ValueObj::Dict(slf.diff(&other)).into())
|
Ok(ValueObj::Dict(slf.diff(&other)).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,7 +415,9 @@ pub(crate) fn array_union(mut args: ValueArgs, ctx: &Context) -> EvalValueResult
|
||||||
let slf = args
|
let slf = args
|
||||||
.remove_left_or_key("Self")
|
.remove_left_or_key("Self")
|
||||||
.ok_or_else(|| not_passed("Self"))?;
|
.ok_or_else(|| not_passed("Self"))?;
|
||||||
let slf = enum_unwrap!(slf, ValueObj::Array);
|
let ValueObj::Array(slf) = slf else {
|
||||||
|
return Err(type_mismatch("Array", slf, "Self"));
|
||||||
|
};
|
||||||
let slf = slf
|
let slf = slf
|
||||||
.iter()
|
.iter()
|
||||||
.map(|t| ctx.convert_value_into_type(t.clone()).unwrap())
|
.map(|t| ctx.convert_value_into_type(t.clone()).unwrap())
|
||||||
|
@ -423,7 +446,12 @@ fn _arr_shape(arr: ValueObj, ctx: &Context) -> Result<Vec<TyParam>, String> {
|
||||||
}
|
}
|
||||||
ValueObj::Type(ref t) if &t.typ().qual_name()[..] == "Array" => {
|
ValueObj::Type(ref t) if &t.typ().qual_name()[..] == "Array" => {
|
||||||
let mut tps = t.typ().typarams();
|
let mut tps = t.typ().typarams();
|
||||||
let elem = ctx.convert_tp_into_type(tps.remove(0)).unwrap();
|
let elem = match ctx.convert_tp_into_type(tps.remove(0)) {
|
||||||
|
Ok(elem) => elem,
|
||||||
|
Err(err) => {
|
||||||
|
return Err(err.to_string());
|
||||||
|
}
|
||||||
|
};
|
||||||
let len = tps.remove(0);
|
let len = tps.remove(0);
|
||||||
shape.push(len);
|
shape.push(len);
|
||||||
arr = ValueObj::builtin_type(elem);
|
arr = ValueObj::builtin_type(elem);
|
||||||
|
@ -452,24 +480,31 @@ pub(crate) fn array_shape(mut args: ValueArgs, ctx: &Context) -> EvalValueResult
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn __range_getitem__(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
|
pub(crate) fn __range_getitem__(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<TyParam> {
|
||||||
let (_name, fields) = enum_unwrap!(
|
let slf = args
|
||||||
args.remove_left_or_key("Self")
|
.remove_left_or_key("Self")
|
||||||
.ok_or_else(|| not_passed("Self"))?,
|
.ok_or_else(|| not_passed("Self"))?;
|
||||||
ValueObj::DataClass { name, fields }
|
let ValueObj::DataClass { name: _, fields } = slf else {
|
||||||
);
|
return Err(type_mismatch("Range", slf, "Self"));
|
||||||
|
};
|
||||||
let index = args
|
let index = args
|
||||||
.remove_left_or_key("Index")
|
.remove_left_or_key("Index")
|
||||||
.ok_or_else(|| not_passed("Index"))?;
|
.ok_or_else(|| not_passed("Index"))?;
|
||||||
let index = enum_unwrap!(index, ValueObj::Nat);
|
let Ok(index) = usize::try_from(&index) else {
|
||||||
|
return Err(type_mismatch("Nat", index, "Index"));
|
||||||
|
};
|
||||||
let start = fields
|
let start = fields
|
||||||
.get("start")
|
.get("start")
|
||||||
.ok_or_else(|| no_key(&fields, "start"))?;
|
.ok_or_else(|| no_key(&fields, "start"))?;
|
||||||
let start = *enum_unwrap!(start, ValueObj::Nat);
|
let Ok(start) = usize::try_from(start) else {
|
||||||
|
return Err(type_mismatch("Nat", start, "start"));
|
||||||
|
};
|
||||||
let end = fields.get("end").ok_or_else(|| no_key(&fields, "end"))?;
|
let end = fields.get("end").ok_or_else(|| no_key(&fields, "end"))?;
|
||||||
let end = *enum_unwrap!(end, ValueObj::Nat);
|
let Ok(end) = usize::try_from(end) else {
|
||||||
|
return Err(type_mismatch("Nat", end, "end"));
|
||||||
|
};
|
||||||
// FIXME <= if inclusive
|
// FIXME <= if inclusive
|
||||||
if start + index < end {
|
if start + index < end {
|
||||||
Ok(ValueObj::Nat(start + index).into())
|
Ok(ValueObj::Nat((start + index) as u64).into())
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorCore::new(
|
Err(ErrorCore::new(
|
||||||
vec![SubMessage::only_loc(Location::Unknown)],
|
vec![SubMessage::only_loc(Location::Unknown)],
|
||||||
|
|
|
@ -826,55 +826,27 @@ impl<'c, 'l, 'u, L: Locational> Unifier<'c, 'l, 'u, L> {
|
||||||
self.sub_unify(&rsub, &union)?;
|
self.sub_unify(&rsub, &union)?;
|
||||||
// self.sub_unify(&intersec, &lsup, loc, param_name)?;
|
// self.sub_unify(&intersec, &lsup, loc, param_name)?;
|
||||||
// self.sub_unify(&lsub, &union, loc, param_name)?;
|
// self.sub_unify(&lsub, &union, loc, param_name)?;
|
||||||
if union == intersec {
|
match sub_fv
|
||||||
match sub_fv
|
.level()
|
||||||
.level()
|
.unwrap_or(GENERIC_LEVEL)
|
||||||
.unwrap_or(GENERIC_LEVEL)
|
.cmp(&sup_fv.level().unwrap_or(GENERIC_LEVEL))
|
||||||
.cmp(&sup_fv.level().unwrap_or(GENERIC_LEVEL))
|
{
|
||||||
{
|
std::cmp::Ordering::Less => {
|
||||||
std::cmp::Ordering::Less => {
|
maybe_sub.update_tyvar(union, intersec, self.undoable, false);
|
||||||
maybe_sub.link(&union, self.undoable);
|
maybe_sup.link(maybe_sub, self.undoable);
|
||||||
maybe_sup.link(maybe_sub, self.undoable);
|
|
||||||
}
|
|
||||||
std::cmp::Ordering::Greater => {
|
|
||||||
maybe_sup.link(&union, self.undoable);
|
|
||||||
maybe_sub.link(maybe_sup, self.undoable);
|
|
||||||
}
|
|
||||||
std::cmp::Ordering::Equal => {
|
|
||||||
// choose named one
|
|
||||||
if sup_fv.is_named_unbound() {
|
|
||||||
maybe_sup.link(&union, self.undoable);
|
|
||||||
maybe_sub.link(maybe_sup, self.undoable);
|
|
||||||
} else {
|
|
||||||
maybe_sub.link(&union, self.undoable);
|
|
||||||
maybe_sup.link(maybe_sub, self.undoable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
std::cmp::Ordering::Greater => {
|
||||||
let new_constraint = Constraint::new_sandwiched(union, intersec);
|
maybe_sup.update_tyvar(union, intersec, self.undoable, false);
|
||||||
match sub_fv
|
maybe_sub.link(maybe_sup, self.undoable);
|
||||||
.level()
|
}
|
||||||
.unwrap_or(GENERIC_LEVEL)
|
std::cmp::Ordering::Equal => {
|
||||||
.cmp(&sup_fv.level().unwrap_or(GENERIC_LEVEL))
|
// choose named one
|
||||||
{
|
if sup_fv.is_named_unbound() {
|
||||||
std::cmp::Ordering::Less => {
|
maybe_sup.update_tyvar(union, intersec, self.undoable, false);
|
||||||
maybe_sub.update_constraint(new_constraint, self.undoable, false);
|
|
||||||
maybe_sup.link(maybe_sub, self.undoable);
|
|
||||||
}
|
|
||||||
std::cmp::Ordering::Greater => {
|
|
||||||
maybe_sup.update_constraint(new_constraint, self.undoable, false);
|
|
||||||
maybe_sub.link(maybe_sup, self.undoable);
|
maybe_sub.link(maybe_sup, self.undoable);
|
||||||
}
|
} else {
|
||||||
std::cmp::Ordering::Equal => {
|
maybe_sub.update_tyvar(union, intersec, self.undoable, false);
|
||||||
// choose named one
|
maybe_sup.link(maybe_sub, self.undoable);
|
||||||
if sup_fv.is_named_unbound() {
|
|
||||||
maybe_sup.update_constraint(new_constraint, self.undoable, false);
|
|
||||||
maybe_sub.link(maybe_sup, self.undoable);
|
|
||||||
} else {
|
|
||||||
maybe_sub.update_constraint(new_constraint, self.undoable, false);
|
|
||||||
maybe_sup.link(maybe_sub, self.undoable);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -947,12 +919,7 @@ impl<'c, 'l, 'u, L: Locational> Unifier<'c, 'l, 'u, L> {
|
||||||
self.sub_unify(&rsub, &union)?;
|
self.sub_unify(&rsub, &union)?;
|
||||||
// self.sub_unify(&intersec, &lsup, loc, param_name)?;
|
// self.sub_unify(&intersec, &lsup, loc, param_name)?;
|
||||||
// self.sub_unify(&lsub, &union, loc, param_name)?;
|
// self.sub_unify(&lsub, &union, loc, param_name)?;
|
||||||
if union == intersec {
|
maybe_sup.update_tyvar(union, intersec, self.undoable, false);
|
||||||
maybe_sup.link(&union, self.undoable);
|
|
||||||
} else {
|
|
||||||
let new_constraint = Constraint::new_sandwiched(union, intersec);
|
|
||||||
maybe_sup.update_constraint(new_constraint, self.undoable, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// (Int or ?T) <: (?U or Int)
|
// (Int or ?T) <: (?U or Int)
|
||||||
// OK: (Int <: Int); (?T <: ?U)
|
// OK: (Int <: Int); (?T <: ?U)
|
||||||
|
|
|
@ -1078,6 +1078,7 @@ impl ASTLowerer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// TODO: expect var_args
|
||||||
if let Some(var_args) = var_args {
|
if let Some(var_args) = var_args {
|
||||||
match self.lower_expr(var_args.expr, None) {
|
match self.lower_expr(var_args.expr, None) {
|
||||||
Ok(expr) => hir_args.var_args = Some(Box::new(hir::PosArg::new(expr))),
|
Ok(expr) => hir_args.var_args = Some(Box::new(hir::PosArg::new(expr))),
|
||||||
|
@ -1089,7 +1090,12 @@ impl ASTLowerer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for arg in kw_args.into_iter() {
|
for arg in kw_args.into_iter() {
|
||||||
match self.lower_expr(arg.expr, None) {
|
let kw_param = expect.as_ref().and_then(|subr| {
|
||||||
|
subr.non_var_params()
|
||||||
|
.find(|pt| pt.name().is_some_and(|n| n == &arg.keyword.content))
|
||||||
|
.map(|pt| pt.typ())
|
||||||
|
});
|
||||||
|
match self.lower_expr(arg.expr, kw_param) {
|
||||||
Ok(expr) => hir_args.push_kw(hir::KwArg::new(arg.keyword, expr)),
|
Ok(expr) => hir_args.push_kw(hir::KwArg::new(arg.keyword, expr)),
|
||||||
Err(es) => {
|
Err(es) => {
|
||||||
errs.extend(es);
|
errs.extend(es);
|
||||||
|
|
|
@ -564,10 +564,15 @@ impl SubrType {
|
||||||
.non_default_params
|
.non_default_params
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|pt| !pt.name().is_some_and(|n| &n[..] == "self"));
|
.filter(|pt| !pt.name().is_some_and(|n| &n[..] == "self"));
|
||||||
|
let defaults = self.default_params.iter();
|
||||||
if let Some(var_params) = self.var_params.as_ref() {
|
if let Some(var_params) = self.var_params.as_ref() {
|
||||||
non_defaults.chain(std::iter::repeat(var_params.as_ref()))
|
non_defaults
|
||||||
|
.chain([].iter())
|
||||||
|
.chain(std::iter::repeat(var_params.as_ref()))
|
||||||
} else {
|
} else {
|
||||||
non_defaults.chain(std::iter::repeat(&ParamTy::Pos(Type::Failure)))
|
non_defaults
|
||||||
|
.chain(defaults)
|
||||||
|
.chain(std::iter::repeat(&ParamTy::Pos(Type::Failure)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1771,6 +1776,46 @@ impl Type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn immutate(&self) -> Option<Self> {
|
||||||
|
match self {
|
||||||
|
Self::FreeVar(fv) if fv.is_linked() => {
|
||||||
|
let t = fv.crack().clone();
|
||||||
|
if let Some(t) = t.immutate() {
|
||||||
|
fv.link(&t);
|
||||||
|
Some(Self::FreeVar(fv.clone()))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Self::Mono(name) => match &name[..] {
|
||||||
|
"Int!" => Some(Self::Int),
|
||||||
|
"Nat!" => Some(Self::Nat),
|
||||||
|
"Ratio!" => Some(Self::Ratio),
|
||||||
|
"Float!" => Some(Self::Float),
|
||||||
|
"Complex!" => Some(Self::Complex),
|
||||||
|
"Bool!" => Some(Self::Bool),
|
||||||
|
"Str!" => Some(Self::Str),
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
|
Self::Poly { name, params } => match &name[..] {
|
||||||
|
"Array!" => Some(Self::Poly {
|
||||||
|
name: "Array".into(),
|
||||||
|
params: params.clone(),
|
||||||
|
}),
|
||||||
|
"Set!" => Some(Self::Poly {
|
||||||
|
name: "Set".into(),
|
||||||
|
params: params.clone(),
|
||||||
|
}),
|
||||||
|
"Dict!" => Some(Self::Poly {
|
||||||
|
name: "Dict".into(),
|
||||||
|
params: params.clone(),
|
||||||
|
}),
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn quantify(self) -> Self {
|
pub fn quantify(self) -> Self {
|
||||||
debug_assert!(self.is_subr(), "{self} is not subr");
|
debug_assert!(self.is_subr(), "{self} is not subr");
|
||||||
match self {
|
match self {
|
||||||
|
@ -1835,6 +1880,10 @@ impl Type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_mut_value_class(&self) -> bool {
|
||||||
|
self.immutate().is_some_and(|t| t.is_value_class())
|
||||||
|
}
|
||||||
|
|
||||||
/// Procedure
|
/// Procedure
|
||||||
pub fn is_procedure(&self) -> bool {
|
pub fn is_procedure(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
|
@ -3567,6 +3616,21 @@ impl Type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn update_tyvar(
|
||||||
|
&self,
|
||||||
|
new_sub: Type,
|
||||||
|
new_sup: Type,
|
||||||
|
list: Option<&UndoableLinkedList>,
|
||||||
|
in_instantiation: bool,
|
||||||
|
) {
|
||||||
|
if new_sub == new_sup {
|
||||||
|
self.link(&new_sub, list);
|
||||||
|
} else {
|
||||||
|
let new_constraint = Constraint::new_sandwiched(new_sub, new_sup);
|
||||||
|
self.update_constraint(new_constraint, list, in_instantiation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn inc_undo_count(&self) {
|
fn inc_undo_count(&self) {
|
||||||
match self {
|
match self {
|
||||||
Self::FreeVar(fv) => fv.inc_undo_count(),
|
Self::FreeVar(fv) => fv.inc_undo_count(),
|
||||||
|
|
|
@ -668,6 +668,10 @@ impl TryFrom<TyParam> for ValueObj {
|
||||||
}
|
}
|
||||||
Ok(ValueObj::Array(Arc::from(vals)))
|
Ok(ValueObj::Array(Arc::from(vals)))
|
||||||
}
|
}
|
||||||
|
TyParam::UnsizedArray(elem) => {
|
||||||
|
let elem = ValueObj::try_from(*elem)?;
|
||||||
|
Ok(ValueObj::UnsizedArray(Box::new(elem)))
|
||||||
|
}
|
||||||
TyParam::Tuple(tps) => {
|
TyParam::Tuple(tps) => {
|
||||||
let mut vals = vec![];
|
let mut vals = vec![];
|
||||||
for tp in tps {
|
for tp in tps {
|
||||||
|
@ -689,6 +693,13 @@ impl TryFrom<TyParam> for ValueObj {
|
||||||
}
|
}
|
||||||
Ok(ValueObj::Record(vals))
|
Ok(ValueObj::Record(vals))
|
||||||
}
|
}
|
||||||
|
TyParam::Set(tps) => {
|
||||||
|
let mut vals = set! {};
|
||||||
|
for tp in tps {
|
||||||
|
vals.insert(ValueObj::try_from(tp)?);
|
||||||
|
}
|
||||||
|
Ok(ValueObj::Set(vals))
|
||||||
|
}
|
||||||
TyParam::DataClass { name, fields } => {
|
TyParam::DataClass { name, fields } => {
|
||||||
let mut vals = dict! {};
|
let mut vals = dict! {};
|
||||||
for (k, v) in fields {
|
for (k, v) in fields {
|
||||||
|
@ -710,7 +721,7 @@ impl TryFrom<TyParam> for ValueObj {
|
||||||
TyParam::Type(t) => Ok(ValueObj::builtin_type(*t)),
|
TyParam::Type(t) => Ok(ValueObj::builtin_type(*t)),
|
||||||
TyParam::Value(v) => Ok(v),
|
TyParam::Value(v) => Ok(v),
|
||||||
_ => {
|
_ => {
|
||||||
log!(err "Expected value, got {tp} ({tp:?})");
|
log!(err "Expected value, got {tp}");
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1167,7 +1167,7 @@ impl ValueObj {
|
||||||
Self::Dict(dict) => {
|
Self::Dict(dict) => {
|
||||||
let tp = dict
|
let tp = dict
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(k, v)| (TyParam::value(k.clone()), TyParam::value(v.clone())));
|
.map(|(k, v)| (TyParam::t(k.class()), TyParam::t(v.class())));
|
||||||
dict_t(TyParam::Dict(tp.collect()))
|
dict_t(TyParam::Dict(tp.collect()))
|
||||||
}
|
}
|
||||||
Self::Tuple(tup) => tuple_t(tup.iter().map(|v| v.class()).collect()),
|
Self::Tuple(tup) => tuple_t(tup.iter().map(|v| v.class()).collect()),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue