]> Nishi Git Mirror - gwion.git/commitdiff
:art: Improve new semantics
authorJérémie Astor <fennecdjay@gmail.com>
Tue, 29 Mar 2022 09:51:04 +0000 (11:51 +0200)
committerJérémie Astor <fennecdjay@gmail.com>
Tue, 29 Mar 2022 09:51:04 +0000 (11:51 +0200)
plug
src/lib/lib_func.c
src/lib/opfunc.c
src/parse/check.c
src/parse/scan2.c
tests/ctor/missing.gw [new file with mode: 0644]
tests/tree/inherit.gw [new file with mode: 0644]

diff --git a/plug b/plug
index 7fa0a948f67335204cab7b72e4837b99699c2d32..3cdb9feede115e9c1728ebc93d6de7d08f0e7891 160000 (submodule)
--- a/plug
+++ b/plug
@@ -1 +1 @@
-Subproject commit 7fa0a948f67335204cab7b72e4837b99699c2d32
+Subproject commit 3cdb9feede115e9c1728ebc93d6de7d08f0e7891
index f0af55591a1ab9588c6cd72f4745c7f2e084ff11..dd20b8f16fb3b13eb277bb23686a908db550b7ce 100644 (file)
@@ -588,7 +588,7 @@ static OP_CHECK(opck_op_impl) {
 //  if (eff && !check_effect_overload(eff, func))
 //    ERR_N(impl->pos, _("`{+Y}%s{0}` has effects not present in `{+G}%s{0}`\n"),
 //          s_name(impl->e->d.prim.d.var), func->name);
-  Value v = nspc_lookup_value0(opi.nspc, impl->e->d.prim.d.var);
+  const Value v = nspc_lookup_value0(opi.nspc, impl->e->d.prim.d.var);
   if (v) {
     const m_uint scope = env_push(env, NULL, opi.nspc);
     _lhs.next          = &_rhs;
index 9ec842fd75d7444c070c35ebc7b0ca4a9a0a51f5..a3ca7f07234a22ad3f483365dd9181f8beaf2e04 100644 (file)
@@ -136,6 +136,9 @@ OP_CHECK(opck_new) {
     self->d.exp_call.tmpl = NULL;
     self->exp_type = ae_exp_call;
     CHECK_BN(traverse_exp(env, self));
+    const Type tbase = func->type->info->value->from->owner_class;
+    if(!tflag(base->type, tflag_union) && tbase != base->type)
+      ERR_N(base->pos, "'%s' has no matching constructor", base->type->name);
     return self->type;
   }
   if (GET_FLAG(t, abstract) &&
index a546b49429c3738bd81c4ee2daee35955f5d6a67..8cf11d709de563935dc1b63fd674d860f722114b 100644 (file)
@@ -1867,7 +1867,6 @@ ANN static inline bool type_is_recurs(const Type t, const Type tgt) {
 ANN static m_bool recursive_type_base(const Env env, const Type t);
 ANN static bool recursive_type(const Env env, const Type t, const Type tgt);
 ANN static bool recursive_value(const Env env, const Type t, const Value v) {
-//if(!v->from->owner_class)exit(13);
   const Type tgt = array_base(v->type);
   if(type_is_recurs(t, tgt)) {
     env_err(env, v->from->loc, _("recursive type"));
@@ -1949,6 +1948,11 @@ ANN static m_bool _check_class_def(const Env env, const Class_Def cdef) {
     if (cflag(cdef, cflag_struct) || class_def_has_body(env, cdef->body))
       set_tflag(t, tflag_ctor);
   }
+  if(t->info->parent->nspc && nspc_lookup_value0(t->info->parent->nspc, insert_symbol("new")) && !nspc_lookup_value0(t->nspc, insert_symbol("new"))) {
+    env_err(env, cdef->pos, "must define 'new' operator");
+    env_warn(env, t->info->parent->info->value->from->loc, "defined here");
+    return GW_ERROR;
+  }
   if (!GET_FLAG(cdef, abstract)) CHECK_BB(check_abstract(env, cdef));
   if (cdef->traits) {
     ID_List list        = cdef->traits;
index f706fe69c5960de427aef474cdc68a2d8247d7bc..993aca8a931889004eaab4e3a8dd06b0b68f4de3 100644 (file)
@@ -568,6 +568,7 @@ ANN m_bool _scan2_func_def(const Env env, const Func_Def fdef) {
   if(!strcmp(s_name(fdef->base->xid), "new")) {
     if(!env->class_def)
       ERR_B(fdef->base->pos, _("{G+}new{0} operator must be set inside {C+}class{0}"));
+    SET_FLAG(env->class_def, abstract);
     if(!fdef->base->ret_type)
 //      fdef->base->ret_type = env->class_def;
       fdef->base->ret_type = env->gwion->type[et_auto];
diff --git a/tests/ctor/missing.gw b/tests/ctor/missing.gw
new file mode 100644 (file)
index 0000000..ff73ef5
--- /dev/null
@@ -0,0 +1,6 @@
+#! [contains] must define 'new' operator
+class C {
+  operator new() {}
+}
+class D extends C {}
+<<< "lol" >>>;
diff --git a/tests/tree/inherit.gw b/tests/tree/inherit.gw
new file mode 100644 (file)
index 0000000..bdd80d6
--- /dev/null
@@ -0,0 +1,14 @@
+class baseClass {}
+
+class childClass extends baseClass {
+    "test" => var string param;
+}
+
+class testClass {
+    var static baseClass classHolder;
+}
+
+var testClass tc;
+
+var childClass cc => tc.classHolder;
+<<< cc.param >>>;