Skip to content

Commit 661e8be

Browse files
committed
Auto merge of #95291 - Dylan-DPC:rollup-vrb4wlw, r=Dylan-DPC
Rollup of 5 pull requests Successful merges: - #94391 (Fix ice when error reporting recursion errors) - #94655 (Clarify which kinds of MIR are allowed during which phases.) - #95179 (Try to evaluate in try unify and postpone resolution of constants that contain inference variables) - #95270 (debuginfo: Fix debuginfo for Box<T> where T is unsized.) - #95276 (add diagnostic items for clippy's `trim_split_whitespace`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 7941b3f + 3716c42 commit 661e8be

File tree

33 files changed

+497
-352
lines changed

33 files changed

+497
-352
lines changed

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,13 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>(
166166
pointee_type: Ty<'tcx>,
167167
unique_type_id: UniqueTypeId<'tcx>,
168168
) -> DINodeCreationResult<'ll> {
169+
// The debuginfo generated by this function is only valid if `ptr_type` is really just
170+
// a (fat) pointer. Make sure it is not called for e.g. `Box<T, NonZSTAllocator>`.
171+
debug_assert_eq!(
172+
cx.size_and_align_of(ptr_type),
173+
cx.size_and_align_of(cx.tcx.mk_mut_ptr(pointee_type))
174+
);
175+
169176
let pointee_type_di_node = type_di_node(cx, pointee_type);
170177

171178
return_if_di_node_created_in_meantime!(cx, unique_type_id);
@@ -212,7 +219,17 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>(
212219
DIFlags::FlagZero,
213220
),
214221
|cx, owner| {
215-
let layout = cx.layout_of(ptr_type);
222+
// FIXME: If this fat pointer is a `Box` then we don't want to use its
223+
// type layout and instead use the layout of the raw pointer inside
224+
// of it.
225+
// The proper way to handle this is to not treat Box as a pointer
226+
// at all and instead emit regular struct debuginfo for it. We just
227+
// need to make sure that we don't break existing debuginfo consumers
228+
// by doing that (at least not without a warning period).
229+
let layout_type =
230+
if ptr_type.is_box() { cx.tcx.mk_mut_ptr(pointee_type) } else { ptr_type };
231+
232+
let layout = cx.layout_of(layout_type);
216233
let addr_field = layout.field(cx, abi::FAT_PTR_ADDR);
217234
let extra_field = layout.field(cx, abi::FAT_PTR_EXTRA);
218235

compiler/rustc_const_eval/src/transform/promote_consts.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ pub struct PromoteTemps<'tcx> {
4242

4343
impl<'tcx> MirPass<'tcx> for PromoteTemps<'tcx> {
4444
fn phase_change(&self) -> Option<MirPhase> {
45-
Some(MirPhase::ConstPromotion)
45+
Some(MirPhase::ConstsPromoted)
4646
}
4747

4848
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {

compiler/rustc_const_eval/src/transform/validate.rs

+47-27
Original file line numberDiff line numberDiff line change
@@ -266,30 +266,23 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
266266
);
267267
}
268268
}
269-
// The deaggregator currently does not deaggreagate arrays.
270-
// So for now, we ignore them here.
271-
Rvalue::Aggregate(box AggregateKind::Array { .. }, _) => {}
272-
// All other aggregates must be gone after some phases.
273-
Rvalue::Aggregate(box kind, _) => {
274-
if self.mir_phase > MirPhase::DropLowering
275-
&& !matches!(kind, AggregateKind::Generator(..))
276-
{
277-
// Generators persist until the state machine transformation, but all
278-
// other aggregates must have been lowered.
279-
self.fail(
280-
location,
281-
format!("{:?} have been lowered to field assignments", rvalue),
282-
)
283-
} else if self.mir_phase > MirPhase::GeneratorLowering {
284-
// No more aggregates after drop and generator lowering.
269+
Rvalue::Aggregate(agg_kind, _) => {
270+
let disallowed = match **agg_kind {
271+
AggregateKind::Array(..) => false,
272+
AggregateKind::Generator(..) => {
273+
self.mir_phase >= MirPhase::GeneratorsLowered
274+
}
275+
_ => self.mir_phase >= MirPhase::Deaggregated,
276+
};
277+
if disallowed {
285278
self.fail(
286279
location,
287280
format!("{:?} have been lowered to field assignments", rvalue),
288281
)
289282
}
290283
}
291284
Rvalue::Ref(_, BorrowKind::Shallow, _) => {
292-
if self.mir_phase > MirPhase::DropLowering {
285+
if self.mir_phase >= MirPhase::DropsLowered {
293286
self.fail(
294287
location,
295288
"`Assign` statement with a `Shallow` borrow should have been removed after drop lowering phase",
@@ -300,15 +293,15 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
300293
}
301294
}
302295
StatementKind::AscribeUserType(..) => {
303-
if self.mir_phase > MirPhase::DropLowering {
296+
if self.mir_phase >= MirPhase::DropsLowered {
304297
self.fail(
305298
location,
306299
"`AscribeUserType` should have been removed after drop lowering phase",
307300
);
308301
}
309302
}
310303
StatementKind::FakeRead(..) => {
311-
if self.mir_phase > MirPhase::DropLowering {
304+
if self.mir_phase >= MirPhase::DropsLowered {
312305
self.fail(
313306
location,
314307
"`FakeRead` should have been removed after drop lowering phase",
@@ -351,10 +344,18 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
351344
self.fail(location, format!("bad arg ({:?} != usize)", op_cnt_ty))
352345
}
353346
}
354-
StatementKind::SetDiscriminant { .. }
355-
| StatementKind::StorageLive(..)
347+
StatementKind::SetDiscriminant { .. } => {
348+
if self.mir_phase < MirPhase::DropsLowered {
349+
self.fail(location, "`SetDiscriminant` is not allowed until drop elaboration");
350+
}
351+
}
352+
StatementKind::Retag(_, _) => {
353+
// FIXME(JakobDegen) The validator should check that `self.mir_phase <
354+
// DropsLowered`. However, this causes ICEs with generation of drop shims, which
355+
// seem to fail to set their `MirPhase` correctly.
356+
}
357+
StatementKind::StorageLive(..)
356358
| StatementKind::StorageDead(..)
357-
| StatementKind::Retag(_, _)
358359
| StatementKind::Coverage(_)
359360
| StatementKind::Nop => {}
360361
}
@@ -424,10 +425,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
424425
}
425426
}
426427
TerminatorKind::DropAndReplace { target, unwind, .. } => {
427-
if self.mir_phase > MirPhase::DropLowering {
428+
if self.mir_phase >= MirPhase::DropsLowered {
428429
self.fail(
429430
location,
430-
"`DropAndReplace` is not permitted to exist after drop elaboration",
431+
"`DropAndReplace` should have been removed during drop elaboration",
431432
);
432433
}
433434
self.check_edge(location, *target, EdgeKind::Normal);
@@ -494,7 +495,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
494495
}
495496
}
496497
TerminatorKind::Yield { resume, drop, .. } => {
497-
if self.mir_phase > MirPhase::GeneratorLowering {
498+
if self.mir_phase >= MirPhase::GeneratorsLowered {
498499
self.fail(location, "`Yield` should have been replaced by generator lowering");
499500
}
500501
self.check_edge(location, *resume, EdgeKind::Normal);
@@ -503,10 +504,22 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
503504
}
504505
}
505506
TerminatorKind::FalseEdge { real_target, imaginary_target } => {
507+
if self.mir_phase >= MirPhase::DropsLowered {
508+
self.fail(
509+
location,
510+
"`FalseEdge` should have been removed after drop elaboration",
511+
);
512+
}
506513
self.check_edge(location, *real_target, EdgeKind::Normal);
507514
self.check_edge(location, *imaginary_target, EdgeKind::Normal);
508515
}
509516
TerminatorKind::FalseUnwind { real_target, unwind } => {
517+
if self.mir_phase >= MirPhase::DropsLowered {
518+
self.fail(
519+
location,
520+
"`FalseUnwind` should have been removed after drop elaboration",
521+
);
522+
}
510523
self.check_edge(location, *real_target, EdgeKind::Normal);
511524
if let Some(unwind) = unwind {
512525
self.check_edge(location, *unwind, EdgeKind::Unwind);
@@ -520,12 +533,19 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
520533
self.check_edge(location, *cleanup, EdgeKind::Unwind);
521534
}
522535
}
536+
TerminatorKind::GeneratorDrop => {
537+
if self.mir_phase >= MirPhase::GeneratorsLowered {
538+
self.fail(
539+
location,
540+
"`GeneratorDrop` should have been replaced by generator lowering",
541+
);
542+
}
543+
}
523544
// Nothing to validate for these.
524545
TerminatorKind::Resume
525546
| TerminatorKind::Abort
526547
| TerminatorKind::Return
527-
| TerminatorKind::Unreachable
528-
| TerminatorKind::GeneratorDrop => {}
548+
| TerminatorKind::Unreachable => {}
529549
}
530550

531551
self.super_terminator(terminator, location);

compiler/rustc_infer/src/infer/mod.rs

+22-6
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
2020
use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues};
2121
use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
2222
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType};
23-
use rustc_middle::mir::interpret::ErrorHandled;
24-
use rustc_middle::mir::interpret::EvalToConstValueResult;
23+
use rustc_middle::mir::interpret::{ErrorHandled, EvalToConstValueResult};
2524
use rustc_middle::traits::select;
2625
use rustc_middle::ty::error::{ExpectedFound, TypeError};
2726
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
@@ -71,7 +70,6 @@ mod sub;
7170
pub mod type_variable;
7271
mod undo_log;
7372

74-
use crate::infer::canonical::OriginalQueryValues;
7573
pub use rustc_middle::infer::unify_key;
7674

7775
#[must_use]
@@ -687,15 +685,28 @@ pub struct CombinedSnapshot<'a, 'tcx> {
687685
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
688686
/// calls `tcx.try_unify_abstract_consts` after
689687
/// canonicalizing the consts.
688+
#[instrument(skip(self), level = "debug")]
690689
pub fn try_unify_abstract_consts(
691690
&self,
692691
a: ty::Unevaluated<'tcx, ()>,
693692
b: ty::Unevaluated<'tcx, ()>,
693+
param_env: ty::ParamEnv<'tcx>,
694694
) -> bool {
695-
let canonical = self.canonicalize_query((a, b), &mut OriginalQueryValues::default());
696-
debug!("canonical consts: {:?}", &canonical.value);
695+
// Reject any attempt to unify two unevaluated constants that contain inference
696+
// variables, since inference variables in queries lead to ICEs.
697+
if a.substs.has_infer_types_or_consts()
698+
|| b.substs.has_infer_types_or_consts()
699+
|| param_env.has_infer_types_or_consts()
700+
{
701+
debug!("a or b or param_env contain infer vars in its substs -> cannot unify");
702+
return false;
703+
}
704+
705+
let param_env_and = param_env.and((a, b));
706+
let erased = self.tcx.erase_regions(param_env_and);
707+
debug!("after erase_regions: {:?}", erased);
697708

698-
self.tcx.try_unify_abstract_consts(canonical.value)
709+
self.tcx.try_unify_abstract_consts(erased)
699710
}
700711

701712
pub fn is_in_snapshot(&self) -> bool {
@@ -1598,22 +1609,27 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
15981609
///
15991610
/// This handles inferences variables within both `param_env` and `substs` by
16001611
/// performing the operation on their respective canonical forms.
1612+
#[instrument(skip(self), level = "debug")]
16011613
pub fn const_eval_resolve(
16021614
&self,
16031615
param_env: ty::ParamEnv<'tcx>,
16041616
unevaluated: ty::Unevaluated<'tcx>,
16051617
span: Option<Span>,
16061618
) -> EvalToConstValueResult<'tcx> {
16071619
let substs = self.resolve_vars_if_possible(unevaluated.substs);
1620+
debug!(?substs);
16081621

16091622
// Postpone the evaluation of constants whose substs depend on inference
16101623
// variables
16111624
if substs.has_infer_types_or_consts() {
1625+
debug!("substs have infer types or consts: {:?}", substs);
16121626
return Err(ErrorHandled::TooGeneric);
16131627
}
16141628

16151629
let param_env_erased = self.tcx.erase_regions(param_env);
16161630
let substs_erased = self.tcx.erase_regions(substs);
1631+
debug!(?param_env_erased);
1632+
debug!(?substs_erased);
16171633

16181634
let unevaluated = ty::Unevaluated {
16191635
def: unevaluated.def,

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

+11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use super::{ErrorHandled, EvalToConstValueResult, GlobalId};
22

33
use crate::mir;
4+
use crate::ty::fold::TypeFoldable;
45
use crate::ty::subst::InternalSubsts;
56
use crate::ty::{self, TyCtxt};
67
use rustc_hir::def_id::DefId;
@@ -38,6 +39,16 @@ impl<'tcx> TyCtxt<'tcx> {
3839
ct: ty::Unevaluated<'tcx>,
3940
span: Option<Span>,
4041
) -> EvalToConstValueResult<'tcx> {
42+
// Cannot resolve `Unevaluated` constants that contain inference
43+
// variables. We reject those here since `resolve_opt_const_arg`
44+
// would fail otherwise.
45+
//
46+
// When trying to evaluate constants containing inference variables,
47+
// use `Infcx::const_eval_resolve` instead.
48+
if ct.substs.has_infer_types_or_consts() {
49+
bug!("did not expect inference variables here");
50+
}
51+
4152
match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs) {
4253
Ok(Some(instance)) => {
4354
let cid = GlobalId { instance, promoted: ct.promoted };

0 commit comments

Comments
 (0)