about summary refs log tree commit diff
path: root/tests/ui/structs/default-field-values/support.rs
blob: 8209d6dd4a09379b5aa61372e2dcb0b4862717c6 (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
// Exercise the `default_field_values` feature to confirm it interacts correctly with other nightly
// features. In particular, we want to verify that interaction with consts coming from different
// contexts are usable as a default field value.
//@ run-pass
//@ aux-build:struct_field_default.rs
#![feature(const_trait_impl, default_field_values, generic_const_exprs)]
#![allow(unused_variables, dead_code, incomplete_features)]

extern crate struct_field_default as xc;

pub struct S;

// Basic expressions and `Default` expansion
#[derive(Default)]
pub struct Foo {
    pub bar: S = S,
    pub baz: i32 = 42 + 3,
}

// Enum support for deriving `Default` when all fields have default values
#[derive(Default)]
pub enum Bar {
    #[default]
    Foo {
        bar: S = S,
        baz: i32 = 42 + 3,
    }
}

#[const_trait] pub trait ConstDefault {
    fn value() -> Self;
}

impl const ConstDefault for i32 {
    fn value() -> i32 {
        101
    }
}

pub struct Qux<A, const C: i32, X: const ConstDefault> {
    bar: S = Qux::<A, C, X>::S, // Associated constant from inherent impl
    baz: i32 = foo(), // Constant function
    bat: i32 = <Qux<A, C, X> as T>::K, // Associated constant from explicit trait
    baq: i32 = Self::K, // Associated constant from implicit trait
    bay: i32 = C, // `const` parameter
    bak: Vec<A> = Vec::new(), // Associated constant function
    ban: X = X::value(), // Associated constant function from `const` trait parameter
}

impl<A, const C: i32, X: const ConstDefault> Qux<A, C, X> {
    const S: S = S;
}

trait T {
    const K: i32;
}

impl<A, const C: i32, X: const ConstDefault> T for Qux<A, C, X> {
    const K: i32 = 2;
}

const fn foo() -> i32 {
    42
}

fn main () {
    let x = Foo { .. };
    let y = Foo::default();
    let z = Foo { baz: 1, .. };

    assert_eq!(45, x.baz);
    assert_eq!(45, y.baz);
    assert_eq!(1, z.baz);

    let x = Bar::Foo { .. };
    let y = Bar::default();
    let z = Bar::Foo { baz: 1, .. };

    assert!(matches!(Bar::Foo { bar: S, baz: 45 }, x));
    assert!(matches!(Bar::Foo { bar: S, baz: 45 }, y));
    assert!(matches!(Bar::Foo { bar: S, baz: 1 }, z));

    let x = Qux::<i32, 4, i32> { .. };
    assert!(matches!(
        Qux::<i32, 4, i32> {
            bar: S,
            baz: 42,
            bat: 2,
            baq: 2,
            bay: 4,
            ban: 101,
            ..
        },
        x,
    ));
    assert!(x.bak.is_empty());

    let x = xc::A { .. };
    assert!(matches!(xc::A { a: 42 }, x));
}