mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-28 12:14:43 +00:00
fix: const call bug
This commit is contained in:
parent
477778c9fe
commit
2ddff1512f
6 changed files with 35 additions and 13 deletions
|
@ -1925,11 +1925,20 @@ impl Context {
|
||||||
self.convert_tp_into_type(t)
|
self.convert_tp_into_type(t)
|
||||||
}
|
}
|
||||||
// TyParam(Ts: Array(Type)) -> Type(Ts: Array(Type))
|
// TyParam(Ts: Array(Type)) -> Type(Ts: Array(Type))
|
||||||
TyParam::FreeVar(fv) if fv.get_type().is_some() => Ok(named_free_var(
|
// TyParam(?S(: Str)) -> Err(...),
|
||||||
fv.unbound_name().unwrap(),
|
// TyParam(?D(: GenericDict)) -> Ok(?D(: GenericDict)),
|
||||||
fv.level().unwrap(),
|
// FIXME: GenericDict
|
||||||
fv.constraint().unwrap(),
|
TyParam::FreeVar(fv)
|
||||||
)),
|
if fv.get_type().is_some_and(|t| {
|
||||||
|
self.subtype_of(&t, &Type::Type) || &t.qual_name() == "GenericDict"
|
||||||
|
}) =>
|
||||||
|
{
|
||||||
|
Ok(named_free_var(
|
||||||
|
fv.unbound_name().unwrap(),
|
||||||
|
fv.level().unwrap(),
|
||||||
|
fv.constraint().unwrap(),
|
||||||
|
))
|
||||||
|
}
|
||||||
TyParam::Type(t) => Ok(t.as_ref().clone()),
|
TyParam::Type(t) => Ok(t.as_ref().clone()),
|
||||||
TyParam::Mono(name) => Ok(Type::Mono(name)),
|
TyParam::Mono(name) => Ok(Type::Mono(name)),
|
||||||
TyParam::App { name, args } => Ok(Type::Poly { name, params: args }),
|
TyParam::App { name, args } => Ok(Type::Poly { name, params: args }),
|
||||||
|
@ -2599,7 +2608,16 @@ impl Context {
|
||||||
TyParam::App { ref name, ref args } => self
|
TyParam::App { ref name, ref args } => self
|
||||||
.rec_get_const_obj(name)
|
.rec_get_const_obj(name)
|
||||||
.and_then(|v| {
|
.and_then(|v| {
|
||||||
let ty = self.convert_value_into_type(v.clone()).ok()?;
|
let ty = match self.convert_value_into_type(v.clone()) {
|
||||||
|
Ok(ty) => ty,
|
||||||
|
Err(ValueObj::Subr(subr)) => {
|
||||||
|
// REVIEW: evaluation of polymorphic types
|
||||||
|
return subr.sig_t().return_t().cloned();
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
};
|
||||||
let instance = self
|
let instance = self
|
||||||
.instantiate_def_type(&ty)
|
.instantiate_def_type(&ty)
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
|
|
|
@ -665,7 +665,7 @@ impl Context {
|
||||||
);
|
);
|
||||||
let patch = ConstSubr::Builtin(BuiltinConstSubr::new(PATCH, patch_func, patch_t, None));
|
let patch = ConstSubr::Builtin(BuiltinConstSubr::new(PATCH, patch_func, patch_t, None));
|
||||||
self.register_builtin_const(PATCH, vis.clone(), ValueObj::Subr(patch));
|
self.register_builtin_const(PATCH, vis.clone(), ValueObj::Subr(patch));
|
||||||
let t_resolve_path = nd_func(vec![kw(KW_PATH, Str)], None, mono(GENERIC_MODULE));
|
let t_resolve_path = nd_func(vec![kw(KW_PATH, Str)], None, Str);
|
||||||
let resolve_path = ConstSubr::Builtin(BuiltinConstSubr::new(
|
let resolve_path = ConstSubr::Builtin(BuiltinConstSubr::new(
|
||||||
FUNC_RESOLVE_PATH,
|
FUNC_RESOLVE_PATH,
|
||||||
resolve_path_func,
|
resolve_path_func,
|
||||||
|
@ -673,7 +673,7 @@ impl Context {
|
||||||
None,
|
None,
|
||||||
));
|
));
|
||||||
self.register_builtin_const(FUNC_RESOLVE_PATH, vis.clone(), ValueObj::Subr(resolve_path));
|
self.register_builtin_const(FUNC_RESOLVE_PATH, vis.clone(), ValueObj::Subr(resolve_path));
|
||||||
let t_resolve_decl_path = nd_func(vec![kw(KW_PATH, Str)], None, mono(GENERIC_MODULE));
|
let t_resolve_decl_path = nd_func(vec![kw(KW_PATH, Str)], None, Str);
|
||||||
let resolve_decl_path = ConstSubr::Builtin(BuiltinConstSubr::new(
|
let resolve_decl_path = ConstSubr::Builtin(BuiltinConstSubr::new(
|
||||||
FUNC_RESOLVE_DECL_PATH,
|
FUNC_RESOLVE_DECL_PATH,
|
||||||
resolve_decl_path_func,
|
resolve_decl_path_func,
|
||||||
|
|
|
@ -2246,7 +2246,7 @@ impl Context {
|
||||||
);
|
);
|
||||||
log!(info "Substituted:\ninstance: {instance}");
|
log!(info "Substituted:\ninstance: {instance}");
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
instance.is_type() || instance.has_no_qvar(),
|
self.subtype_of(&instance, &Type::Type) || instance.has_no_qvar(),
|
||||||
"{instance} has qvar (obj: {obj}, attr: {}",
|
"{instance} has qvar (obj: {obj}, attr: {}",
|
||||||
fmt_option!(attr_name)
|
fmt_option!(attr_name)
|
||||||
);
|
);
|
||||||
|
|
|
@ -623,7 +623,7 @@ impl<A: ASTBuildable> GenericASTLowerer<A> {
|
||||||
let arg_ts = ctx.params.iter().map(|(_, vi)| &vi.t);
|
let arg_ts = ctx.params.iter().map(|(_, vi)| &vi.t);
|
||||||
for ((tp, arg), arg_t) in ctx.typ.typarams().iter().zip(args.pos_args()).zip(arg_ts) {
|
for ((tp, arg), arg_t) in ctx.typ.typarams().iter().zip(args.pos_args()).zip(arg_ts) {
|
||||||
if let ast::Expr::Accessor(ast::Accessor::Ident(ident)) = &arg.expr {
|
if let ast::Expr::Accessor(ast::Accessor::Ident(ident)) = &arg.expr {
|
||||||
if arg_t.is_type() {
|
if self.module.context.subtype_of(arg_t, &Type::Type) {
|
||||||
if let Ok(tv) = self.module.context.convert_tp_into_type(tp.clone()) {
|
if let Ok(tv) = self.module.context.convert_tp_into_type(tp.clone()) {
|
||||||
tv_ctx.push_or_init_tyvar(&ident.name, &tv, &self.module.context);
|
tv_ctx.push_or_init_tyvar(&ident.name, &tv, &self.module.context);
|
||||||
continue;
|
continue;
|
||||||
|
@ -861,7 +861,10 @@ impl<A: ASTBuildable> GenericASTLowerer<A> {
|
||||||
.module
|
.module
|
||||||
.context
|
.context
|
||||||
.registered_info(ident.inspect(), ident.is_const())
|
.registered_info(ident.inspect(), ident.is_const())
|
||||||
.is_some_and(|(_, vi)| t.is_type() || vi.t.is_type())
|
.is_some_and(|(_, vi)| {
|
||||||
|
self.module.context.subtype_of(t, &Type::Type)
|
||||||
|
|| self.module.context.subtype_of(&vi.t, &Type::Type)
|
||||||
|
})
|
||||||
{
|
{
|
||||||
let typ = self.module.context.get_type_ctx(ident.inspect());
|
let typ = self.module.context.get_type_ctx(ident.inspect());
|
||||||
if typ.is_some_and(|ctx| ctx.has("__call__")) {
|
if typ.is_some_and(|ctx| ctx.has("__call__")) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.util = pyimport "util"
|
.util = pyimport "util"
|
||||||
.machinery = pyimport "machinery"
|
.machinery = pyimport "machinery"
|
||||||
|
|
||||||
.__import__: |S: Str|(name: {S}, globals := {Str: Obj}) -> Module S
|
.__import__: (name: Str, globals := {Str: Obj}) -> GenericModule
|
||||||
.import_module: |S: Str|(name: {S}, package := Str or NoneType) -> Module S
|
.import_module: (name: Str, package := Str or NoneType) -> GenericModule
|
||||||
.reload!: (GenericModule, ) => NoneType
|
.reload!: (GenericModule, ) => NoneType
|
||||||
|
|
|
@ -2245,6 +2245,7 @@ impl Type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// NOTE: don't use this, use `Context::subtype_of(t, &Type::Type)` instead
|
||||||
pub fn is_type(&self) -> bool {
|
pub fn is_type(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::FreeVar(fv) if fv.is_linked() => fv.crack().is_type(),
|
Self::FreeVar(fv) if fv.is_linked() => fv.crack().is_type(),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue