Skip to content

Commit 2ad8c7b

Browse files
committed
Auto merge of #55330 - scalexm:bound-ty, r=nikomatsakis
Add support for bound types This PR may have some slight performance impacts, I don't know how hot is the code I touched. Also, this breaks clippy and miri. r? @nikomatsakis
2 parents b6e8f9d + c5ed72f commit 2ad8c7b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+555
-390
lines changed

src/librustc/ich/impls_ty.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,6 @@ for ty::RegionKind {
100100
ty::ReEmpty => {
101101
// No variant fields to hash for these ...
102102
}
103-
ty::ReCanonical(c) => {
104-
c.hash_stable(hcx, hasher);
105-
}
106103
ty::ReLateBound(db, ty::BrAnon(i)) => {
107104
db.hash_stable(hcx, hasher);
108105
i.hash_stable(hcx, hasher);
@@ -147,7 +144,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for ty::RegionVid {
147144
}
148145
}
149146

150-
impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::BoundTyIndex {
147+
impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::BoundVar {
151148
#[inline]
152149
fn hash_stable<W: StableHasherResult>(&self,
153150
hcx: &mut StableHashingContext<'gcx>,
@@ -852,6 +849,9 @@ for ty::TyKind<'gcx>
852849
Param(param_ty) => {
853850
param_ty.hash_stable(hcx, hasher);
854851
}
852+
Bound(bound_ty) => {
853+
bound_ty.hash_stable(hcx, hasher);
854+
}
855855
Foreign(def_id) => {
856856
def_id.hash_stable(hcx, hasher);
857857
}
@@ -869,7 +869,6 @@ impl_stable_hash_for!(enum ty::InferTy {
869869
FreshTy(a),
870870
FreshIntTy(a),
871871
FreshFloatTy(a),
872-
BoundTy(a),
873872
});
874873

875874
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>

src/librustc/infer/canonical/canonicalizer.rs

+42-30
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use infer::InferCtxt;
2323
use std::sync::atomic::Ordering;
2424
use ty::fold::{TypeFoldable, TypeFolder};
2525
use ty::subst::Kind;
26-
use ty::{self, BoundTy, BoundTyIndex, Lift, List, Ty, TyCtxt, TypeFlags};
26+
use ty::{self, BoundTy, BoundVar, Lift, List, Ty, TyCtxt, TypeFlags};
2727

2828
use rustc_data_structures::fx::FxHashMap;
2929
use rustc_data_structures::indexed_vec::Idx;
@@ -277,21 +277,35 @@ struct Canonicalizer<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
277277
query_state: &'cx mut OriginalQueryValues<'tcx>,
278278
// Note that indices is only used once `var_values` is big enough to be
279279
// heap-allocated.
280-
indices: FxHashMap<Kind<'tcx>, BoundTyIndex>,
280+
indices: FxHashMap<Kind<'tcx>, BoundVar>,
281281
canonicalize_region_mode: &'cx dyn CanonicalizeRegionMode,
282282
needs_canonical_flags: TypeFlags,
283+
284+
binder_index: ty::DebruijnIndex,
283285
}
284286

285287
impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx> {
286288
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> {
287289
self.tcx
288290
}
289291

292+
fn fold_binder<T>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T>
293+
where T: TypeFoldable<'tcx>
294+
{
295+
self.binder_index.shift_in(1);
296+
let t = t.super_fold_with(self);
297+
self.binder_index.shift_out(1);
298+
t
299+
}
300+
290301
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
291302
match *r {
292-
ty::ReLateBound(..) => {
293-
// leave bound regions alone
294-
r
303+
ty::ReLateBound(index, ..) => {
304+
if index >= self.binder_index {
305+
bug!("escaping late bound region during canonicalization")
306+
} else {
307+
r
308+
}
295309
}
296310

297311
ty::ReVar(vid) => {
@@ -317,8 +331,8 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
317331
| ty::ReErased => self.canonicalize_region_mode
318332
.canonicalize_free_region(self, r),
319333

320-
ty::ReClosureBound(..) | ty::ReCanonical(_) => {
321-
bug!("canonical region encountered during canonicalization")
334+
ty::ReClosureBound(..) => {
335+
bug!("closure bound region encountered during canonicalization")
322336
}
323337
}
324338
}
@@ -337,8 +351,12 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
337351
bug!("encountered a fresh type during canonicalization")
338352
}
339353

340-
ty::Infer(ty::BoundTy(_)) => {
341-
bug!("encountered a canonical type during canonicalization")
354+
ty::Bound(bound_ty) => {
355+
if bound_ty.index >= self.binder_index {
356+
bug!("escaping bound type during canonicalization")
357+
} else {
358+
t
359+
}
342360
}
343361

344362
ty::Closure(..)
@@ -389,12 +407,6 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
389407
where
390408
V: TypeFoldable<'tcx> + Lift<'gcx>,
391409
{
392-
debug_assert!(
393-
!value.has_type_flags(TypeFlags::HAS_CANONICAL_VARS),
394-
"canonicalizing a canonical value: {:?}",
395-
value,
396-
);
397-
398410
let needs_canonical_flags = if canonicalize_region_mode.any() {
399411
TypeFlags::HAS_FREE_REGIONS | TypeFlags::KEEP_IN_LOCAL_TCX
400412
} else {
@@ -422,6 +434,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
422434
variables: SmallVec::new(),
423435
query_state,
424436
indices: FxHashMap::default(),
437+
binder_index: ty::INNERMOST,
425438
};
426439
let out_value = value.fold_with(&mut canonicalizer);
427440

@@ -455,7 +468,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
455468
/// or returns an existing variable if `kind` has already been
456469
/// seen. `kind` is expected to be an unbound variable (or
457470
/// potentially a free region).
458-
fn canonical_var(&mut self, info: CanonicalVarInfo, kind: Kind<'tcx>) -> BoundTy {
471+
fn canonical_var(&mut self, info: CanonicalVarInfo, kind: Kind<'tcx>) -> BoundVar {
459472
let Canonicalizer {
460473
variables,
461474
query_state,
@@ -475,7 +488,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
475488
// direct linear search of `var_values`.
476489
if let Some(idx) = var_values.iter().position(|&k| k == kind) {
477490
// `kind` is already present in `var_values`.
478-
BoundTyIndex::new(idx)
491+
BoundVar::new(idx)
479492
} else {
480493
// `kind` isn't present in `var_values`. Append it. Likewise
481494
// for `info` and `variables`.
@@ -490,26 +503,23 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
490503
*indices = var_values
491504
.iter()
492505
.enumerate()
493-
.map(|(i, &kind)| (kind, BoundTyIndex::new(i)))
506+
.map(|(i, &kind)| (kind, BoundVar::new(i)))
494507
.collect();
495508
}
496509
// The cv is the index of the appended element.
497-
BoundTyIndex::new(var_values.len() - 1)
510+
BoundVar::new(var_values.len() - 1)
498511
}
499512
} else {
500513
// `var_values` is large. Do a hashmap search via `indices`.
501514
*indices.entry(kind).or_insert_with(|| {
502515
variables.push(info);
503516
var_values.push(kind);
504517
assert_eq!(variables.len(), var_values.len());
505-
BoundTyIndex::new(variables.len() - 1)
518+
BoundVar::new(variables.len() - 1)
506519
})
507520
};
508521

509-
BoundTy {
510-
level: ty::INNERMOST,
511-
var,
512-
}
522+
var
513523
}
514524

515525
/// Shorthand helper that creates a canonical region variable for
@@ -552,9 +562,12 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
552562
info: CanonicalVarInfo,
553563
r: ty::Region<'tcx>,
554564
) -> ty::Region<'tcx> {
555-
let b = self.canonical_var(info, r.into());
556-
debug_assert_eq!(ty::INNERMOST, b.level);
557-
self.tcx().mk_region(ty::ReCanonical(b.var))
565+
let var = self.canonical_var(info, r.into());
566+
let region = ty::ReLateBound(
567+
self.binder_index,
568+
ty::BoundRegion::BrAnon(var.as_u32())
569+
);
570+
self.tcx().mk_region(region)
558571
}
559572

560573
/// Given a type variable `ty_var` of the given kind, first check
@@ -570,9 +583,8 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
570583
let info = CanonicalVarInfo {
571584
kind: CanonicalVarKind::Ty(ty_kind),
572585
};
573-
let b = self.canonical_var(info, ty_var.into());
574-
debug_assert_eq!(ty::INNERMOST, b.level);
575-
self.tcx().mk_infer(ty::InferTy::BoundTy(b))
586+
let var = self.canonical_var(info, ty_var.into());
587+
self.tcx().mk_ty(ty::Bound(BoundTy::new(self.binder_index, var)))
576588
}
577589
}
578590
}

src/librustc/infer/canonical/mod.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
//! - a map M (of type `CanonicalVarValues`) from those canonical
2121
//! variables back to the original.
2222
//!
23-
//! We can then do queries using T2. These will give back constriants
23+
//! We can then do queries using T2. These will give back constraints
2424
//! on the canonical variables which can be translated, using the map
2525
//! M, into constraints in our source context. This process of
2626
//! translating the results back is done by the
@@ -40,7 +40,7 @@ use std::ops::Index;
4040
use syntax::source_map::Span;
4141
use ty::fold::TypeFoldable;
4242
use ty::subst::Kind;
43-
use ty::{self, BoundTyIndex, Lift, List, Region, TyCtxt};
43+
use ty::{self, BoundVar, Lift, List, Region, TyCtxt};
4444

4545
mod canonicalizer;
4646

@@ -73,7 +73,7 @@ impl<'gcx> UseSpecializedDecodable for CanonicalVarInfos<'gcx> {}
7373
/// canonicalized query response.
7474
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)]
7575
pub struct CanonicalVarValues<'tcx> {
76-
pub var_values: IndexVec<BoundTyIndex, Kind<'tcx>>,
76+
pub var_values: IndexVec<BoundVar, Kind<'tcx>>,
7777
}
7878

7979
/// When we canonicalize a value to form a query, we wind up replacing
@@ -337,7 +337,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
337337
variables: &List<CanonicalVarInfo>,
338338
universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
339339
) -> CanonicalVarValues<'tcx> {
340-
let var_values: IndexVec<BoundTyIndex, Kind<'tcx>> = variables
340+
let var_values: IndexVec<BoundVar, Kind<'tcx>> = variables
341341
.iter()
342342
.map(|info| self.instantiate_canonical_var(span, *info, &universe_map))
343343
.collect();
@@ -456,10 +456,10 @@ BraceStructLiftImpl! {
456456
} where R: Lift<'tcx>
457457
}
458458

459-
impl<'tcx> Index<BoundTyIndex> for CanonicalVarValues<'tcx> {
459+
impl<'tcx> Index<BoundVar> for CanonicalVarValues<'tcx> {
460460
type Output = Kind<'tcx>;
461461

462-
fn index(&self, value: BoundTyIndex) -> &Kind<'tcx> {
462+
fn index(&self, value: BoundVar) -> &Kind<'tcx> {
463463
&self.var_values[value]
464464
}
465465
}

0 commit comments

Comments
 (0)