aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/actualize.c28
-rw-r--r--src/compiler.c1
-rw-r--r--src/parser.y6
3 files changed, 32 insertions, 3 deletions
diff --git a/src/actualize.c b/src/actualize.c
index 11c8db7..991beed 100644
--- a/src/actualize.c
+++ b/src/actualize.c
@@ -2131,6 +2131,22 @@ static int params_match(struct scope *scope, struct ast *base, struct ast *node)
return 1;
}
+/* slightly hacky but works well enough for now */
+static int trait_exported(struct scope *scope, struct ast *def)
+{
+ assert(file_scope_find_type(scope, def->s) == def);
+
+ while (!scope_flags(scope, SCOPE_FILE) && scope->parent)
+ scope = scope->parent;
+
+ assert(scope && scope_flags(scope, SCOPE_FILE));
+ struct scope *parent = scope->parent;
+ if (!parent)
+ return true;
+
+ return file_scope_find_type(parent, def->s) == def;
+}
+
static int expand_struct_body(struct act_state *state,
struct scope *scope,
struct ast *node,
@@ -2178,6 +2194,17 @@ static int expand_struct_body(struct act_state *state,
if (actualize_type(&type_state, scope, type))
return -1;
+ if (ast_flags(node, AST_FLAG_PUBLIC)) {
+ struct ast *def = type->d;
+ /* traits should only show up during the initial
+ * expansion, but should maybe make sure somehow */
+ if (def->k == AST_TRAIT_DEF && !trait_exported(scope, def)) {
+ semantic_error(struct_scope->fctx, n,
+ "trait used in pub def must also be exported");
+ return -1;
+ }
+ }
+
type_append(&types, type);
struct ast *alias = gen_alias(strdup(id), type, n->loc);
@@ -2187,6 +2214,7 @@ static int expand_struct_body(struct act_state *state,
struct act_state state = {0};
if (actualize(&state, struct_scope, alias))
return -1;
+
}
if (node->k == AST_STRUCT_CONT_DEF
diff --git a/src/compiler.c b/src/compiler.c
index f7e6a14..2041efd 100644
--- a/src/compiler.c
+++ b/src/compiler.c
@@ -160,6 +160,7 @@ static struct scopes scopes;
static void destroy_scopes()
{
+ if (scopes_len(&scopes))
foreach(scopes, n, &scopes) {
free(n->key);
}
diff --git a/src/parser.y b/src/parser.y
index 18de0e1..45cac92 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -683,7 +683,7 @@ opt_types
| { $$ = NULL; }
type_expand
- : APPLY "[" opt_types "]" { $$ = gen_type_expand($1, $3, src_loc(@$)); }
+ : APPLY { $$ = gen_type_expand($1, NULL, src_loc(@$)); }
var_decl
: type ID { $$ = gen_var($2, $1, NULL, src_loc(@$)); }
@@ -810,8 +810,8 @@ opt_type_params
| { $$ = NULL; }
trait
- : "define" ID "[" opt_type_params "]" "{" opt_behaviours "}" {
- $$ = gen_trait($2, $4, $7, src_loc(@$));
+ : "define" ID "{" opt_behaviours "}" {
+ $$ = gen_trait($2, NULL, $4, src_loc(@$));
}
enum_val