Skip to content

Commit 0757641

Browse files
committed
Unconditionally error at definition if default field value has const errors
Emit E0080 always on struct definition with default fields that have unconditional const errors and remove `default_field_always_invalid_const` lint.
1 parent 2d6e763 commit 0757641

File tree

8 files changed

+29
-148
lines changed

8 files changed

+29
-148
lines changed

Diff for: compiler/rustc_hir_analysis/src/check/wfcheck.rs

+19
Original file line numberDiff line numberDiff line change
@@ -1104,6 +1104,25 @@ fn check_type_defn<'tcx>(
11041104
for variant in variants.iter() {
11051105
// All field types must be well-formed.
11061106
for field in &variant.fields {
1107+
if let Some(def_id) = field.value
1108+
&& let Some(_ty) = tcx.type_of(def_id).no_bound_vars()
1109+
{
1110+
// FIXME(generic_const_exprs, default_field_values): this is a hack and needs to
1111+
// be refactored to check the instantiate-ability of the code better.
1112+
if let Some(def_id) = def_id.as_local()
1113+
&& let hir::Node::AnonConst(anon) = tcx.hir_node_by_def_id(def_id)
1114+
&& let expr = &tcx.hir().body(anon.body).value
1115+
&& let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
1116+
&& let Res::Def(DefKind::ConstParam, _def_id) = path.res
1117+
{
1118+
// Do not evaluate bare `const` params, as those would ICE and are only
1119+
// usable if `#![feature(generic_const_exprs)]` is enabled.
1120+
} else {
1121+
// Evaluate the constant proactively, to emit an error if the constant has
1122+
// an unconditional error. We only do so if the const has no type params.
1123+
let _ = tcx.const_eval_poly(def_id.into());
1124+
}
1125+
}
11071126
let field_id = field.did.expect_local();
11081127
let hir::FieldDef { ty: hir_ty, .. } =
11091128
tcx.hir_node_by_def_id(field_id).expect_field();

Diff for: compiler/rustc_lint/messages.ftl

-4
Original file line numberDiff line numberDiff line change
@@ -211,10 +211,6 @@ lint_dangling_pointers_from_temporaries = a dangling pointer will be produced be
211211
.note = pointers do not have a lifetime; when calling `{$callee}` the `{$ty}` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned
212212
.help = for more information, see <https://doc.rust-lang.org/reference/destructors.html>
213213
214-
lint_default_field_always_invalid_const = default field fails const-evaluation
215-
.label = this field's constant fails const-evaluation, as seen in the previous error
216-
.help = you can skip const-evaluation of default fields by enabling this lint
217-
218214
lint_default_hash_types = prefer `{$preferred}` over `{$used}`, it has better performance
219215
.note = a `use rustc_data_structures::fx::{$preferred}` may be necessary
220216

Diff for: compiler/rustc_lint/src/default_field_always_invalid.rs

-91
This file was deleted.

Diff for: compiler/rustc_lint/src/lib.rs

-3
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ mod async_fn_in_trait;
4141
pub mod builtin;
4242
mod context;
4343
mod dangling;
44-
mod default_field_always_invalid;
4544
mod deref_into_dyn_supertrait;
4645
mod drop_forget_useless;
4746
mod early;
@@ -86,7 +85,6 @@ use async_closures::AsyncClosureUsage;
8685
use async_fn_in_trait::AsyncFnInTrait;
8786
use builtin::*;
8887
use dangling::*;
89-
use default_field_always_invalid::*;
9088
use deref_into_dyn_supertrait::*;
9189
use drop_forget_useless::*;
9290
use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums;
@@ -195,7 +193,6 @@ late_lint_methods!(
195193
DropForgetUseless: DropForgetUseless,
196194
ImproperCTypesDeclarations: ImproperCTypesDeclarations,
197195
ImproperCTypesDefinitions: ImproperCTypesDefinitions,
198-
DefaultFieldAlwaysInvalid: DefaultFieldAlwaysInvalid,
199196
InvalidFromUtf8: InvalidFromUtf8,
200197
VariantSizeDifferences: VariantSizeDifferences,
201198
PathStatements: PathStatements,

Diff for: compiler/rustc_lint/src/lints.rs

-9
Original file line numberDiff line numberDiff line change
@@ -730,15 +730,6 @@ pub(crate) struct UndroppedManuallyDropsSuggestion {
730730
pub end_span: Span,
731731
}
732732

733-
#[derive(LintDiagnostic)]
734-
#[diag(lint_default_field_always_invalid_const)]
735-
pub(crate) struct DefaultFieldAlwaysInvalidConst {
736-
#[label]
737-
pub span: Span,
738-
#[help]
739-
pub help: (),
740-
}
741-
742733
// invalid_from_utf8.rs
743734
#[derive(LintDiagnostic)]
744735
pub(crate) enum InvalidFromUtf8Diag {

Diff for: tests/ui/structs/default-field-values-failures.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ error: default fields are not supported in tuple structs
2121
LL | pub struct Rak(i32 = 42);
2222
| ^^ default fields are only supported on structs
2323

24+
error: generic `Self` types are currently not permitted in anonymous constants
25+
--> $DIR/default-field-values-failures.rs:20:14
26+
|
27+
LL | bar: S = Self::S,
28+
| ^^^^
29+
2430
error[E0277]: the trait bound `S: Default` is not satisfied
2531
--> $DIR/default-field-values-failures.rs:14:5
2632
|
@@ -106,12 +112,6 @@ LL - let _ = Rak(.., 0);
106112
LL + let _ = Rak(0);
107113
|
108114

109-
error: generic `Self` types are currently not permitted in anonymous constants
110-
--> $DIR/default-field-values-failures.rs:20:14
111-
|
112-
LL | bar: S = Self::S,
113-
| ^^^^
114-
115115
error: aborting due to 9 previous errors
116116

117117
Some errors have detailed explanations: E0061, E0277, E0308.

Diff for: tests/ui/structs/default-field-values-invalid-const.rs

-3
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
#![feature(default_field_values, generic_const_exprs)]
22
#![allow(incomplete_features)]
33

4-
#[warn(default_field_always_invalid_const)] //~ WARN lint `default_field_always_invalid_const` can't be warned on
54
pub struct Bat {
65
pub bax: u8 = panic!("asdf"),
76
//~^ ERROR evaluation of constant value failed
8-
//~| WARN default field fails const-evaluation
97
}
108

119
pub struct Baz<const C: u8> {
1210
pub bax: u8 = 130 + C, // ok
1311
pub bat: u8 = 130 + 130,
1412
//~^ ERROR evaluation of `Baz::<C>::bat::{constant#0}` failed
15-
//~| ERROR default field fails const-evaluation
1613
pub bay: u8 = 1, // ok
1714
}
1815

+4-32
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,17 @@
1-
warning: lint `default_field_always_invalid_const` can't be warned on
2-
--> $DIR/default-field-values-invalid-const.rs:4:8
3-
|
4-
LL | #[warn(default_field_always_invalid_const)]
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ either `deny` or `allow`, no other lint level is supported for this lint
6-
71
error[E0080]: evaluation of constant value failed
8-
--> $DIR/default-field-values-invalid-const.rs:6:19
2+
--> $DIR/default-field-values-invalid-const.rs:5:19
93
|
104
LL | pub bax: u8 = panic!("asdf"),
11-
| ^^^^^^^^^^^^^^ the evaluated program panicked at 'asdf', $DIR/default-field-values-invalid-const.rs:6:19
5+
| ^^^^^^^^^^^^^^ the evaluated program panicked at 'asdf', $DIR/default-field-values-invalid-const.rs:5:19
126
|
137
= 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)
148

15-
warning: default field fails const-evaluation
16-
--> $DIR/default-field-values-invalid-const.rs:6:5
17-
|
18-
LL | pub bax: u8 = panic!("asdf"),
19-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this field's constant fails const-evaluation, as seen in the previous error
20-
|
21-
= help: you can skip const-evaluation of default fields by enabling this lint
22-
note: the lint level is defined here
23-
--> $DIR/default-field-values-invalid-const.rs:4:8
24-
|
25-
LL | #[warn(default_field_always_invalid_const)]
26-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
27-
289
error[E0080]: evaluation of `Baz::<C>::bat::{constant#0}` failed
29-
--> $DIR/default-field-values-invalid-const.rs:13:19
10+
--> $DIR/default-field-values-invalid-const.rs:11:19
3011
|
3112
LL | pub bat: u8 = 130 + 130,
3213
| ^^^^^^^^^ attempt to compute `130_u8 + 130_u8`, which would overflow
3314

34-
error: default field fails const-evaluation
35-
--> $DIR/default-field-values-invalid-const.rs:13:5
36-
|
37-
LL | pub bat: u8 = 130 + 130,
38-
| ^^^^^^^^^^^^^^^^^^^^^^^ this field's constant fails const-evaluation, as seen in the previous error
39-
|
40-
= help: you can skip const-evaluation of default fields by enabling this lint
41-
= note: `#[deny(default_field_always_invalid_const)]` on by default
42-
43-
error: aborting due to 3 previous errors; 2 warnings emitted
15+
error: aborting due to 2 previous errors
4416

4517
For more information about this error, try `rustc --explain E0080`.

0 commit comments

Comments
 (0)