Skip to content

Commit 812d4d5

Browse files
committed
introduce Unnormalized wrapper and make instantiation use it
1 parent 7659cec commit 812d4d5

4 files changed

Lines changed: 71 additions & 36 deletions

File tree

compiler/rustc_middle/src/ty/generics.rs

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_macros::{HashStable, TyDecodable, TyEncodable};
55
use rustc_span::{Span, Symbol, kw};
66
use tracing::instrument;
77

8-
use super::{Clause, InstantiatedPredicates, ParamConst, ParamTy, Ty, TyCtxt};
8+
use super::{Clause, InstantiatedPredicates, ParamConst, ParamTy, Ty, TyCtxt, Unnormalized};
99
use crate::ty;
1010
use crate::ty::{EarlyBinder, GenericArgsRef};
1111

@@ -368,23 +368,25 @@ impl<'tcx> GenericPredicates<'tcx> {
368368
self,
369369
tcx: TyCtxt<'tcx>,
370370
args: GenericArgsRef<'tcx>,
371-
) -> InstantiatedPredicates<'tcx> {
371+
) -> Unnormalized<InstantiatedPredicates<'tcx>> {
372372
let mut instantiated = InstantiatedPredicates::empty();
373373
self.instantiate_into(tcx, &mut instantiated, args);
374-
instantiated
374+
Unnormalized::new(instantiated)
375375
}
376376

377377
pub fn instantiate_own(
378378
self,
379379
tcx: TyCtxt<'tcx>,
380380
args: GenericArgsRef<'tcx>,
381-
) -> impl Iterator<Item = (Clause<'tcx>, Span)> + DoubleEndedIterator + ExactSizeIterator {
381+
) -> impl Iterator<Item = Unnormalized<(Clause<'tcx>, Span)>> + DoubleEndedIterator + ExactSizeIterator
382+
{
382383
EarlyBinder::bind(self.predicates).iter_instantiated_copied(tcx, args)
383384
}
384385

385386
pub fn instantiate_own_identity(
386387
self,
387-
) -> impl Iterator<Item = (Clause<'tcx>, Span)> + DoubleEndedIterator + ExactSizeIterator {
388+
) -> impl Iterator<Item = Unnormalized<(Clause<'tcx>, Span)>> + DoubleEndedIterator + ExactSizeIterator
389+
{
388390
EarlyBinder::bind(self.predicates).iter_identity_copied()
389391
}
390392

@@ -399,15 +401,20 @@ impl<'tcx> GenericPredicates<'tcx> {
399401
tcx.predicates_of(def_id).instantiate_into(tcx, instantiated, args);
400402
}
401403
instantiated.predicates.extend(
402-
self.predicates.iter().map(|(p, _)| EarlyBinder::bind(*p).instantiate(tcx, args)),
404+
self.predicates
405+
.iter()
406+
.map(|(p, _)| EarlyBinder::bind(*p).instantiate(tcx, args).skip_normalization()),
403407
);
404408
instantiated.spans.extend(self.predicates.iter().map(|(_, sp)| *sp));
405409
}
406410

407-
pub fn instantiate_identity(self, tcx: TyCtxt<'tcx>) -> InstantiatedPredicates<'tcx> {
411+
pub fn instantiate_identity(
412+
self,
413+
tcx: TyCtxt<'tcx>,
414+
) -> Unnormalized<InstantiatedPredicates<'tcx>> {
408415
let mut instantiated = InstantiatedPredicates::empty();
409416
self.instantiate_identity_into(tcx, &mut instantiated);
410-
instantiated
417+
Unnormalized::new(instantiated)
411418
}
412419

413420
fn instantiate_identity_into(
@@ -438,25 +445,27 @@ impl<'tcx> ConstConditions<'tcx> {
438445
self,
439446
tcx: TyCtxt<'tcx>,
440447
args: GenericArgsRef<'tcx>,
441-
) -> Vec<(ty::PolyTraitRef<'tcx>, Span)> {
448+
) -> Unnormalized<Vec<(ty::PolyTraitRef<'tcx>, Span)>> {
442449
let mut instantiated = vec![];
443450
self.instantiate_into(tcx, &mut instantiated, args);
444-
instantiated
451+
Unnormalized::new(instantiated)
445452
}
446453

447454
pub fn instantiate_own(
448455
self,
449456
tcx: TyCtxt<'tcx>,
450457
args: GenericArgsRef<'tcx>,
451-
) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, Span)> + DoubleEndedIterator + ExactSizeIterator
452-
{
458+
) -> impl Iterator<Item = Unnormalized<(ty::PolyTraitRef<'tcx>, Span)>>
459+
+ DoubleEndedIterator
460+
+ ExactSizeIterator {
453461
EarlyBinder::bind(self.predicates).iter_instantiated_copied(tcx, args)
454462
}
455463

456464
pub fn instantiate_own_identity(
457465
self,
458-
) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, Span)> + DoubleEndedIterator + ExactSizeIterator
459-
{
466+
) -> impl Iterator<Item = Unnormalized<(ty::PolyTraitRef<'tcx>, Span)>>
467+
+ DoubleEndedIterator
468+
+ ExactSizeIterator {
460469
EarlyBinder::bind(self.predicates).iter_identity_copied()
461470
}
462471

@@ -471,14 +480,19 @@ impl<'tcx> ConstConditions<'tcx> {
471480
tcx.const_conditions(def_id).instantiate_into(tcx, instantiated, args);
472481
}
473482
instantiated.extend(
474-
self.predicates.iter().map(|&(p, s)| (EarlyBinder::bind(p).instantiate(tcx, args), s)),
483+
self.predicates.iter().map(|&(p, s)| {
484+
(EarlyBinder::bind(p).instantiate(tcx, args).skip_normalization(), s)
485+
}),
475486
);
476487
}
477488

478-
pub fn instantiate_identity(self, tcx: TyCtxt<'tcx>) -> Vec<(ty::PolyTraitRef<'tcx>, Span)> {
489+
pub fn instantiate_identity(
490+
self,
491+
tcx: TyCtxt<'tcx>,
492+
) -> Unnormalized<Vec<(ty::PolyTraitRef<'tcx>, Span)>> {
479493
let mut instantiated = vec![];
480494
self.instantiate_identity_into(tcx, &mut instantiated);
481-
instantiated
495+
Unnormalized::new(instantiated)
482496
}
483497

484498
fn instantiate_identity_into(

compiler/rustc_type_ir/src/binder.rs

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldabl
1616
use crate::inherent::*;
1717
use crate::lift::Lift;
1818
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
19-
use crate::{self as ty, DebruijnIndex, Interner, UniverseIndex};
19+
use crate::{self as ty, DebruijnIndex, Interner, UniverseIndex, Unnormalized};
2020

2121
/// `Binder` is a binder for higher-ranked lifetimes or types. It is part of the
2222
/// compiler's representation for things like `for<'a> Fn(&'a isize)`
@@ -459,8 +459,8 @@ where
459459

460460
/// Similar to [`instantiate_identity`](EarlyBinder::instantiate_identity),
461461
/// but on an iterator of `TypeFoldable` values.
462-
pub fn iter_identity(self) -> Iter::IntoIter {
463-
self.value.into_iter()
462+
pub fn iter_identity(self) -> impl Iterator<Item = Unnormalized<Iter::Item>> {
463+
self.value.into_iter().map(Unnormalized::new)
464464
}
465465
}
466466

@@ -475,7 +475,7 @@ where
475475
Iter::Item: TypeFoldable<I>,
476476
A: SliceLike<Item = I::GenericArg>,
477477
{
478-
type Item = Iter::Item;
478+
type Item = Unnormalized<Iter::Item>;
479479

480480
fn next(&mut self) -> Option<Self::Item> {
481481
Some(
@@ -526,8 +526,8 @@ where
526526

527527
/// Similar to [`instantiate_identity`](EarlyBinder::instantiate_identity),
528528
/// but on an iterator of values that deref to a `TypeFoldable`.
529-
pub fn iter_identity_copied(self) -> IterIdentityCopied<Iter> {
530-
IterIdentityCopied { it: self.value.into_iter() }
529+
pub fn iter_identity_copied(self) -> IterIdentityCopied<I, Iter> {
530+
IterIdentityCopied { it: self.value.into_iter(), _tcx: PhantomData }
531531
}
532532
}
533533

@@ -542,7 +542,7 @@ where
542542
Iter::Item: Deref,
543543
<Iter::Item as Deref>::Target: Copy + TypeFoldable<I>,
544544
{
545-
type Item = <Iter::Item as Deref>::Target;
545+
type Item = Unnormalized<<Iter::Item as Deref>::Target>;
546546

547547
fn next(&mut self) -> Option<Self::Item> {
548548
self.it.next().map(|value| {
@@ -576,38 +576,39 @@ where
576576
{
577577
}
578578

579-
pub struct IterIdentityCopied<Iter: IntoIterator> {
579+
pub struct IterIdentityCopied<I: Interner, Iter: IntoIterator> {
580580
it: Iter::IntoIter,
581+
_tcx: PhantomData<fn() -> I>,
581582
}
582583

583-
impl<Iter: IntoIterator> Iterator for IterIdentityCopied<Iter>
584+
impl<I: Interner, Iter: IntoIterator> Iterator for IterIdentityCopied<I, Iter>
584585
where
585586
Iter::Item: Deref,
586587
<Iter::Item as Deref>::Target: Copy,
587588
{
588-
type Item = <Iter::Item as Deref>::Target;
589+
type Item = Unnormalized<<Iter::Item as Deref>::Target>;
589590

590591
fn next(&mut self) -> Option<Self::Item> {
591-
self.it.next().map(|i| *i)
592+
self.it.next().map(|i| Unnormalized::new(*i))
592593
}
593594

594595
fn size_hint(&self) -> (usize, Option<usize>) {
595596
self.it.size_hint()
596597
}
597598
}
598599

599-
impl<Iter: IntoIterator> DoubleEndedIterator for IterIdentityCopied<Iter>
600+
impl<I: Interner, Iter: IntoIterator> DoubleEndedIterator for IterIdentityCopied<I, Iter>
600601
where
601602
Iter::IntoIter: DoubleEndedIterator,
602603
Iter::Item: Deref,
603604
<Iter::Item as Deref>::Target: Copy,
604605
{
605606
fn next_back(&mut self) -> Option<Self::Item> {
606-
self.it.next_back().map(|i| *i)
607+
self.it.next_back().map(|i| Unnormalized::new(*i))
607608
}
608609
}
609610

610-
impl<Iter: IntoIterator> ExactSizeIterator for IterIdentityCopied<Iter>
611+
impl<I: Interner, Iter: IntoIterator> ExactSizeIterator for IterIdentityCopied<I, Iter>
611612
where
612613
Iter::IntoIter: ExactSizeIterator,
613614
Iter::Item: Deref,
@@ -638,7 +639,7 @@ impl<I: Interner, T: Iterator> Iterator for EarlyBinderIter<I, T> {
638639
}
639640

640641
impl<I: Interner, T: TypeFoldable<I>> ty::EarlyBinder<I, T> {
641-
pub fn instantiate<A>(self, cx: I, args: A) -> T
642+
pub fn instantiate<A>(self, cx: I, args: A) -> Unnormalized<T>
642643
where
643644
A: SliceLike<Item = I::GenericArg>,
644645
{
@@ -651,10 +652,10 @@ impl<I: Interner, T: TypeFoldable<I>> ty::EarlyBinder<I, T> {
651652
"{:?} has parameters, but no args were provided in instantiate",
652653
self.value,
653654
);
654-
return self.value;
655+
return Unnormalized::new(self.value);
655656
}
656657
let mut folder = ArgFolder { cx, args: args.as_slice(), binders_passed: 0 };
657-
self.value.fold_with(&mut folder)
658+
Unnormalized::new(self.value.fold_with(&mut folder))
658659
}
659660

660661
/// Makes the identity replacement `T0 => T0, ..., TN => TN`.
@@ -665,8 +666,8 @@ impl<I: Interner, T: TypeFoldable<I>> ty::EarlyBinder<I, T> {
665666
/// - Outside of `foo`, `T` is bound (represented by the presence of `EarlyBinder`).
666667
/// - Inside of the body of `foo`, we treat `T` as a placeholder by calling
667668
/// `instantiate_identity` to discharge the `EarlyBinder`.
668-
pub fn instantiate_identity(self) -> T {
669-
self.value
669+
pub fn instantiate_identity(self) -> Unnormalized<T> {
670+
Unnormalized::new(self.value)
670671
}
671672

672673
/// Returns the inner value, but only if it contains no bound vars.

compiler/rustc_type_ir/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ mod predicate_kind;
5353
mod region_kind;
5454
mod ty_info;
5555
mod ty_kind;
56+
mod unnormalized;
5657
mod upcast;
5758
mod visit;
5859

@@ -80,6 +81,7 @@ pub use rustc_ast_ir::{FloatTy, IntTy, Movability, Mutability, Pinnedness, UintT
8081
use rustc_type_ir_macros::GenericTypeVisitable;
8182
pub use ty_info::*;
8283
pub use ty_kind::*;
84+
pub use unnormalized::Unnormalized;
8385
pub use upcast::*;
8486
pub use visit::*;
8587

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/// A wrapper for value that needs normalization.
2+
/// FIXME: This is very WIP. It's planned to replace the `skip_normalization` spreaded
3+
/// in the codebase with proper normalization. It's the first step toward switching to eager
4+
/// normalization with the next solver.
5+
#[derive(Clone, PartialOrd, PartialEq, Debug)]
6+
pub struct Unnormalized<T> {
7+
value: T,
8+
}
9+
10+
impl<T> Unnormalized<T> {
11+
pub fn new(value: T) -> Unnormalized<T> {
12+
Unnormalized { value }
13+
}
14+
15+
pub fn skip_normalization(self) -> T {
16+
self.value
17+
}
18+
}

0 commit comments

Comments
 (0)