Skip to content

Commit 1c771fe

Browse files
committed
Auto merge of #108861 - b-naber:eager-nll-type-relating, r=lcnr
Make NLL Type Relating Eager We previously instantiated bound regions in nll type relating lazily. Making this eager is more consistent with how we handle type relating in [`higher_ranked_sub`](https://github.com/rust-lang/rust/blob/0a3b557d528dd7c8a88ceca6f7dc0699b89a3ef4/compiler/rustc_infer/src/infer/higher_ranked/mod.rs#L28) and should allow us to short circuit in case there's structural equality.
2 parents 8859fde + 8f4cf2e commit 1c771fe

File tree

7 files changed

+159
-199
lines changed

7 files changed

+159
-199
lines changed

compiler/rustc_borrowck/src/lib.rs

+4-14
Original file line numberDiff line numberDiff line change
@@ -510,16 +510,11 @@ impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> {
510510
.as_var()
511511
.unwrap_or_else(|| bug!("expected RegionKind::RegionVar on {:?}", next_region));
512512

513-
if cfg!(debug_assertions) {
513+
if cfg!(debug_assertions) && !self.inside_canonicalization_ctxt() {
514514
debug!("inserting vid {:?} with origin {:?} into var_to_origin", vid, origin);
515515
let ctxt = get_ctxt_fn();
516516
let mut var_to_origin = self.reg_var_to_origin.borrow_mut();
517-
let prev = var_to_origin.insert(vid, ctxt);
518-
519-
// This only makes sense if not called in a canonicalization context. If this
520-
// ever changes we either want to get rid of `BorrowckInferContext::reg_var_to_origin`
521-
// or modify how we track nll region vars for that map.
522-
assert!(matches!(prev, None));
517+
var_to_origin.insert(vid, ctxt);
523518
}
524519

525520
next_region
@@ -539,16 +534,11 @@ impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> {
539534
.as_var()
540535
.unwrap_or_else(|| bug!("expected RegionKind::RegionVar on {:?}", next_region));
541536

542-
if cfg!(debug_assertions) {
537+
if cfg!(debug_assertions) && !self.inside_canonicalization_ctxt() {
543538
debug!("inserting vid {:?} with origin {:?} into var_to_origin", vid, origin);
544539
let ctxt = get_ctxt_fn();
545540
let mut var_to_origin = self.reg_var_to_origin.borrow_mut();
546-
let prev = var_to_origin.insert(vid, ctxt);
547-
548-
// This only makes sense if not called in a canonicalization context. If this
549-
// ever changes we either want to get rid of `BorrowckInferContext::reg_var_to_origin`
550-
// or modify how we track nll region vars for that map.
551-
assert!(matches!(prev, None));
541+
var_to_origin.insert(vid, ctxt);
552542
}
553543

554544
next_region

compiler/rustc_borrowck/src/region_infer/mod.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -256,11 +256,12 @@ fn sccs_info<'cx, 'tcx>(
256256

257257
let mut var_to_origin_sorted = var_to_origin.clone().into_iter().collect::<Vec<_>>();
258258
var_to_origin_sorted.sort_by_key(|vto| vto.0);
259-
let mut debug_str = "region variables to origins:\n".to_string();
259+
260+
let mut reg_vars_to_origins_str = "region variables to origins:\n".to_string();
260261
for (reg_var, origin) in var_to_origin_sorted.into_iter() {
261-
debug_str.push_str(&format!("{:?}: {:?}\n", reg_var, origin));
262+
reg_vars_to_origins_str.push_str(&format!("{:?}: {:?}\n", reg_var, origin));
262263
}
263-
debug!(debug_str);
264+
debug!("{}", reg_vars_to_origins_str);
264265

265266
let num_components = sccs.scc_data().ranges().len();
266267
let mut components = vec![FxIndexSet::default(); num_components];
@@ -275,12 +276,12 @@ fn sccs_info<'cx, 'tcx>(
275276
for (scc_idx, reg_vars_origins) in components.iter().enumerate() {
276277
let regions_info = reg_vars_origins.clone().into_iter().collect::<Vec<_>>();
277278
components_str.push_str(&format!(
278-
"{:?}: {:?})",
279+
"{:?}: {:?},\n)",
279280
ConstraintSccIndex::from_usize(scc_idx),
280281
regions_info,
281282
))
282283
}
283-
debug!(components_str);
284+
debug!("{}", components_str);
284285

285286
// calculate the best representative for each component
286287
let components_representatives = components

compiler/rustc_borrowck/src/type_check/relate_tys.rs

+8-10
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,12 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
132132

133133
let reg_var =
134134
reg.as_var().unwrap_or_else(|| bug!("expected region {:?} to be of kind ReVar", reg));
135-
let mut var_to_origin = self.type_checker.infcx.reg_var_to_origin.borrow_mut();
136-
let prev = var_to_origin.insert(reg_var, RegionCtxt::Placeholder(reg_info));
137-
assert!(matches!(prev, None));
135+
136+
if cfg!(debug_assertions) && !self.type_checker.infcx.inside_canonicalization_ctxt() {
137+
let mut var_to_origin = self.type_checker.infcx.reg_var_to_origin.borrow_mut();
138+
debug!(?reg_var);
139+
var_to_origin.insert(reg_var, RegionCtxt::Placeholder(reg_info));
140+
}
138141

139142
reg
140143
}
@@ -149,14 +152,9 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
149152
let reg_var =
150153
reg.as_var().unwrap_or_else(|| bug!("expected region {:?} to be of kind ReVar", reg));
151154

152-
if cfg!(debug_assertions) {
155+
if cfg!(debug_assertions) && !self.type_checker.infcx.inside_canonicalization_ctxt() {
153156
let mut var_to_origin = self.type_checker.infcx.reg_var_to_origin.borrow_mut();
154-
let prev = var_to_origin.insert(reg_var, RegionCtxt::Existential(None));
155-
156-
// It only makes sense to track region vars in non-canonicalization contexts. If this
157-
// ever changes we either want to get rid of `BorrowckInferContext::reg_var_to_origin`
158-
// or modify how we track nll region vars for that map.
159-
assert!(matches!(prev, None));
157+
var_to_origin.insert(reg_var, RegionCtxt::Existential(None));
160158
}
161159

162160
reg

compiler/rustc_infer/src/infer/at.rs

+3
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ use super::*;
3030
use rustc_middle::ty::relate::{Relate, TypeRelation};
3131
use rustc_middle::ty::{Const, ImplSubject};
3232

33+
use std::cell::Cell;
34+
3335
/// Whether we should define opaque types or just treat them opaquely.
3436
///
3537
/// Currently only used to prevent predicate matching from matching anything
@@ -82,6 +84,7 @@ impl<'tcx> InferCtxt<'tcx> {
8284
in_snapshot: self.in_snapshot.clone(),
8385
universe: self.universe.clone(),
8486
intercrate: self.intercrate,
87+
inside_canonicalization_ctxt: Cell::new(self.inside_canonicalization_ctxt()),
8588
}
8689
}
8790
}

compiler/rustc_infer/src/infer/canonical/canonicalizer.rs

+2
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,8 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
561561
where
562562
V: TypeFoldable<TyCtxt<'tcx>>,
563563
{
564+
let _inside_canonical_ctxt_guard = infcx.set_canonicalization_ctxt();
565+
564566
let needs_canonical_flags = if canonicalize_region_mode.any() {
565567
TypeFlags::NEEDS_INFER |
566568
TypeFlags::HAS_FREE_REGIONS | // `HAS_RE_PLACEHOLDER` implies `HAS_FREE_REGIONS`

compiler/rustc_infer/src/infer/mod.rs

+32
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use rustc_span::Span;
3939

4040
use std::cell::{Cell, RefCell};
4141
use std::fmt;
42+
use std::ops::Drop;
4243

4344
use self::combine::CombineFields;
4445
use self::error_reporting::TypeErrCtxt;
@@ -342,6 +343,11 @@ pub struct InferCtxt<'tcx> {
342343
/// there is no type that the user could *actually name* that
343344
/// would satisfy it. This avoids crippling inference, basically.
344345
pub intercrate: bool,
346+
347+
/// Flag that is set when we enter canonicalization. Used for debugging to ensure
348+
/// that we only collect region information for `BorrowckInferCtxt::reg_var_to_origin`
349+
/// inside non-canonicalization contexts.
350+
inside_canonicalization_ctxt: Cell<bool>,
345351
}
346352

347353
/// See the `error_reporting` module for more details.
@@ -633,6 +639,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
633639
skip_leak_check: Cell::new(false),
634640
universe: Cell::new(ty::UniverseIndex::ROOT),
635641
intercrate,
642+
inside_canonicalization_ctxt: Cell::new(false),
636643
}
637644
}
638645
}
@@ -1728,6 +1735,31 @@ impl<'tcx> InferCtxt<'tcx> {
17281735
}
17291736
}
17301737
}
1738+
1739+
pub fn inside_canonicalization_ctxt(&self) -> bool {
1740+
self.inside_canonicalization_ctxt.get()
1741+
}
1742+
1743+
pub fn set_canonicalization_ctxt(&self) -> CanonicalizationCtxtGuard<'_, 'tcx> {
1744+
let prev_ctxt = self.inside_canonicalization_ctxt();
1745+
self.inside_canonicalization_ctxt.set(true);
1746+
CanonicalizationCtxtGuard { prev_ctxt, infcx: self }
1747+
}
1748+
1749+
fn set_canonicalization_ctxt_to(&self, ctxt: bool) {
1750+
self.inside_canonicalization_ctxt.set(ctxt);
1751+
}
1752+
}
1753+
1754+
pub struct CanonicalizationCtxtGuard<'cx, 'tcx> {
1755+
prev_ctxt: bool,
1756+
infcx: &'cx InferCtxt<'tcx>,
1757+
}
1758+
1759+
impl<'cx, 'tcx> Drop for CanonicalizationCtxtGuard<'cx, 'tcx> {
1760+
fn drop(&mut self) {
1761+
self.infcx.set_canonicalization_ctxt_to(self.prev_ctxt)
1762+
}
17311763
}
17321764

17331765
impl<'tcx> TypeErrCtxt<'_, 'tcx> {

0 commit comments

Comments
 (0)