authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-03-10 22:18:56+00:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-03-11 11:21:03-07:00
log623d5cc7f6b7ef84e8a465b5818e7c1e6060e8b5
treecc29ecf9e5de1c1d40e6151d9e6e75e013a72d6e
parentba97b1a2a22a52fba4289b1851937ad9772f36f4

Sema: fix handling of `@This()` on opaques

Resolves: #22869

2 files changed, 21 insertions(+), 7 deletions(-)

src/Sema.zig+12-6
......@@ -17841,11 +17841,18 @@ fn zirThis(
1784117841 const zcu = pt.zcu;
1784217842 const namespace = pt.zcu.namespacePtr(block.namespace);
1784317843
17844 const new_ty = try pt.ensureTypeUpToDate(namespace.owner_type);
17845
17846 switch (pt.zcu.intern_pool.indexToKey(new_ty)) {
17847 .struct_type, .union_type => try sema.declareDependency(.{ .interned = new_ty }),
17844 switch (pt.zcu.intern_pool.indexToKey(namespace.owner_type)) {
17845 .opaque_type => {
17846 // Opaque types are never outdated since they don't undergo type resolution, so nothing to do!
17847 return Air.internedToRef(namespace.owner_type);
17848 },
17849 .struct_type, .union_type => {
17850 const new_ty = try pt.ensureTypeUpToDate(namespace.owner_type);
17851 try sema.declareDependency(.{ .interned = new_ty });
17852 return Air.internedToRef(new_ty);
17853 },
1784817854 .enum_type => {
17855 const new_ty = try pt.ensureTypeUpToDate(namespace.owner_type);
1784917856 try sema.declareDependency(.{ .interned = new_ty });
1785017857 // Since this is an enum, it has to be resolved immediately.
1785117858 // `ensureTypeUpToDate` has resolved the new type if necessary.
......@@ -17854,11 +17861,10 @@ fn zirThis(
1785417861 if (zcu.failed_analysis.contains(ty_unit) or zcu.transitive_failed_analysis.contains(ty_unit)) {
1785517862 return error.AnalysisFail;
1785617863 }
17864 return Air.internedToRef(new_ty);
1785717865 },
17858 .opaque_type => {},
1785917866 else => unreachable,
1786017867 }
17861 return Air.internedToRef(new_ty);
1786217868}
1786317869
1786417870fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
test/behavior/this.zig+9-1
......@@ -1,4 +1,5 @@
1const expect = @import("std").testing.expect;
1const std = @import("std");
2const expect = std.testing.expect;
23const builtin = @import("builtin");
34
45const module = @This();
......@@ -55,3 +56,10 @@ test "this used as optional function parameter" {
5556 global.enter = prev;
5657 global.enter(null);
5758}
59
60test "@This() in opaque" {
61 const T = opaque {
62 const Self = @This();
63 };
64 comptime std.debug.assert(T.Self == T);
65}