From: Jérémie Astor Date: Mon, 16 Aug 2021 10:45:19 +0000 (+0200) Subject: :art: Improve final and shadowing for inlining X-Git-Tag: nightly~470^2~79 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=1dc9e8ceeca162eab3f5f947decfca327270d9ed;p=gwion.git :art: Improve final and shadowing for inlining --- diff --git a/include/env/env.h b/include/env/env.h index f10594db..0e550a0a 100644 --- a/include/env/env.h +++ b/include/env/env.h @@ -25,6 +25,7 @@ struct Env_Scope_ { uint16_t depth; bool in_try; bool in_loop; + bool shadowing; }; typedef struct Env_ { diff --git a/src/emit/emit.c b/src/emit/emit.c index f80dab13..e941e38e 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1287,6 +1287,8 @@ ANN static inline m_bool traverse_emit_func_def(const Emitter emit, ANN m_bool traverse_dot_tmpl(const Emitter emit, const struct dottmpl_ *dt) { const m_uint scope = emit->env->scope->depth; + const bool shadowing = emit->env->scope->shadowing; + emit->env->scope->shadowing = true; struct EnvSet es = {.env = emit->env, .data = emit, .func = (_exp_func)emit_cdef, @@ -1297,6 +1299,7 @@ ANN m_bool traverse_dot_tmpl(const Emitter emit, const struct dottmpl_ *dt) { const m_bool ret = traverse_emit_func_def(emit, dt->def); if (es.run) envset_pop(&es, dt->owner_class); emit_pop(emit, scope); + emit->env->scope->shadowing = shadowing; return ret; } diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 32a2bc4d..db0e1bf3 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -328,6 +328,8 @@ ANN static inline m_bool stmt_each_defined(const restrict Env env, ANN static inline m_bool shadow_err(const Env env, const Value v, const loc_t loc) { + if(env->scope->shadowing) + return GW_OK; gwerr_basic(_("shadowing a previously defined variable"), NULL, NULL, env->name, loc, 0); defined_here(v); diff --git a/src/parse/scan2.c b/src/parse/scan2.c index f7f03d4d..5279a382 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -294,7 +294,7 @@ ANN static m_bool scan2_func_def_overload(const Env env, const Func_Def f, } const Func obase = !fptr ? overload->d.func_ref : _class_base(overload->type)->info->func; - if (GET_FLAG(obase->def->base, final)) + if (GET_FLAG(obase->def->base, final) && obase->value_ref->from->owner_class != env->class_def) ERR_B(f->base->pos, _("can't overload final function %s"), overload->name) const m_bool base = tmpl_base(f->base->tmpl); const m_bool tmpl = fflag(obase, fflag_tmpl);