aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-10-01 14:01:51 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-10-01 14:01:51 -0400
commit7494c89a4e1baa08a2720817b06676b34eebb284 (patch)
tree5b042252242d218cbbdb9a6448b9d04d3f41c27f /src
parent235dbc07a9dd15967cebe136342249372b0285e0 (diff)
Fixes for indexing into lists with optional item types
Diffstat (limited to 'src')
-rw-r--r--src/compile/indexing.c16
-rw-r--r--src/typecheck.c6
2 files changed, 18 insertions, 4 deletions
diff --git a/src/compile/indexing.c b/src/compile/indexing.c
index af5056d7..13062641 100644
--- a/src/compile/indexing.c
+++ b/src/compile/indexing.c
@@ -43,8 +43,20 @@ Text_t compile_indexing(env_t *env, ast_t *ast, bool checked) {
: Texts("(Int64_t)(", compile(env, indexing->index), ")"));
if (checked) {
int64_t start = (int64_t)(ast->start - ast->file->text), end = (int64_t)(ast->end - ast->file->text);
- return Texts("List_get_checked(", list, ", ", index_code, ", ", compile_type(item_type), ", ", start, ", ",
- end, ")");
+ Text_t code = Texts("List_get_checked(", list, ", ", index_code, ", ", compile_type(item_type), ", ", start,
+ ", ", end, ")");
+ if (item_type->tag == OptionalType) {
+ int64_t line = get_line_number(ast->file, ast->start);
+ return Texts("({ ", compile_declaration(item_type, Text("opt")), " = ", code, "; ", "if unlikely (",
+ check_none(item_type, Text("opt")), ")\n", "#line ", line, "\n", "fail_source(",
+ quoted_str(ast->file->filename), ", ", start, ", ", end, ", ",
+ "\"This was expected to be a value, but it's `none`\\n\");\n",
+ optional_into_nonnone(item_type, Text("opt")), "; })");
+ }
+ return code;
+ } else if (item_type->tag == OptionalType) {
+ return Texts("List_get(", list, ", ", index_code, ", ", compile_type(item_type), ", value, value,",
+ compile_none(item_type), ")");
} else {
return Texts("List_get(", list, ", ", index_code, ", ", compile_type(item_type), ", value, ",
promote_to_optional(item_type, Text("value")), ", ", compile_none(item_type), ")");
diff --git a/src/typecheck.c b/src/typecheck.c
index 3c820fa9..eff894be 100644
--- a/src/typecheck.c
+++ b/src/typecheck.c
@@ -934,8 +934,10 @@ type_t *get_type(env_t *env, ast_t *ast) {
if (value_t->tag == ListType) {
if (!indexing->index) return indexed_t;
type_t *index_t = get_type(env, indexing->index);
- if (index_t->tag == IntType || index_t->tag == BigIntType || index_t->tag == ByteType)
- return Type(OptionalType, Match(value_t, ListType)->item_type);
+ if (index_t->tag == IntType || index_t->tag == BigIntType || index_t->tag == ByteType) {
+ type_t *item_type = Match(value_t, ListType)->item_type;
+ return item_type->tag == OptionalType ? item_type : Type(OptionalType, item_type);
+ }
code_err(indexing->index, "I only know how to index lists using integers, not ", type_to_text(index_t));
} else if (value_t->tag == TableType) {
DeclareMatch(table_type, value_t, TableType);