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:
commit
050e0cc6eb
8 changed files with 46 additions and 23 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
| ^^^
|
|
@ -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
|
|
@ -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() {}
|
Loading…
Add table
Add a link
Reference in a new issue