Skip to content

Commit 98d29d4

Browse files
bors[bot]Veykril
andauthored
Merge #8101
8101: Replace Projection variant in GenericPredicate with AliasEq r=flodiebold a=Veykril Co-authored-by: Lukas Wirth <[email protected]>
2 parents 26fdd17 + 8996b1a commit 98d29d4

File tree

10 files changed

+221
-131
lines changed

10 files changed

+221
-131
lines changed

crates/hir/src/lib.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ use hir_ty::{
5656
primitive::UintTy,
5757
to_assoc_type_id,
5858
traits::{FnTrait, Solution, SolutionVariables},
59-
AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate,
60-
InEnvironment, Interner, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substitution,
61-
Ty, TyDefId, TyKind, TyVariableKind,
59+
AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex,
60+
GenericPredicate, InEnvironment, Interner, Obligation, ProjectionTy, Scalar, Substitution, Ty,
61+
TyDefId, TyKind, TyVariableKind,
6262
};
6363
use itertools::Itertools;
6464
use rustc_hash::FxHashSet;
@@ -1786,17 +1786,17 @@ impl Type {
17861786
.push(self.ty.value.clone())
17871787
.fill(args.iter().map(|t| t.ty.value.clone()))
17881788
.build();
1789-
let predicate = ProjectionPredicate {
1790-
projection_ty: ProjectionTy {
1791-
associated_ty_id: to_assoc_type_id(alias.id),
1792-
substitution: subst,
1793-
},
1794-
ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner),
1795-
};
17961789
let goal = Canonical {
17971790
value: InEnvironment::new(
17981791
self.ty.environment.clone(),
1799-
Obligation::Projection(predicate),
1792+
Obligation::AliasEq(AliasEq {
1793+
alias: AliasTy::Projection(ProjectionTy {
1794+
associated_ty_id: to_assoc_type_id(alias.id),
1795+
substitution: subst,
1796+
}),
1797+
ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
1798+
.intern(&Interner),
1799+
}),
18001800
),
18011801
kinds: Arc::new([TyVariableKind::General]),
18021802
};

crates/hir_ty/src/autoderef.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ use crate::{
1515
to_assoc_type_id, to_chalk_trait_id,
1616
traits::{InEnvironment, Solution},
1717
utils::generics,
18-
BoundVar, Canonical, DebruijnIndex, Interner, Obligation, Substitution, TraitRef, Ty, TyKind,
18+
AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, Interner, Obligation, ProjectionTy,
19+
Substitution, TraitRef, Ty, TyKind,
1920
};
2021

2122
const AUTODEREF_RECURSION_LIMIT: usize = 10;
@@ -82,16 +83,16 @@ fn deref_by_trait(
8283
}
8384

8485
// Now do the assoc type projection
85-
let projection = super::traits::ProjectionPredicate {
86-
ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len()))
87-
.intern(&Interner),
88-
projection_ty: super::ProjectionTy {
86+
let projection = AliasEq {
87+
alias: AliasTy::Projection(ProjectionTy {
8988
associated_ty_id: to_assoc_type_id(target),
9089
substitution: parameters,
91-
},
90+
}),
91+
ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len()))
92+
.intern(&Interner),
9293
};
9394

94-
let obligation = super::Obligation::Projection(projection);
95+
let obligation = super::Obligation::AliasEq(projection);
9596

9697
let in_env = InEnvironment { value: obligation, environment: ty.environment };
9798

crates/hir_ty/src/display.rs

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ use hir_expand::name::Name;
1818

1919
use crate::{
2020
db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive,
21-
to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasTy, CallableDefId,
22-
CallableSig, GenericPredicate, ImplTraitId, Interner, Lifetime, Obligation, OpaqueTy,
23-
ProjectionTy, Scalar, Substitution, TraitRef, Ty, TyKind,
21+
to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy,
22+
CallableDefId, CallableSig, GenericPredicate, ImplTraitId, Interner, Lifetime, Obligation,
23+
OpaqueTy, ProjectionTy, Scalar, Substitution, TraitRef, Ty, TyKind,
2424
};
2525

2626
pub struct HirFormatter<'a> {
@@ -268,6 +268,16 @@ impl HirDisplay for ProjectionTy {
268268
}
269269
}
270270

271+
impl HirDisplay for OpaqueTy {
272+
fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
273+
if f.should_truncate() {
274+
return write!(f, "{}", TYPE_HINT_TRUNCATION);
275+
}
276+
277+
self.substitution[0].hir_fmt(f)
278+
}
279+
}
280+
271281
impl HirDisplay for Ty {
272282
fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
273283
if f.should_truncate() {
@@ -700,12 +710,12 @@ fn write_bounds_like_dyn_trait(
700710
}
701711
}
702712
}
703-
GenericPredicate::Projection(projection_pred) if is_fn_trait => {
713+
GenericPredicate::AliasEq(alias_eq) if is_fn_trait => {
704714
is_fn_trait = false;
705715
write!(f, " -> ")?;
706-
projection_pred.ty.hir_fmt(f)?;
716+
alias_eq.ty.hir_fmt(f)?;
707717
}
708-
GenericPredicate::Projection(projection_pred) => {
718+
GenericPredicate::AliasEq(AliasEq { ty, alias }) => {
709719
// in types in actual Rust, these will always come
710720
// after the corresponding Implemented predicate
711721
if angle_open {
@@ -714,11 +724,12 @@ fn write_bounds_like_dyn_trait(
714724
write!(f, "<")?;
715725
angle_open = true;
716726
}
717-
let type_alias = f.db.type_alias_data(from_assoc_type_id(
718-
projection_pred.projection_ty.associated_ty_id,
719-
));
720-
write!(f, "{} = ", type_alias.name)?;
721-
projection_pred.ty.hir_fmt(f)?;
727+
if let AliasTy::Projection(proj) = alias {
728+
let type_alias =
729+
f.db.type_alias_data(from_assoc_type_id(proj.associated_ty_id));
730+
write!(f, "{} = ", type_alias.name)?;
731+
}
732+
ty.hir_fmt(f)?;
722733
}
723734
GenericPredicate::Error => {
724735
if angle_open {
@@ -775,20 +786,20 @@ impl HirDisplay for GenericPredicate {
775786

776787
match self {
777788
GenericPredicate::Implemented(trait_ref) => trait_ref.hir_fmt(f)?,
778-
GenericPredicate::Projection(projection_pred) => {
789+
GenericPredicate::AliasEq(AliasEq {
790+
alias: AliasTy::Projection(projection_ty),
791+
ty,
792+
}) => {
779793
write!(f, "<")?;
780-
projection_pred.projection_ty.trait_ref(f.db).hir_fmt_ext(f, true)?;
794+
projection_ty.trait_ref(f.db).hir_fmt_ext(f, true)?;
781795
write!(
782796
f,
783797
">::{} = ",
784-
f.db.type_alias_data(from_assoc_type_id(
785-
projection_pred.projection_ty.associated_ty_id
786-
))
787-
.name,
798+
f.db.type_alias_data(from_assoc_type_id(projection_ty.associated_ty_id)).name,
788799
)?;
789-
projection_pred.ty.hir_fmt(f)?;
800+
ty.hir_fmt(f)?;
790801
}
791-
GenericPredicate::Error => write!(f, "{{error}}")?,
802+
GenericPredicate::AliasEq(_) | GenericPredicate::Error => write!(f, "{{error}}")?,
792803
}
793804
Ok(())
794805
}
@@ -815,11 +826,14 @@ impl HirDisplay for Obligation {
815826
tr.hir_fmt(f)?;
816827
write!(f, ")")
817828
}
818-
Obligation::Projection(proj) => {
829+
Obligation::AliasEq(AliasEq { alias, ty }) => {
819830
write!(f, "Normalize(")?;
820-
proj.projection_ty.hir_fmt(f)?;
831+
match alias {
832+
AliasTy::Projection(projection_ty) => projection_ty.hir_fmt(f)?,
833+
AliasTy::Opaque(opaque) => opaque.hir_fmt(f)?,
834+
}
821835
write!(f, " => ")?;
822-
proj.ty.hir_fmt(f)?;
836+
ty.hir_fmt(f)?;
823837
write!(f, ")")
824838
}
825839
}

crates/hir_ty/src/infer.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,12 @@ use stdx::impl_from;
3737
use syntax::SmolStr;
3838

3939
use super::{
40-
traits::{Guidance, Obligation, ProjectionPredicate, Solution},
40+
traits::{Guidance, Obligation, Solution},
4141
InEnvironment, ProjectionTy, Substitution, TraitEnvironment, TraitRef, Ty, TypeWalk,
4242
};
4343
use crate::{
4444
db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode,
45-
to_assoc_type_id, to_chalk_trait_id, AliasTy, Interner, TyKind,
45+
to_assoc_type_id, to_chalk_trait_id, AliasEq, AliasTy, Interner, TyKind,
4646
};
4747

4848
pub(crate) use unify::unify;
@@ -396,15 +396,15 @@ impl<'a> InferenceContext<'a> {
396396
.build();
397397
let trait_ref =
398398
TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs.clone() };
399-
let projection = ProjectionPredicate {
400-
ty: ty.clone(),
401-
projection_ty: ProjectionTy {
399+
let alias_eq = AliasEq {
400+
alias: AliasTy::Projection(ProjectionTy {
402401
associated_ty_id: to_assoc_type_id(res_assoc_ty),
403402
substitution: substs,
404-
},
403+
}),
404+
ty: ty.clone(),
405405
};
406406
self.obligations.push(Obligation::Trait(trait_ref));
407-
self.obligations.push(Obligation::Projection(projection));
407+
self.obligations.push(Obligation::AliasEq(alias_eq));
408408
self.resolve_ty_as_possible(ty)
409409
}
410410
None => self.err_ty(),
@@ -429,8 +429,8 @@ impl<'a> InferenceContext<'a> {
429429

430430
fn normalize_projection_ty(&mut self, proj_ty: ProjectionTy) -> Ty {
431431
let var = self.table.new_type_var();
432-
let predicate = ProjectionPredicate { projection_ty: proj_ty, ty: var.clone() };
433-
let obligation = Obligation::Projection(predicate);
432+
let alias_eq = AliasEq { alias: AliasTy::Projection(proj_ty), ty: var.clone() };
433+
let obligation = Obligation::AliasEq(alias_eq);
434434
self.obligations.push(obligation);
435435
var
436436
}

crates/hir_ty/src/infer/unify.rs

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
77

88
use super::{InferenceContext, Obligation};
99
use crate::{
10-
BoundVar, Canonical, DebruijnIndex, FnPointer, GenericPredicate, InEnvironment, InferenceVar,
11-
Interner, Scalar, Substitution, Ty, TyKind, TypeWalk,
10+
AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, FnPointer, GenericPredicate,
11+
InEnvironment, InferenceVar, Interner, Scalar, Substitution, Ty, TyKind, TypeWalk,
1212
};
1313

1414
impl<'a> InferenceContext<'a> {
@@ -93,8 +93,8 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
9393
Obligation::Trait(tr) => {
9494
Obligation::Trait(self.do_canonicalize(tr, DebruijnIndex::INNERMOST))
9595
}
96-
Obligation::Projection(pr) => {
97-
Obligation::Projection(self.do_canonicalize(pr, DebruijnIndex::INNERMOST))
96+
Obligation::AliasEq(alias_eq) => {
97+
Obligation::AliasEq(self.do_canonicalize(alias_eq, DebruijnIndex::INNERMOST))
9898
}
9999
};
100100
self.into_canonicalized(InEnvironment {
@@ -394,14 +394,25 @@ impl InferenceTable {
394394
{
395395
self.unify_substs(&tr1.substitution, &tr2.substitution, depth + 1)
396396
}
397-
(GenericPredicate::Projection(proj1), GenericPredicate::Projection(proj2))
398-
if proj1.projection_ty.associated_ty_id == proj2.projection_ty.associated_ty_id =>
399-
{
400-
self.unify_substs(
401-
&proj1.projection_ty.substitution,
402-
&proj2.projection_ty.substitution,
403-
depth + 1,
404-
) && self.unify_inner(&proj1.ty, &proj2.ty, depth + 1)
397+
(
398+
GenericPredicate::AliasEq(AliasEq { alias: alias1, ty: ty1 }),
399+
GenericPredicate::AliasEq(AliasEq { alias: alias2, ty: ty2 }),
400+
) => {
401+
let (substitution1, substitution2) = match (alias1, alias2) {
402+
(AliasTy::Projection(projection_ty1), AliasTy::Projection(projection_ty2))
403+
if projection_ty1.associated_ty_id == projection_ty2.associated_ty_id =>
404+
{
405+
(&projection_ty1.substitution, &projection_ty2.substitution)
406+
}
407+
(AliasTy::Opaque(opaque1), AliasTy::Opaque(opaque2))
408+
if opaque1.opaque_ty_id == opaque2.opaque_ty_id =>
409+
{
410+
(&opaque1.substitution, &opaque2.substitution)
411+
}
412+
_ => return false,
413+
};
414+
self.unify_substs(&substitution1, &substitution2, depth + 1)
415+
&& self.unify_inner(&ty1, &ty2, depth + 1)
405416
}
406417
_ => false,
407418
}

crates/hir_ty/src/lib.rs

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ pub use lower::{
4545
associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode,
4646
TyDefId, TyLoweringContext, ValueTyDefId,
4747
};
48-
pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment};
48+
pub use traits::{AliasEq, InEnvironment, Obligation, TraitEnvironment};
4949

5050
pub use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind};
5151

@@ -72,6 +72,20 @@ pub struct OpaqueTy {
7272
pub substitution: Substitution,
7373
}
7474

75+
impl TypeWalk for OpaqueTy {
76+
fn walk(&self, f: &mut impl FnMut(&Ty)) {
77+
self.substitution.walk(f);
78+
}
79+
80+
fn walk_mut_binders(
81+
&mut self,
82+
f: &mut impl FnMut(&mut Ty, DebruijnIndex),
83+
binders: DebruijnIndex,
84+
) {
85+
self.substitution.walk_mut_binders(f, binders);
86+
}
87+
}
88+
7589
/// A "projection" type corresponds to an (unnormalized)
7690
/// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the
7791
/// trait and all its parameters are fully known.
@@ -133,6 +147,25 @@ pub enum AliasTy {
133147
Opaque(OpaqueTy),
134148
}
135149

150+
impl TypeWalk for AliasTy {
151+
fn walk(&self, f: &mut impl FnMut(&Ty)) {
152+
match self {
153+
AliasTy::Projection(it) => it.walk(f),
154+
AliasTy::Opaque(it) => it.walk(f),
155+
}
156+
}
157+
158+
fn walk_mut_binders(
159+
&mut self,
160+
f: &mut impl FnMut(&mut Ty, DebruijnIndex),
161+
binders: DebruijnIndex,
162+
) {
163+
match self {
164+
AliasTy::Projection(it) => it.walk_mut_binders(f, binders),
165+
AliasTy::Opaque(it) => it.walk_mut_binders(f, binders),
166+
}
167+
}
168+
}
136169
/// A type.
137170
///
138171
/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents
@@ -535,7 +568,7 @@ pub enum GenericPredicate {
535568
/// The given trait needs to be implemented for its type parameters.
536569
Implemented(TraitRef),
537570
/// An associated type bindings like in `Iterator<Item = T>`.
538-
Projection(ProjectionPredicate),
571+
AliasEq(AliasEq),
539572
/// We couldn't resolve the trait reference. (If some type parameters can't
540573
/// be resolved, they will just be Unknown).
541574
Error,
@@ -553,8 +586,10 @@ impl GenericPredicate {
553586
pub fn trait_ref(&self, db: &dyn HirDatabase) -> Option<TraitRef> {
554587
match self {
555588
GenericPredicate::Implemented(tr) => Some(tr.clone()),
556-
GenericPredicate::Projection(proj) => Some(proj.projection_ty.trait_ref(db)),
557-
GenericPredicate::Error => None,
589+
GenericPredicate::AliasEq(AliasEq { alias: AliasTy::Projection(proj), .. }) => {
590+
Some(proj.trait_ref(db))
591+
}
592+
GenericPredicate::AliasEq(_) | GenericPredicate::Error => None,
558593
}
559594
}
560595
}
@@ -563,7 +598,7 @@ impl TypeWalk for GenericPredicate {
563598
fn walk(&self, f: &mut impl FnMut(&Ty)) {
564599
match self {
565600
GenericPredicate::Implemented(trait_ref) => trait_ref.walk(f),
566-
GenericPredicate::Projection(projection_pred) => projection_pred.walk(f),
601+
GenericPredicate::AliasEq(alias_eq) => alias_eq.walk(f),
567602
GenericPredicate::Error => {}
568603
}
569604
}
@@ -575,9 +610,7 @@ impl TypeWalk for GenericPredicate {
575610
) {
576611
match self {
577612
GenericPredicate::Implemented(trait_ref) => trait_ref.walk_mut_binders(f, binders),
578-
GenericPredicate::Projection(projection_pred) => {
579-
projection_pred.walk_mut_binders(f, binders)
580-
}
613+
GenericPredicate::AliasEq(alias_eq) => alias_eq.walk_mut_binders(f, binders),
581614
GenericPredicate::Error => {}
582615
}
583616
}

0 commit comments

Comments
 (0)