Skip to content

Commit c57b351

Browse files
Rollup merge of #132403 - lcnr:typing-mode, r=compiler-errors
continue `TypingMode` refactor There are still quite a few places which (indirectly) rely on the `Reveal` of a `ParamEnv`, but we're slowly getting there r? `@compiler-errors`
2 parents 6da4221 + dc75066 commit c57b351

File tree

20 files changed

+155
-105
lines changed

20 files changed

+155
-105
lines changed

compiler/rustc_const_eval/src/check_consts/check.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc_middle::mir::visit::Visitor;
1616
use rustc_middle::mir::*;
1717
use rustc_middle::span_bug;
1818
use rustc_middle::ty::adjustment::PointerCoercion;
19-
use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TypeVisitableExt, TypingMode};
19+
use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TypeVisitableExt};
2020
use rustc_mir_dataflow::Analysis;
2121
use rustc_mir_dataflow::impls::MaybeStorageLive;
2222
use rustc_mir_dataflow::storage::always_storage_live_locals;
@@ -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(TypingMode::from_param_env(param_env));
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/mod.rs

-7
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,7 @@ impl<'mir, 'tcx> ConstCx<'mir, 'tcx> {
3232
pub fn new(tcx: TyCtxt<'tcx>, body: &'mir mir::Body<'tcx>) -> Self {
3333
let def_id = body.source.def_id().expect_local();
3434
let param_env = tcx.param_env(def_id);
35-
Self::new_with_param_env(tcx, body, param_env)
36-
}
3735

38-
pub fn new_with_param_env(
39-
tcx: TyCtxt<'tcx>,
40-
body: &'mir mir::Body<'tcx>,
41-
param_env: ty::ParamEnv<'tcx>,
42-
) -> Self {
4336
let const_kind = tcx.hir().body_const_context(body.source.def_id().expect_local());
4437
ConstCx { body, tcx, param_env, const_kind }
4538
}

compiler/rustc_const_eval/src/check_consts/ops.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_middle::mir::CallSource;
1212
use rustc_middle::span_bug;
1313
use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths};
1414
use rustc_middle::ty::{
15-
self, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef, Param, TraitRef, Ty, TypingMode,
15+
self, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef, Param, TraitRef, Ty,
1616
suggest_constraining_type_param,
1717
};
1818
use rustc_middle::util::{CallDesugaringKind, CallKind, call_kind};
@@ -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(TypingMode::from_param_env(param_env));
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

+17-4
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

+4-1
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

+8-2
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

+7-6
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

+6-15
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

+1-1
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

+10-1
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

+5-6
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,8 @@ use smallvec::SmallVec;
1919

2020
use super::{BasicBlock, Const, Local, UserTypeProjection};
2121
use crate::mir::coverage::CoverageKind;
22-
use crate::traits::Reveal;
2322
use crate::ty::adjustment::PointerCoercion;
24-
use crate::ty::{self, GenericArgsRef, List, Region, Ty, UserTypeAnnotationIndex};
23+
use crate::ty::{self, GenericArgsRef, List, Region, Ty, TyCtxt, UserTypeAnnotationIndex};
2524

2625
/// Represents the "flavors" of MIR.
2726
///
@@ -102,10 +101,10 @@ impl MirPhase {
102101
}
103102
}
104103

105-
pub fn reveal(&self) -> Reveal {
106-
match *self {
107-
MirPhase::Built | MirPhase::Analysis(_) => Reveal::UserFacing,
108-
MirPhase::Runtime(_) => Reveal::All,
104+
pub fn param_env<'tcx>(&self, tcx: TyCtxt<'tcx>, body_def_id: DefId) -> ty::ParamEnv<'tcx> {
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),
109108
}
110109
}
111110
}

compiler/rustc_mir_transform/src/inline.rs

+21-6
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
}

0 commit comments

Comments
 (0)