Skip to content

Commit ed9b32e

Browse files
Rollup merge of rust-lang#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 rust-lang#134298 r? estebank or reassign
2 parents 4853cc3 + f870761 commit ed9b32e

File tree

8 files changed

+46
-23
lines changed

8 files changed

+46
-23
lines changed

compiler/rustc_mir_build/src/build/expr/into.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -367,14 +367,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
367367
.collect()
368368
}
369369
AdtExprBase::DefaultFields(field_types) => {
370-
itertools::zip_eq(field_names, &**field_types)
371-
.map(|(n, ty)| match fields_map.get(&n) {
370+
itertools::zip_eq(field_names, field_types)
371+
.map(|(n, &ty)| match fields_map.get(&n) {
372372
Some(v) => v.clone(),
373373
None => match variant.fields[n].value {
374374
Some(def) => {
375-
let value = Const::from_unevaluated(this.tcx, def)
376-
.instantiate(this.tcx, args);
377-
this.literal_operand(expr_span, value)
375+
let value = Const::Unevaluated(
376+
UnevaluatedConst::new(def, args),
377+
ty,
378+
);
379+
Operand::Constant(Box::new(ConstOperand {
380+
span: expr_span,
381+
user_ty: None,
382+
const_: value,
383+
}))
378384
}
379385
None => {
380386
let name = variant.fields[n].name;

tests/ui/structs/default-field-values-failures.stderr tests/ui/structs/default-field-values/failures.stderr

+15-15
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error: the `#[default]` attribute may only be used on unit enum variants or variants where every field has a default value
2-
--> $DIR/default-field-values-failures.rs:47:5
2+
--> $DIR/failures.rs:47:5
33
|
44
LL | Variant {}
55
| ^^^^^^^
66
|
77
= help: consider a manual implementation of `Default`
88

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

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

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

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

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

5252
error[E0308]: mismatched types
53-
--> $DIR/default-field-values-failures.rs:57:17
53+
--> $DIR/failures.rs:57:17
5454
|
5555
LL | let _ = Rak(..);
5656
| --- ^^ expected `i32`, found `RangeFull`
5757
| |
5858
| arguments to this struct are incorrect
5959
|
6060
note: tuple struct defined here
61-
--> $DIR/default-field-values-failures.rs:26:12
61+
--> $DIR/failures.rs:26:12
6262
|
6363
LL | pub struct Rak(i32 = 42);
6464
| ^^^
6565
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
66-
--> $DIR/default-field-values-failures.rs:57:17
66+
--> $DIR/failures.rs:57:17
6767
|
6868
LL | let _ = Rak(..);
6969
| ^^
7070

7171
error[E0061]: this struct takes 1 argument but 2 arguments were supplied
72-
--> $DIR/default-field-values-failures.rs:59:13
72+
--> $DIR/failures.rs:59:13
7373
|
7474
LL | let _ = Rak(0, ..);
7575
| ^^^ -- unexpected argument #2 of type `RangeFull`
7676
|
7777
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
78-
--> $DIR/default-field-values-failures.rs:59:20
78+
--> $DIR/failures.rs:59:20
7979
|
8080
LL | let _ = Rak(0, ..);
8181
| ^^
8282
note: tuple struct defined here
83-
--> $DIR/default-field-values-failures.rs:26:12
83+
--> $DIR/failures.rs:26:12
8484
|
8585
LL | pub struct Rak(i32 = 42);
8686
| ^^^
@@ -91,18 +91,18 @@ LL + let _ = Rak(0);
9191
|
9292

9393
error[E0061]: this struct takes 1 argument but 2 arguments were supplied
94-
--> $DIR/default-field-values-failures.rs:61:13
94+
--> $DIR/failures.rs:61:13
9595
|
9696
LL | let _ = Rak(.., 0);
9797
| ^^^ -- unexpected argument #1 of type `RangeFull`
9898
|
9999
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
100-
--> $DIR/default-field-values-failures.rs:61:17
100+
--> $DIR/failures.rs:61:17
101101
|
102102
LL | let _ = Rak(.., 0);
103103
| ^^
104104
note: tuple struct defined here
105-
--> $DIR/default-field-values-failures.rs:26:12
105+
--> $DIR/failures.rs:26:12
106106
|
107107
LL | pub struct Rak(i32 = 42);
108108
| ^^^

tests/ui/structs/default-field-values-invalid-const.stderr tests/ui/structs/default-field-values/invalid-const.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error[E0080]: evaluation of constant value failed
2-
--> $DIR/default-field-values-invalid-const.rs:5:19
2+
--> $DIR/invalid-const.rs:5:19
33
|
44
LL | pub bax: u8 = panic!("asdf"),
5-
| ^^^^^^^^^^^^^^ the evaluated program panicked at 'asdf', $DIR/default-field-values-invalid-const.rs:5:19
5+
| ^^^^^^^^^^^^^^ the evaluated program panicked at 'asdf', $DIR/invalid-const.rs:5:19
66
|
77
= 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)
88

99
error[E0080]: evaluation of `Baz::<C>::bat::{constant#0}` failed
10-
--> $DIR/default-field-values-invalid-const.rs:11:19
10+
--> $DIR/invalid-const.rs:11:19
1111
|
1212
LL | pub bat: u8 = 130 + 130,
1313
| ^^^^^^^^^ attempt to compute `130_u8 + 130_u8`, which would overflow
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//@ check-pass
2+
3+
#![feature(default_field_values)]
4+
5+
struct Value<const VALUE: u8>;
6+
7+
impl<const VALUE: u8> Value<VALUE> {
8+
pub const VALUE: Self = Self;
9+
}
10+
11+
pub struct WithUse {
12+
_use: Value<{ 0 + 0 }> = Value::VALUE
13+
}
14+
15+
const _: WithUse = WithUse { .. };
16+
17+
fn main() {}

0 commit comments

Comments
 (0)