summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_const_eval/src/transform/validate.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
commit9835e2ae736235810b4ea1c162ca5e65c547e770 (patch)
tree3fcebf40ed70e581d776a8a4c65923e8ec20e026 /compiler/rustc_const_eval/src/transform/validate.rs
parentReleasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff)
downloadrustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz
rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_const_eval/src/transform/validate.rs')
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs82
1 files changed, 64 insertions, 18 deletions
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index d4bed9738..3c350e25b 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -2,15 +2,16 @@
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_index::bit_set::BitSet;
-use rustc_index::vec::IndexVec;
+use rustc_index::IndexVec;
use rustc_infer::traits::Reveal;
use rustc_middle::mir::interpret::Scalar;
use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor};
use rustc_middle::mir::{
traversal, BasicBlock, BinOp, Body, BorrowKind, CastKind, CopyNonOverlapping, Local, Location,
- MirPass, MirPhase, NonDivergingIntrinsic, Operand, Place, PlaceElem, PlaceRef, ProjectionElem,
- RetagKind, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind, Terminator,
- TerminatorKind, UnOp, UnwindAction, VarDebugInfo, VarDebugInfoContents, START_BLOCK,
+ MirPass, MirPhase, NonDivergingIntrinsic, NullOp, Operand, Place, PlaceElem, PlaceRef,
+ ProjectionElem, RetagKind, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind,
+ Terminator, TerminatorKind, UnOp, UnwindAction, VarDebugInfo, VarDebugInfoContents,
+ START_BLOCK,
};
use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt};
use rustc_mir_dataflow::impls::MaybeStorageLive;
@@ -106,7 +107,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
// occurred.
self.tcx.sess.diagnostic().delay_span_bug(
span,
- &format!(
+ format!(
"broken MIR in {:?} ({}) at {:?}:\n{}",
self.body.source.instance,
self.when,
@@ -163,7 +164,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
if let Some(root) = post_contract_node.get(&bb) {
break *root;
}
- let parent = doms.immediate_dominator(bb);
+ let parent = doms.immediate_dominator(bb).unwrap();
dom_path.push(bb);
if !self.body.basic_blocks[parent].is_cleanup {
break bb;
@@ -262,7 +263,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
// We sometimes have to use `defining_opaque_types` for subtyping
// to succeed here and figuring out how exactly that should work
// is annoying. It is harmless enough to just not validate anything
- // in that case. We still check this after analysis as all opque
+ // in that case. We still check this after analysis as all opaque
// types have been revealed at this point.
if (src, dest).has_opaque_types() {
return true;
@@ -447,7 +448,15 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
};
match debuginfo.value {
VarDebugInfoContents::Const(_) => {}
- VarDebugInfoContents::Place(place) => check_place(place),
+ VarDebugInfoContents::Place(place) => {
+ check_place(place);
+ if debuginfo.references != 0 && place.projection.last() == Some(&PlaceElem::Deref) {
+ self.fail(
+ START_BLOCK.start_location(),
+ format!("debuginfo {:?}, has both ref and deref", debuginfo),
+ );
+ }
+ }
VarDebugInfoContents::Composite { ty, ref fragments } => {
for f in fragments {
check_place(f.contents);
@@ -711,10 +720,54 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}
}
}
+ Rvalue::NullaryOp(NullOp::OffsetOf(fields), container) => {
+ let fail_out_of_bounds = |this: &Self, location, field, ty| {
+ this.fail(location, format!("Out of bounds field {field:?} for {ty:?}"));
+ };
+
+ let mut current_ty = *container;
+
+ for field in fields.iter() {
+ match current_ty.kind() {
+ ty::Tuple(fields) => {
+ let Some(&f_ty) = fields.get(field.as_usize()) else {
+ fail_out_of_bounds(self, location, field, current_ty);
+ return;
+ };
+
+ current_ty = self.tcx.normalize_erasing_regions(self.param_env, f_ty);
+ }
+ ty::Adt(adt_def, substs) => {
+ if adt_def.is_enum() {
+ self.fail(
+ location,
+ format!("Cannot get field offset from enum {current_ty:?}"),
+ );
+ return;
+ }
+
+ let Some(field) = adt_def.non_enum_variant().fields.get(field) else {
+ fail_out_of_bounds(self, location, field, current_ty);
+ return;
+ };
+
+ let f_ty = field.ty(self.tcx, substs);
+ current_ty = self.tcx.normalize_erasing_regions(self.param_env, f_ty);
+ }
+ _ => {
+ self.fail(
+ location,
+ format!("Cannot get field offset from non-adt type {current_ty:?}"),
+ );
+ return;
+ }
+ }
+ }
+ }
Rvalue::Repeat(_, _)
| Rvalue::ThreadLocalRef(_)
| Rvalue::AddressOf(_, _)
- | Rvalue::NullaryOp(_, _)
+ | Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _)
| Rvalue::Discriminant(_) => {}
}
self.super_rvalue(rvalue, location);
@@ -757,14 +810,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}
}
}
- StatementKind::PlaceMention(..) => {
- if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
- self.fail(
- location,
- "`PlaceMention` should have been removed after drop lowering phase",
- );
- }
- }
StatementKind::AscribeUserType(..) => {
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
self.fail(
@@ -874,6 +919,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
StatementKind::StorageDead(_)
| StatementKind::Coverage(_)
| StatementKind::ConstEvalCounter
+ | StatementKind::PlaceMention(..)
| StatementKind::Nop => {}
}
@@ -1056,7 +1102,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
if self.body.source_scopes.get(scope).is_none() {
self.tcx.sess.diagnostic().delay_span_bug(
self.body.span,
- &format!(
+ format!(
"broken MIR in {:?} ({}):\ninvalid source scope {:?}",
self.body.source.instance, self.when, scope,
),