assertion for only collection nll region variable information for debug in non-canonicalization contexts
This commit is contained in:
parent
439292bc79
commit
da0fe80137
5 changed files with 49 additions and 24 deletions
|
@ -511,16 +511,11 @@ impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> {
|
||||||
.as_var()
|
.as_var()
|
||||||
.unwrap_or_else(|| bug!("expected RegionKind::RegionVar on {:?}", next_region));
|
.unwrap_or_else(|| bug!("expected RegionKind::RegionVar on {:?}", next_region));
|
||||||
|
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) && !self.inside_canonicalization_ctxt() {
|
||||||
debug!("inserting vid {:?} with origin {:?} into var_to_origin", vid, origin);
|
debug!("inserting vid {:?} with origin {:?} into var_to_origin", vid, origin);
|
||||||
let ctxt = get_ctxt_fn();
|
let ctxt = get_ctxt_fn();
|
||||||
let mut var_to_origin = self.reg_var_to_origin.borrow_mut();
|
let mut var_to_origin = self.reg_var_to_origin.borrow_mut();
|
||||||
let prev = var_to_origin.insert(vid, ctxt);
|
var_to_origin.insert(vid, ctxt);
|
||||||
|
|
||||||
// This only makes sense if not called in a canonicalization context. If this
|
|
||||||
// ever changes we either want to get rid of `BorrowckInferContext::reg_var_to_origin`
|
|
||||||
// or modify how we track nll region vars for that map.
|
|
||||||
assert!(matches!(prev, None));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
next_region
|
next_region
|
||||||
|
@ -540,16 +535,11 @@ impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> {
|
||||||
.as_var()
|
.as_var()
|
||||||
.unwrap_or_else(|| bug!("expected RegionKind::RegionVar on {:?}", next_region));
|
.unwrap_or_else(|| bug!("expected RegionKind::RegionVar on {:?}", next_region));
|
||||||
|
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) && !self.inside_canonicalization_ctxt() {
|
||||||
debug!("inserting vid {:?} with origin {:?} into var_to_origin", vid, origin);
|
debug!("inserting vid {:?} with origin {:?} into var_to_origin", vid, origin);
|
||||||
let ctxt = get_ctxt_fn();
|
let ctxt = get_ctxt_fn();
|
||||||
let mut var_to_origin = self.reg_var_to_origin.borrow_mut();
|
let mut var_to_origin = self.reg_var_to_origin.borrow_mut();
|
||||||
let prev = var_to_origin.insert(vid, ctxt);
|
var_to_origin.insert(vid, ctxt);
|
||||||
|
|
||||||
// This only makes sense if not called in a canonicalization context. If this
|
|
||||||
// ever changes we either want to get rid of `BorrowckInferContext::reg_var_to_origin`
|
|
||||||
// or modify how we track nll region vars for that map.
|
|
||||||
assert!(matches!(prev, None));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
next_region
|
next_region
|
||||||
|
|
|
@ -132,9 +132,12 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
|
||||||
|
|
||||||
let reg_var =
|
let reg_var =
|
||||||
reg.as_var().unwrap_or_else(|| bug!("expected region {:?} to be of kind ReVar", reg));
|
reg.as_var().unwrap_or_else(|| bug!("expected region {:?} to be of kind ReVar", reg));
|
||||||
let mut var_to_origin = self.type_checker.infcx.reg_var_to_origin.borrow_mut();
|
|
||||||
let prev = var_to_origin.insert(reg_var, RegionCtxt::Placeholder(reg_info));
|
if cfg!(debug_assertions) && !self.type_checker.infcx.inside_canonicalization_ctxt() {
|
||||||
assert!(matches!(prev, None));
|
let mut var_to_origin = self.type_checker.infcx.reg_var_to_origin.borrow_mut();
|
||||||
|
debug!(?reg_var);
|
||||||
|
var_to_origin.insert(reg_var, RegionCtxt::Placeholder(reg_info));
|
||||||
|
}
|
||||||
|
|
||||||
reg
|
reg
|
||||||
}
|
}
|
||||||
|
@ -149,14 +152,9 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
|
||||||
let reg_var =
|
let reg_var =
|
||||||
reg.as_var().unwrap_or_else(|| bug!("expected region {:?} to be of kind ReVar", reg));
|
reg.as_var().unwrap_or_else(|| bug!("expected region {:?} to be of kind ReVar", reg));
|
||||||
|
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) && !self.type_checker.infcx.inside_canonicalization_ctxt() {
|
||||||
let mut var_to_origin = self.type_checker.infcx.reg_var_to_origin.borrow_mut();
|
let mut var_to_origin = self.type_checker.infcx.reg_var_to_origin.borrow_mut();
|
||||||
let prev = var_to_origin.insert(reg_var, RegionCtxt::Existential(None));
|
var_to_origin.insert(reg_var, RegionCtxt::Existential(None));
|
||||||
|
|
||||||
// It only makes sense to track region vars in non-canonicalization contexts. If this
|
|
||||||
// ever changes we either want to get rid of `BorrowckInferContext::reg_var_to_origin`
|
|
||||||
// or modify how we track nll region vars for that map.
|
|
||||||
assert!(matches!(prev, None));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
reg
|
reg
|
||||||
|
|
|
@ -30,6 +30,8 @@ use super::*;
|
||||||
use rustc_middle::ty::relate::{Relate, TypeRelation};
|
use rustc_middle::ty::relate::{Relate, TypeRelation};
|
||||||
use rustc_middle::ty::{Const, ImplSubject};
|
use rustc_middle::ty::{Const, ImplSubject};
|
||||||
|
|
||||||
|
use std::cell::Cell;
|
||||||
|
|
||||||
/// Whether we should define opaque types or just treat them opaquely.
|
/// Whether we should define opaque types or just treat them opaquely.
|
||||||
///
|
///
|
||||||
/// Currently only used to prevent predicate matching from matching anything
|
/// Currently only used to prevent predicate matching from matching anything
|
||||||
|
@ -82,6 +84,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
in_snapshot: self.in_snapshot.clone(),
|
in_snapshot: self.in_snapshot.clone(),
|
||||||
universe: self.universe.clone(),
|
universe: self.universe.clone(),
|
||||||
intercrate: self.intercrate,
|
intercrate: self.intercrate,
|
||||||
|
inside_canonicalization_ctxt: Cell::new(self.inside_canonicalization_ctxt()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -561,6 +561,8 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
||||||
where
|
where
|
||||||
V: TypeFoldable<TyCtxt<'tcx>>,
|
V: TypeFoldable<TyCtxt<'tcx>>,
|
||||||
{
|
{
|
||||||
|
let _inside_canonical_ctxt_guard = infcx.set_canonicalization_ctxt();
|
||||||
|
|
||||||
let needs_canonical_flags = if canonicalize_region_mode.any() {
|
let needs_canonical_flags = if canonicalize_region_mode.any() {
|
||||||
TypeFlags::NEEDS_INFER |
|
TypeFlags::NEEDS_INFER |
|
||||||
TypeFlags::HAS_FREE_REGIONS | // `HAS_RE_PLACEHOLDER` implies `HAS_FREE_REGIONS`
|
TypeFlags::HAS_FREE_REGIONS | // `HAS_RE_PLACEHOLDER` implies `HAS_FREE_REGIONS`
|
||||||
|
|
|
@ -39,6 +39,7 @@ use rustc_span::Span;
|
||||||
|
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::ops::Drop;
|
||||||
|
|
||||||
use self::combine::CombineFields;
|
use self::combine::CombineFields;
|
||||||
use self::error_reporting::TypeErrCtxt;
|
use self::error_reporting::TypeErrCtxt;
|
||||||
|
@ -342,6 +343,11 @@ pub struct InferCtxt<'tcx> {
|
||||||
/// there is no type that the user could *actually name* that
|
/// there is no type that the user could *actually name* that
|
||||||
/// would satisfy it. This avoids crippling inference, basically.
|
/// would satisfy it. This avoids crippling inference, basically.
|
||||||
pub intercrate: bool,
|
pub intercrate: bool,
|
||||||
|
|
||||||
|
/// Flag that is set when we enter canonicalization. Used for debugging to ensure
|
||||||
|
/// that we only collect region information for `BorrowckInferCtxt::reg_var_to_origin`
|
||||||
|
/// inside non-canonicalization contexts.
|
||||||
|
inside_canonicalization_ctxt: Cell<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See the `error_reporting` module for more details.
|
/// See the `error_reporting` module for more details.
|
||||||
|
@ -633,6 +639,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
|
||||||
skip_leak_check: Cell::new(false),
|
skip_leak_check: Cell::new(false),
|
||||||
universe: Cell::new(ty::UniverseIndex::ROOT),
|
universe: Cell::new(ty::UniverseIndex::ROOT),
|
||||||
intercrate,
|
intercrate,
|
||||||
|
inside_canonicalization_ctxt: Cell::new(false),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1728,6 +1735,31 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn inside_canonicalization_ctxt(&self) -> bool {
|
||||||
|
self.inside_canonicalization_ctxt.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_canonicalization_ctxt(&self) -> CanonicalizationCtxtGuard<'_, 'tcx> {
|
||||||
|
let prev_ctxt = self.inside_canonicalization_ctxt();
|
||||||
|
self.inside_canonicalization_ctxt.set(true);
|
||||||
|
CanonicalizationCtxtGuard { prev_ctxt, infcx: self }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_canonicalization_ctxt_to(&self, ctxt: bool) {
|
||||||
|
self.inside_canonicalization_ctxt.set(ctxt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct CanonicalizationCtxtGuard<'cx, 'tcx> {
|
||||||
|
prev_ctxt: bool,
|
||||||
|
infcx: &'cx InferCtxt<'tcx>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'cx, 'tcx> Drop for CanonicalizationCtxtGuard<'cx, 'tcx> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.infcx.set_canonicalization_ctxt_to(self.prev_ctxt)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue