summaryrefslogtreecommitdiffstats
path: root/tests/run-make/reproducible-build/reproducible-build.rs
blob: a6c04774c869a26dc110e270393ffbb0475ec34f (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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// This test case makes sure that two identical invocations of the compiler
// (i.e., same code base, same compile-flags, same compiler-versions, etc.)
// produce the same output. In the past, symbol names of monomorphized functions
// were not deterministic (which we want to avoid).
//
// The test tries to exercise as many different paths into symbol name
// generation as possible:
//
// - regular functions
// - generic functions
// - methods
// - statics
// - closures
// - enum variant constructors
// - tuple struct constructors
// - drop glue
// - FnOnce adapters
// - Trait object shims
// - Fn Pointer shims

#![allow(dead_code, warnings)]

extern crate reproducible_build_aux;

static STATIC: i32 = 1234;

pub struct Struct<T1, T2> {
    x: T1,
    y: T2,
}

fn regular_fn(_: i32) {}

fn generic_fn<T1, T2>() {}

impl<T1, T2> Drop for Struct<T1, T2> {
    fn drop(&mut self) {}
}

pub enum Enum {
    Variant1,
    Variant2(u32),
    Variant3 { x: u32 }
}

struct TupleStruct(i8, i16, i32, i64);

impl TupleStruct {
    pub fn bar(&self) {}
}

trait Trait<T1, T2> {
    fn foo(&self);
}

impl Trait<i32, u64> for u64 {
    fn foo(&self) {}
}

impl reproducible_build_aux::Trait<char, String> for TupleStruct {
    fn foo(&self) {}
}

fn main() {
    regular_fn(STATIC);
    generic_fn::<u32, char>();
    generic_fn::<char, Struct<u32, u64>>();
    generic_fn::<Struct<u64, u32>, reproducible_build_aux::Struct<u32, u64>>();

    let dropped = Struct {
        x: "",
        y: 'a',
    };

    let _ = Enum::Variant1;
    let _ = Enum::Variant2(0);
    let _ = Enum::Variant3 { x: 0 };
    let _ = TupleStruct(1, 2, 3, 4);

    let closure  = |x| {
        x + 1i32
    };

    fn inner<F: Fn(i32) -> i32>(f: F) -> i32 {
        f(STATIC)
    }

    println!("{}", inner(closure));

    let object_shim: &Trait<i32, u64> = &0u64;
    object_shim.foo();

    fn with_fn_once_adapter<F: FnOnce(i32)>(f: F) {
        f(0);
    }

    with_fn_once_adapter(|_:i32| { });

    reproducible_build_aux::regular_fn(STATIC);
    reproducible_build_aux::generic_fn::<u32, char>();
    reproducible_build_aux::generic_fn::<char, Struct<u32, u64>>();
    reproducible_build_aux::generic_fn::<Struct<u64, u32>,
                                         reproducible_build_aux::Struct<u32, u64>>();

    let _ = reproducible_build_aux::Enum::Variant1;
    let _ = reproducible_build_aux::Enum::Variant2(0);
    let _ = reproducible_build_aux::Enum::Variant3 { x: 0 };
    let _ = reproducible_build_aux::TupleStruct(1, 2, 3, 4);

    let object_shim: &reproducible_build_aux::Trait<char, String> = &TupleStruct(0, 1, 2, 3);
    object_shim.foo();

    let pointer_shim: &Fn(i32) = &regular_fn;

    TupleStruct(1, 2, 3, 4).bar();
}