From d0c022f7347b5cda34751a986a535aee3b1f45dc Mon Sep 17 00:00:00 2001 From: mlugg Date: Tue, 5 Mar 2024 06:02:58 +0000 Subject: compiler: namespace type equivalence based on AST node + captures This implements the accepted proposal #18816. Namespace-owning types (struct, enum, union, opaque) are no longer unique whenever analysed; instead, their identity is determined based on their AST node and the set of values they capture. Reified types (`@Type`) are deduplicated based on the structure of the type created. For instance, if two structs are created by the same reification with identical fields, layout, etc, they will be the same type. This commit does not produce a working compiler; the next commit, adding captures for decl references, is necessary. It felt appropriate to split this up. Resolves: #18816 --- src/type.zig | 44 ++++++++++++++++++-------------------------- 1 file changed, 18 insertions(+), 26 deletions(-) (limited to 'src/type.zig') diff --git a/src/type.zig b/src/type.zig index d19ad6f02e..8b2c6f2a1e 100644 --- a/src/type.zig +++ b/src/type.zig @@ -355,16 +355,16 @@ pub const Type = struct { try writer.writeAll("}"); }, - .union_type => |union_type| { - const decl = mod.declPtr(union_type.decl); + .union_type => { + const decl = mod.declPtr(ip.loadUnionType(ty.toIntern()).decl); try decl.renderFullyQualifiedName(mod, writer); }, - .opaque_type => |opaque_type| { - const decl = mod.declPtr(opaque_type.decl); + .opaque_type => { + const decl = mod.declPtr(ip.loadOpaqueType(ty.toIntern()).decl); try decl.renderFullyQualifiedName(mod, writer); }, - .enum_type => |enum_type| { - const decl = mod.declPtr(enum_type.decl); + .enum_type => { + const decl = mod.declPtr(ip.loadEnumType(ty.toIntern()).decl); try decl.renderFullyQualifiedName(mod, writer); }, .func_type => |fn_info| { @@ -2845,9 +2845,9 @@ pub const Type = struct { pub fn getNamespaceIndex(ty: Type, mod: *Module) InternPool.OptionalNamespaceIndex { const ip = &mod.intern_pool; return switch (ip.indexToKey(ty.toIntern())) { - .opaque_type => ip.loadOpaqueType(ty.toIntern()).namespace.toOptional(), + .opaque_type => ip.loadOpaqueType(ty.toIntern()).namespace, .struct_type => ip.loadStructType(ty.toIntern()).namespace, - .union_type => ip.loadUnionType(ty.toIntern()).namespace.toOptional(), + .union_type => ip.loadUnionType(ty.toIntern()).namespace, .enum_type => ip.loadEnumType(ty.toIntern()).namespace, else => .none, @@ -3180,17 +3180,8 @@ pub const Type = struct { } pub fn declSrcLocOrNull(ty: Type, mod: *Module) ?Module.SrcLoc { - return switch (mod.intern_pool.indexToKey(ty.toIntern())) { - .struct_type => |struct_type| { - return mod.declPtr(struct_type.decl.unwrap() orelse return null).srcLoc(mod); - }, - .union_type => |union_type| { - return mod.declPtr(union_type.decl).srcLoc(mod); - }, - .opaque_type => |opaque_type| mod.opaqueSrcLoc(opaque_type), - .enum_type => |enum_type| mod.declPtr(enum_type.decl).srcLoc(mod), - else => null, - }; + const decl = ty.getOwnerDeclOrNull(mod) orelse return null; + return mod.declPtr(decl).srcLoc(mod); } pub fn getOwnerDecl(ty: Type, mod: *Module) InternPool.DeclIndex { @@ -3198,11 +3189,12 @@ pub const Type = struct { } pub fn getOwnerDeclOrNull(ty: Type, mod: *Module) ?InternPool.DeclIndex { - return switch (mod.intern_pool.indexToKey(ty.toIntern())) { - .struct_type => |struct_type| struct_type.decl.unwrap(), - .union_type => |union_type| union_type.decl, - .opaque_type => |opaque_type| opaque_type.decl, - .enum_type => |enum_type| enum_type.decl, + const ip = &mod.intern_pool; + return switch (ip.indexToKey(ty.toIntern())) { + .struct_type => ip.loadStructType(ty.toIntern()).decl.unwrap(), + .union_type => ip.loadUnionType(ty.toIntern()).decl, + .opaque_type => ip.loadOpaqueType(ty.toIntern()).decl, + .enum_type => ip.loadEnumType(ty.toIntern()).decl, else => null, }; } @@ -3287,9 +3279,9 @@ pub const Type = struct { const ip = &zcu.intern_pool; return switch (ip.indexToKey(ty.toIntern())) { .struct_type => ip.loadStructType(ty.toIntern()).zir_index.unwrap(), - .union_type => ip.loadUnionType(ty.toIntern()).zir_index.unwrap(), + .union_type => ip.loadUnionType(ty.toIntern()).zir_index, .enum_type => ip.loadEnumType(ty.toIntern()).zir_index.unwrap(), - .opaque_type => ip.loadOpaqueType(ty.toIntern()).zir_index.unwrap(), + .opaque_type => ip.loadOpaqueType(ty.toIntern()).zir_index, else => null, }; } -- cgit v1.2.3