Skip to content

Commit 3b23b98

Browse files
sw17cheddyb
authored andcommitted
Two test cases where Rust calls C using enums by value
One calls into C functions passing non-c-like enumerations by value. The other calls into C expecting non-C-like enumerations as returns. These test cases are based on the tests provided by @bitwalker on issue rust-lang#68190. The original tests were provided at: https://github.com/bitwalker/rust_non_c_like_enums_issue/tree/2688d5c672bd4e289085fcdf1c6110e99e7e8ab1
1 parent 26bb0f1 commit 3b23b98

File tree

6 files changed

+216
-0
lines changed

6 files changed

+216
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-include ../tools.mk
2+
3+
all:
4+
$(CC) -c test.c -o $(call STATICLIB,test) $(EXTRACFLAGS) $(EXTRACXXFLAGS)
5+
$(RUSTC) nonclike.rs -L$(TMPDIR) -ltest
6+
$(call RUN,nonclike)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#![crate_type = "bin"]
2+
#![crate_name = "nonclike"]
3+
4+
#[repr(C, u8)]
5+
pub enum TT {
6+
AA(u64, u64),
7+
BB,
8+
}
9+
10+
#[repr(C,u8)]
11+
pub enum T {
12+
A(u64),
13+
B,
14+
}
15+
16+
extern "C" {
17+
pub fn t_add(a: T, b: T) -> u64;
18+
pub fn tt_add(a: TT, b: TT) -> u64;
19+
}
20+
21+
fn main() {
22+
assert_eq!(33, unsafe { tt_add(TT::AA(1,2), TT::AA(10,20)) });
23+
assert_eq!(11, unsafe { t_add(T::A(1), T::A(10)) });
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#include <stdint.h>
2+
3+
/* This is the code generated by cbindgen 0.12.1 for the `enum TT`
4+
* type in nonclike.rs . */
5+
enum TT_Tag {
6+
AA,
7+
BB,
8+
};
9+
typedef uint8_t TT_Tag;
10+
11+
typedef struct {
12+
uint64_t _0;
13+
uint64_t _1;
14+
} AA_Body;
15+
16+
typedef struct {
17+
TT_Tag tag;
18+
union {
19+
AA_Body aa;
20+
};
21+
} TT;
22+
23+
/* This is the code generated by cbindgen 0.12.1 for the `enum T` type
24+
* in nonclike.rs . */
25+
enum T_Tag {
26+
A,
27+
B,
28+
};
29+
typedef uint8_t T_Tag;
30+
31+
typedef struct {
32+
uint64_t _0;
33+
} A_Body;
34+
35+
typedef struct {
36+
T_Tag tag;
37+
union {
38+
A_Body a;
39+
};
40+
} T;
41+
42+
uint64_t tt_add(TT a, TT b) {
43+
if (a.tag == AA && b.tag == AA) {
44+
return a.aa._0 + a.aa._1 + b.aa._0 + b.aa._1;
45+
} else if (a.tag == AA) {
46+
return a.aa._0 + a.aa._1;
47+
} else if (b.tag == BB) {
48+
return b.aa._0 + b.aa._1;
49+
} else {
50+
return 0;
51+
}
52+
}
53+
54+
uint64_t t_add(T a, T b) {
55+
if (a.tag == A && b.tag == A) {
56+
return a.a._0 + b.a._0;
57+
} else if (a.tag == AA) {
58+
return a.a._0;
59+
} else if (b.tag == BB) {
60+
return b.a._0;
61+
} else {
62+
return 0;
63+
}
64+
}
65+
66+
TT tt_new(uint64_t a, uint64_t b) {
67+
TT tt = {
68+
.tag = AA,
69+
.aa = {
70+
._0 = a,
71+
._1 = b,
72+
},
73+
};
74+
return tt;
75+
}
76+
77+
T t_new(uint64_t a) {
78+
T t = {
79+
.tag = A,
80+
.a = {
81+
._0 = a,
82+
},
83+
};
84+
return t;
85+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-include ../tools.mk
2+
3+
all:
4+
$(CC) -c test.c -o $(call STATICLIB,test) $(EXTRACFLAGS) $(EXTRACXXFLAGS)
5+
$(RUSTC) nonclike.rs -L$(TMPDIR) -ltest
6+
$(call RUN,nonclike)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#![crate_type = "bin"]
2+
#![crate_name = "nonclike"]
3+
4+
#[repr(C, u8)]
5+
pub enum TT {
6+
AA(u64, u64),
7+
BB,
8+
}
9+
10+
#[repr(C,u8)]
11+
pub enum T {
12+
A(u64),
13+
B,
14+
}
15+
16+
extern "C" {
17+
pub fn t_new(a: u64) -> T;
18+
pub fn tt_new(a: u64, b: u64) -> TT;
19+
}
20+
21+
fn main() {
22+
if let TT::AA(a, b) = unsafe { tt_new(10, 11) } {
23+
assert_eq!(10, a);
24+
assert_eq!(11, b);
25+
} else {
26+
panic!("expected TT::AA");
27+
}
28+
29+
if let T::A(a) = unsafe { t_new(10) } {
30+
assert_eq!(10, a);
31+
} else {
32+
panic!("expected T::A");
33+
}
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#include <stdint.h>
2+
3+
/* This is the code generated by cbindgen 0.12.1 for the `enum TT`
4+
* type in nonclike.rs . */
5+
enum TT_Tag {
6+
AA,
7+
BB,
8+
};
9+
typedef uint8_t TT_Tag;
10+
11+
typedef struct {
12+
uint64_t _0;
13+
uint64_t _1;
14+
} AA_Body;
15+
16+
typedef struct {
17+
TT_Tag tag;
18+
union {
19+
AA_Body aa;
20+
};
21+
} TT;
22+
23+
/* This is the code generated by cbindgen 0.12.1 for the `enum T` type
24+
* in nonclike.rs . */
25+
enum T_Tag {
26+
A,
27+
B,
28+
};
29+
typedef uint8_t T_Tag;
30+
31+
typedef struct {
32+
uint64_t _0;
33+
} A_Body;
34+
35+
typedef struct {
36+
T_Tag tag;
37+
union {
38+
A_Body a;
39+
};
40+
} T;
41+
42+
TT tt_new(uint64_t a, uint64_t b) {
43+
TT tt = {
44+
.tag = AA,
45+
.aa = {
46+
._0 = a,
47+
._1 = b,
48+
},
49+
};
50+
return tt;
51+
}
52+
53+
T t_new(uint64_t a) {
54+
T t = {
55+
.tag = A,
56+
.a = {
57+
._0 = a,
58+
},
59+
};
60+
return t;
61+
}

0 commit comments

Comments
 (0)