Skip to content

Commit 965c7b6

Browse files
committed
Add some more tail call tests
1 parent 65e7db6 commit 965c7b6

File tree

5 files changed

+116
-0
lines changed

5 files changed

+116
-0
lines changed

Diff for: tests/ui/explicit-tail-calls/dyn-fn-once.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![feature(explicit_tail_calls)]
2+
3+
fn f() {
4+
become (Box::new(|| ()) as Box<dyn FnOnce() -> ()>)();
5+
//~^ error: mismatched function ABIs
6+
//~| error: mismatched signatures
7+
}
8+
9+
fn g() {
10+
become (&g as &dyn FnOnce() -> ())();
11+
//~^ error: mismatched function ABIs
12+
//~| error: mismatched signatures
13+
}
14+
15+
fn main() {}

Diff for: tests/ui/explicit-tail-calls/dyn-fn-once.stderr

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
error: mismatched function ABIs
2+
--> $DIR/dyn-fn-once.rs:4:5
3+
|
4+
LL | become (Box::new(|| ()) as Box<dyn FnOnce() -> ()>)();
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: `become` requires caller and callee to have the same ABI
8+
= note: caller ABI is `"Rust"`, while callee ABI is `"rust-call"`
9+
10+
error: mismatched signatures
11+
--> $DIR/dyn-fn-once.rs:4:5
12+
|
13+
LL | become (Box::new(|| ()) as Box<dyn FnOnce() -> ()>)();
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
15+
|
16+
= note: `become` requires caller and callee to have matching signatures
17+
= note: caller signature: `fn()`
18+
= note: callee signature: `extern "rust-call" fn(Box<dyn FnOnce()>, ())`
19+
20+
error: mismatched function ABIs
21+
--> $DIR/dyn-fn-once.rs:10:5
22+
|
23+
LL | become (&g as &dyn FnOnce() -> ())();
24+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
25+
|
26+
= note: `become` requires caller and callee to have the same ABI
27+
= note: caller ABI is `"Rust"`, while callee ABI is `"rust-call"`
28+
29+
error: mismatched signatures
30+
--> $DIR/dyn-fn-once.rs:10:5
31+
|
32+
LL | become (&g as &dyn FnOnce() -> ())();
33+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
34+
|
35+
= note: `become` requires caller and callee to have matching signatures
36+
= note: caller signature: `fn()`
37+
= note: callee signature: `extern "rust-call" fn(dyn FnOnce(), ())`
38+
39+
error: aborting due to 4 previous errors
40+

Diff for: tests/ui/explicit-tail-calls/fn-pointers.rs

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// run-pass
2+
#![feature(explicit_tail_calls)]
3+
4+
fn main() {
5+
use Inst::*;
6+
7+
let program = [
8+
Inc, // st + 1 = 1
9+
ShiftLeft, // st * 2 = 2
10+
ShiftLeft, // st * 2 = 4
11+
ShiftLeft, // st * 2 = 8
12+
Inc, // st + 1 = 9
13+
Inc, // st + 1 = 10
14+
Inc, // st + 1 = 11
15+
ShiftLeft, // st * 2 = 22
16+
Halt, // st = 22
17+
];
18+
19+
assert_eq!(run(0, &program), 22);
20+
}
21+
22+
#[derive(Clone, Copy, Debug, PartialEq)]
23+
enum Inst {
24+
Inc,
25+
ShiftLeft,
26+
Halt,
27+
}
28+
29+
fn run(state: u32, program: &[Inst]) -> u32 {
30+
const DISPATCH_TABLE: [fn(u32, &[Inst]) -> u32; 3] = [inc, shift_left, |st, _| st];
31+
32+
become DISPATCH_TABLE[program[0] as usize](state, program);
33+
}
34+
35+
fn inc(state: u32, program: &[Inst]) -> u32 {
36+
assert_eq!(program[0], Inst::Inc);
37+
become run(state + 1, &program[1..])
38+
}
39+
40+
fn shift_left(state: u32, program: &[Inst]) -> u32 {
41+
assert_eq!(program[0], Inst::ShiftLeft);
42+
become run(state << 1, &program[1..])
43+
}

Diff for: tests/ui/explicit-tail-calls/from-main-1.rs

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// run-pass
2+
#![feature(explicit_tail_calls)]
3+
4+
fn main() {
5+
become f();
6+
}
7+
8+
fn f() {}

Diff for: tests/ui/explicit-tail-calls/from-main-2.rs

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// run-pass
2+
#![feature(explicit_tail_calls)]
3+
4+
fn main() -> Result<(), i32> {
5+
become f();
6+
}
7+
8+
fn f() -> Result<(), i32> {
9+
Ok(())
10+
}

0 commit comments

Comments
 (0)