1
Fork 0

Remove TypeckResults from InferCtxt

This commit is contained in:
Cameron Steffen 2022-09-09 13:01:06 -05:00
parent 4a68373217
commit 349415d1c6
67 changed files with 240 additions and 280 deletions

View file

@ -16,7 +16,6 @@ use rustc_data_structures::undo_log::Rollback;
use rustc_data_structures::unify as ut;
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::hir_id::OwnerId;
use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues};
use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType};
@ -36,7 +35,7 @@ use rustc_middle::ty::{ConstVid, FloatVid, IntVid, TyVid};
use rustc_span::symbol::Symbol;
use rustc_span::{Span, DUMMY_SP};
use std::cell::{Cell, Ref, RefCell};
use std::cell::{Cell, RefCell};
use std::fmt;
use self::combine::CombineFields;
@ -254,7 +253,7 @@ pub enum DefiningAnchor {
Error,
}
pub struct InferCtxt<'a, 'tcx> {
pub struct InferCtxt<'tcx> {
pub tcx: TyCtxt<'tcx>,
/// The `DefId` of the item in whose context we are performing inference or typeck.
@ -274,12 +273,6 @@ pub struct InferCtxt<'a, 'tcx> {
/// solving is left to borrowck instead.
pub considering_regions: bool,
/// During type-checking/inference of a body, `in_progress_typeck_results`
/// contains a reference to the typeck results being built up, which are
/// used for reading closure kinds/signatures as they are inferred,
/// and for error reporting logic to read arbitrary node types.
pub in_progress_typeck_results: Option<&'a RefCell<ty::TypeckResults<'tcx>>>,
pub inner: RefCell<InferCtxtInner<'tcx>>,
/// If set, this flag causes us to skip the 'leak check' during
@ -342,7 +335,7 @@ pub struct InferCtxt<'a, 'tcx> {
universe: Cell<ty::UniverseIndex>,
normalize_fn_sig_for_diagnostic:
Option<Lrc<dyn Fn(&InferCtxt<'_, 'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>>,
Option<Lrc<dyn Fn(&InferCtxt<'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>>,
}
/// See the `error_reporting` module for more details.
@ -553,16 +546,13 @@ impl<'tcx> fmt::Display for FixupError<'tcx> {
}
}
/// A temporary returned by `tcx.infer_ctxt()`. This is necessary
/// for multiple `InferCtxt` to share the same `in_progress_typeck_results`
/// without using `Rc` or something similar.
/// Used to configure inference contexts before their creation
pub struct InferCtxtBuilder<'tcx> {
tcx: TyCtxt<'tcx>,
defining_use_anchor: DefiningAnchor,
considering_regions: bool,
fresh_typeck_results: Option<RefCell<ty::TypeckResults<'tcx>>>,
normalize_fn_sig_for_diagnostic:
Option<Lrc<dyn Fn(&InferCtxt<'_, 'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>>,
Option<Lrc<dyn Fn(&InferCtxt<'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>>,
}
pub trait TyCtxtInferExt<'tcx> {
@ -575,26 +565,17 @@ impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
tcx: self,
defining_use_anchor: DefiningAnchor::Error,
considering_regions: true,
fresh_typeck_results: None,
normalize_fn_sig_for_diagnostic: None,
}
}
}
impl<'tcx> InferCtxtBuilder<'tcx> {
/// Used only by `rustc_hir_analysis` during body type-checking/inference,
/// will initialize `in_progress_typeck_results` with fresh `TypeckResults`.
/// Will also change the scope for opaque type defining use checks to the given owner.
pub fn with_fresh_in_progress_typeck_results(mut self, table_owner: OwnerId) -> Self {
self.fresh_typeck_results = Some(RefCell::new(ty::TypeckResults::new(table_owner)));
self.with_opaque_type_inference(DefiningAnchor::Bind(table_owner.def_id))
}
/// Whenever the `InferCtxt` should be able to handle defining uses of opaque types,
/// you need to call this function. Otherwise the opaque type will be treated opaquely.
///
/// It is only meant to be called in two places, for typeck
/// (via `with_fresh_in_progress_typeck_results`) and for the inference context used
/// (via `Inherited::build`) and for the inference context used
/// in mir borrowck.
pub fn with_opaque_type_inference(mut self, defining_use_anchor: DefiningAnchor) -> Self {
self.defining_use_anchor = defining_use_anchor;
@ -608,7 +589,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
pub fn with_normalize_fn_sig_for_diagnostic(
mut self,
fun: Lrc<dyn Fn(&InferCtxt<'_, 'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>,
fun: Lrc<dyn Fn(&InferCtxt<'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>,
) -> Self {
self.normalize_fn_sig_for_diagnostic = Some(fun);
self
@ -625,7 +606,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
&mut self,
span: Span,
canonical: &Canonical<'tcx, T>,
f: impl for<'a> FnOnce(InferCtxt<'a, 'tcx>, T, CanonicalVarValues<'tcx>) -> R,
f: impl FnOnce(InferCtxt<'tcx>, T, CanonicalVarValues<'tcx>) -> R,
) -> R
where
T: TypeFoldable<'tcx>,
@ -637,20 +618,17 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
})
}
pub fn enter<R>(&mut self, f: impl for<'a> FnOnce(InferCtxt<'a, 'tcx>) -> R) -> R {
pub fn enter<R>(&mut self, f: impl FnOnce(InferCtxt<'tcx>) -> R) -> R {
let InferCtxtBuilder {
tcx,
defining_use_anchor,
considering_regions,
ref fresh_typeck_results,
ref normalize_fn_sig_for_diagnostic,
} = *self;
let in_progress_typeck_results = fresh_typeck_results.as_ref();
f(InferCtxt {
tcx,
defining_use_anchor,
considering_regions,
in_progress_typeck_results,
inner: RefCell::new(InferCtxtInner::new()),
lexical_region_resolutions: RefCell::new(None),
selection_cache: Default::default(),
@ -677,7 +655,7 @@ impl<'tcx, T> InferOk<'tcx, T> {
/// Extracts `value`, registering any obligations into `fulfill_cx`.
pub fn into_value_registering_obligations(
self,
infcx: &InferCtxt<'_, 'tcx>,
infcx: &InferCtxt<'tcx>,
fulfill_cx: &mut dyn TraitEngine<'tcx>,
) -> T {
let InferOk { value, obligations } = self;
@ -693,18 +671,17 @@ impl<'tcx> InferOk<'tcx, ()> {
}
#[must_use = "once you start a snapshot, you should always consume it"]
pub struct CombinedSnapshot<'a, 'tcx> {
pub struct CombinedSnapshot<'tcx> {
undo_snapshot: Snapshot<'tcx>,
region_constraints_snapshot: RegionSnapshot,
universe: ty::UniverseIndex,
was_in_snapshot: bool,
_in_progress_typeck_results: Option<Ref<'a, ty::TypeckResults<'tcx>>>,
}
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
impl<'tcx> InferCtxt<'tcx> {
/// Creates a `TypeErrCtxt` for emitting various inference errors.
/// During typeck, use `FnCtxt::infer_err` instead.
pub fn err_ctxt(&'a self) -> TypeErrCtxt<'a, 'tcx> {
pub fn err_ctxt(&self) -> TypeErrCtxt<'_, 'tcx> {
TypeErrCtxt { infcx: self, typeck_results: None }
}
@ -746,7 +723,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
/// if this is not a type variable.
///
/// No attempt is made to resolve `ty`.
pub fn type_var_origin(&'a self, ty: Ty<'tcx>) -> Option<TypeVariableOrigin> {
pub fn type_var_origin(&self, ty: Ty<'tcx>) -> Option<TypeVariableOrigin> {
match *ty.kind() {
ty::Infer(ty::TyVar(vid)) => {
Some(*self.inner.borrow_mut().type_variables().var_origin(vid))
@ -787,7 +764,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
vars
}
fn combine_fields(
fn combine_fields<'a>(
&'a self,
trace: TypeTrace<'tcx>,
param_env: ty::ParamEnv<'tcx>,
@ -829,7 +806,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
result
}
fn start_snapshot(&self) -> CombinedSnapshot<'a, 'tcx> {
fn start_snapshot(&self) -> CombinedSnapshot<'tcx> {
debug!("start_snapshot()");
let in_snapshot = self.in_snapshot.replace(true);
@ -841,22 +818,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
region_constraints_snapshot: inner.unwrap_region_constraints().start_snapshot(),
universe: self.universe(),
was_in_snapshot: in_snapshot,
// Borrow typeck results "in progress" (i.e., during typeck)
// to ban writes from within a snapshot to them.
_in_progress_typeck_results: self
.in_progress_typeck_results
.map(|typeck_results| typeck_results.borrow()),
}
}
#[instrument(skip(self, snapshot), level = "debug")]
fn rollback_to(&self, cause: &str, snapshot: CombinedSnapshot<'a, 'tcx>) {
fn rollback_to(&self, cause: &str, snapshot: CombinedSnapshot<'tcx>) {
let CombinedSnapshot {
undo_snapshot,
region_constraints_snapshot,
universe,
was_in_snapshot,
_in_progress_typeck_results,
} = snapshot;
self.in_snapshot.set(was_in_snapshot);
@ -868,13 +839,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
#[instrument(skip(self, snapshot), level = "debug")]
fn commit_from(&self, snapshot: CombinedSnapshot<'a, 'tcx>) {
fn commit_from(&self, snapshot: CombinedSnapshot<'tcx>) {
let CombinedSnapshot {
undo_snapshot,
region_constraints_snapshot: _,
universe: _,
was_in_snapshot,
_in_progress_typeck_results,
} = snapshot;
self.in_snapshot.set(was_in_snapshot);
@ -886,7 +856,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
#[instrument(skip(self, f), level = "debug")]
pub fn commit_if_ok<T, E, F>(&self, f: F) -> Result<T, E>
where
F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> Result<T, E>,
F: FnOnce(&CombinedSnapshot<'tcx>) -> Result<T, E>,
{
let snapshot = self.start_snapshot();
let r = f(&snapshot);
@ -906,7 +876,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
#[instrument(skip(self, f), level = "debug")]
pub fn probe<R, F>(&self, f: F) -> R
where
F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> R,
F: FnOnce(&CombinedSnapshot<'tcx>) -> R,
{
let snapshot = self.start_snapshot();
let r = f(&snapshot);
@ -918,7 +888,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
#[instrument(skip(self, f), level = "debug")]
pub fn probe_maybe_skip_leak_check<R, F>(&self, should_skip: bool, f: F) -> R
where
F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> R,
F: FnOnce(&CombinedSnapshot<'tcx>) -> R,
{
let snapshot = self.start_snapshot();
let was_skip_leak_check = self.skip_leak_check.get();
@ -938,7 +908,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
/// - `Some(false)` -- if there are `'a: 'b` constraints but none involve placeholders
pub fn region_constraints_added_in_snapshot(
&self,
snapshot: &CombinedSnapshot<'a, 'tcx>,
snapshot: &CombinedSnapshot<'tcx>,
) -> Option<bool> {
self.inner
.borrow_mut()
@ -946,7 +916,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
.region_constraints_added_in_snapshot(&snapshot.undo_snapshot)
}
pub fn opaque_types_added_in_snapshot(&self, snapshot: &CombinedSnapshot<'a, 'tcx>) -> bool {
pub fn opaque_types_added_in_snapshot(&self, snapshot: &CombinedSnapshot<'tcx>) -> bool {
self.inner.borrow().undo_log.opaque_types_in_snapshot(&snapshot.undo_snapshot)
}
@ -1519,7 +1489,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
struct ToFreshVars<'a, 'tcx> {
infcx: &'a InferCtxt<'a, 'tcx>,
infcx: &'a InferCtxt<'tcx>,
span: Span,
lbrct: LateBoundRegionConversionTime,
map: FxHashMap<ty::BoundVar, ty::GenericArg<'tcx>>,
@ -1893,7 +1863,7 @@ impl<'tcx> TypeFolder<'tcx> for InferenceLiteralEraser<'tcx> {
}
struct ShallowResolver<'a, 'tcx> {
infcx: &'a InferCtxt<'a, 'tcx>,
infcx: &'a InferCtxt<'tcx>,
}
impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> {