Commit 13c584d325

Andrew Kelley <andrew@ziglang.org>
2019-08-16 17:27:29
add compile error for casting const frame to anyframe
See #3063
1 parent cba3b82
src/ir.cpp
@@ -12112,6 +12112,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
 
     // *@Frame(func) to anyframe->T or anyframe
     if (actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.ptr_len == PtrLenSingle &&
+        !actual_type->data.pointer.is_const &&
         actual_type->data.pointer.child_type->id == ZigTypeIdFnFrame && wanted_type->id == ZigTypeIdAnyFrame)
     {
         bool ok = true;
std/event/channel.zig
@@ -331,7 +331,7 @@ async fn testChannelGetter(loop: *Loop, channel: *Channel(i32)) void {
     const value3 = channel.getOrNull();
     testing.expect(value3 == null);
 
-    const last_put = async testPut(channel, 4444);
+    var last_put = async testPut(channel, 4444);
     const value4 = channel.getOrNull();
     testing.expect(value4.? == 4444);
     await last_put;
std/event/future.zig
@@ -100,9 +100,9 @@ test "std.event.Future" {
 async fn testFuture(loop: *Loop) void {
     var future = Future(i32).init(loop);
 
-    const a = async waitOnFuture(&future);
-    const b = async waitOnFuture(&future);
-    const c = async resolveFuture(&future);
+    var a = async waitOnFuture(&future);
+    var b = async waitOnFuture(&future);
+    var c = async resolveFuture(&future);
 
     // TODO make this work:
     //const result = (await a) + (await b);
std/event/lock.zig
@@ -135,7 +135,7 @@ test "std.event.Lock" {
 }
 
 async fn testLock(loop: *Loop, lock: *Lock) void {
-    const handle1 = async lockRunner(lock);
+    var handle1 = async lockRunner(lock);
     var tick_node1 = Loop.NextTickNode{
         .prev = undefined,
         .next = undefined,
@@ -143,7 +143,7 @@ async fn testLock(loop: *Loop, lock: *Lock) void {
     };
     loop.onNextTick(&tick_node1);
 
-    const handle2 = async lockRunner(lock);
+    var handle2 = async lockRunner(lock);
     var tick_node2 = Loop.NextTickNode{
         .prev = undefined,
         .next = undefined,
@@ -151,7 +151,7 @@ async fn testLock(loop: *Loop, lock: *Lock) void {
     };
     loop.onNextTick(&tick_node2);
 
-    const handle3 = async lockRunner(lock);
+    var handle3 = async lockRunner(lock);
     var tick_node3 = Loop.NextTickNode{
         .prev = undefined,
         .next = undefined,
@@ -172,8 +172,8 @@ async fn lockRunner(lock: *Lock) void {
 
     var i: usize = 0;
     while (i < shared_test_data.len) : (i += 1) {
-        const lock_promise = async lock.acquire();
-        const handle = await lock_promise;
+        var lock_frame = async lock.acquire();
+        const handle = await lock_frame;
         defer handle.release();
 
         shared_test_index = 0;
std/event/loop.zig
@@ -900,8 +900,8 @@ test "std.event.Loop - call" {
     defer loop.deinit();
 
     var did_it = false;
-    const handle = async Loop.call(testEventLoop);
-    const handle2 = async Loop.call(testEventLoop2, &handle, &did_it);
+    var handle = async Loop.call(testEventLoop);
+    var handle2 = async Loop.call(testEventLoop2, &handle, &did_it);
 
     loop.run();
 
test/stage1/behavior/async_fn.zig
@@ -6,7 +6,7 @@ const expectEqual = std.testing.expectEqual;
 var global_x: i32 = 1;
 
 test "simple coroutine suspend and resume" {
-    const frame = async simpleAsyncFn();
+    var frame = async simpleAsyncFn();
     expect(global_x == 2);
     resume frame;
     expect(global_x == 3);
@@ -25,7 +25,7 @@ fn simpleAsyncFn() void {
 var global_y: i32 = 1;
 
 test "pass parameter to coroutine" {
-    const p = async simpleAsyncFnWithArg(2);
+    var p = async simpleAsyncFnWithArg(2);
     expect(global_y == 3);
     resume p;
     expect(global_y == 5);
@@ -60,7 +60,7 @@ test "local variable in async function" {
 
         fn doTheTest() void {
             expect(x == 0);
-            const p = async add(1, 2);
+            var p = async add(1, 2);
             expect(x == 0);
             resume p;
             expect(x == 0);
@@ -201,7 +201,7 @@ var await_final_result: i32 = 0;
 
 test "coroutine await" {
     await_seq('a');
-    const p = async await_amain();
+    var p = async await_amain();
     await_seq('f');
     resume await_a_promise;
     await_seq('i');
@@ -210,7 +210,7 @@ test "coroutine await" {
 }
 async fn await_amain() void {
     await_seq('b');
-    const p = async await_another();
+    var p = async await_another();
     await_seq('e');
     await_final_result = await p;
     await_seq('h');
@@ -237,14 +237,14 @@ var early_final_result: i32 = 0;
 
 test "coroutine await early return" {
     early_seq('a');
-    const p = async early_amain();
+    var p = async early_amain();
     early_seq('f');
     expect(early_final_result == 1234);
     expect(std.mem.eql(u8, early_points, "abcdef"));
 }
 async fn early_amain() void {
     early_seq('b');
-    const p = async early_another();
+    var p = async early_another();
     early_seq('d');
     early_final_result = await p;
     early_seq('e');
test/stage1/behavior/await_struct.zig
@@ -11,7 +11,7 @@ var await_final_result = Foo{ .x = 0 };
 
 test "coroutine await struct" {
     await_seq('a');
-    const p = async await_amain();
+    var p = async await_amain();
     await_seq('f');
     resume await_a_promise;
     await_seq('i');
@@ -20,7 +20,7 @@ test "coroutine await struct" {
 }
 async fn await_amain() void {
     await_seq('b');
-    const p = async await_another();
+    var p = async await_another();
     await_seq('e');
     await_final_result = await p;
     await_seq('h');
test/compile_errors.zig
@@ -2,6 +2,24 @@ const tests = @import("tests.zig");
 const builtin = @import("builtin");
 
 pub fn addCases(cases: *tests.CompileErrorContext) void {
+    cases.add(
+        "const frame cast to anyframe",
+        \\export fn a() void {
+        \\    const f = async func();
+        \\    resume f;
+        \\}
+        \\export fn b() void {
+        \\    const f = async func();
+        \\    var x: anyframe = &f;
+        \\}
+        \\fn func() void {
+        \\    suspend;
+        \\}
+    ,
+        "tmp.zig:3:12: error: expected type 'anyframe', found '*const @Frame(func)'",
+        "tmp.zig:7:24: error: expected type 'anyframe', found '*const @Frame(func)'",
+    );
+
     cases.add(
         "prevent bad implicit casting of anyframe types",
         \\export fn a() void {