From 0958d5d7db24222bdcc0fb8e8cdc9838953b9857 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Thu, 11 May 2023 12:23:39 +0300 Subject: [PATCH] Sema: fix crash when generating anon name on invalid code Closes #15615 --- src/Sema.zig | 11 +++++++---- src/print_air.zig | 1 - ...struct_type_returned_from_non-generic_function.zig | 10 ++++++++++ 3 files changed, 17 insertions(+), 5 deletions(-) create mode 100644 test/cases/compile_errors/struct_type_returned_from_non-generic_function.zig diff --git a/src/Sema.zig b/src/Sema.zig index 2521bddce0..a3502726bb 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -2730,9 +2730,13 @@ fn createAnonymousDeclTypeNamed( for (fn_info.param_body) |zir_inst| switch (zir_tags[zir_inst]) { .param, .param_comptime, .param_anytype, .param_anytype_comptime => { const arg = sema.inst_map.get(zir_inst).?; - // The comptime call code in analyzeCall already did this, so we're - // just repeating it here and it's guaranteed to work. - const arg_val = sema.resolveConstMaybeUndefVal(block, .unneeded, arg, "") catch unreachable; + // If this is being called in a generic function then analyzeCall will + // have already resolved the args and this will work. + // If not then this is a struct type being returned from a non-generic + // function and the name doesn't matter since it will later + // result in a compile error. + const arg_val = sema.resolveConstMaybeUndefVal(block, .unneeded, arg, "") catch + return sema.createAnonymousDeclTypeNamed(block, src, typed_value, .anon, anon_prefix, null); if (arg_i != 0) try buf.appendSlice(","); try buf.writer().print("{}", .{arg_val.fmtValue(sema.typeOf(arg), sema.mod)}); @@ -6562,7 +6566,6 @@ fn analyzeCall( ) CompileError!Air.Inst.Ref { const mod = sema.mod; - const callee_ty = sema.typeOf(func); const func_ty_info = func_ty.fnInfo(); const fn_params_len = func_ty_info.param_types.len; diff --git a/src/print_air.zig b/src/print_air.zig index d90d31ec67..6ed2e48bbc 100644 --- a/src/print_air.zig +++ b/src/print_air.zig @@ -917,7 +917,6 @@ const Writer = struct { try s.writeAll("\n"); try s.writeByteNTimes(' ', old_indent); - try s.writeAll("}"); } fn writeWasmMemorySize(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { diff --git a/test/cases/compile_errors/struct_type_returned_from_non-generic_function.zig b/test/cases/compile_errors/struct_type_returned_from_non-generic_function.zig new file mode 100644 index 0000000000..27e2b7b1db --- /dev/null +++ b/test/cases/compile_errors/struct_type_returned_from_non-generic_function.zig @@ -0,0 +1,10 @@ +pub export fn entry(param: usize) usize { + return struct{ param }; +} + +// error +// backend=stage2 +// target=native +// +// :2:12: error: expected type 'usize', found 'type' +// :1:35: note: function return type declared here