Commit 423907c270

mlugg <mlugg@mlugg.co.uk>
2025-03-10 23:18:56
Sema: fix handling of `@This()` on opaques
Resolves: #22869
1 parent 7e751e8
Changed files (2)
src
test
behavior
src/Sema.zig
@@ -17841,11 +17841,18 @@ fn zirThis(
     const zcu = pt.zcu;
     const namespace = pt.zcu.namespacePtr(block.namespace);
 
-    const new_ty = try pt.ensureTypeUpToDate(namespace.owner_type);
-
-    switch (pt.zcu.intern_pool.indexToKey(new_ty)) {
-        .struct_type, .union_type => try sema.declareDependency(.{ .interned = new_ty }),
+    switch (pt.zcu.intern_pool.indexToKey(namespace.owner_type)) {
+        .opaque_type => {
+            // Opaque types are never outdated since they don't undergo type resolution, so nothing to do!
+            return Air.internedToRef(namespace.owner_type);
+        },
+        .struct_type, .union_type => {
+            const new_ty = try pt.ensureTypeUpToDate(namespace.owner_type);
+            try sema.declareDependency(.{ .interned = new_ty });
+            return Air.internedToRef(new_ty);
+        },
         .enum_type => {
+            const new_ty = try pt.ensureTypeUpToDate(namespace.owner_type);
             try sema.declareDependency(.{ .interned = new_ty });
             // Since this is an enum, it has to be resolved immediately.
             // `ensureTypeUpToDate` has resolved the new type if necessary.
@@ -17854,11 +17861,10 @@ fn zirThis(
             if (zcu.failed_analysis.contains(ty_unit) or zcu.transitive_failed_analysis.contains(ty_unit)) {
                 return error.AnalysisFail;
             }
+            return Air.internedToRef(new_ty);
         },
-        .opaque_type => {},
         else => unreachable,
     }
-    return Air.internedToRef(new_ty);
 }
 
 fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
test/behavior/this.zig
@@ -1,4 +1,5 @@
-const expect = @import("std").testing.expect;
+const std = @import("std");
+const expect = std.testing.expect;
 const builtin = @import("builtin");
 
 const module = @This();
@@ -55,3 +56,10 @@ test "this used as optional function parameter" {
     global.enter = prev;
     global.enter(null);
 }
+
+test "@This() in opaque" {
+    const T = opaque {
+        const Self = @This();
+    };
+    comptime std.debug.assert(T.Self == T);
+}