authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-05 13:05:03-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-05 13:05:03-07:00
log9b0868776646934bdec84888dabebbb2b8d9924e
tree3639f84c9895f4a16687296ced79ebde232bd9b5
parentb7da1b2d45bc42a56eea3a143e4237a0712c4769

stage1: recursively resolve lazy values before hashing

When putting ZigValues into a hash map. The hash of a lazy value and a fully resolved value must equal, and so we must resolve the lazy values prior. The hash function asserts that none of the values are lazy.

1 files changed, 98 insertions(+), 0 deletions(-)

src/stage1/ir.cpp+98
......@@ -272,6 +272,10 @@ static bool value_cmp_numeric_val_all(ZigValue *left, Cmp predicate, ZigValue *r
272272static void memoize_field_init_val(CodeGen *codegen, ZigType *container_type, TypeStructField *field);
273273static void value_to_bigfloat(BigFloat *out, ZigValue *val);
274274
275static Error ir_resolve_lazy_recurse(AstNode *source_node, ZigValue *val);
276static Error ir_resolve_lazy_recurse_array(AstNode *source_node, ZigValue *val, size_t len);
277
278
275279static void ir_assert_impl(bool ok, IrInstGen *source_instruction, char const *file, unsigned int line) {
276280 if (ok) return;
277281 src_assert_impl(ok, source_instruction->source_node, file, line);
......@@ -12935,6 +12939,18 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, Scope *scope, AstNode *sour
1293512939 break;
1293612940 }
1293712941
12942 // We are about to put ZigValues into a hash map. The hash of a lazy value and a
12943 // fully resolved value must equal, and so we must resolve the lazy values here.
12944 // The hash function asserts that none of the values are lazy.
12945 for (size_t i = 0; i < generic_id->param_count; i += 1) {
12946 ZigValue *generic_param = &generic_id->params[i];
12947 if (generic_param->special != ConstValSpecialRuntime) {
12948 if ((err = ir_resolve_lazy_recurse(source_node, generic_param))) {
12949 return ira->codegen->invalid_inst_gen;
12950 }
12951 }
12952 }
12953
1293812954 auto existing_entry = ira->codegen->generic_table.put_unique(generic_id, impl_fn);
1293912955 if (existing_entry) {
1294012956 // throw away all our work and use the existing function
......@@ -25515,6 +25531,88 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
2551525531 zig_unreachable();
2551625532}
2551725533
25534static Error ir_resolve_lazy_recurse_array(AstNode *source_node, ZigValue *val, size_t len) {
25535 Error err;
25536 switch (val->data.x_array.special) {
25537 case ConstArraySpecialUndef:
25538 case ConstArraySpecialBuf:
25539 return ErrorNone;
25540 case ConstArraySpecialNone:
25541 break;
25542 }
25543 ZigValue *elems = val->data.x_array.data.s_none.elements;
25544
25545 for (size_t i = 0; i < len; i += 1) {
25546 if ((err = ir_resolve_lazy_recurse(source_node, &elems[i])))
25547 return err;
25548 }
25549
25550 return ErrorNone;
25551}
25552
25553static Error ir_resolve_lazy_recurse(AstNode *source_node, ZigValue *val) {
25554 Error err;
25555 if ((err = ir_resolve_lazy_raw(source_node, val)))
25556 return err;
25557 if (val->special != ConstValSpecialStatic)
25558 return ErrorNone;
25559 switch (val->type->id) {
25560 case ZigTypeIdOpaque:
25561 case ZigTypeIdEnum:
25562 case ZigTypeIdMetaType:
25563 case ZigTypeIdBool:
25564 case ZigTypeIdVoid:
25565 case ZigTypeIdComptimeFloat:
25566 case ZigTypeIdInt:
25567 case ZigTypeIdComptimeInt:
25568 case ZigTypeIdEnumLiteral:
25569 case ZigTypeIdErrorSet:
25570 case ZigTypeIdUndefined:
25571 case ZigTypeIdNull:
25572 case ZigTypeIdPointer:
25573 case ZigTypeIdFn:
25574 case ZigTypeIdAnyFrame:
25575 case ZigTypeIdBoundFn:
25576 case ZigTypeIdInvalid:
25577 case ZigTypeIdUnreachable:
25578 case ZigTypeIdFloat:
25579 return ErrorNone;
25580 case ZigTypeIdFnFrame:
25581 zig_panic("TODO: ir_resolve_lazy_recurse ZigTypeIdFnFrame");
25582 case ZigTypeIdUnion: {
25583 ConstUnionValue *union_val = &val->data.x_union;
25584 return ir_resolve_lazy_recurse(source_node, union_val->payload);
25585 }
25586 case ZigTypeIdVector:
25587 return ir_resolve_lazy_recurse_array(source_node, val, val->type->data.vector.len);
25588 case ZigTypeIdArray:
25589 return ir_resolve_lazy_recurse_array(source_node, val, val->type->data.array.len);
25590 case ZigTypeIdStruct:
25591 for (size_t i = 0; i < val->type->data.structure.src_field_count; i += 1) {
25592 ZigValue *field = val->data.x_struct.fields[i];
25593 if ((err = ir_resolve_lazy_recurse(source_node, field)))
25594 return err;
25595 }
25596 return ErrorNone;
25597 case ZigTypeIdOptional:
25598 if (get_src_ptr_type(val->type) != nullptr)
25599 return ErrorNone;
25600 if (val->data.x_optional == nullptr)
25601 return ErrorNone;
25602
25603 return ir_resolve_lazy_recurse(source_node, val->data.x_optional);
25604 case ZigTypeIdErrorUnion: {
25605 bool is_err = val->data.x_err_union.error_set->data.x_err_set != nullptr;
25606 if (is_err) {
25607 return ir_resolve_lazy_recurse(source_node, val->data.x_err_union.error_set);
25608 } else {
25609 return ir_resolve_lazy_recurse(source_node, val->data.x_err_union.payload);
25610 }
25611 }
25612 }
25613 zig_unreachable();
25614}
25615
2551825616Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ZigValue *val) {
2551925617 Error err;
2552025618 if ((err = ir_resolve_lazy_raw(source_node, val))) {