Skip to content

Commit 7bb8bbe

Browse files
committed
Add const eq where clauses
1 parent 8075c30 commit 7bb8bbe

File tree

6 files changed

+65
-1
lines changed

6 files changed

+65
-1
lines changed

chalk-integration/src/lowering.rs

+6
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,12 @@ impl LowerWithEnv for WhereClause {
171171
}),
172172
chalk_ir::WhereClause::Implemented(projection.trait_ref.lower(env)?),
173173
],
174+
WhereClause::ConstProjectionEq { projection, val } => vec![
175+
chalk_ir::WhereClause::ConstEq(chalk_ir::ConstEq {
176+
term: chalk_ir::AliasTy::Projection(projection.lower(env)?),
177+
ct: val.lower(env)?,
178+
}),
179+
],
174180
WhereClause::LifetimeOutlives { a, b } => {
175181
vec![chalk_ir::WhereClause::LifetimeOutlives(
176182
chalk_ir::LifetimeOutlives {

chalk-ir/src/debug.rs

+7
Original file line numberDiff line numberDiff line change
@@ -786,11 +786,18 @@ impl<I: Interner> Debug for AliasEq<I> {
786786
}
787787
}
788788

789+
impl<I: Interner> Debug for ConstEq<I> {
790+
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
791+
write!(fmt, "ConstEq(const {:?} = {:?})", self.term, self.ct)
792+
}
793+
}
794+
789795
impl<I: Interner> Debug for WhereClause<I> {
790796
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
791797
match self {
792798
WhereClause::Implemented(tr) => write!(fmt, "Implemented({:?})", tr.with_colon()),
793799
WhereClause::AliasEq(a) => write!(fmt, "{:?}", a),
800+
WhereClause::ConstEq(a) => write!(fmt, "{:?}", a),
794801
WhereClause::LifetimeOutlives(l_o) => write!(fmt, "{:?}", l_o),
795802
WhereClause::TypeOutlives(t_o) => write!(fmt, "{:?}", t_o),
796803
}

chalk-ir/src/lib.rs

+41
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,21 @@ impl<I: Interner> TyKind<I> {
728728
dyn_flags |= alias_eq.alias.compute_flags(interner);
729729
dyn_flags |= alias_eq.ty.data(interner).flags;
730730
}
731+
WhereClause::ConstEq(ct_eq) => {
732+
// TODO it's not a type projection but is that fine?
733+
// TODO do I need to add other flags here?
734+
dyn_flags |= TypeFlags::HAS_TY_PROJECTION;
735+
let const_data = ct_eq.ct.data(interner);
736+
dyn_flags |= const_data.ty.data(interner).flags | match const_data.value {
737+
ConstValue::BoundVar(_) | ConstValue::Concrete(_) => TypeFlags::empty(),
738+
ConstValue::InferenceVar(_) => {
739+
TypeFlags::HAS_CT_INFER | TypeFlags::STILL_FURTHER_SPECIALIZABLE
740+
}
741+
ConstValue::Placeholder(_) => {
742+
TypeFlags::HAS_CT_PLACEHOLDER | TypeFlags::STILL_FURTHER_SPECIALIZABLE
743+
}
744+
}
745+
}
731746
WhereClause::LifetimeOutlives(lifetime_outlives) => {
732747
dyn_flags |= lifetime_outlives.a.compute_flags(interner)
733748
| lifetime_outlives.b.compute_flags(interner);
@@ -1743,13 +1758,16 @@ pub enum WhereClause<I: Interner> {
17431758
LifetimeOutlives(LifetimeOutlives<I>),
17441759
/// Type outlives a lifetime.
17451760
TypeOutlives(TypeOutlives<I>),
1761+
/// Const is equal to another const
1762+
ConstEq(ConstEq<I>),
17461763
}
17471764

17481765
impl<I: Interner> Copy for WhereClause<I>
17491766
where
17501767
I::InternedSubstitution: Copy,
17511768
I::InternedLifetime: Copy,
17521769
I::InternedType: Copy,
1770+
I::InternedConst: Copy,
17531771
{
17541772
}
17551773

@@ -1908,6 +1926,7 @@ where
19081926
I::InternedSubstitution: Copy,
19091927
I::InternedLifetime: Copy,
19101928
I::InternedType: Copy,
1929+
I::InternedConst: Copy,
19111930
{
19121931
}
19131932

@@ -1939,6 +1958,7 @@ impl<I: Interner> WhereClause<I> {
19391958
match self {
19401959
WhereClause::Implemented(trait_ref) => Some(trait_ref.trait_id),
19411960
WhereClause::AliasEq(_) => None,
1961+
WhereClause::ConstEq(_) => None,
19421962
WhereClause::LifetimeOutlives(_) => None,
19431963
WhereClause::TypeOutlives(_) => None,
19441964
}
@@ -2046,6 +2066,26 @@ impl<I: Interner> HasInterner for AliasEq<I> {
20462066
type Interner = I;
20472067
}
20482068

2069+
/// Proves **equality** between an alias and a type.
2070+
#[derive(Clone, PartialEq, Eq, Hash, Fold, Visit, Zip)]
2071+
#[allow(missing_docs)]
2072+
pub struct ConstEq<I: Interner> {
2073+
/// The id for the associated type member.
2074+
pub term: AssocItemId<I>,
2075+
2076+
pub ct: Const<I>,
2077+
}
2078+
impl<I: Interner> Copy for ConstEq<I>
2079+
where
2080+
I::InternedSubstitution: Copy,
2081+
I::InternedConst: Copy,
2082+
{
2083+
}
2084+
2085+
impl<I: Interner> HasInterner for ConstEq<I> {
2086+
type Interner = I;
2087+
}
2088+
20492089
/// Indicates that the `value` is universally quantified over `N`
20502090
/// parameters of the given kinds, where `N == self.binders.len()`. A
20512091
/// variable with depth `i < N` refers to the value at
@@ -2610,6 +2650,7 @@ pub enum GoalData<I: Interner> {
26102650
impl<I: Interner> Copy for GoalData<I>
26112651
where
26122652
I::InternedType: Copy,
2653+
I::InternedConst: Copy,
26132654
I::InternedLifetime: Copy,
26142655
I::InternedGenericArg: Copy,
26152656
I::InternedSubstitution: Copy,

chalk-parse/src/ast.rs

+2
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,8 @@ impl fmt::Display for Identifier {
457457
pub enum WhereClause {
458458
Implemented { trait_ref: TraitRef },
459459
ProjectionEq { projection: ProjectionTerm, ty: Ty },
460+
ConstProjectionEq { projection: ProjectionTerm, val: Const },
461+
460462
LifetimeOutlives { a: Lifetime, b: Lifetime },
461463
TypeOutlives { ty: Ty, lifetime: Lifetime },
462464
}

chalk-parse/src/parser.lalrpop

+8
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,14 @@ InlineClause: Clause = {
588588
WhereClause: WhereClause = {
589589
<t:TraitRef<":">> => WhereClause::Implemented { trait_ref: t },
590590

591+
<s:Ty> ":" <t:Id> "<" "const" <name:Id> "=" <val: Const> ">" => {
592+
let args = vec![GenericArg::Ty(s)];
593+
let trait_ref = TraitRef { trait_name: t, args: args };
594+
let projection = ProjectionTerm { trait_ref, name, args: vec![] };
595+
596+
WhereClause::ConstProjectionEq { projection, val }
597+
},
598+
591599
// `T: Foo<U = Bar>` -- projection equality
592600
<s:Ty> ":" <t:Id> "<" <a:(<Comma<GenericArg>> ",")?> <name:Id> <a2:Angle<GenericArg>>
593601
"=" <ty:Ty> ">" =>

tests/test/projection.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1116,7 +1116,7 @@ fn const_projection() {
11161116
const ID: usize;
11171117
}
11181118
trait OtherTrait {}
1119-
impl OtherTrait for U where U: ConstTrait<ID = 3> {}
1119+
impl OtherTrait for U where U: ConstTrait<const ID = 3> {}
11201120
impl ConstTrait for () {
11211121
const ID: usize = 3;
11221122
}

0 commit comments

Comments
 (0)