Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Do not assert layout in KnownPanicsLint.
  • Loading branch information
cjgillot committed Jul 25, 2025
commit 6b4181f1e39f2e309de6aa15e69f0b2f6889570d
11 changes: 11 additions & 0 deletions compiler/rustc_const_eval/src/interpret/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,17 @@ impl<'tcx, Prov: Provenance> std::ops::Deref for ImmTy<'tcx, Prov> {
}

impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
#[inline(always)]
pub fn try_from_immediate(imm: Immediate<Prov>, layout: TyAndLayout<'tcx>) -> Option<Self> {
Copy link
Member

@RalfJung RalfJung Jul 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a fan of these functions. The point of the assertions is that they are a last line of defense to detect defective callers. They are not exhaustive checks. If the caller can't ensure that the value has the right type, that can only be fixed in the caller.

IOW, matches_abi here really is more of a maybe_matches_abi. It is necessary, but not sufficient. And trying to make it sufficient is the wrong approach; the right approach is figuring out why someone is feeding bogus data into these functions.

let matches_abi = match (imm, layout.backend_repr) {
(Immediate::Scalar(..), BackendRepr::Scalar(..)) => true,
(Immediate::ScalarPair(..), BackendRepr::ScalarPair(..)) => true,
(Immediate::Uninit, _) => layout.is_sized(),
_ => false,
};
if matches_abi { Some(ImmTy { imm, layout }) } else { None }
}

#[inline]
pub fn from_scalar(val: Scalar<Prov>, layout: TyAndLayout<'tcx>) -> Self {
debug_assert!(layout.backend_repr.is_scalar(), "`ImmTy::from_scalar` on non-scalar layout");
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_const_eval/src/interpret/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,14 @@ impl<'tcx, Prov: Provenance> Projectable<'tcx, Prov> for PlaceTy<'tcx, Prov> {

// These are defined here because they produce a place.
impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> {
#[inline(always)]
pub fn try_as_immediate(&self) -> Option<ImmTy<'tcx, Prov>> {
match self.op() {
Operand::Indirect(_) => None,
Operand::Immediate(imm) => ImmTy::try_from_immediate(*imm, self.layout),
}
}

#[inline(always)]
pub fn as_mplace_or_imm(&self) -> Either<MPlaceTy<'tcx, Prov>, ImmTy<'tcx, Prov>> {
match self.op() {
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_mir_transform/src/known_panics_lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,9 +263,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
// manually normalized.
let val = self.tcx.try_normalize_erasing_regions(self.typing_env, c.const_).ok()?;

self.use_ecx(|this| this.ecx.eval_mir_constant(&val, c.span, None))?
.as_mplace_or_imm()
.right()
self.use_ecx(|this| this.ecx.eval_mir_constant(&val, c.span, None))?.try_as_immediate()
}

/// Returns the value, if any, of evaluating `place`.
Expand Down
9 changes: 0 additions & 9 deletions tests/crashes/121176.rs

This file was deleted.

12 changes: 0 additions & 12 deletions tests/crashes/139872.rs

This file was deleted.

7 changes: 0 additions & 7 deletions tests/crashes/140332.rs

This file was deleted.

14 changes: 14 additions & 0 deletions tests/ui/mir/static-by-value-dyn.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//! Regression test for #121176
//! KnownPanicsLint used to assert ABI compatibility in the interpreter,
//! which ICEs with unsized statics.
//@ needs-rustc-debug-assertions

use std::fmt::Debug;

static STATIC_1: dyn Debug + Sync = *();
Copy link
Member

@RalfJung RalfJung Jul 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For instance, this is a clearly ill-formed static. Nothing should ever look at its MIR. Trying to make the MIR interpreter APIs resistant against bogus MIR is a pointless game of whack-a-mole.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea those cases are straight forward to prevent within type_of, we don't even need to compute the layout, just doing a sizedness check.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That doesn't quite work since we allow extern statics that have extern types, which are unsized.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, we can check the tail manually for slices and dyn trait

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But that requires unfolding the type which will trigger the same cycle error, won't it?

//~^ ERROR the size for values of type `(dyn Debug + Sync + 'static)` cannot be known
//~| ERROR type `()` cannot be dereferenced

fn main() {
println!("{:?}", &STATIC_1);
}
19 changes: 19 additions & 0 deletions tests/ui/mir/static-by-value-dyn.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
error[E0277]: the size for values of type `(dyn Debug + Sync + 'static)` cannot be known at compilation time
--> $DIR/static-by-value-dyn.rs:8:1
|
LL | static STATIC_1: dyn Debug + Sync = *();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `(dyn Debug + Sync + 'static)`
= note: statics and constants must have a statically known size

error[E0614]: type `()` cannot be dereferenced
--> $DIR/static-by-value-dyn.rs:8:37
|
LL | static STATIC_1: dyn Debug + Sync = *();
| ^^^ can't be dereferenced

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0277, E0614.
For more information about an error, try `rustc --explain E0277`.
13 changes: 13 additions & 0 deletions tests/ui/mir/static-by-value-slice.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//! Regression test for #140332
//! KnownPanicsLint used to assert ABI compatibility in the interpreter,
//! which ICEs with unsized statics.

static mut S: [i8] = ["Some thing"; 1];
//~^ ERROR the size for values of type `[i8]` cannot be known
//~| ERROR mismatched types
//~| ERROR mismatched types

fn main() {
assert_eq!(S, [0; 1]);
//~^ ERROR use of mutable static is unsafe
}
33 changes: 33 additions & 0 deletions tests/ui/mir/static-by-value-slice.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
error[E0277]: the size for values of type `[i8]` cannot be known at compilation time
--> $DIR/static-by-value-slice.rs:5:1
|
LL | static mut S: [i8] = ["Some thing"; 1];
| ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[i8]`
= note: statics and constants must have a statically known size

error[E0308]: mismatched types
--> $DIR/static-by-value-slice.rs:5:23
|
LL | static mut S: [i8] = ["Some thing"; 1];
| ^^^^^^^^^^^^ expected `i8`, found `&str`

error[E0308]: mismatched types
--> $DIR/static-by-value-slice.rs:5:22
|
LL | static mut S: [i8] = ["Some thing"; 1];
| ^^^^^^^^^^^^^^^^^ expected `[i8]`, found `[i8; 1]`

error[E0133]: use of mutable static is unsafe and requires unsafe function or block
--> $DIR/static-by-value-slice.rs:11:16
|
LL | assert_eq!(S, [0; 1]);
| ^ use of mutable static
|
= note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior

error: aborting due to 4 previous errors

Some errors have detailed explanations: E0133, E0277, E0308.
For more information about an error, try `rustc --explain E0133`.
17 changes: 17 additions & 0 deletions tests/ui/mir/static-by-value-str.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//! Regression test for #139872
//! KnownPanicsLint used to assert ABI compatibility in the interpreter,
//! which ICEs with unsized statics.

enum E {
V16(u16),
V32(u32),
}

static C: (E, u16, str) = (E::V16(0xDEAD), 0x600D, 0xBAD);
//~^ ERROR the size for values of type `str` cannot be known
//~| ERROR the size for values of type `str` cannot be known
//~| ERROR mismatched types

pub fn main() {
let (_, n, _) = C;
}
30 changes: 30 additions & 0 deletions tests/ui/mir/static-by-value-str.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/static-by-value-str.rs:10:1
|
LL | static C: (E, u16, str) = (E::V16(0xDEAD), 0x600D, 0xBAD);
| ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `(E, u16, str)`, the trait `Sized` is not implemented for `str`
= note: required because it appears within the type `(E, u16, str)`
= note: statics and constants must have a statically known size

error[E0308]: mismatched types
--> $DIR/static-by-value-str.rs:10:52
|
LL | static C: (E, u16, str) = (E::V16(0xDEAD), 0x600D, 0xBAD);
| ^^^^^ expected `str`, found integer

error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/static-by-value-str.rs:10:27
|
LL | static C: (E, u16, str) = (E::V16(0xDEAD), 0x600D, 0xBAD);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `(E, u16, str)`, the trait `Sized` is not implemented for `str`
= note: required because it appears within the type `(E, u16, str)`
= note: tuples must have a statically known size to be initialized

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.