aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Sema.zig22
-rw-r--r--src/type.zig1
-rw-r--r--test/behavior.zig6
-rw-r--r--test/behavior/enum.zig48
-rw-r--r--test/behavior/enum_llvm.zig24
-rw-r--r--test/behavior/enum_stage1.zig62
-rw-r--r--test/behavior/misc.zig38
7 files changed, 103 insertions, 98 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 8d27553f94..544681f5f9 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -4187,10 +4187,17 @@ fn analyzeCall(
return sema.failWithNeededComptime(block, arg_src);
}
} else if (is_anytype) {
- // We insert into the map an instruction which is runtime-known
- // but has the type of the argument.
- const child_arg = try child_block.addArg(sema.typeOf(arg), 0);
- child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg);
+ const arg_ty = sema.typeOf(arg);
+ if (arg_ty.requiresComptime()) {
+ const arg_val = try sema.resolveConstValue(block, arg_src, arg);
+ const child_arg = try child_sema.addConstant(arg_ty, arg_val);
+ child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg);
+ } else {
+ // We insert into the map an instruction which is runtime-known
+ // but has the type of the argument.
+ const child_arg = try child_block.addArg(arg_ty, 0);
+ child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg);
+ }
}
arg_i += 1;
}
@@ -5130,9 +5137,8 @@ fn funcCommon(
const comptime_params = try sema.arena.alloc(bool, block.params.items.len);
for (block.params.items) |param, i| {
param_types[i] = param.ty;
- comptime_params[i] = param.is_comptime;
- is_generic = is_generic or param.is_comptime or
- param.ty.tag() == .generic_poison or param.ty.requiresComptime();
+ comptime_params[i] = param.is_comptime or param.ty.requiresComptime();
+ is_generic = is_generic or comptime_params[i] or param.ty.tag() == .generic_poison;
}
if (align_val.tag() != .null_value) {
@@ -13146,7 +13152,7 @@ fn coerceInMemoryAllowedFns(
return .no_match;
}
- // TODO: nolias
+ // TODO: noalias
// Note: Cast direction is reversed here.
const param = try sema.coerceInMemoryAllowed(block, src_param_ty, dest_param_ty, false, target, dest_src, src_src);
diff --git a/src/type.zig b/src/type.zig
index 1482710e51..fb543e1f2c 100644
--- a/src/type.zig
+++ b/src/type.zig
@@ -4275,7 +4275,6 @@ pub const Type = extern union {
is_generic: bool,
pub fn paramIsComptime(self: @This(), i: usize) bool {
- if (!self.is_generic) return false;
assert(i < self.param_types.len);
return self.comptime_params[i];
}
diff --git a/test/behavior.zig b/test/behavior.zig
index 46b4cf083d..7bc52ff518 100644
--- a/test/behavior.zig
+++ b/test/behavior.zig
@@ -67,6 +67,7 @@ test {
_ = @import("behavior/bugs/394.zig");
_ = @import("behavior/bugs/656.zig");
_ = @import("behavior/bugs/1277.zig");
+ _ = @import("behavior/bugs/1310.zig");
_ = @import("behavior/bugs/1381.zig");
_ = @import("behavior/bugs/1500.zig");
_ = @import("behavior/bugs/1741.zig");
@@ -74,7 +75,9 @@ test {
_ = @import("behavior/bugs/2578.zig");
_ = @import("behavior/bugs/3007.zig");
_ = @import("behavior/bugs/3112.zig");
+ _ = @import("behavior/bugs/3367.zig");
_ = @import("behavior/bugs/7250.zig");
+ _ = @import("behavior/bugs/9584.zig");
_ = @import("behavior/cast_llvm.zig");
_ = @import("behavior/enum_llvm.zig");
_ = @import("behavior/eval.zig");
@@ -121,7 +124,6 @@ test {
_ = @import("behavior/bugs/1025.zig");
_ = @import("behavior/bugs/1076.zig");
_ = @import("behavior/bugs/1120.zig");
- _ = @import("behavior/bugs/1310.zig");
_ = @import("behavior/bugs/1322.zig");
_ = @import("behavior/bugs/1421.zig");
_ = @import("behavior/bugs/1442.zig");
@@ -130,7 +132,6 @@ test {
_ = @import("behavior/bugs/1851.zig");
_ = @import("behavior/bugs/1914.zig");
_ = @import("behavior/bugs/2114.zig");
- _ = @import("behavior/bugs/3367.zig");
_ = @import("behavior/bugs/3384.zig");
_ = @import("behavior/bugs/3742.zig");
_ = @import("behavior/bugs/3779.zig");
@@ -144,7 +145,6 @@ test {
_ = @import("behavior/bugs/7003.zig");
_ = @import("behavior/bugs/7027.zig");
_ = @import("behavior/bugs/7047.zig");
- _ = @import("behavior/bugs/9584.zig");
_ = @import("behavior/bugs/10147.zig");
_ = @import("behavior/byteswap.zig");
_ = @import("behavior/call_stage1.zig");
diff --git a/test/behavior/enum.zig b/test/behavior/enum.zig
index 6de1763deb..d044619edf 100644
--- a/test/behavior/enum.zig
+++ b/test/behavior/enum.zig
@@ -822,3 +822,51 @@ test "enum with one member default to u0 tag type" {
const E0 = enum { X };
comptime try expect(Tag(E0) == u0);
}
+
+const EnumWithOneMember = enum { Eof };
+
+fn doALoopThing(id: EnumWithOneMember) void {
+ while (true) {
+ if (id == EnumWithOneMember.Eof) {
+ break;
+ }
+ @compileError("above if condition should be comptime");
+ }
+}
+
+test "comparison operator on enum with one member is comptime known" {
+ doALoopThing(EnumWithOneMember.Eof);
+}
+
+const State = enum { Start };
+test "switch on enum with one member is comptime known" {
+ var state = State.Start;
+ switch (state) {
+ State.Start => return,
+ }
+ @compileError("analysis should not reach here");
+}
+
+test "method call on an enum" {
+ const S = struct {
+ const E = enum {
+ one,
+ two,
+
+ fn method(self: *E) bool {
+ return self.* == .two;
+ }
+
+ fn generic_method(self: *E, foo: anytype) bool {
+ return self.* == .two and foo == bool;
+ }
+ };
+ fn doTheTest() !void {
+ var e = E.two;
+ try expect(e.method());
+ try expect(e.generic_method(bool));
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
diff --git a/test/behavior/enum_llvm.zig b/test/behavior/enum_llvm.zig
index 6d57aac2c1..81a1c72e59 100644
--- a/test/behavior/enum_llvm.zig
+++ b/test/behavior/enum_llvm.zig
@@ -96,30 +96,6 @@ fn getC(data: *const BitFieldOfEnums) C {
return data.c;
}
-const EnumWithOneMember = enum { Eof };
-
-fn doALoopThing(id: EnumWithOneMember) void {
- while (true) {
- if (id == EnumWithOneMember.Eof) {
- break;
- }
- @compileError("above if condition should be comptime");
- }
-}
-
-test "comparison operator on enum with one member is comptime known" {
- doALoopThing(EnumWithOneMember.Eof);
-}
-
-const State = enum { Start };
-test "switch on enum with one member is comptime known" {
- var state = State.Start;
- switch (state) {
- State.Start => return,
- }
- @compileError("analysis should not reach here");
-}
-
test "enum literal in array literal" {
const Items = enum { one, two };
const array = [_]Items{ .one, .two };
diff --git a/test/behavior/enum_stage1.zig b/test/behavior/enum_stage1.zig
index 0f9c1dc6f5..c9658918f8 100644
--- a/test/behavior/enum_stage1.zig
+++ b/test/behavior/enum_stage1.zig
@@ -43,30 +43,6 @@ test "enum literal casting to error union with payload enum" {
try expect((try bar) == Bar.B);
}
-test "method call on an enum" {
- const S = struct {
- const E = enum {
- one,
- two,
-
- fn method(self: *E) bool {
- return self.* == .two;
- }
-
- fn generic_method(self: *E, foo: anytype) bool {
- return self.* == .two and foo == bool;
- }
- };
- fn doTheTest() !void {
- var e = E.two;
- try expect(e.method());
- try expect(e.generic_method(bool));
- }
- };
- try S.doTheTest();
- comptime try S.doTheTest();
-}
-
test "exporting enum type and value" {
const S = struct {
const E = enum(c_int) { one, two };
@@ -80,3 +56,41 @@ test "exporting enum type and value" {
};
try expect(S.e == .two);
}
+
+test "constant enum initialization with differing sizes" {
+ try test3_1(test3_foo);
+ try test3_2(test3_bar);
+}
+const Test3Foo = union(enum) {
+ One: void,
+ Two: f32,
+ Three: Test3Point,
+};
+const Test3Point = struct {
+ x: i32,
+ y: i32,
+};
+const test3_foo = Test3Foo{
+ .Three = Test3Point{
+ .x = 3,
+ .y = 4,
+ },
+};
+const test3_bar = Test3Foo{ .Two = 13 };
+fn test3_1(f: Test3Foo) !void {
+ switch (f) {
+ Test3Foo.Three => |pt| {
+ try expect(pt.x == 3);
+ try expect(pt.y == 4);
+ },
+ else => unreachable,
+ }
+}
+fn test3_2(f: Test3Foo) !void {
+ switch (f) {
+ Test3Foo.Two => |x| {
+ try expect(x == 13);
+ },
+ else => unreachable,
+ }
+}
diff --git a/test/behavior/misc.zig b/test/behavior/misc.zig
index 7a248ed320..df435ac60c 100644
--- a/test/behavior/misc.zig
+++ b/test/behavior/misc.zig
@@ -34,44 +34,6 @@ test "explicit cast optional pointers" {
_ = b;
}
-test "constant enum initialization with differing sizes" {
- try test3_1(test3_foo);
- try test3_2(test3_bar);
-}
-const Test3Foo = union(enum) {
- One: void,
- Two: f32,
- Three: Test3Point,
-};
-const Test3Point = struct {
- x: i32,
- y: i32,
-};
-const test3_foo = Test3Foo{
- .Three = Test3Point{
- .x = 3,
- .y = 4,
- },
-};
-const test3_bar = Test3Foo{ .Two = 13 };
-fn test3_1(f: Test3Foo) !void {
- switch (f) {
- Test3Foo.Three => |pt| {
- try expect(pt.x == 3);
- try expect(pt.y == 4);
- },
- else => unreachable,
- }
-}
-fn test3_2(f: Test3Foo) !void {
- switch (f) {
- Test3Foo.Two => |x| {
- try expect(x == 13);
- },
- else => unreachable,
- }
-}
-
test "pointer comparison" {
const a = @as([]const u8, "a");
const b = &a;