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(...@@ -17841,11 +17841,18 @@ fn zirThis(
17841 const zcu = pt.zcu;17841 const zcu = pt.zcu;
17842 const namespace = pt.zcu.namespacePtr(block.namespace);17842 const namespace = pt.zcu.namespacePtr(block.namespace);
1784317843
17844 const new_ty = try pt.ensureTypeUpToDate(namespace.owner_type);17844 switch (pt.zcu.intern_pool.indexToKey(namespace.owner_type)) {
1784517845 .opaque_type => {
17846 switch (pt.zcu.intern_pool.indexToKey(new_ty)) {17846 // Opaque types are never outdated since they don't undergo type resolution, so nothing to do!
17847 .struct_type, .union_type => try sema.declareDependency(.{ .interned = new_ty }),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 },
17848 .enum_type => {17854 .enum_type => {
17855 const new_ty = try pt.ensureTypeUpToDate(namespace.owner_type);
17849 try sema.declareDependency(.{ .interned = new_ty });17856 try sema.declareDependency(.{ .interned = new_ty });
17850 // Since this is an enum, it has to be resolved immediately.17857 // Since this is an enum, it has to be resolved immediately.
17851 // `ensureTypeUpToDate` has resolved the new type if necessary.17858 // `ensureTypeUpToDate` has resolved the new type if necessary.
...@@ -17854,11 +17861,10 @@ fn zirThis(...@@ -17854,11 +17861,10 @@ fn zirThis(
17854 if (zcu.failed_analysis.contains(ty_unit) or zcu.transitive_failed_analysis.contains(ty_unit)) {17861 if (zcu.failed_analysis.contains(ty_unit) or zcu.transitive_failed_analysis.contains(ty_unit)) {
17855 return error.AnalysisFail;17862 return error.AnalysisFail;
17856 }17863 }
17864 return Air.internedToRef(new_ty);
17857 },17865 },
17858 .opaque_type => {},
17859 else => unreachable,17866 else => unreachable,
17860 }17867 }
17861 return Air.internedToRef(new_ty);
17862}17868}
1786317869
17864fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {17870fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
test/behavior/this.zig+9-1
...@@ -1,4 +1,5 @@...@@ -1,4 +1,5 @@
1const expect = @import("std").testing.expect;1const std = @import("std");
2const expect = std.testing.expect;
2const builtin = @import("builtin");3const builtin = @import("builtin");
34
4const module = @This();5const module = @This();
...@@ -55,3 +56,10 @@ test "this used as optional function parameter" {...@@ -55,3 +56,10 @@ test "this used as optional function parameter" {
55 global.enter = prev;56 global.enter = prev;
56 global.enter(null);57 global.enter(null);
57}58}
59
60test "@This() in opaque" {
61 const T = opaque {
62 const Self = @This();
63 };
64 comptime std.debug.assert(T.Self == T);
65}