only use FnCtxt for regionck inside of bodies

This commit is contained in:
lcnr 2022-06-27 18:46:16 +02:00
parent edd45f9d41
commit 68d70fc5bd
7 changed files with 54 additions and 54 deletions

View File

@ -69,6 +69,7 @@
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::{self, Region, Ty, TyCtxt, TypeFoldable};
use crate::infer::outlives::env::OutlivesEnvironment;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::undo_log::UndoLogs;
use rustc_hir as hir;
@ -177,6 +178,18 @@ pub fn process_registered_region_obligations(
}
}
}
pub fn check_region_obligations_and_report_errors(
&self,
outlives_env: &OutlivesEnvironment<'tcx>,
) {
self.process_registered_region_obligations(
outlives_env.region_bound_pairs_map(),
outlives_env.param_env,
);
self.resolve_regions_and_report_errors(outlives_env)
}
}
/// The `TypeOutlives` struct has the job of "lowering" a `T: 'a`

View File

@ -13,6 +13,7 @@
use rustc_hir::intravisit::Visitor;
use rustc_hir::lang_items::LangItem;
use rustc_hir::{ItemKind, Node, PathSegment};
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
use rustc_infer::traits::Obligation;
@ -736,10 +737,9 @@ fn check_opaque_meets_bounds<'tcx>(
hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => {}
// Can have different predicates to their defining use
hir::OpaqueTyOrigin::TyAlias => {
// Finally, resolve all regions. This catches wily misuses of
// lifetime parameters.
let fcx = FnCtxt::new(&inh, param_env, hir_id);
fcx.regionck_item(hir_id, span, FxHashSet::default());
let mut outlives_environment = OutlivesEnvironment::new(param_env);
outlives_environment.save_implied_bounds(hir_id);
infcx.check_region_obligations_and_report_errors(&outlives_environment);
}
}

View File

@ -1,3 +1,4 @@
use crate::check::regionck::OutlivesEnvironmentExt;
use crate::errors::LifetimesOrBoundsMismatchOnTrait;
use rustc_data_structures::stable_set::FxHashSet;
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId, ErrorGuaranteed};
@ -5,6 +6,7 @@
use rustc_hir::def::{DefKind, Res};
use rustc_hir::intravisit;
use rustc_hir::{GenericParamKind, ImplItemKind, TraitItemKind};
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
use rustc_infer::infer::{self, InferOk, TyCtxtInferExt};
use rustc_infer::traits::util;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
@ -78,10 +80,11 @@ fn compare_predicate_entailment<'tcx>(
let trait_to_impl_substs = impl_trait_ref.substs;
// This node-id should be used for the `body_id` field on each
// `ObligationCause` (and the `FnCtxt`). This is what
// `regionck_item` expects.
// `ObligationCause` (and the `FnCtxt`).
//
// FIXME(@lcnr): remove that after removing `cause.body_id` from
// obligations.
let impl_m_hir_id = tcx.hir().local_def_id_to_hir_id(impl_m.def_id.expect_local());
// We sometimes modify the span further down.
let mut cause = ObligationCause::new(
impl_m_span,
@ -398,8 +401,10 @@ fn compare_predicate_entailment<'tcx>(
// Finally, resolve all regions. This catches wily misuses of
// lifetime parameters.
let fcx = FnCtxt::new(&inh, param_env, impl_m_hir_id);
fcx.regionck_item(impl_m_hir_id, impl_m_span, wf_tys);
let mut outlives_environment = OutlivesEnvironment::new(param_env);
outlives_environment.add_implied_bounds(infcx, wf_tys, impl_m_hir_id);
outlives_environment.save_implied_bounds(impl_m_hir_id);
infcx.check_region_obligations_and_report_errors(&outlives_environment);
Ok(())
})
@ -1154,8 +1159,9 @@ pub(crate) fn compare_const_impl<'tcx>(
return;
}
let fcx = FnCtxt::new(&inh, param_env, impl_c_hir_id);
fcx.regionck_item(impl_c_hir_id, impl_c_span, FxHashSet::default());
let mut outlives_environment = OutlivesEnvironment::new(param_env);
outlives_environment.save_implied_bounds(impl_c_hir_id);
infcx.resolve_regions_and_report_errors(&outlives_environment);
});
}
@ -1273,8 +1279,9 @@ fn compare_type_predicate_entailment<'tcx>(
// Finally, resolve all regions. This catches wily misuses of
// lifetime parameters.
let fcx = FnCtxt::new(&inh, param_env, impl_ty_hir_id);
fcx.regionck_item(impl_ty_hir_id, impl_ty_span, FxHashSet::default());
let mut outlives_environment = OutlivesEnvironment::new(param_env);
outlives_environment.save_implied_bounds(impl_ty_hir_id);
infcx.check_region_obligations_and_report_errors(&outlives_environment);
Ok(())
})
@ -1498,12 +1505,17 @@ pub fn check_type_bounds<'tcx>(
// Finally, resolve all regions. This catches wily misuses of
// lifetime parameters.
//
// FIXME: Remove that `FnCtxt`.
let fcx = FnCtxt::new(&inh, param_env, impl_ty_hir_id);
let implied_bounds = match impl_ty.container {
ty::TraitContainer(_) => FxHashSet::default(),
ty::ImplContainer(def_id) => fcx.impl_implied_bounds(def_id, impl_ty_span),
};
fcx.regionck_item(impl_ty_hir_id, impl_ty_span, implied_bounds);
let mut outlives_environment = OutlivesEnvironment::new(param_env);
outlives_environment.add_implied_bounds(infcx, implied_bounds, impl_ty_hir_id);
outlives_environment.save_implied_bounds(impl_ty_hir_id);
infcx.check_region_obligations_and_report_errors(&outlives_environment);
Ok(())
})

View File

@ -491,7 +491,7 @@ fn typeck_with_fallback<'tcx>(
fcx.check_asms();
if fn_sig.is_some() {
fcx.regionck_fn(id, body, span, wf_tys);
fcx.regionck_fn(id, body, wf_tys);
} else {
fcx.regionck_body(body);
}

View File

@ -108,7 +108,6 @@ fn add_implied_bounds(
infcx: &InferCtxt<'_, 'tcx>,
fn_sig_tys: FxHashSet<Ty<'tcx>>,
body_id: hir::HirId,
span: Span,
);
}
@ -135,11 +134,10 @@ fn add_implied_bounds<'a>(
infcx: &InferCtxt<'a, 'tcx>,
fn_sig_tys: FxHashSet<Ty<'tcx>>,
body_id: hir::HirId,
span: Span,
) {
for ty in fn_sig_tys {
let ty = infcx.resolve_vars_if_possible(ty);
let implied_bounds = infcx.implied_outlives_bounds(self.param_env, body_id, ty, span);
let implied_bounds = infcx.implied_outlives_bounds(self.param_env, body_id, ty);
self.add_outlives_bounds(Some(infcx), implied_bounds)
}
}
@ -166,18 +164,6 @@ pub fn regionck_body(&self, body: &'tcx hir::Body<'tcx>) {
rcx.fcx.skip_region_resolution();
}
/// Region checking during the WF phase for items. `wf_tys` are the
/// types from which we should derive implied bounds, if any.
#[instrument(level = "debug", skip(self))]
pub fn regionck_item(&self, item_id: hir::HirId, span: Span, wf_tys: FxHashSet<Ty<'tcx>>) {
let body_owner = self.tcx.hir().local_def_id(item_id);
let mut rcx = RegionCtxt::new(self, body_owner, self.param_env);
rcx.outlives_environment.add_implied_bounds(self, wf_tys, item_id, span);
rcx.outlives_environment.save_implied_bounds(rcx.body_id());
rcx.visit_region_obligations(item_id);
rcx.resolve_regions_and_report_errors();
}
/// Region check a function body. Not invoked on closures, but
/// only on the "root" fn item (in which closures may be
/// embedded). Walks the function body and adds various add'l
@ -190,19 +176,18 @@ pub(crate) fn regionck_fn(
&self,
fn_id: hir::HirId,
body: &'tcx hir::Body<'tcx>,
span: Span,
wf_tys: FxHashSet<Ty<'tcx>>,
) {
debug!("regionck_fn(id={})", fn_id);
let body_owner = self.tcx.hir().body_owner_def_id(body.id());
let mut rcx = RegionCtxt::new(self, body_owner, self.param_env);
// We need to add the implied bounds from the function signature
rcx.outlives_environment.add_implied_bounds(self, wf_tys, fn_id, span);
rcx.outlives_environment.add_implied_bounds(self, wf_tys, fn_id);
rcx.outlives_environment.save_implied_bounds(fn_id);
if !self.errors_reported_since_creation() {
// regionck assumes typeck succeeded
rcx.visit_fn_body(fn_id, body, self.tcx.hir().span(fn_id));
rcx.visit_fn_body(fn_id, body);
}
// Checked by NLL
@ -294,7 +279,6 @@ fn visit_fn_body(
&mut self,
id: hir::HirId, // the id of the fn itself
body: &'tcx hir::Body<'tcx>,
span: Span,
) {
// When we enter a function, we can derive
debug!("visit_fn_body(id={:?})", id);
@ -313,7 +297,7 @@ fn visit_fn_body(
let fn_sig_tys: FxHashSet<_> =
fn_sig.inputs().iter().cloned().chain(Some(fn_sig.output())).collect();
self.outlives_environment.add_implied_bounds(self.fcx, fn_sig_tys, body_id.hir_id, span);
self.outlives_environment.add_implied_bounds(self.fcx, fn_sig_tys, body_id.hir_id);
self.outlives_environment.save_implied_bounds(body_id.hir_id);
self.link_fn_params(body.params);
self.visit_body(body);
@ -349,15 +333,6 @@ fn visit_region_obligations(&mut self, hir_id: hir::HirId) {
self.select_all_obligations_or_error();
}
fn resolve_regions_and_report_errors(&self) {
self.infcx.process_registered_region_obligations(
self.outlives_environment.region_bound_pairs_map(),
self.param_env,
);
self.fcx.resolve_regions_and_report_errors(&self.outlives_environment);
}
fn constrain_bindings_in_pat(&mut self, pat: &hir::Pat<'_>) {
debug!("regionck::visit_pat(pat={:?})", pat);
pat.each_binding(|_, hir_id, span, _| {
@ -382,7 +357,7 @@ fn visit_fn(
fk: intravisit::FnKind<'tcx>,
_: &'tcx hir::FnDecl<'tcx>,
body_id: hir::BodyId,
span: Span,
_span: Span,
hir_id: hir::HirId,
) {
assert!(
@ -396,7 +371,7 @@ fn visit_fn(
let env_snapshot = self.outlives_environment.push_snapshot_pre_typeck_child();
let body = self.tcx.hir().body(body_id);
self.visit_fn_body(hir_id, body, span);
self.visit_fn_body(hir_id, body);
// Restore state from previous function.
self.outlives_environment.pop_snapshot_post_typeck_child(env_snapshot);

View File

@ -62,7 +62,11 @@ pub(super) fn with_fcx<F>(&mut self, f: F)
}
let wf_tys = f(&fcx);
fcx.select_all_obligations_or_error();
fcx.regionck_item(id, span, wf_tys);
let mut outlives_environment = OutlivesEnvironment::new(param_env);
outlives_environment.add_implied_bounds(&fcx.infcx, wf_tys, id);
outlives_environment.save_implied_bounds(id);
fcx.infcx.check_region_obligations_and_report_errors(&outlives_environment);
});
}
}
@ -655,7 +659,7 @@ fn resolve_regions_with_wf_tys<'tcx>(
// call individually.
tcx.infer_ctxt().enter(|infcx| {
let mut outlives_environment = OutlivesEnvironment::new(param_env);
outlives_environment.add_implied_bounds(&infcx, wf_tys.clone(), id, DUMMY_SP);
outlives_environment.add_implied_bounds(&infcx, wf_tys.clone(), id);
outlives_environment.save_implied_bounds(id);
let region_bound_pairs = outlives_environment.region_bound_pairs_map().get(&id).unwrap();

View File

@ -1,6 +1,5 @@
use rustc_hir as hir;
use rustc_middle::ty::{self, Ty};
use rustc_span::source_map::Span;
use rustc_trait_selection::infer::InferCtxt;
use rustc_trait_selection::traits::query::type_op::{self, TypeOp, TypeOpOutput};
use rustc_trait_selection::traits::query::NoSolution;
@ -14,7 +13,6 @@ fn implied_outlives_bounds(
param_env: ty::ParamEnv<'tcx>,
body_id: hir::HirId,
ty: Ty<'tcx>,
span: Span,
) -> Vec<OutlivesBound<'tcx>>;
}
@ -38,16 +36,14 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
/// Note that this may cause outlives obligations to be injected
/// into the inference context with this body-id.
/// - `ty`, the type that we are supposed to assume is WF.
/// - `span`, a span to use when normalizing, hopefully not important,
/// might be useful if a `bug!` occurs.
#[instrument(level = "debug", skip(self, param_env, body_id, span))]
#[instrument(level = "debug", skip(self, param_env, body_id))]
fn implied_outlives_bounds(
&self,
param_env: ty::ParamEnv<'tcx>,
body_id: hir::HirId,
ty: Ty<'tcx>,
span: Span,
) -> Vec<OutlivesBound<'tcx>> {
let span = self.tcx.hir().span(body_id);
let result = param_env
.and(type_op::implied_outlives_bounds::ImpliedOutlivesBounds { ty })
.fully_perform(self);