mirror of https://github.com/rust-lang/rust.git
101 lines
2.5 KiB
Rust
101 lines
2.5 KiB
Rust
// 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));
|
|
}
|