Skip to content

Commit

Permalink
Rollup merge of #134136 - estebank:const-trait-default-field-test, r=…
Browse files Browse the repository at this point in the history
…jieyouxu

Exercise const trait interaction with default fields

Add a test case for using the result of a fn call of an associated function of a `const` trait in a struct default field.

```rust
struct X;
trait Trait {
    fn value() -> Self;
}
impl const Trait for X {
    fn value() -> Self { X }
}
struct S<T: const Trait> {
    a: T = T::value(),
}
```
  • Loading branch information
jhpratt authored Dec 11, 2024
2 parents 5cf16d8 + 979eb4e commit fe7fc76
Showing 1 changed file with 39 additions and 13 deletions.
52 changes: 39 additions & 13 deletions tests/ui/structs/default-field-values-support.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
// 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(default_field_values, generic_const_exprs)]
#![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]
Expand All @@ -22,25 +27,35 @@ pub enum Bar {
}
}

#[derive(Default)]
pub struct Qux<A, const C: i32> {
bar: S = Qux::<A, C>::S,
baz: i32 = foo(),
bat: i32 = <Qux<A, C> as T>::K,
baq: i32 = Self::K,
bay: i32 = C,
bak: Vec<A> = Vec::new(),
#[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> Qux<A, C> {
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> T for Qux<A, C> {
impl<A, const C: i32, X: const ConstDefault> T for Qux<A, C, X> {
const K: i32 = 2;
}

Expand All @@ -65,8 +80,19 @@ fn main () {
assert!(matches!(Bar::Foo { bar: S, baz: 45 }, y));
assert!(matches!(Bar::Foo { bar: S, baz: 1 }, z));

let x = Qux::<i32, 4> { .. };
assert!(matches!(Qux::<i32, 4> { bar: S, baz: 42, bat: 2, baq: 2, bay: 4, .. }, x));
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 { .. };
Expand Down

0 comments on commit fe7fc76

Please sign in to comment.