Skip to content

Commit 2cde638

Browse files
committed
stop using ParamEnv::reveal while handling MIR
1 parent 563c473 commit 2cde638

File tree

14 files changed

+100
-60
lines changed

14 files changed

+100
-60
lines changed

compiler/rustc_const_eval/src/check_consts/check.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
589589
// Typeck only does a "non-const" check since it operates on HIR and cannot distinguish
590590
// which path expressions are getting called on and which path expressions are only used
591591
// as function pointers. This is required for correctness.
592-
let infcx = tcx.infer_ctxt().build(body.phase.typing_mode());
592+
let infcx = tcx.infer_ctxt().build(body.typing_mode(tcx));
593593
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
594594

595595
let predicates = tcx.predicates_of(callee).instantiate(tcx, fn_args);

compiler/rustc_const_eval/src/check_consts/ops.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
116116
let obligation =
117117
Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref);
118118

119-
let infcx = tcx.infer_ctxt().build(body.phase.typing_mode());
119+
let infcx = tcx.infer_ctxt().build(body.typing_mode(tcx));
120120
let mut selcx = SelectionContext::new(&infcx);
121121
let implsrc = selcx.select(&obligation);
122122

compiler/rustc_const_eval/src/interpret/eval_context.rs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use rustc_errors::DiagCtxtHandle;
33
use rustc_hir::def_id::DefId;
44
use rustc_infer::infer::TyCtxtInferExt;
55
use rustc_infer::infer::at::ToTrace;
6-
use rustc_infer::traits::ObligationCause;
6+
use rustc_infer::traits::{ObligationCause, Reveal};
77
use rustc_middle::mir::interpret::{ErrorHandled, InvalidMetaKind, ReportedErrorInfo};
88
use rustc_middle::query::TyCtxtAt;
99
use rustc_middle::ty::layout::{
@@ -116,6 +116,7 @@ impl<'tcx, M: Machine<'tcx>> FnAbiOfHelpers<'tcx> for InterpCx<'tcx, M> {
116116
/// This test should be symmetric, as it is primarily about layout compatibility.
117117
pub(super) fn mir_assign_valid_types<'tcx>(
118118
tcx: TyCtxt<'tcx>,
119+
typing_mode: TypingMode<'tcx>,
119120
param_env: ParamEnv<'tcx>,
120121
src: TyAndLayout<'tcx>,
121122
dest: TyAndLayout<'tcx>,
@@ -124,7 +125,7 @@ pub(super) fn mir_assign_valid_types<'tcx>(
124125
// all normal lifetimes are erased, higher-ranked types with their
125126
// late-bound lifetimes are still around and can lead to type
126127
// differences.
127-
if util::relate_types(tcx, param_env, Variance::Covariant, src.ty, dest.ty) {
128+
if util::relate_types(tcx, typing_mode, param_env, Variance::Covariant, src.ty, dest.ty) {
128129
// Make sure the layout is equal, too -- just to be safe. Miri really
129130
// needs layout equality. For performance reason we skip this check when
130131
// the types are equal. Equal types *can* have different layouts when
@@ -144,6 +145,7 @@ pub(super) fn mir_assign_valid_types<'tcx>(
144145
#[cfg_attr(not(debug_assertions), inline(always))]
145146
pub(super) fn from_known_layout<'tcx>(
146147
tcx: TyCtxtAt<'tcx>,
148+
typing_mode: TypingMode<'tcx>,
147149
param_env: ParamEnv<'tcx>,
148150
known_layout: Option<TyAndLayout<'tcx>>,
149151
compute: impl FnOnce() -> InterpResult<'tcx, TyAndLayout<'tcx>>,
@@ -153,7 +155,13 @@ pub(super) fn from_known_layout<'tcx>(
153155
Some(known_layout) => {
154156
if cfg!(debug_assertions) {
155157
let check_layout = compute()?;
156-
if !mir_assign_valid_types(tcx.tcx, param_env, check_layout, known_layout) {
158+
if !mir_assign_valid_types(
159+
tcx.tcx,
160+
typing_mode,
161+
param_env,
162+
check_layout,
163+
known_layout,
164+
) {
157165
span_bug!(
158166
tcx.span,
159167
"expected type differs from actual type.\nexpected: {}\nactual: {}",
@@ -203,6 +211,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
203211
}
204212
}
205213

214+
pub fn typing_mode(&self) -> TypingMode<'tcx> {
215+
debug_assert_eq!(self.param_env.reveal(), Reveal::All);
216+
TypingMode::PostAnalysis
217+
}
218+
206219
/// Returns the span of the currently executed statement/terminator.
207220
/// This is the span typically used for error reporting.
208221
#[inline(always)]
@@ -327,7 +340,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
327340
return true;
328341
}
329342
// Slow path: spin up an inference context to check if these traits are sufficiently equal.
330-
let infcx = self.tcx.infer_ctxt().build(TypingMode::from_param_env(self.param_env));
343+
let infcx = self.tcx.infer_ctxt().build(self.typing_mode());
331344
let ocx = ObligationCtxt::new(&infcx);
332345
let cause = ObligationCause::dummy_with_span(self.cur_span());
333346
// equate the two trait refs after normalization

compiler/rustc_const_eval/src/interpret/operand.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
773773
)?;
774774
if !mir_assign_valid_types(
775775
*self.tcx,
776+
self.typing_mode(),
776777
self.param_env,
777778
self.layout_of(normalized_place_ty)?,
778779
op.layout,
@@ -832,7 +833,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
832833
})
833834
};
834835
let layout =
835-
from_known_layout(self.tcx, self.param_env, layout, || self.layout_of(ty).into())?;
836+
from_known_layout(self.tcx, self.typing_mode(), self.param_env, layout, || {
837+
self.layout_of(ty).into()
838+
})?;
836839
let imm = match val_val {
837840
mir::ConstValue::Indirect { alloc_id, offset } => {
838841
// This is const data, no mutation allowed.

compiler/rustc_const_eval/src/interpret/place.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,7 @@ where
540540
)?;
541541
if !mir_assign_valid_types(
542542
*self.tcx,
543+
self.typing_mode(),
543544
self.param_env,
544545
self.layout_of(normalized_place_ty)?,
545546
place.layout,
@@ -870,8 +871,13 @@ where
870871
) -> InterpResult<'tcx> {
871872
// We do NOT compare the types for equality, because well-typed code can
872873
// actually "transmute" `&mut T` to `&T` in an assignment without a cast.
873-
let layout_compat =
874-
mir_assign_valid_types(*self.tcx, self.param_env, src.layout(), dest.layout());
874+
let layout_compat = mir_assign_valid_types(
875+
*self.tcx,
876+
self.typing_mode(),
877+
self.param_env,
878+
src.layout(),
879+
dest.layout(),
880+
);
875881
if !allow_transmute && !layout_compat {
876882
span_bug!(
877883
self.cur_span(),

compiler/rustc_const_eval/src/interpret/stack.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -596,12 +596,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
596596
return interp_ok(layout);
597597
}
598598

599-
let layout = from_known_layout(self.tcx, self.param_env, layout, || {
600-
let local_ty = frame.body.local_decls[local].ty;
601-
let local_ty =
602-
self.instantiate_from_frame_and_normalize_erasing_regions(frame, local_ty)?;
603-
self.layout_of(local_ty).into()
604-
})?;
599+
let layout =
600+
from_known_layout(self.tcx, self.typing_mode(), self.param_env, layout, || {
601+
let local_ty = frame.body.local_decls[local].ty;
602+
let local_ty =
603+
self.instantiate_from_frame_and_normalize_erasing_regions(frame, local_ty)?;
604+
self.layout_of(local_ty).into()
605+
})?;
605606

606607
// Layouts of locals are requested a lot, so we cache them.
607608
state.layout.set(Some(layout));

compiler/rustc_const_eval/src/util/compare_types.rs

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,15 @@ use rustc_middle::traits::ObligationCause;
88
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt, TypingMode, Variance};
99
use rustc_trait_selection::traits::ObligationCtxt;
1010

11-
/// Returns whether the two types are equal up to subtyping.
12-
///
13-
/// This is used in case we don't know the expected subtyping direction
14-
/// and still want to check whether anything is broken.
15-
pub fn is_equal_up_to_subtyping<'tcx>(
11+
/// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`.
12+
pub fn sub_types<'tcx>(
1613
tcx: TyCtxt<'tcx>,
14+
typing_mode: TypingMode<'tcx>,
1715
param_env: ParamEnv<'tcx>,
1816
src: Ty<'tcx>,
1917
dest: Ty<'tcx>,
2018
) -> bool {
21-
// Fast path.
22-
if src == dest {
23-
return true;
24-
}
25-
26-
// Check for subtyping in either direction.
27-
relate_types(tcx, param_env, Variance::Covariant, src, dest)
28-
|| relate_types(tcx, param_env, Variance::Covariant, dest, src)
19+
relate_types(tcx, typing_mode, param_env, Variance::Covariant, src, dest)
2920
}
3021

3122
/// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`.
@@ -35,6 +26,7 @@ pub fn is_equal_up_to_subtyping<'tcx>(
3526
/// because we want to check for type equality.
3627
pub fn relate_types<'tcx>(
3728
tcx: TyCtxt<'tcx>,
29+
typing_mode: TypingMode<'tcx>,
3830
param_env: ParamEnv<'tcx>,
3931
variance: Variance,
4032
src: Ty<'tcx>,
@@ -45,8 +37,7 @@ pub fn relate_types<'tcx>(
4537
}
4638

4739
let mut builder = tcx.infer_ctxt().ignoring_regions();
48-
// FIXME(#132279): This should eventually use the already defined hidden types.
49-
let infcx = builder.build(TypingMode::from_param_env(param_env));
40+
let infcx = builder.build(typing_mode);
5041
let ocx = ObligationCtxt::new(&infcx);
5142
let cause = ObligationCause::dummy();
5243
let src = ocx.normalize(&cause, param_env, src);

compiler/rustc_const_eval/src/util/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ mod type_name;
88

99
pub use self::alignment::{is_disaligned, is_within_packed};
1010
pub use self::check_validity_requirement::check_validity_requirement;
11-
pub use self::compare_types::{is_equal_up_to_subtyping, relate_types};
11+
pub use self::compare_types::{relate_types, sub_types};
1212
pub use self::type_name::type_name;
1313

1414
/// Classify whether an operator is "left-homogeneous", i.e., the LHS has the

compiler/rustc_middle/src/mir/mod.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use crate::ty::fold::{FallibleTypeFolder, TypeFoldable};
3939
use crate::ty::print::{FmtPrinter, Printer, pretty_print_const, with_no_trimmed_paths};
4040
use crate::ty::visit::TypeVisitableExt;
4141
use crate::ty::{
42-
self, AdtDef, GenericArg, GenericArgsRef, Instance, InstanceKind, List, Ty, TyCtxt,
42+
self, AdtDef, GenericArg, GenericArgsRef, Instance, InstanceKind, List, Ty, TyCtxt, TypingMode,
4343
UserTypeAnnotationIndex,
4444
};
4545

@@ -452,6 +452,15 @@ impl<'tcx> Body<'tcx> {
452452
self.basic_blocks.as_mut()
453453
}
454454

455+
pub fn typing_mode(&self, _tcx: TyCtxt<'tcx>) -> TypingMode<'tcx> {
456+
match self.phase {
457+
// FIXME(#132279): the MIR is quite clearly inside of a body, so we
458+
// should instead reveal opaques defined by that body here.
459+
MirPhase::Built | MirPhase::Analysis(_) => TypingMode::non_body_analysis(),
460+
MirPhase::Runtime(_) => TypingMode::PostAnalysis,
461+
}
462+
}
463+
455464
#[inline]
456465
pub fn local_kind(&self, local: Local) -> LocalKind {
457466
let index = local.as_usize();

compiler/rustc_middle/src/mir/syntax.rs

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@ use smallvec::SmallVec;
2020
use super::{BasicBlock, Const, Local, UserTypeProjection};
2121
use crate::mir::coverage::CoverageKind;
2222
use crate::ty::adjustment::PointerCoercion;
23-
use crate::ty::{
24-
self, GenericArgsRef, List, Region, Ty, TyCtxt, TypingMode, UserTypeAnnotationIndex,
25-
};
23+
use crate::ty::{self, GenericArgsRef, List, Region, Ty, TyCtxt, UserTypeAnnotationIndex};
2624

2725
/// Represents the "flavors" of MIR.
2826
///
@@ -103,20 +101,10 @@ impl MirPhase {
103101
}
104102
}
105103

106-
pub fn typing_mode<'tcx>(&self) -> TypingMode<'tcx> {
107-
match self {
108-
// FIXME(#132279): the MIR is quite clearly inside of a body, so we
109-
// should instead reveal opaques defined by that body here.
110-
MirPhase::Built | MirPhase::Analysis(_) => TypingMode::non_body_analysis(),
111-
MirPhase::Runtime(_) => TypingMode::PostAnalysis,
112-
}
113-
}
114-
115104
pub fn param_env<'tcx>(&self, tcx: TyCtxt<'tcx>, body_def_id: DefId) -> ty::ParamEnv<'tcx> {
116-
match self.typing_mode() {
117-
TypingMode::Coherence => unreachable!(),
118-
TypingMode::Analysis { defining_opaque_types: _ } => tcx.param_env(body_def_id),
119-
TypingMode::PostAnalysis => tcx.param_env_reveal_all_normalized(body_def_id),
105+
match self {
106+
MirPhase::Built | MirPhase::Analysis(_) => tcx.param_env(body_def_id),
107+
MirPhase::Runtime(_) => tcx.param_env_reveal_all_normalized(body_def_id),
120108
}
121109
}
122110
}

compiler/rustc_mir_transform/src/inline.rs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,13 @@ impl<'tcx> Inliner<'tcx> {
244244
// Normally, this shouldn't be required, but trait normalization failure can create a
245245
// validation ICE.
246246
let output_type = callee_body.return_ty();
247-
if !util::relate_types(self.tcx, self.param_env, ty::Covariant, output_type, destination_ty)
248-
{
247+
if !util::sub_types(
248+
self.tcx,
249+
caller_body.typing_mode(self.tcx),
250+
self.param_env,
251+
output_type,
252+
destination_ty,
253+
) {
249254
trace!(?output_type, ?destination_ty);
250255
return Err("failed to normalize return type");
251256
}
@@ -275,8 +280,13 @@ impl<'tcx> Inliner<'tcx> {
275280
self_arg_ty.into_iter().chain(arg_tuple_tys).zip(callee_body.args_iter())
276281
{
277282
let input_type = callee_body.local_decls[input].ty;
278-
if !util::relate_types(self.tcx, self.param_env, ty::Covariant, input_type, arg_ty)
279-
{
283+
if !util::sub_types(
284+
self.tcx,
285+
caller_body.typing_mode(self.tcx),
286+
self.param_env,
287+
input_type,
288+
arg_ty,
289+
) {
280290
trace!(?arg_ty, ?input_type);
281291
return Err("failed to normalize tuple argument type");
282292
}
@@ -285,8 +295,13 @@ impl<'tcx> Inliner<'tcx> {
285295
for (arg, input) in args.iter().zip(callee_body.args_iter()) {
286296
let input_type = callee_body.local_decls[input].ty;
287297
let arg_ty = arg.node.ty(&caller_body.local_decls, self.tcx);
288-
if !util::relate_types(self.tcx, self.param_env, ty::Covariant, input_type, arg_ty)
289-
{
298+
if !util::sub_types(
299+
self.tcx,
300+
caller_body.typing_mode(self.tcx),
301+
self.param_env,
302+
input_type,
303+
arg_ty,
304+
) {
290305
trace!(?arg_ty, ?input_type);
291306
return Err("failed to normalize argument type");
292307
}

compiler/rustc_mir_transform/src/validate.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use rustc_target::spec::abi::Abi;
2020
use rustc_trait_selection::traits::ObligationCtxt;
2121
use rustc_type_ir::Upcast;
2222

23-
use crate::util::{is_within_packed, relate_types};
23+
use crate::util::{self, is_within_packed};
2424

2525
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
2626
enum EdgeKind {
@@ -583,7 +583,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
583583
Variance::Covariant
584584
};
585585

586-
crate::util::relate_types(self.tcx, self.param_env, variance, src, dest)
586+
crate::util::relate_types(
587+
self.tcx,
588+
self.body.typing_mode(self.tcx),
589+
self.param_env,
590+
variance,
591+
src,
592+
dest,
593+
)
587594
}
588595

589596
/// Check that the given predicate definitely holds in the param-env of this MIR body.
@@ -602,7 +609,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
602609
return true;
603610
}
604611

605-
let infcx = self.tcx.infer_ctxt().build(self.body.phase.typing_mode());
612+
let infcx = self.tcx.infer_ctxt().build(self.body.typing_mode(self.tcx));
606613
let ocx = ObligationCtxt::new(&infcx);
607614
ocx.register_obligation(Obligation::new(
608615
self.tcx,
@@ -794,10 +801,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
794801
}
795802
}
796803
ProjectionElem::Subtype(ty) => {
797-
if !relate_types(
804+
if !util::sub_types(
798805
self.tcx,
806+
self.body.typing_mode(self.tcx),
799807
self.param_env,
800-
Variance::Covariant,
801808
ty,
802809
place_ref.ty(&self.body.local_decls, self.tcx).ty,
803810
) {

compiler/rustc_type_ir/src/infer_ctxt.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ use crate::{self as ty, Interner};
1212
/// The current typing mode of an inference context. We unfortunately have some
1313
/// slightly different typing rules depending on the current context. See the
1414
/// doc comment for each variant for how and why they are used.
15+
///
16+
/// In most cases you can get the correct typing mode automically via:
17+
/// - `mir::Body::typing_mode`
18+
/// - `rustc_lint::LateContext::typing_mode`
19+
///
20+
/// If neither of these functions are available, feel free to reach out to
21+
/// t-types for help.
1522
#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
1623
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
1724
pub enum TypingMode<I: Interner> {

src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ fn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx>
420420
TraitRef::new(tcx, tcx.require_lang_item(LangItem::Destruct, Some(body.span)), [ty]),
421421
);
422422

423-
let infcx = tcx.infer_ctxt().build(body.phase.typing_mode());
423+
let infcx = tcx.infer_ctxt().build(body.typing_mode(tcx));
424424
let mut selcx = SelectionContext::new(&infcx);
425425
let Some(impl_src) = selcx.select(&obligation).ok().flatten() else {
426426
return false;

0 commit comments

Comments
 (0)