Sema: do not immediately destroy failed generic instantiation

Closes #12535
Closes #12765
Closes #12927
This commit is contained in:
Veikka Tuominen
2022-09-30 15:44:28 +03:00
parent daeb992c73
commit abd005f302
5 changed files with 332 additions and 222 deletions

View File

@@ -3540,8 +3540,8 @@ pub fn destroyDecl(mod: *Module, decl_index: Decl.Index) void {
if (decl.getInnerNamespace()) |namespace| {
namespace.destroyDecls(mod);
}
decl.clearValues(mod);
}
decl.clearValues(mod);
decl.dependants.deinit(gpa);
decl.dependencies.deinit(gpa);
decl.clearName(gpa);
@@ -4610,9 +4610,18 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
// We need the memory for the Type to go into the arena for the Decl
var decl_arena = std.heap.ArenaAllocator.init(gpa);
errdefer decl_arena.deinit();
const decl_arena_allocator = decl_arena.allocator();
const decl_arena_state = blk: {
errdefer decl_arena.deinit();
const s = try decl_arena_allocator.create(std.heap.ArenaAllocator.State);
break :blk s;
};
defer {
decl_arena_state.* = decl_arena.state;
decl.value_arena = decl_arena_state;
}
var analysis_arena = std.heap.ArenaAllocator.init(gpa);
defer analysis_arena.deinit();
const analysis_arena_allocator = analysis_arena.allocator();
@@ -4681,8 +4690,6 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
// not the struct itself.
try sema.resolveTypeLayout(decl_tv.ty);
const decl_arena_state = try decl_arena_allocator.create(std.heap.ArenaAllocator.State);
if (decl.is_usingnamespace) {
if (!decl_tv.ty.eql(Type.type, mod)) {
return sema.fail(&block_scope, ty_src, "expected type, found {}", .{
@@ -4701,8 +4708,6 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
decl.@"linksection" = null;
decl.has_tv = true;
decl.owns_tv = false;
decl_arena_state.* = decl_arena.state;
decl.value_arena = decl_arena_state;
decl.analysis = .complete;
decl.generation = mod.generation;
@@ -4723,16 +4728,14 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
if (decl.getFunction()) |prev_func| {
prev_is_inline = prev_func.state == .inline_only;
}
decl.clearValues(mod);
}
decl.clearValues(mod);
decl.ty = try decl_tv.ty.copy(decl_arena_allocator);
decl.val = try decl_tv.val.copy(decl_arena_allocator);
// linksection, align, and addrspace were already set by Sema
decl.has_tv = true;
decl.owns_tv = owns_tv;
decl_arena_state.* = decl_arena.state;
decl.value_arena = decl_arena_state;
decl.analysis = .complete;
decl.generation = mod.generation;
@@ -4767,8 +4770,8 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
var type_changed = true;
if (decl.has_tv) {
type_changed = !decl.ty.eql(decl_tv.ty, mod);
decl.clearValues(mod);
}
decl.clearValues(mod);
decl.owns_tv = false;
var queue_linker_work = false;
@@ -4841,8 +4844,6 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
};
};
decl.has_tv = true;
decl_arena_state.* = decl_arena.state;
decl.value_arena = decl_arena_state;
decl.analysis = .complete;
decl.generation = mod.generation;
@@ -5447,8 +5448,8 @@ pub fn clearDecl(
if (decl.getInnerNamespace()) |namespace| {
try namespace.deleteAllDecls(mod, outdated_decls);
}
decl.clearValues(mod);
}
decl.clearValues(mod);
if (decl.deletion_flag) {
decl.deletion_flag = false;