Skip to content

Commit

Permalink
assertion for only collection nll region variable information for deb…
Browse files Browse the repository at this point in the history
…ug in non-canonicalization contexts
  • Loading branch information
b-naber committed Mar 22, 2023
1 parent 439292b commit da0fe80
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 24 deletions.
18 changes: 4 additions & 14 deletions compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -511,16 +511,11 @@ impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> {
.as_var()
.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);
let ctxt = get_ctxt_fn();
let mut var_to_origin = self.reg_var_to_origin.borrow_mut();
let prev = 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));
var_to_origin.insert(vid, ctxt);
}

next_region
Expand All @@ -540,16 +535,11 @@ impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> {
.as_var()
.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);
let ctxt = get_ctxt_fn();
let mut var_to_origin = self.reg_var_to_origin.borrow_mut();
let prev = 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));
var_to_origin.insert(vid, ctxt);
}

next_region
Expand Down
18 changes: 8 additions & 10 deletions compiler/rustc_borrowck/src/type_check/relate_tys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,12 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>

let reg_var =
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));
assert!(matches!(prev, None));

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();
debug!(?reg_var);
var_to_origin.insert(reg_var, RegionCtxt::Placeholder(reg_info));
}

reg
}
Expand All @@ -149,14 +152,9 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
let reg_var =
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 prev = 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));
var_to_origin.insert(reg_var, RegionCtxt::Existential(None));
}

reg
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_infer/src/infer/at.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ use super::*;
use rustc_middle::ty::relate::{Relate, TypeRelation};
use rustc_middle::ty::{Const, ImplSubject};

use std::cell::Cell;

/// Whether we should define opaque types or just treat them opaquely.
///
/// Currently only used to prevent predicate matching from matching anything
Expand Down Expand Up @@ -82,6 +84,7 @@ impl<'tcx> InferCtxt<'tcx> {
in_snapshot: self.in_snapshot.clone(),
universe: self.universe.clone(),
intercrate: self.intercrate,
inside_canonicalization_ctxt: Cell::new(self.inside_canonicalization_ctxt()),
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,8 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
where
V: TypeFoldable<TyCtxt<'tcx>>,
{
let _inside_canonical_ctxt_guard = infcx.set_canonicalization_ctxt();

let needs_canonical_flags = if canonicalize_region_mode.any() {
TypeFlags::NEEDS_INFER |
TypeFlags::HAS_FREE_REGIONS | // `HAS_RE_PLACEHOLDER` implies `HAS_FREE_REGIONS`
Expand Down
32 changes: 32 additions & 0 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ use rustc_span::Span;

use std::cell::{Cell, RefCell};
use std::fmt;
use std::ops::Drop;

use self::combine::CombineFields;
use self::error_reporting::TypeErrCtxt;
Expand Down Expand Up @@ -342,6 +343,11 @@ pub struct InferCtxt<'tcx> {
/// there is no type that the user could *actually name* that
/// would satisfy it. This avoids crippling inference, basically.
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.
Expand Down Expand Up @@ -633,6 +639,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
skip_leak_check: Cell::new(false),
universe: Cell::new(ty::UniverseIndex::ROOT),
intercrate,
inside_canonicalization_ctxt: Cell::new(false),
}
}
}
Expand Down Expand Up @@ -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> {
Expand Down

0 comments on commit da0fe80

Please sign in to comment.