aboutsummaryrefslogtreecommitdiff
path: root/test/behavior/bugs/4328.zig
blob: 3158cb2c0d816fb514fc0866fc6d6886ef8863f1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
const expect = @import("std").testing.expect;
const builtin = @import("builtin");

const FILE = extern struct {
    dummy_field: u8,
};

extern fn printf([*c]const u8, ...) c_int;
extern fn fputs([*c]const u8, noalias [*c]FILE) c_int;
extern fn ftell([*c]FILE) c_long;
extern fn fopen([*c]const u8, [*c]const u8) [*c]FILE;

const S = extern struct {
    state: c_short,

    extern fn s_do_thing([*c]S, b: c_int) c_short;
};

test "Extern function calls in @TypeOf" {
    const Test = struct {
        fn test_fn_1(a: anytype, b: anytype) @TypeOf(printf("%d %s\n", a, b)) {
            return 0;
        }

        fn test_fn_2(s: anytype, a: anytype) @TypeOf(s.s_do_thing(a)) {
            return 1;
        }

        fn doTheTest() !void {
            try expect(@TypeOf(test_fn_1(0, 42)) == c_int);
            try expect(@TypeOf(test_fn_2(&S{ .state = 1 }, 0)) == c_short);
        }
    };

    try Test.doTheTest();
    comptime try Test.doTheTest();
}

test "Peer resolution of extern function calls in @TypeOf" {
    const Test = struct {
        fn test_fn() @TypeOf(ftell(null), fputs(null, null)) {
            return 0;
        }

        fn doTheTest() !void {
            try expect(@TypeOf(test_fn()) == c_long);
        }
    };

    try Test.doTheTest();
    comptime try Test.doTheTest();
}

test "Extern function calls, dereferences and field access in @TypeOf" {
    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;

    const Test = struct {
        fn test_fn_1(a: c_long) @TypeOf(fopen("test", "r").*) {
            _ = a;
            return .{ .dummy_field = 0 };
        }

        fn test_fn_2(a: anytype) @TypeOf(fopen("test", "r").*.dummy_field) {
            _ = a;
            return 255;
        }

        fn doTheTest() !void {
            try expect(@TypeOf(test_fn_1(0)) == FILE);
            try expect(@TypeOf(test_fn_2(0)) == u8);
        }
    };

    try Test.doTheTest();
    comptime try Test.doTheTest();
}