ANEW ANN m_str tl2str(const Env, const Type_List); // in type_decl.c
ANN m_bool compat_func(const __restrict__ Func_Def, const __restrict__ Func_Def);
ANN Type known_type(const Env env, const Type_Decl*);
-ANN Type known_type_noref(const Env env, const Type_Decl* td);
+ANN Type type_nonnull(const Env env, const Type base);
ANN Type prim_ref(const Env env, const Type t, const Type_Decl* td);
ANN m_bool env_access(const Env env, const ae_flag flag, const loc_t pos);
ANN m_bool env_storage(const Env env, ae_flag flag, const loc_t pos);
ANN static m_bool fptr_do(const Env env, struct FptrInfo *info) {
if(isa(info->exp->type, t_lambda) < 0) {
+ m_bool nonnull = GET_FLAG(info->exp->type, nonnull);
CHECK_BB(fptr_check(env, info))
DECL_OB(const Type, t, = fptr_type(env, info))
- info->exp->type = t;
+ info->exp->type = !nonnull ? t : type_nonnull(env, t);
return GW_OK;
}
return fptr_lambda(env, info);
Exp_Cast* cast = (Exp_Cast*)data;
if(exp_self(cast)->type->e->d.func->def->base->tmpl)
fptr_instr(emit, cast->exp->type->e->d.func, 1);
- if(GET_FLAG(cast->exp->type->e->d.func, member))
+ if(GET_FLAG(cast->exp->type->e->d.func, member) &&
+ !(GET_FLAG(cast->exp->type, nonnull) || GET_FLAG(exp_self(cast)->type, nonnull)))
member_fptr(emit);
return GW_OK;
}
static OP_EMIT(opem_fptr_impl) {
struct Implicit *impl = (struct Implicit*)data;
- if(GET_FLAG(impl->t->e->d.func, member))
+ if(GET_FLAG(impl->t->e->d.func, member) &&
+ !(GET_FLAG(impl->e->type, nonnull) || GET_FLAG(impl->t, nonnull)))
member_fptr(emit);
if(impl->t->e->d.func->def->base->tmpl)
fptr_instr(emit, ((Exp)impl->e)->type->e->d.func, 1);
Value v;
if(!a->is_union) {
while(scope_iter(&iter, &v) > 0) {
- if(isa(v->type, t_object) > 0)
- nspc_release_object(a, v, gwion);
- REM_REF(v, gwion);
+ if(v) {
+ if(isa(v->type, t_object) > 0)
+ nspc_release_object(a, v, gwion);
+ REM_REF(v, gwion);
+ }
}
}
free_scope(gwion->mp, a->info->value);
(func->def->base->tmpl && is_fptr(func->value_ref->type) > 0)) {
if(SAFE_FLAG(func->value_ref->owner_class, template))
CHECK_BO(template_push_types(env, func->value_ref->owner_class->e->def->base.tmpl))
- e1->type = known_type(env, e1->td);
+ e1->type = known_type(env, e1->td);
if(SAFE_FLAG(func->value_ref->owner_class, template))
nspc_pop_type(env->gwion->mp, env->curr);
+ CHECK_OO(e1->type)
}
if(func_match_inner(env, e, e1->type, implicit, specific) < 0)
break;
}
ANN static void print_arg(Arg_List e) {
- do gw_err(" \033[32m%s\033[0m \033[1m%s\033[0m", e->type->name,
+ do gw_err(" \033[32m%s\033[0m \033[1m%s\033[0m", e->type ? e->type->name : NULL,
e->var_decl->xid ? s_name(e->var_decl->xid) : "");
while((e = e->next) && gw_err(","));
}
#define STR_NONNULL ":nonnull"
#define STRLEN_NONNULL strlen(STR_NONNULL)
+#include "func.h"
+
+ANN Type type_nonnull(const Env env, const Type base) {
+ char c[strlen(base->name) + 9];
+ sprintf(c, "%s%s", base->name, STR_NONNULL);
+ const Symbol sym = insert_symbol(c);
+ const Type exist = nspc_lookup_type1(base->e->owner, sym);
+ if(exist)
+ return exist;
+ const Type t = type_copy(env->gwion->mp, base);
+ t->e->parent = base;
+ if(t->nspc)
+ ADD_REF(t->nspc)
+ t->name = s_name(sym);
+ t->flag = base->flag;
+ SET_FLAG(t, nonnull);
+ map_set(&t->e->owner->info->type->map, (vtype)sym, (vtype)t);
+ return t;
+}
+
ANN Type type_decl_resolve(const Env env, const Type_Decl* td) {
DECL_OO(const Type, base, = find_type(env, td->xid))
DECL_OO(const Type, t, = scan_type(env, base, td))
ERR_O(td_pos(td), _("void types can't be nonnull."))
if(isa(ret, t_object) < 0 && isa(ret, t_function) < 0)
return ret;
- char c[strlen(t->name) + 9];
- sprintf(c, "%s%s", ret->name, STR_NONNULL);
- const Symbol sym = insert_symbol(c);
- const Type exist = nspc_lookup_type1(t->e->owner, sym);
- if(exist)
- return exist;
- const Type t = type_copy(env->gwion->mp, ret);
- t->e->parent = ret;
- if(t->nspc)
- ADD_REF(t->nspc)
- t->name = s_name(sym);
- t->flag = ret->flag;
- SET_FLAG(t, nonnull);
- map_set(&t->e->owner->info->type->map, (vtype)sym, (vtype)t);
- return t;
+ return type_nonnull(env, ret);
}
return ret;
}