Auto merge of #132460 - lcnr:questionable-uwu, r=compiler-errors
Use `TypingMode` throughout the compiler instead of `ParamEnv` Hopefully the biggest single PR as part of https://github.com/rust-lang/types-team/issues/128. ## `infcx.typing_env` while defining opaque types I don't know how'll be able to correctly handle opaque types when using something taking a `TypingEnv` while defining opaque types. To correctly handle the opaques we need to be able to pass in the current `opaque_type_storage` and return constraints, i.e. we need to use a proper canonical query. We should migrate all the queries used during HIR typeck and borrowck where this matters to proper canonical queries. This is ## `layout_of` and `Reveal::All` We convert the `ParamEnv` to `Reveal::All` right at the start of the `layout_of` query, so I've changed callers of `layout_of` to already use a post analysis `TypingEnv` when encountering it.ca87b535a0/compiler/rustc_ty_utils/src/layout.rs (L51)## `Ty::is_[unpin|sized|whatever]` I haven't migrated `fn is_item_raw` to use `TypingEnv`, will do so in a followup PR, this should significantly reduce the amount of `typing_env.param_env`. At some point there will probably be zero such uses as using the type system while ignoring the `typing_mode` is incorrect. ## `MirPhase` and phase-transitions When inside of a MIR-body, we can mostly use its `MirPhase` to figure out the right `typing_mode`. This does not work during phase transitions, most notably when transitioning from `Analysis` to `Runtime`:dae7ac133b/compiler/rustc_mir_transform/src/lib.rs (L606-L625)All these passes still run with `MirPhase::Analysis`, but we should only use `Reveal::All` once we're run the `RevealAll` pass. This required me to manually construct the right `TypingEnv` in all these passes. Given that it feels somewhat easy to accidentally miss this going forward, I would maybe like to change `Body::phase` to an `Option` and replace it at the start of phase transitions. This then makes it clear that the MIR is currently in a weird state. r? `@ghost`
This commit is contained in:
@@ -388,7 +388,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
|
||||
return false;
|
||||
}
|
||||
|
||||
let infcx = tcx.infer_ctxt().build(self.body.typing_mode(tcx));
|
||||
let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(self.body.typing_env(tcx));
|
||||
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
|
||||
|
||||
let body_id = self.body.source.def_id().expect_local();
|
||||
@@ -398,11 +398,8 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
|
||||
ty::BoundConstness::Const
|
||||
}
|
||||
};
|
||||
let const_conditions = ocx.normalize(
|
||||
&ObligationCause::misc(call_span, body_id),
|
||||
self.param_env,
|
||||
const_conditions,
|
||||
);
|
||||
let const_conditions =
|
||||
ocx.normalize(&ObligationCause::misc(call_span, body_id), param_env, const_conditions);
|
||||
ocx.register_obligations(const_conditions.into_iter().map(|(trait_ref, span)| {
|
||||
Obligation::new(
|
||||
tcx,
|
||||
@@ -411,7 +408,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
|
||||
body_id,
|
||||
ObligationCauseCode::WhereClause(callee, span),
|
||||
),
|
||||
self.param_env,
|
||||
param_env,
|
||||
trait_ref.to_host_effect_clause(tcx, host_polarity),
|
||||
)
|
||||
}));
|
||||
|
||||
@@ -24,17 +24,15 @@ mod resolver;
|
||||
pub struct ConstCx<'mir, 'tcx> {
|
||||
pub body: &'mir mir::Body<'tcx>,
|
||||
pub tcx: TyCtxt<'tcx>,
|
||||
pub param_env: ty::ParamEnv<'tcx>,
|
||||
pub typing_env: ty::TypingEnv<'tcx>,
|
||||
pub const_kind: Option<hir::ConstContext>,
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx> ConstCx<'mir, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'tcx>, body: &'mir mir::Body<'tcx>) -> Self {
|
||||
let def_id = body.source.def_id().expect_local();
|
||||
let param_env = tcx.param_env(def_id);
|
||||
|
||||
let typing_env = body.typing_env(tcx);
|
||||
let const_kind = tcx.hir().body_const_context(body.source.def_id().expect_local());
|
||||
ConstCx { body, tcx, param_env, const_kind }
|
||||
ConstCx { body, tcx, typing_env, const_kind }
|
||||
}
|
||||
|
||||
pub(crate) fn dcx(&self) -> DiagCtxtHandle<'tcx> {
|
||||
|
||||
@@ -120,7 +120,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, _: Span) -> Diag<'tcx> {
|
||||
let FnCallNonConst { callee, args, span, call_source } = *self;
|
||||
let ConstCx { tcx, param_env, .. } = *ccx;
|
||||
let ConstCx { tcx, typing_env, .. } = *ccx;
|
||||
let caller = ccx.def_id();
|
||||
|
||||
let diag_trait = |err, self_ty: Ty<'_>, trait_id| {
|
||||
@@ -146,13 +146,11 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
||||
}
|
||||
}
|
||||
ty::Adt(..) => {
|
||||
let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);
|
||||
let obligation =
|
||||
Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref);
|
||||
|
||||
let infcx = tcx.infer_ctxt().build(ccx.body.typing_mode(tcx));
|
||||
let mut selcx = SelectionContext::new(&infcx);
|
||||
let implsrc = selcx.select(&obligation);
|
||||
|
||||
if let Ok(Some(ImplSource::UserDefined(data))) = implsrc {
|
||||
// FIXME(const_trait_impl) revisit this
|
||||
if !tcx.is_const_trait_impl(data.impl_def_id) {
|
||||
@@ -166,7 +164,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
||||
};
|
||||
|
||||
let call_kind =
|
||||
call_kind(tcx, ccx.param_env, callee, args, span, call_source.from_hir_call(), None);
|
||||
call_kind(tcx, ccx.typing_env, callee, args, span, call_source.from_hir_call(), None);
|
||||
|
||||
debug!(?call_kind);
|
||||
|
||||
|
||||
@@ -32,17 +32,15 @@ pub fn checking_enabled(ccx: &ConstCx<'_, '_>) -> bool {
|
||||
/// This is separate from the rest of the const checking logic because it must run after drop
|
||||
/// elaboration.
|
||||
pub fn check_live_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mir::Body<'tcx>) {
|
||||
let def_id = body.source.def_id().expect_local();
|
||||
let const_kind = tcx.hir().body_const_context(def_id);
|
||||
if const_kind.is_none() {
|
||||
let ccx = ConstCx::new(tcx, body);
|
||||
if ccx.const_kind.is_none() {
|
||||
return;
|
||||
}
|
||||
|
||||
if tcx.has_attr(def_id, sym::rustc_do_not_const_check) {
|
||||
if tcx.has_attr(body.source.def_id(), sym::rustc_do_not_const_check) {
|
||||
return;
|
||||
}
|
||||
|
||||
let ccx = ConstCx { body, tcx, const_kind, param_env: tcx.param_env(def_id) };
|
||||
if !checking_enabled(&ccx) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -106,20 +106,24 @@ impl Qualif for HasMutInterior {
|
||||
// Instead we invoke an obligation context manually, and provide the opaque type inference settings
|
||||
// that allow the trait solver to just error out instead of cycling.
|
||||
let freeze_def_id = cx.tcx.require_lang_item(LangItem::Freeze, Some(cx.body.span));
|
||||
|
||||
// FIXME(#132279): Once we've got a typing mode which reveals opaque types using the HIR
|
||||
// typeck results without causing query cycles, we should use this here instead of defining
|
||||
// opaque types.
|
||||
let typing_env = ty::TypingEnv {
|
||||
typing_mode: ty::TypingMode::analysis_in_body(
|
||||
cx.tcx,
|
||||
cx.body.source.def_id().expect_local(),
|
||||
),
|
||||
param_env: cx.typing_env.param_env,
|
||||
};
|
||||
let (infcx, param_env) = cx.tcx.infer_ctxt().build_with_typing_env(typing_env);
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
let obligation = Obligation::new(
|
||||
cx.tcx,
|
||||
ObligationCause::dummy_with_span(cx.body.span),
|
||||
cx.param_env,
|
||||
param_env,
|
||||
ty::TraitRef::new(cx.tcx, freeze_def_id, [ty::GenericArg::from(ty)]),
|
||||
);
|
||||
|
||||
// FIXME(#132279): This should eventually use the already defined hidden types.
|
||||
let infcx = cx.tcx.infer_ctxt().build(ty::TypingMode::analysis_in_body(
|
||||
cx.tcx,
|
||||
cx.body.source.def_id().expect_local(),
|
||||
));
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
ocx.register_obligation(obligation);
|
||||
let errors = ocx.select_all_or_error();
|
||||
!errors.is_empty()
|
||||
@@ -156,7 +160,7 @@ impl Qualif for NeedsDrop {
|
||||
}
|
||||
|
||||
fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
ty.needs_drop(cx.tcx, cx.param_env)
|
||||
ty.needs_drop(cx.tcx, cx.typing_env)
|
||||
}
|
||||
|
||||
fn in_adt_inherently<'tcx>(
|
||||
|
||||
@@ -120,7 +120,10 @@ where
|
||||
///
|
||||
/// [rust-lang/unsafe-code-guidelines#134]: https://github.com/rust-lang/unsafe-code-guidelines/issues/134
|
||||
fn shared_borrow_allows_mutation(&self, place: mir::Place<'tcx>) -> bool {
|
||||
!place.ty(self.ccx.body, self.ccx.tcx).ty.is_freeze(self.ccx.tcx, self.ccx.param_env)
|
||||
!place
|
||||
.ty(self.ccx.body, self.ccx.tcx)
|
||||
.ty
|
||||
.is_freeze(self.ccx.tcx, self.ccx.typing_env.param_env)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user