1
Fork 0

Rollup merge of #134314 - compiler-errors:default-struct-value-const, 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
This commit is contained in:
Matthias Krüger 2024-12-16 08:03:32 +01:00 committed by GitHub
commit 050e0cc6eb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 46 additions and 23 deletions

View file

@ -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;

View file

@ -1,5 +1,5 @@
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 {}
| ^^^^^^^
@ -7,7 +7,7 @@ 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`
@ -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
@ -44,13 +44,13 @@ 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`
@ -58,29 +58,29 @@ LL | let _ = Rak(..);
| 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);
| ^^^
@ -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);
| ^^^

View file

@ -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

View file

@ -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() {}