Commit e9eee8dace

Will Lillis <will.lillis24@gmail.com>
2025-08-11 02:14:51
fix: print error set members in a consistent order
Co-authored-by: Matthew Lugg <mlugg@mlugg.co.uk>
1 parent e395c24
Changed files (4)
src/Type.zig
@@ -254,9 +254,23 @@ pub fn print(ty: Type, writer: *std.io.Writer, pt: Zcu.PerThread) std.io.Writer.
             });
         },
         .error_set_type => |error_set_type| {
-            const names = error_set_type.names;
+            const NullTerminatedString = InternPool.NullTerminatedString;
+            const sorted_names = zcu.gpa.dupe(NullTerminatedString, error_set_type.names.get(ip)) catch {
+                zcu.comp.setAllocFailure();
+                return writer.writeAll("error{...}");
+            };
+            defer zcu.gpa.free(sorted_names);
+
+            std.mem.sortUnstable(NullTerminatedString, sorted_names, ip, struct {
+                fn lessThan(ip_: *InternPool, lhs: NullTerminatedString, rhs: NullTerminatedString) bool {
+                    const lhs_slice = lhs.toSlice(ip_);
+                    const rhs_slice = rhs.toSlice(ip_);
+                    return std.mem.lessThan(u8, lhs_slice, rhs_slice);
+                }
+            }.lessThan);
+
             try writer.writeAll("error{");
-            for (names.get(ip), 0..) |name, i| {
+            for (sorted_names, 0..) |name, i| {
                 if (i != 0) try writer.writeByte(',');
                 try writer.print("{f}", .{name.fmt(ip)});
             }
test/cases/compile_errors/error_set_display.zig
@@ -0,0 +1,11 @@
+const Set0 = error{ A, B, C, D, E, F };
+const Set1 = error{ F, E, D, C, A };
+comptime {
+    const x = Set0.B;
+    const y: Set1 = @errorCast(x);
+    _ = y;
+}
+
+// error
+//
+// :5:21: error: 'error.B' not a member of error set 'error{A,C,D,E,F}'
test/cases/compile_errors/invalid_pointer_coercions.zig
@@ -54,8 +54,8 @@ export fn ptr_to_underaligned_ptr() void {
 
 // error
 //
-// :16:33: error: expected type '*error{Foo,Bar}', found '*error{Foo}'
-// :16:33: note: pointer type child 'error{Foo}' cannot cast into pointer type child 'error{Foo,Bar}'
+// :16:33: error: expected type '*error{Bar,Foo}', found '*error{Foo}'
+// :16:33: note: pointer type child 'error{Foo}' cannot cast into pointer type child 'error{Bar,Foo}'
 // :16:33: note: 'error.Bar' not a member of destination error set
 // :22:24: error: expected type '*anyerror', found '*error{Foo}'
 // :22:24: note: pointer type child 'error{Foo}' cannot cast into pointer type child 'anyerror'
test/src/Debugger.zig
@@ -491,16 +491,16 @@ pub fn addTestsForTarget(db: *Debugger, target: *const Target) void {
             \\    (error{One,Two}) Two = error.Two
             \\  }
             \\  (type) Three = error {
-            \\    (error{One,Two,Three}) One = error.One
-            \\    (error{One,Two,Three}) Two = error.Two
-            \\    (error{One,Two,Three}) Three = error.Three
+            \\    (error{One,Three,Two}) One = error.One
+            \\    (error{One,Three,Two}) Two = error.Two
+            \\    (error{One,Three,Two}) Three = error.Three
             \\  }
             \\}
             \\(lldb) frame variable --show-types -- errors
             \\(root.errors.Errors) errors = {
             \\  (error{One}) .one = error.One
             \\  (error{One,Two}) .two = error.Two
-            \\  (error{One,Two,Three}) .three = error.Three
+            \\  (error{One,Three,Two}) .three = error.Three
             \\  (anyerror) .any = error.Any
             \\  (anyerror!void) .any_void = {
             \\    (anyerror) .error = error.NotVoid