Skip to content

Commit a250112

Browse files
committed
Check static is sized when building MIR.
1 parent 53ae5c6 commit a250112

File tree

10 files changed

+62
-68
lines changed

10 files changed

+62
-68
lines changed

compiler/rustc_const_eval/src/interpret/operand.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -243,17 +243,6 @@ impl<'tcx, Prov: Provenance> std::ops::Deref for ImmTy<'tcx, Prov> {
243243
}
244244

245245
impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
246-
#[inline(always)]
247-
pub fn try_from_immediate(imm: Immediate<Prov>, layout: TyAndLayout<'tcx>) -> Option<Self> {
248-
let matches_abi = match (imm, layout.backend_repr) {
249-
(Immediate::Scalar(..), BackendRepr::Scalar(..)) => true,
250-
(Immediate::ScalarPair(..), BackendRepr::ScalarPair(..)) => true,
251-
(Immediate::Uninit, _) => layout.is_sized(),
252-
_ => false,
253-
};
254-
if matches_abi { Some(ImmTy { imm, layout }) } else { None }
255-
}
256-
257246
#[inline]
258247
pub fn from_scalar(val: Scalar<Prov>, layout: TyAndLayout<'tcx>) -> Self {
259248
debug_assert!(layout.backend_repr.is_scalar(), "`ImmTy::from_scalar` on non-scalar layout");

compiler/rustc_const_eval/src/interpret/place.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -313,14 +313,6 @@ impl<'tcx, Prov: Provenance> Projectable<'tcx, Prov> for PlaceTy<'tcx, Prov> {
313313

314314
// These are defined here because they produce a place.
315315
impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> {
316-
#[inline(always)]
317-
pub fn try_as_immediate(&self) -> Option<ImmTy<'tcx, Prov>> {
318-
match self.op() {
319-
Operand::Indirect(_) => None,
320-
Operand::Immediate(imm) => ImmTy::try_from_immediate(*imm, self.layout),
321-
}
322-
}
323-
324316
#[inline(always)]
325317
pub fn as_mplace_or_imm(&self) -> Either<MPlaceTy<'tcx, Prov>, ImmTy<'tcx, Prov>> {
326318
match self.op() {

compiler/rustc_mir_build/src/builder/custom/parse/instruction.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> {
309309
| ExprKind::ConstParam { .. }
310310
| ExprKind::ConstBlock { .. } => {
311311
Ok(Operand::Constant(Box::new(
312-
as_constant_inner(expr, |_| None, self.tcx)
312+
as_constant_inner(self.tcx, self.typing_env, expr, |_| None)
313313
)))
314314
},
315315
_ => self.parse_place(expr_id).map(Operand::Copy),
@@ -393,7 +393,7 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> {
393393
| ExprKind::NamedConst { .. }
394394
| ExprKind::NonHirLiteral { .. }
395395
| ExprKind::ConstBlock { .. } => Ok({
396-
let value = as_constant_inner(expr, |_| None, self.tcx);
396+
let value = as_constant_inner(self.tcx, self.typing_env, expr, |_| None);
397397
value.const_.eval_bits(self.tcx, self.typing_env)
398398
}),
399399
)

compiler/rustc_mir_build/src/builder/expr/as_constant.rs

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_middle::mir::*;
88
use rustc_middle::thir::*;
99
use rustc_middle::ty::{
1010
self, CanonicalUserType, CanonicalUserTypeAnnotation, Ty, TyCtxt, TypeVisitableExt as _,
11-
UserTypeAnnotationIndex,
11+
TypingEnv, UserTypeAnnotationIndex,
1212
};
1313
use rustc_middle::{bug, mir, span_bug};
1414
use tracing::{instrument, trace};
@@ -19,32 +19,27 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1919
/// Compile `expr`, yielding a compile-time constant. Assumes that
2020
/// `expr` is a valid compile-time constant!
2121
pub(crate) fn as_constant(&mut self, expr: &Expr<'tcx>) -> ConstOperand<'tcx> {
22-
let this = self;
23-
let tcx = this.tcx;
2422
let Expr { ty, temp_lifetime: _, span, ref kind } = *expr;
2523
match kind {
2624
ExprKind::Scope { region_scope: _, lint_level: _, value } => {
27-
this.as_constant(&this.thir[*value])
25+
self.as_constant(&self.thir[*value])
2826
}
29-
_ => as_constant_inner(
30-
expr,
31-
|user_ty| {
32-
Some(this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
33-
span,
34-
user_ty: user_ty.clone(),
35-
inferred_ty: ty,
36-
}))
37-
},
38-
tcx,
39-
),
27+
_ => as_constant_inner(self.tcx, self.typing_env(), expr, |user_ty| {
28+
Some(self.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
29+
span,
30+
user_ty: user_ty.clone(),
31+
inferred_ty: ty,
32+
}))
33+
}),
4034
}
4135
}
4236
}
4337

4438
pub(crate) fn as_constant_inner<'tcx>(
39+
tcx: TyCtxt<'tcx>,
40+
typing_env: TypingEnv<'tcx>,
4541
expr: &Expr<'tcx>,
4642
push_cuta: impl FnMut(&Box<CanonicalUserType<'tcx>>) -> Option<UserTypeAnnotationIndex>,
47-
tcx: TyCtxt<'tcx>,
4843
) -> ConstOperand<'tcx> {
4944
let Expr { ty, temp_lifetime: _, span, ref kind } = *expr;
5045
match *kind {
@@ -88,8 +83,19 @@ pub(crate) fn as_constant_inner<'tcx>(
8883
ConstOperand { user_ty: None, span, const_ }
8984
}
9085
ExprKind::StaticRef { alloc_id, ty, .. } => {
91-
let const_val = ConstValue::Scalar(Scalar::from_pointer(alloc_id.into(), &tcx));
92-
let const_ = Const::Val(const_val, ty);
86+
let pointee = ty.builtin_deref(true).expect("StaticRef's type must be pointer");
87+
let const_ = if pointee.is_sized(tcx, typing_env) {
88+
let const_val = ConstValue::Scalar(Scalar::from_pointer(alloc_id.into(), &tcx));
89+
Const::Val(const_val, ty)
90+
} else {
91+
// Ill-formed code may produce instances where `pointee` is not `Sized`.
92+
// This should be reported by wfcheck on the static itself.
93+
// Still, producing a single scalar constant would be inconsistent, as pointers to
94+
// non-`Sized` types are scalar pairs. Avoid an ICE by producing an error constant.
95+
let guar =
96+
tcx.dcx().span_delayed_bug(span, format!("static's type `{ty}` is not Sized"));
97+
Const::Ty(ty, ty::Const::new_error(tcx, guar))
98+
};
9399

94100
ConstOperand { span, user_ty: None, const_ }
95101
}

compiler/rustc_mir_transform/src/known_panics_lint.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
263263
// manually normalized.
264264
let val = self.tcx.try_normalize_erasing_regions(self.typing_env, c.const_).ok()?;
265265

266-
self.use_ecx(|this| this.ecx.eval_mir_constant(&val, c.span, None))?.try_as_immediate()
266+
self.use_ecx(|this| this.ecx.eval_mir_constant(&val, c.span, None))?
267+
.as_mplace_or_imm()
268+
.right()
267269
}
268270

269271
/// Returns the value, if any, of evaluating `place`.

tests/crashes/129109.rs

Lines changed: 0 additions & 10 deletions
This file was deleted.

tests/crashes/130970.rs

Lines changed: 0 additions & 9 deletions
This file was deleted.

tests/crashes/131347.rs

Lines changed: 0 additions & 9 deletions
This file was deleted.

tests/ui/mir/unsized-extern-static.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//! Regression test for #129109
2+
//! MIR building used to produce erroneous constants when referring to statics of unsized type.
3+
//@ compile-flags: -Zmir-enable-passes=+GVN -Zvalidate-mir
4+
5+
extern "C" {
6+
pub static mut symbol: [i8];
7+
//~^ ERROR the size for values of type `[i8]`
8+
}
9+
10+
fn main() {
11+
println!("C", unsafe { &symbol });
12+
//~^ ERROR argument never used
13+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error: argument never used
2+
--> $DIR/unsized-extern-static.rs:11:19
3+
|
4+
LL | println!("C", unsafe { &symbol });
5+
| --- ^^^^^^^^^^^^^^^^^^ argument never used
6+
| |
7+
| formatting specifier missing
8+
9+
error[E0277]: the size for values of type `[i8]` cannot be known at compilation time
10+
--> $DIR/unsized-extern-static.rs:6:5
11+
|
12+
LL | pub static mut symbol: [i8];
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
14+
|
15+
= help: the trait `Sized` is not implemented for `[i8]`
16+
= note: statics and constants must have a statically known size
17+
18+
error: aborting due to 2 previous errors
19+
20+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)