Skip to content

Commit 20142d3

Browse files
committed
fix ICE when promoted has layout size overflow
1 parent 6c76ed5 commit 20142d3

25 files changed

+218
-79
lines changed

compiler/rustc_const_eval/src/const_eval/error.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -139,29 +139,36 @@ where
139139
match error {
140140
// Don't emit a new diagnostic for these errors, they are already reported elsewhere or
141141
// should remain silent.
142+
err_inval!(AlreadyReported(info)) => ErrorHandled::Reported(info, span),
142143
err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => {
143144
ErrorHandled::TooGeneric(span)
144145
}
145-
err_inval!(AlreadyReported(guar)) => ErrorHandled::Reported(guar, span),
146146
err_inval!(Layout(LayoutError::ReferencesError(guar))) => {
147-
ErrorHandled::Reported(ReportedErrorInfo::tainted_by_errors(guar), span)
147+
// This can occur in infallible promoteds e.g. when a non-existent type or field is
148+
// encountered.
149+
ErrorHandled::Reported(ReportedErrorInfo::allowed_in_infallible(guar), span)
148150
}
149151
// Report remaining errors.
150152
_ => {
151153
let (our_span, frames) = get_span_and_frames();
152154
let span = span.substitute_dummy(our_span);
153155
let err = mk(span, frames);
154156
let mut err = tcx.dcx().create_err(err);
155-
let can_be_spurious = matches!(error, InterpErrorKind::ResourceExhaustion(_));
157+
// We allow invalid programs in infallible promoteds since invalid layouts can occur
158+
// anyway (e.g. due to size overflow). And we allow OOM as that can happy any time.
159+
let allowed_in_infallible = matches!(
160+
error,
161+
InterpErrorKind::ResourceExhaustion(_) | InterpErrorKind::InvalidProgram(_)
162+
);
156163

157164
let msg = error.diagnostic_message();
158165
error.add_args(&mut err);
159166

160167
// Use *our* span to label the interp error
161168
err.span_label(our_span, msg);
162169
let g = err.emit();
163-
let reported = if can_be_spurious {
164-
ReportedErrorInfo::spurious(g)
170+
let reported = if allowed_in_infallible {
171+
ReportedErrorInfo::allowed_in_infallible(g)
165172
} else {
166173
ReportedErrorInfo::from(g)
167174
};

compiler/rustc_const_eval/src/interpret/eval_context.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
268268
};
269269
// do not continue if typeck errors occurred (can only occur in local crate)
270270
if let Some(err) = body.tainted_by_errors {
271-
throw_inval!(AlreadyReported(ReportedErrorInfo::tainted_by_errors(err)));
271+
throw_inval!(AlreadyReported(ReportedErrorInfo::from(err)));
272272
}
273273
interp_ok(body)
274274
}
@@ -585,13 +585,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
585585
match err {
586586
ErrorHandled::TooGeneric(..) => {},
587587
ErrorHandled::Reported(reported, span) => {
588-
if reported.is_tainted_by_errors() {
589-
// const-eval will return "tainted" errors if e.g. the layout cannot
590-
// be computed as the type references non-existing names.
591-
// See <https://github.com/rust-lang/rust/issues/124348>.
592-
} else if reported.can_be_spurious() {
588+
if reported.is_allowed_in_infallible() {
593589
// These errors can just sometimes happen, even when the expression
594-
// is nominally "infallible", e.g. when running out of memory.
590+
// is nominally "infallible", e.g. when running out of memory
591+
// or when some layout could not be computed.
595592
} else {
596593
// Looks like the const is not captured by `required_consts`, that's bad.
597594
span_bug!(span, "interpret const eval failure of {val:?} which is not in required_consts");

compiler/rustc_middle/src/mir/interpret/error.rs

+9-17
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ impl ErrorHandled {
4646
pub fn emit_note(&self, tcx: TyCtxt<'_>) {
4747
match self {
4848
&ErrorHandled::Reported(err, span) => {
49-
if !err.is_tainted_by_errors && !span.is_dummy() {
49+
if !err.allowed_in_infallible && !span.is_dummy() {
5050
tcx.dcx().emit_note(error::ErroneousConstant { span });
5151
}
5252
}
@@ -58,34 +58,26 @@ impl ErrorHandled {
5858
#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
5959
pub struct ReportedErrorInfo {
6060
error: ErrorGuaranteed,
61-
is_tainted_by_errors: bool,
62-
/// Whether this is the kind of error that can sometimes occur, and sometimes not.
63-
/// Used for resource exhaustion errors.
64-
can_be_spurious: bool,
61+
/// Whether this error is allowed to show up even in otherwise "infallible" promoteds.
62+
/// This is for things like overflows during size computation or resource exhaustion.
63+
allowed_in_infallible: bool,
6564
}
6665

6766
impl ReportedErrorInfo {
6867
#[inline]
69-
pub fn tainted_by_errors(error: ErrorGuaranteed) -> ReportedErrorInfo {
70-
ReportedErrorInfo { is_tainted_by_errors: true, can_be_spurious: false, error }
71-
}
72-
#[inline]
73-
pub fn spurious(error: ErrorGuaranteed) -> ReportedErrorInfo {
74-
ReportedErrorInfo { can_be_spurious: true, is_tainted_by_errors: false, error }
68+
pub fn allowed_in_infallible(error: ErrorGuaranteed) -> ReportedErrorInfo {
69+
ReportedErrorInfo { allowed_in_infallible: true, error }
7570
}
7671

77-
pub fn is_tainted_by_errors(&self) -> bool {
78-
self.is_tainted_by_errors
79-
}
80-
pub fn can_be_spurious(&self) -> bool {
81-
self.can_be_spurious
72+
pub fn is_allowed_in_infallible(&self) -> bool {
73+
self.allowed_in_infallible
8274
}
8375
}
8476

8577
impl From<ErrorGuaranteed> for ReportedErrorInfo {
8678
#[inline]
8779
fn from(error: ErrorGuaranteed) -> ReportedErrorInfo {
88-
ReportedErrorInfo { is_tainted_by_errors: false, can_be_spurious: false, error }
80+
ReportedErrorInfo { allowed_in_infallible: false, error }
8981
}
9082
}
9183

tests/crashes/125476.rs

-4
This file was deleted.

tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr

+14
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,20 @@ help: add `#![feature(adt_const_params)]` to the crate attributes to enable more
7272
LL + #![feature(adt_const_params)]
7373
|
7474

75+
note: erroneous constant encountered
76+
--> $DIR/unevaluated-const-ice-119731.rs:22:19
77+
|
78+
LL | impl v17<512, v0> {
79+
| ^^
80+
81+
note: erroneous constant encountered
82+
--> $DIR/unevaluated-const-ice-119731.rs:22:19
83+
|
84+
LL | impl v17<512, v0> {
85+
| ^^
86+
|
87+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
88+
7589
error: maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#0}
7690
--> $DIR/unevaluated-const-ice-119731.rs:28:37
7791
|

tests/ui/consts/const-integer-bool-ops.stderr

+60
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ error[E0308]: mismatched types
1616
LL | const X: usize = 42 && 39;
1717
| ^^^^^^^^ expected `usize`, found `bool`
1818

19+
note: erroneous constant encountered
20+
--> $DIR/const-integer-bool-ops.rs:8:18
21+
|
22+
LL | const ARR: [i32; X] = [99; 34];
23+
| ^
24+
1925
error[E0308]: mismatched types
2026
--> $DIR/const-integer-bool-ops.rs:10:19
2127
|
@@ -34,6 +40,12 @@ error[E0308]: mismatched types
3440
LL | const X1: usize = 42 || 39;
3541
| ^^^^^^^^ expected `usize`, found `bool`
3642

43+
note: erroneous constant encountered
44+
--> $DIR/const-integer-bool-ops.rs:17:19
45+
|
46+
LL | const ARR1: [i32; X1] = [99; 47];
47+
| ^^
48+
3749
error[E0308]: mismatched types
3850
--> $DIR/const-integer-bool-ops.rs:19:19
3951
|
@@ -52,6 +64,12 @@ error[E0308]: mismatched types
5264
LL | const X2: usize = -42 || -39;
5365
| ^^^^^^^^^^ expected `usize`, found `bool`
5466

67+
note: erroneous constant encountered
68+
--> $DIR/const-integer-bool-ops.rs:26:19
69+
|
70+
LL | const ARR2: [i32; X2] = [99; 18446744073709551607];
71+
| ^^
72+
5573
error[E0308]: mismatched types
5674
--> $DIR/const-integer-bool-ops.rs:28:19
5775
|
@@ -70,42 +88,84 @@ error[E0308]: mismatched types
7088
LL | const X3: usize = -42 && -39;
7189
| ^^^^^^^^^^ expected `usize`, found `bool`
7290

91+
note: erroneous constant encountered
92+
--> $DIR/const-integer-bool-ops.rs:35:19
93+
|
94+
LL | const ARR3: [i32; X3] = [99; 6];
95+
| ^^
96+
7397
error[E0308]: mismatched types
7498
--> $DIR/const-integer-bool-ops.rs:37:18
7599
|
76100
LL | const Y: usize = 42.0 == 42.0;
77101
| ^^^^^^^^^^^^ expected `usize`, found `bool`
78102

103+
note: erroneous constant encountered
104+
--> $DIR/const-integer-bool-ops.rs:40:19
105+
|
106+
LL | const ARRR: [i32; Y] = [99; 1];
107+
| ^
108+
79109
error[E0308]: mismatched types
80110
--> $DIR/const-integer-bool-ops.rs:42:19
81111
|
82112
LL | const Y1: usize = 42.0 >= 42.0;
83113
| ^^^^^^^^^^^^ expected `usize`, found `bool`
84114

115+
note: erroneous constant encountered
116+
--> $DIR/const-integer-bool-ops.rs:45:20
117+
|
118+
LL | const ARRR1: [i32; Y1] = [99; 1];
119+
| ^^
120+
85121
error[E0308]: mismatched types
86122
--> $DIR/const-integer-bool-ops.rs:47:19
87123
|
88124
LL | const Y2: usize = 42.0 <= 42.0;
89125
| ^^^^^^^^^^^^ expected `usize`, found `bool`
90126

127+
note: erroneous constant encountered
128+
--> $DIR/const-integer-bool-ops.rs:50:20
129+
|
130+
LL | const ARRR2: [i32; Y2] = [99; 1];
131+
| ^^
132+
91133
error[E0308]: mismatched types
92134
--> $DIR/const-integer-bool-ops.rs:52:19
93135
|
94136
LL | const Y3: usize = 42.0 > 42.0;
95137
| ^^^^^^^^^^^ expected `usize`, found `bool`
96138

139+
note: erroneous constant encountered
140+
--> $DIR/const-integer-bool-ops.rs:55:20
141+
|
142+
LL | const ARRR3: [i32; Y3] = [99; 0];
143+
| ^^
144+
97145
error[E0308]: mismatched types
98146
--> $DIR/const-integer-bool-ops.rs:57:19
99147
|
100148
LL | const Y4: usize = 42.0 < 42.0;
101149
| ^^^^^^^^^^^ expected `usize`, found `bool`
102150

151+
note: erroneous constant encountered
152+
--> $DIR/const-integer-bool-ops.rs:60:20
153+
|
154+
LL | const ARRR4: [i32; Y4] = [99; 0];
155+
| ^^
156+
103157
error[E0308]: mismatched types
104158
--> $DIR/const-integer-bool-ops.rs:62:19
105159
|
106160
LL | const Y5: usize = 42.0 != 42.0;
107161
| ^^^^^^^^^^^^ expected `usize`, found `bool`
108162

163+
note: erroneous constant encountered
164+
--> $DIR/const-integer-bool-ops.rs:65:20
165+
|
166+
LL | const ARRR5: [i32; Y5] = [99; 0];
167+
| ^^
168+
109169
error: aborting due to 18 previous errors
110170

111171
For more information about this error, try `rustc --explain E0308`.

tests/ui/consts/const-mut-refs/issue-76510.stderr

+6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ error[E0764]: mutable references are not allowed in the final value of constants
44
LL | const S: &'static mut str = &mut " hello ";
55
| ^^^^^^^^^^^^^^
66

7+
note: erroneous constant encountered
8+
--> $DIR/issue-76510.rs:7:70
9+
|
10+
LL | let s = transmute::<(*const u8, usize), &ManuallyDrop<str>>((S.as_ptr(), 3));
11+
| ^
12+
713
error: aborting due to 1 previous error
814

915
For more information about this error, try `rustc --explain E0764`.

tests/ui/consts/const-tup-index-span.stderr

+6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ help: use a trailing comma to create a tuple with one element
1111
LL | const TUP: (usize,) = (5usize << 64,);
1212
| + ++
1313

14+
note: erroneous constant encountered
15+
--> $DIR/const-tup-index-span.rs:6:18
16+
|
17+
LL | const ARR: [i32; TUP.0] = [];
18+
| ^^^
19+
1420
error: aborting due to 1 previous error
1521

1622
For more information about this error, try `rustc --explain E0308`.

tests/ui/consts/issue-54954.stderr

+18
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,24 @@ LL | | core::mem::size_of::<T>()
1919
LL | | }
2020
| |_____- `Tt::const_val` defined here
2121

22+
note: erroneous constant encountered
23+
--> $DIR/issue-54954.rs:11:15
24+
|
25+
LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] {
26+
| ^^^^^^^
27+
28+
note: erroneous constant encountered
29+
--> $DIR/issue-54954.rs:11:34
30+
|
31+
LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] {
32+
| ^^^^^^^
33+
34+
note: erroneous constant encountered
35+
--> $DIR/issue-54954.rs:16:22
36+
|
37+
LL | let _ = f([1f32; ARR_LEN]);
38+
| ^^^^^^^
39+
2240
error: aborting due to 2 previous errors
2341

2442
Some errors have detailed explanations: E0379, E0790.

tests/ui/consts/missing_assoc_const_type2.stderr

+6
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,11 @@ error: missing type for `const` item
44
LL | const FIRST: = 10;
55
| ^ help: provide a type for the associated constant: `u8`
66

7+
note: erroneous constant encountered
8+
--> $DIR/missing_assoc_const_type2.rs:18:5
9+
|
10+
LL | TwoDigits::FIRST as usize
11+
| ^^^^^^^^^^^^^^^^
12+
713
error: aborting due to 1 previous error
814

tests/ui/consts/promoted_running_out_of_memory_issue-130687.stderr

-6
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,6 @@ error[E0080]: evaluation of constant value failed
44
LL | const _: &'static Data = &Data([0; (1 << 47) - 1]);
55
| ^^^^^^^^^^^^^^^^^^ tried to allocate more memory than available to compiler
66

7-
note: erroneous constant encountered
8-
--> $DIR/promoted_running_out_of_memory_issue-130687.rs:8:26
9-
|
10-
LL | const _: &'static Data = &Data([0; (1 << 47) - 1]);
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^
12-
137
error: aborting due to 1 previous error
148

159
For more information about this error, try `rustc --explain E0080`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
//@ only-64bit
2+
pub struct Data([u8; usize::MAX >> 2]);
3+
const _: &'static [Data] = &[];
4+
//~^ERROR: evaluation of constant value failed
5+
//~| too big for the target architecture
6+
7+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0080]: evaluation of constant value failed
2+
--> $DIR/promoted_size_overflow.rs:3:29
3+
|
4+
LL | const _: &'static [Data] = &[];
5+
| ^^ values of the type `[u8; 4611686018427387903]` are too big for the target architecture
6+
7+
error: aborting due to 1 previous error
8+
9+
For more information about this error, try `rustc --explain E0080`.

tests/ui/consts/uninhabited-const-issue-61744.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ pub const unsafe fn fake_type<T>() -> T {
55
}
66

77
pub const unsafe fn hint_unreachable() -> ! {
8-
fake_type()
8+
fake_type() //~ inside
99
}
1010

1111
trait Const {
12-
const CONSTANT: i32 = unsafe { fake_type() };
12+
const CONSTANT: i32 = unsafe { fake_type() }; //~ inside
1313
}
1414

1515
impl<T> Const for T {}
1616

1717
pub fn main() -> () {
18-
dbg!(i32::CONSTANT); //~ constant
18+
dbg!(i32::CONSTANT);
1919
}

0 commit comments

Comments
 (0)