Skip to content

Commit

Permalink
Rollup merge of #134314 - compiler-errors:default-struct-value-const,…
Browse files Browse the repository at this point in the history
… r=estebank

Make sure to use normalized ty for unevaluated const in default struct value

This cleans up the way that we construct the `mir::Const::Unevaluated` for default struct values. We were previously using `from_unevaluated`, which doesn't normalize the type, and is really only used for inline assembly. Other codepaths (such as `ExprKind::NamedConst`) use the type from the body.

Also, let's stop using `literal_operand`, which also is really not meant for calls other than for literal comparisons in pattern lowering.

Also move all of the tests to a separate subdirectory so they don't need to have the same prefix on all the test files.

Fixes #134298
r? estebank or reassign
  • Loading branch information
matthiaskrgr authored Dec 16, 2024
2 parents f2b91cc + f870761 commit 050e0cc
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 23 deletions.
16 changes: 11 additions & 5 deletions compiler/rustc_mir_build/src/build/expr/into.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,14 +367,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
.collect()
}
AdtExprBase::DefaultFields(field_types) => {
itertools::zip_eq(field_names, &**field_types)
.map(|(n, ty)| match fields_map.get(&n) {
itertools::zip_eq(field_names, field_types)
.map(|(n, &ty)| match fields_map.get(&n) {
Some(v) => v.clone(),
None => match variant.fields[n].value {
Some(def) => {
let value = Const::from_unevaluated(this.tcx, def)
.instantiate(this.tcx, args);
this.literal_operand(expr_span, value)
let value = Const::Unevaluated(
UnevaluatedConst::new(def, args),
ty,
);
Operand::Constant(Box::new(ConstOperand {
span: expr_span,
user_ty: None,
const_: value,
}))
}
None => {
let name = variant.fields[n].name;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
error: the `#[default]` attribute may only be used on unit enum variants or variants where every field has a default value
--> $DIR/default-field-values-failures.rs:47:5
--> $DIR/failures.rs:47:5
|
LL | Variant {}
| ^^^^^^^
|
= help: consider a manual implementation of `Default`

error: generic parameters may not be used in const operations
--> $DIR/default-field-values-failures.rs:22:23
--> $DIR/failures.rs:22:23
|
LL | bat: i32 = <Qux<{ C }> as T>::K,
| ^ cannot perform const operation using `C`
Expand All @@ -16,19 +16,19 @@ LL | bat: i32 = <Qux<{ C }> as T>::K,
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions

error: default fields are not supported in tuple structs
--> $DIR/default-field-values-failures.rs:26:22
--> $DIR/failures.rs:26:22
|
LL | pub struct Rak(i32 = 42);
| ^^ default fields are only supported on structs

error: generic `Self` types are currently not permitted in anonymous constants
--> $DIR/default-field-values-failures.rs:20:14
--> $DIR/failures.rs:20:14
|
LL | bar: S = Self::S,
| ^^^^

error[E0277]: the trait bound `S: Default` is not satisfied
--> $DIR/default-field-values-failures.rs:14:5
--> $DIR/failures.rs:14:5
|
LL | #[derive(Debug, Default)]
| ------- in this derive macro expansion
Expand All @@ -44,43 +44,43 @@ LL | pub struct S;
|

error: missing mandatory field `bar`
--> $DIR/default-field-values-failures.rs:53:21
--> $DIR/failures.rs:53:21
|
LL | let _ = Bar { .. };
| ^

error[E0308]: mismatched types
--> $DIR/default-field-values-failures.rs:57:17
--> $DIR/failures.rs:57:17
|
LL | let _ = Rak(..);
| --- ^^ expected `i32`, found `RangeFull`
| |
| arguments to this struct are incorrect
|
note: tuple struct defined here
--> $DIR/default-field-values-failures.rs:26:12
--> $DIR/failures.rs:26:12
|
LL | pub struct Rak(i32 = 42);
| ^^^
help: you might have meant to use `..` to skip providing a value for expected fields, but this is only supported on non-tuple struct literals; it is instead interpreted as a `std::ops::RangeFull` literal
--> $DIR/default-field-values-failures.rs:57:17
--> $DIR/failures.rs:57:17
|
LL | let _ = Rak(..);
| ^^

error[E0061]: this struct takes 1 argument but 2 arguments were supplied
--> $DIR/default-field-values-failures.rs:59:13
--> $DIR/failures.rs:59:13
|
LL | let _ = Rak(0, ..);
| ^^^ -- unexpected argument #2 of type `RangeFull`
|
help: you might have meant to use `..` to skip providing a value for expected fields, but this is only supported on non-tuple struct literals; it is instead interpreted as a `std::ops::RangeFull` literal
--> $DIR/default-field-values-failures.rs:59:20
--> $DIR/failures.rs:59:20
|
LL | let _ = Rak(0, ..);
| ^^
note: tuple struct defined here
--> $DIR/default-field-values-failures.rs:26:12
--> $DIR/failures.rs:26:12
|
LL | pub struct Rak(i32 = 42);
| ^^^
Expand All @@ -91,18 +91,18 @@ LL + let _ = Rak(0);
|

error[E0061]: this struct takes 1 argument but 2 arguments were supplied
--> $DIR/default-field-values-failures.rs:61:13
--> $DIR/failures.rs:61:13
|
LL | let _ = Rak(.., 0);
| ^^^ -- unexpected argument #1 of type `RangeFull`
|
help: you might have meant to use `..` to skip providing a value for expected fields, but this is only supported on non-tuple struct literals; it is instead interpreted as a `std::ops::RangeFull` literal
--> $DIR/default-field-values-failures.rs:61:17
--> $DIR/failures.rs:61:17
|
LL | let _ = Rak(.., 0);
| ^^
note: tuple struct defined here
--> $DIR/default-field-values-failures.rs:26:12
--> $DIR/failures.rs:26:12
|
LL | pub struct Rak(i32 = 42);
| ^^^
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
error[E0080]: evaluation of constant value failed
--> $DIR/default-field-values-invalid-const.rs:5:19
--> $DIR/invalid-const.rs:5:19
|
LL | pub bax: u8 = panic!("asdf"),
| ^^^^^^^^^^^^^^ the evaluated program panicked at 'asdf', $DIR/default-field-values-invalid-const.rs:5:19
| ^^^^^^^^^^^^^^ the evaluated program panicked at 'asdf', $DIR/invalid-const.rs:5:19
|
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0080]: evaluation of `Baz::<C>::bat::{constant#0}` failed
--> $DIR/default-field-values-invalid-const.rs:11:19
--> $DIR/invalid-const.rs:11:19
|
LL | pub bat: u8 = 130 + 130,
| ^^^^^^^^^ attempt to compute `130_u8 + 130_u8`, which would overflow
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//@ check-pass

#![feature(default_field_values)]

struct Value<const VALUE: u8>;

impl<const VALUE: u8> Value<VALUE> {
pub const VALUE: Self = Self;
}

pub struct WithUse {
_use: Value<{ 0 + 0 }> = Value::VALUE
}

const _: WithUse = WithUse { .. };

fn main() {}

0 comments on commit 050e0cc

Please sign in to comment.