Skip to content

Commit

Permalink
Unrolled build for rust-lang#133704
Browse files Browse the repository at this point in the history
Rollup merge of rust-lang#133704 - RalfJung:promoted-size-overflow-ice, r=compiler-errors

fix ICE when promoted has layout size overflow

Turns out there is no reason to distinguish `tainted_by_errors` and `can_be_spurious` here, we can just track whether we allow this even in "infallible" constants.

Fixes rust-lang#125476
  • Loading branch information
rust-timer authored Dec 3, 2024
2 parents 42b4b9c + a17294d commit 9157923
Show file tree
Hide file tree
Showing 25 changed files with 218 additions and 79 deletions.
17 changes: 12 additions & 5 deletions compiler/rustc_const_eval/src/const_eval/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,29 +139,36 @@ where
match error {
// Don't emit a new diagnostic for these errors, they are already reported elsewhere or
// should remain silent.
err_inval!(AlreadyReported(info)) => ErrorHandled::Reported(info, span),
err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => {
ErrorHandled::TooGeneric(span)
}
err_inval!(AlreadyReported(guar)) => ErrorHandled::Reported(guar, span),
err_inval!(Layout(LayoutError::ReferencesError(guar))) => {
ErrorHandled::Reported(ReportedErrorInfo::tainted_by_errors(guar), span)
// This can occur in infallible promoteds e.g. when a non-existent type or field is
// encountered.
ErrorHandled::Reported(ReportedErrorInfo::allowed_in_infallible(guar), span)
}
// Report remaining errors.
_ => {
let (our_span, frames) = get_span_and_frames();
let span = span.substitute_dummy(our_span);
let err = mk(span, frames);
let mut err = tcx.dcx().create_err(err);
let can_be_spurious = matches!(error, InterpErrorKind::ResourceExhaustion(_));
// We allow invalid programs in infallible promoteds since invalid layouts can occur
// anyway (e.g. due to size overflow). And we allow OOM as that can happen any time.
let allowed_in_infallible = matches!(
error,
InterpErrorKind::ResourceExhaustion(_) | InterpErrorKind::InvalidProgram(_)
);

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

// Use *our* span to label the interp error
err.span_label(our_span, msg);
let g = err.emit();
let reported = if can_be_spurious {
ReportedErrorInfo::spurious(g)
let reported = if allowed_in_infallible {
ReportedErrorInfo::allowed_in_infallible(g)
} else {
ReportedErrorInfo::from(g)
};
Expand Down
11 changes: 4 additions & 7 deletions compiler/rustc_const_eval/src/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
};
// do not continue if typeck errors occurred (can only occur in local crate)
if let Some(err) = body.tainted_by_errors {
throw_inval!(AlreadyReported(ReportedErrorInfo::tainted_by_errors(err)));
throw_inval!(AlreadyReported(ReportedErrorInfo::from(err)));
}
interp_ok(body)
}
Expand Down Expand Up @@ -585,13 +585,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
match err {
ErrorHandled::TooGeneric(..) => {},
ErrorHandled::Reported(reported, span) => {
if reported.is_tainted_by_errors() {
// const-eval will return "tainted" errors if e.g. the layout cannot
// be computed as the type references non-existing names.
// See <https://github.com/rust-lang/rust/issues/124348>.
} else if reported.can_be_spurious() {
if reported.is_allowed_in_infallible() {
// These errors can just sometimes happen, even when the expression
// is nominally "infallible", e.g. when running out of memory.
// is nominally "infallible", e.g. when running out of memory
// or when some layout could not be computed.
} else {
// Looks like the const is not captured by `required_consts`, that's bad.
span_bug!(span, "interpret const eval failure of {val:?} which is not in required_consts");
Expand Down
26 changes: 9 additions & 17 deletions compiler/rustc_middle/src/mir/interpret/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl ErrorHandled {
pub fn emit_note(&self, tcx: TyCtxt<'_>) {
match self {
&ErrorHandled::Reported(err, span) => {
if !err.is_tainted_by_errors && !span.is_dummy() {
if !err.allowed_in_infallible && !span.is_dummy() {
tcx.dcx().emit_note(error::ErroneousConstant { span });
}
}
Expand All @@ -58,34 +58,26 @@ impl ErrorHandled {
#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
pub struct ReportedErrorInfo {
error: ErrorGuaranteed,
is_tainted_by_errors: bool,
/// Whether this is the kind of error that can sometimes occur, and sometimes not.
/// Used for resource exhaustion errors.
can_be_spurious: bool,
/// Whether this error is allowed to show up even in otherwise "infallible" promoteds.
/// This is for things like overflows during size computation or resource exhaustion.
allowed_in_infallible: bool,
}

impl ReportedErrorInfo {
#[inline]
pub fn tainted_by_errors(error: ErrorGuaranteed) -> ReportedErrorInfo {
ReportedErrorInfo { is_tainted_by_errors: true, can_be_spurious: false, error }
}
#[inline]
pub fn spurious(error: ErrorGuaranteed) -> ReportedErrorInfo {
ReportedErrorInfo { can_be_spurious: true, is_tainted_by_errors: false, error }
pub fn allowed_in_infallible(error: ErrorGuaranteed) -> ReportedErrorInfo {
ReportedErrorInfo { allowed_in_infallible: true, error }
}

pub fn is_tainted_by_errors(&self) -> bool {
self.is_tainted_by_errors
}
pub fn can_be_spurious(&self) -> bool {
self.can_be_spurious
pub fn is_allowed_in_infallible(&self) -> bool {
self.allowed_in_infallible
}
}

impl From<ErrorGuaranteed> for ReportedErrorInfo {
#[inline]
fn from(error: ErrorGuaranteed) -> ReportedErrorInfo {
ReportedErrorInfo { is_tainted_by_errors: false, can_be_spurious: false, error }
ReportedErrorInfo { allowed_in_infallible: false, error }
}
}

Expand Down
4 changes: 0 additions & 4 deletions tests/crashes/125476.rs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,20 @@ help: add `#![feature(adt_const_params)]` to the crate attributes to enable more
LL + #![feature(adt_const_params)]
|

note: erroneous constant encountered
--> $DIR/unevaluated-const-ice-119731.rs:22:19
|
LL | impl v17<512, v0> {
| ^^

note: erroneous constant encountered
--> $DIR/unevaluated-const-ice-119731.rs:22:19
|
LL | impl v17<512, v0> {
| ^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#0}
--> $DIR/unevaluated-const-ice-119731.rs:28:37
|
Expand Down
60 changes: 60 additions & 0 deletions tests/ui/consts/const-integer-bool-ops.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ error[E0308]: mismatched types
LL | const X: usize = 42 && 39;
| ^^^^^^^^ expected `usize`, found `bool`

note: erroneous constant encountered
--> $DIR/const-integer-bool-ops.rs:8:18
|
LL | const ARR: [i32; X] = [99; 34];
| ^

error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:10:19
|
Expand All @@ -34,6 +40,12 @@ error[E0308]: mismatched types
LL | const X1: usize = 42 || 39;
| ^^^^^^^^ expected `usize`, found `bool`

note: erroneous constant encountered
--> $DIR/const-integer-bool-ops.rs:17:19
|
LL | const ARR1: [i32; X1] = [99; 47];
| ^^

error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:19:19
|
Expand All @@ -52,6 +64,12 @@ error[E0308]: mismatched types
LL | const X2: usize = -42 || -39;
| ^^^^^^^^^^ expected `usize`, found `bool`

note: erroneous constant encountered
--> $DIR/const-integer-bool-ops.rs:26:19
|
LL | const ARR2: [i32; X2] = [99; 18446744073709551607];
| ^^

error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:28:19
|
Expand All @@ -70,42 +88,84 @@ error[E0308]: mismatched types
LL | const X3: usize = -42 && -39;
| ^^^^^^^^^^ expected `usize`, found `bool`

note: erroneous constant encountered
--> $DIR/const-integer-bool-ops.rs:35:19
|
LL | const ARR3: [i32; X3] = [99; 6];
| ^^

error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:37:18
|
LL | const Y: usize = 42.0 == 42.0;
| ^^^^^^^^^^^^ expected `usize`, found `bool`

note: erroneous constant encountered
--> $DIR/const-integer-bool-ops.rs:40:19
|
LL | const ARRR: [i32; Y] = [99; 1];
| ^

error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:42:19
|
LL | const Y1: usize = 42.0 >= 42.0;
| ^^^^^^^^^^^^ expected `usize`, found `bool`

note: erroneous constant encountered
--> $DIR/const-integer-bool-ops.rs:45:20
|
LL | const ARRR1: [i32; Y1] = [99; 1];
| ^^

error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:47:19
|
LL | const Y2: usize = 42.0 <= 42.0;
| ^^^^^^^^^^^^ expected `usize`, found `bool`

note: erroneous constant encountered
--> $DIR/const-integer-bool-ops.rs:50:20
|
LL | const ARRR2: [i32; Y2] = [99; 1];
| ^^

error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:52:19
|
LL | const Y3: usize = 42.0 > 42.0;
| ^^^^^^^^^^^ expected `usize`, found `bool`

note: erroneous constant encountered
--> $DIR/const-integer-bool-ops.rs:55:20
|
LL | const ARRR3: [i32; Y3] = [99; 0];
| ^^

error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:57:19
|
LL | const Y4: usize = 42.0 < 42.0;
| ^^^^^^^^^^^ expected `usize`, found `bool`

note: erroneous constant encountered
--> $DIR/const-integer-bool-ops.rs:60:20
|
LL | const ARRR4: [i32; Y4] = [99; 0];
| ^^

error[E0308]: mismatched types
--> $DIR/const-integer-bool-ops.rs:62:19
|
LL | const Y5: usize = 42.0 != 42.0;
| ^^^^^^^^^^^^ expected `usize`, found `bool`

note: erroneous constant encountered
--> $DIR/const-integer-bool-ops.rs:65:20
|
LL | const ARRR5: [i32; Y5] = [99; 0];
| ^^

error: aborting due to 18 previous errors

For more information about this error, try `rustc --explain E0308`.
6 changes: 6 additions & 0 deletions tests/ui/consts/const-mut-refs/issue-76510.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ error[E0764]: mutable references are not allowed in the final value of constants
LL | const S: &'static mut str = &mut " hello ";
| ^^^^^^^^^^^^^^

note: erroneous constant encountered
--> $DIR/issue-76510.rs:7:70
|
LL | let s = transmute::<(*const u8, usize), &ManuallyDrop<str>>((S.as_ptr(), 3));
| ^

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0764`.
6 changes: 6 additions & 0 deletions tests/ui/consts/const-tup-index-span.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ help: use a trailing comma to create a tuple with one element
LL | const TUP: (usize,) = (5usize << 64,);
| + ++

note: erroneous constant encountered
--> $DIR/const-tup-index-span.rs:6:18
|
LL | const ARR: [i32; TUP.0] = [];
| ^^^

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0308`.
18 changes: 18 additions & 0 deletions tests/ui/consts/issue-54954.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,24 @@ LL | | core::mem::size_of::<T>()
LL | | }
| |_____- `Tt::const_val` defined here

note: erroneous constant encountered
--> $DIR/issue-54954.rs:11:15
|
LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] {
| ^^^^^^^

note: erroneous constant encountered
--> $DIR/issue-54954.rs:11:34
|
LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] {
| ^^^^^^^

note: erroneous constant encountered
--> $DIR/issue-54954.rs:16:22
|
LL | let _ = f([1f32; ARR_LEN]);
| ^^^^^^^

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0379, E0790.
Expand Down
6 changes: 6 additions & 0 deletions tests/ui/consts/missing_assoc_const_type2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,11 @@ error: missing type for `const` item
LL | const FIRST: = 10;
| ^ help: provide a type for the associated constant: `u8`

note: erroneous constant encountered
--> $DIR/missing_assoc_const_type2.rs:18:5
|
LL | TwoDigits::FIRST as usize
| ^^^^^^^^^^^^^^^^

error: aborting due to 1 previous error

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

note: erroneous constant encountered
--> $DIR/promoted_running_out_of_memory_issue-130687.rs:8:26
|
LL | const _: &'static Data = &Data([0; (1 << 47) - 1]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0080`.
7 changes: 7 additions & 0 deletions tests/ui/consts/promoted_size_overflow.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//@ only-64bit
pub struct Data([u8; usize::MAX >> 2]);
const _: &'static [Data] = &[];
//~^ERROR: evaluation of constant value failed
//~| too big for the target architecture

fn main() {}
9 changes: 9 additions & 0 deletions tests/ui/consts/promoted_size_overflow.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0080]: evaluation of constant value failed
--> $DIR/promoted_size_overflow.rs:3:29
|
LL | const _: &'static [Data] = &[];
| ^^ values of the type `[u8; 4611686018427387903]` are too big for the target architecture

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0080`.
6 changes: 3 additions & 3 deletions tests/ui/consts/uninhabited-const-issue-61744.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ pub const unsafe fn fake_type<T>() -> T {
}

pub const unsafe fn hint_unreachable() -> ! {
fake_type()
fake_type() //~ inside
}

trait Const {
const CONSTANT: i32 = unsafe { fake_type() };
const CONSTANT: i32 = unsafe { fake_type() }; //~ inside
}

impl<T> Const for T {}

pub fn main() -> () {
dbg!(i32::CONSTANT); //~ constant
dbg!(i32::CONSTANT);
}
Loading

0 comments on commit 9157923

Please sign in to comment.