mirror of
https://github.com/erg-lang/erg.git
synced 2025-10-01 05:11:09 +00:00
Enhance: type instantiating
This commit is contained in:
parent
d393ace9a6
commit
f0ecf59af1
2 changed files with 73 additions and 10 deletions
|
@ -27,6 +27,7 @@ use crate::ty::typaram::{IntervalOp, TyParam, TyParamOrdering};
|
||||||
use crate::ty::value::ValueObj;
|
use crate::ty::value::ValueObj;
|
||||||
use crate::ty::{HasType, ParamTy, Predicate, SubrKind, Type};
|
use crate::ty::{HasType, ParamTy, Predicate, SubrKind, Type};
|
||||||
use crate::type_feature_error;
|
use crate::type_feature_error;
|
||||||
|
use crate::unreachable_error;
|
||||||
use TyParamOrdering::*;
|
use TyParamOrdering::*;
|
||||||
use Type::*;
|
use Type::*;
|
||||||
|
|
||||||
|
@ -397,7 +398,7 @@ impl Context {
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
other => type_feature_error!(self, other.loc(), &format!("instantiating {other}")),
|
other => type_feature_error!(self, other.loc(), &format!("instantiating type {other}")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -604,7 +605,49 @@ impl Context {
|
||||||
self.get_similar_name(name.inspect()),
|
self.get_similar_name(name.inspect()),
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
other => type_feature_error!(self, other.loc(), &format!("instantiating {other}")),
|
ast::ConstExpr::Array(array) => {
|
||||||
|
let mut tp_arr = vec![];
|
||||||
|
for (i, elem) in array.elems.pos_args().enumerate() {
|
||||||
|
let el =
|
||||||
|
self.instantiate_const_expr(&elem.expr, Some((self, i)), tmp_tv_cache)?;
|
||||||
|
tp_arr.push(el);
|
||||||
|
}
|
||||||
|
Ok(TyParam::Array(tp_arr))
|
||||||
|
}
|
||||||
|
ast::ConstExpr::Set(set) => {
|
||||||
|
let mut tp_set = set! {};
|
||||||
|
for (i, elem) in set.elems.pos_args().enumerate() {
|
||||||
|
let el =
|
||||||
|
self.instantiate_const_expr(&elem.expr, Some((self, i)), tmp_tv_cache)?;
|
||||||
|
tp_set.insert(el);
|
||||||
|
}
|
||||||
|
Ok(TyParam::Set(tp_set))
|
||||||
|
}
|
||||||
|
ast::ConstExpr::Dict(dict) => {
|
||||||
|
let mut tp_dict = dict! {};
|
||||||
|
for (i, elem) in dict.kvs.iter().enumerate() {
|
||||||
|
let key =
|
||||||
|
self.instantiate_const_expr(&elem.key, Some((self, i)), tmp_tv_cache)?;
|
||||||
|
let val =
|
||||||
|
self.instantiate_const_expr(&elem.value, Some((self, i)), tmp_tv_cache)?;
|
||||||
|
tp_dict.insert(key, val);
|
||||||
|
}
|
||||||
|
Ok(TyParam::Dict(tp_dict))
|
||||||
|
}
|
||||||
|
ast::ConstExpr::Tuple(tuple) => {
|
||||||
|
let mut tp_tuple = vec![];
|
||||||
|
for (i, elem) in tuple.elems.pos_args().enumerate() {
|
||||||
|
let el =
|
||||||
|
self.instantiate_const_expr(&elem.expr, Some((self, i)), tmp_tv_cache)?;
|
||||||
|
tp_tuple.push(el);
|
||||||
|
}
|
||||||
|
Ok(TyParam::Tuple(tp_tuple))
|
||||||
|
}
|
||||||
|
other => type_feature_error!(
|
||||||
|
self,
|
||||||
|
other.loc(),
|
||||||
|
&format!("instantiating const expression {other}")
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -614,10 +657,23 @@ impl Context {
|
||||||
erased_idx: Option<(&Context, usize)>,
|
erased_idx: Option<(&Context, usize)>,
|
||||||
tmp_tv_cache: &mut TyVarCache,
|
tmp_tv_cache: &mut TyVarCache,
|
||||||
) -> TyCheckResult<Type> {
|
) -> TyCheckResult<Type> {
|
||||||
match self.instantiate_const_expr(expr, erased_idx, tmp_tv_cache)? {
|
let tp = self.instantiate_const_expr(expr, erased_idx, tmp_tv_cache)?;
|
||||||
|
self.instantiate_tp_as_type(tp, expr.loc())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn instantiate_tp_as_type(&self, tp: TyParam, loc: Location) -> TyCheckResult<Type> {
|
||||||
|
match tp {
|
||||||
TyParam::Type(t) => Ok(*t),
|
TyParam::Type(t) => Ok(*t),
|
||||||
TyParam::Value(ValueObj::Type(t)) => Ok(t.into_typ()),
|
TyParam::Value(ValueObj::Type(t)) => Ok(t.into_typ()),
|
||||||
other => type_feature_error!(self, expr.loc(), &format!("{other}")),
|
TyParam::Set(set) => {
|
||||||
|
let t = set
|
||||||
|
.iter()
|
||||||
|
.next()
|
||||||
|
.and_then(|tp| self.get_tp_t(tp).ok())
|
||||||
|
.unwrap_or(Type::Never);
|
||||||
|
Ok(tp_enum(t, set))
|
||||||
|
}
|
||||||
|
other => type_feature_error!(self, loc, &format!("instantiate `{other}` as type")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -855,7 +911,11 @@ impl Context {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
TypeSpec::TypeApp { spec, args } => {
|
TypeSpec::TypeApp { spec, args } => {
|
||||||
type_feature_error!(self, t_spec.loc(), &format!("instantiating {spec}{args}"))
|
type_feature_error!(
|
||||||
|
self,
|
||||||
|
t_spec.loc(),
|
||||||
|
&format!("instantiating type spec {spec}{args}")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1014,7 +1074,9 @@ impl Context {
|
||||||
| TyParam::Mono(_)
|
| TyParam::Mono(_)
|
||||||
| TyParam::FreeVar(_)
|
| TyParam::FreeVar(_)
|
||||||
| TyParam::Erased(_)) => Ok(p),
|
| TyParam::Erased(_)) => Ok(p),
|
||||||
other => type_feature_error!(self, loc, &format!("instantiating {other}")),
|
other => {
|
||||||
|
type_feature_error!(self, loc, &format!("instantiating type-parameter {other}"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1136,7 +1198,8 @@ impl Context {
|
||||||
Ok(poly(name, params))
|
Ok(poly(name, params))
|
||||||
}
|
}
|
||||||
Quantified(_) => {
|
Quantified(_) => {
|
||||||
panic!("a quantified type should not be instantiated, instantiate the inner type")
|
log!(err "a quantified type should not be instantiated, instantiate the inner type");
|
||||||
|
unreachable_error!(TyCheckErrors, TyCheckError, self)
|
||||||
}
|
}
|
||||||
FreeVar(fv) if fv.is_linked() => {
|
FreeVar(fv) if fv.is_linked() => {
|
||||||
self.instantiate_t_inner(fv.crack().clone(), tmp_tv_cache, loc)
|
self.instantiate_t_inner(fv.crack().clone(), tmp_tv_cache, loc)
|
||||||
|
@ -1165,7 +1228,7 @@ impl Context {
|
||||||
Ok(not(l, r))
|
Ok(not(l, r))
|
||||||
}
|
}
|
||||||
other if other.is_monomorphic() => Ok(other),
|
other if other.is_monomorphic() => Ok(other),
|
||||||
other => type_feature_error!(self, loc, &format!("instantiating {other}")),
|
other => type_feature_error!(self, loc, &format!("instantiating type {other}")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,14 +26,14 @@ macro_rules! unreachable_error {
|
||||||
($Strcs: ident, $Strc: ident, $ctx: expr) => {
|
($Strcs: ident, $Strc: ident, $ctx: expr) => {
|
||||||
Err($Strcs::from($Strc::unreachable(
|
Err($Strcs::from($Strc::unreachable(
|
||||||
$ctx.cfg.input.clone(),
|
$ctx.cfg.input.clone(),
|
||||||
fn_name!(),
|
$crate::erg_common::fn_name!(),
|
||||||
line!(),
|
line!(),
|
||||||
)))
|
)))
|
||||||
};
|
};
|
||||||
($Strc: ident, $ctx: expr) => {
|
($Strc: ident, $ctx: expr) => {
|
||||||
Err($Strc::unreachable(
|
Err($Strc::unreachable(
|
||||||
$ctx.cfg.input.clone(),
|
$ctx.cfg.input.clone(),
|
||||||
fn_name!(),
|
$crate::erg_common::fn_name!(),
|
||||||
line!(),
|
line!(),
|
||||||
))
|
))
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue