Skip to content

Commit ea1ca4d

Browse files
authored
Merge pull request #451 from jackh726/lifetime_outlives
Add lifetime outlives goal
2 parents ffa2e51 + 887eae1 commit ea1ca4d

File tree

15 files changed

+154
-38
lines changed

15 files changed

+154
-38
lines changed

chalk-engine/src/simplify.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ use crate::{ExClause, Literal, TimeStamp};
55
use chalk_ir::debug;
66
use chalk_ir::interner::Interner;
77
use chalk_ir::{
8-
Environment, Fallible, Goal, GoalData, InEnvironment, QuantifierKind, Substitution,
8+
Constraint, DomainGoal, Environment, Fallible, Goal, GoalData, InEnvironment, LifetimeOutlives,
9+
QuantifierKind, Substitution, WhereClause,
910
};
1011

1112
impl<I: Interner, C: Context<I>> Forest<I, C> {
@@ -68,14 +69,22 @@ impl<I: Interner, C: Context<I>> Forest<I, C> {
6869
&goal.b,
6970
&mut ex_clause,
7071
)?,
71-
GoalData::DomainGoal(domain_goal) => {
72-
ex_clause
73-
.subgoals
74-
.push(Literal::Positive(InEnvironment::new(
72+
GoalData::DomainGoal(domain_goal) => match domain_goal {
73+
DomainGoal::Holds(WhereClause::LifetimeOutlives(LifetimeOutlives { a, b })) => {
74+
ex_clause.constraints.push(InEnvironment::new(
7575
&environment,
76-
context.into_goal(domain_goal.clone()),
77-
)));
78-
}
76+
Constraint::Outlives(a.clone(), b.clone()),
77+
));
78+
}
79+
_ => {
80+
ex_clause
81+
.subgoals
82+
.push(Literal::Positive(InEnvironment::new(
83+
&environment,
84+
context.into_goal(domain_goal.clone()),
85+
)));
86+
}
87+
},
7988
GoalData::CannotProve(()) => {
8089
debug!("Marking Strand as ambiguous because of a `CannotProve` subgoal");
8190
ex_clause.ambiguous = true;

chalk-integration/src/lowering.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,14 @@ impl LowerWhereClause<chalk_ir::WhereClause<ChalkIr>> for WhereClause {
874874
}),
875875
chalk_ir::WhereClause::Implemented(projection.trait_ref.lower(env)?),
876876
],
877+
WhereClause::LifetimeOutlives { a, b } => {
878+
vec![chalk_ir::WhereClause::LifetimeOutlives(
879+
chalk_ir::LifetimeOutlives {
880+
a: a.lower(env)?,
881+
b: b.lower(env)?,
882+
},
883+
)]
884+
}
877885
};
878886
Ok(where_clauses)
879887
}

chalk-ir/src/cast.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@ impl<I: Interner> CastTo<WhereClause<I>> for AliasEq<I> {
9898
}
9999
}
100100

101+
impl<I: Interner> CastTo<WhereClause<I>> for LifetimeOutlives<I> {
102+
fn cast_to(self, _interner: &I) -> WhereClause<I> {
103+
WhereClause::LifetimeOutlives(self)
104+
}
105+
}
106+
101107
impl<T, I> CastTo<DomainGoal<I>> for T
102108
where
103109
T: CastTo<WhereClause<I>>,

chalk-ir/src/debug.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,12 @@ impl<'me, I: Interner> SeparatorTraitRef<'me, I> {
536536
}
537537
}
538538

539+
impl<I: Interner> Debug for LifetimeOutlives<I> {
540+
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
541+
write!(fmt, "{:?}: {:?}", self.a, self.b)
542+
}
543+
}
544+
539545
pub struct ProjectionTyDebug<'a, I: Interner> {
540546
projection_ty: &'a ProjectionTy<I>,
541547
interner: &'a I,
@@ -630,6 +636,7 @@ impl<I: Interner> Debug for WhereClause<I> {
630636
match self {
631637
WhereClause::Implemented(tr) => write!(fmt, "Implemented({:?})", tr.with_colon()),
632638
WhereClause::AliasEq(a) => write!(fmt, "{:?}", a),
639+
WhereClause::LifetimeOutlives(l_o) => write!(fmt, "{:?}", l_o),
633640
}
634641
}
635642
}

chalk-ir/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1184,11 +1184,17 @@ impl<I: Interner> TraitRef<I> {
11841184
}
11851185
}
11861186

1187+
#[derive(Clone, PartialEq, Eq, Hash, Fold, Visit, HasInterner, Zip)]
1188+
pub struct LifetimeOutlives<I: Interner> {
1189+
pub a: Lifetime<I>,
1190+
pub b: Lifetime<I>,
1191+
}
11871192
/// Where clauses that can be written by a Rust programmer.
11881193
#[derive(Clone, PartialEq, Eq, Hash, Fold, SuperVisit, HasInterner, Zip)]
11891194
pub enum WhereClause<I: Interner> {
11901195
Implemented(TraitRef<I>),
11911196
AliasEq(AliasEq<I>),
1197+
LifetimeOutlives(LifetimeOutlives<I>),
11921198
}
11931199

11941200
#[derive(Clone, PartialEq, Eq, Hash, Fold, Visit, HasInterner, Zip)]

chalk-parse/src/ast.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ impl fmt::Display for Identifier {
331331
pub enum WhereClause {
332332
Implemented { trait_ref: TraitRef },
333333
ProjectionEq { projection: ProjectionTy, ty: Ty },
334+
LifetimeOutlives { a: Lifetime, b: Lifetime },
334335
}
335336

336337
#[derive(Clone, PartialEq, Eq, Debug)]

chalk-parse/src/parser.lalrpop

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,11 @@ WhereClause: WhereClause = {
367367
let projection = ProjectionTy { trait_ref, name, args: a2 };
368368
WhereClause::ProjectionEq { projection, ty }
369369
},
370+
371+
// 'a: 'b
372+
<a:Lifetime> ":" <b:Lifetime> => {
373+
WhereClause::LifetimeOutlives { a, b }
374+
}
370375
};
371376

372377
QuantifiedWhereClause: QuantifiedWhereClause = {

chalk-solve/src/clauses.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ fn program_clauses_that_could_match<I: Interner>(
322322
.opaque_ty_data(opaque_ty.opaque_ty_id)
323323
.to_program_clauses(builder),
324324
},
325+
DomainGoal::Holds(WhereClause::LifetimeOutlives(_)) => {}
325326
DomainGoal::WellFormed(WellFormed::Trait(trait_ref))
326327
| DomainGoal::LocalImplAllowed(trait_ref) => {
327328
db.trait_datum(trait_ref.trait_id)

chalk-solve/src/clauses/dyn_ty.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ pub(super) fn build_dyn_self_ty_clauses<I: Interner>(
7272
}
7373
// Associated item bindings are just taken as facts (?)
7474
WhereClause::AliasEq(_) => builder.push_fact(wc),
75+
WhereClause::LifetimeOutlives(..) => {}
7576
});
7677
}
7778
});
@@ -160,6 +161,7 @@ pub fn super_traits<I: Interner>(
160161
Some(tr.clone())
161162
}
162163
WhereClause::AliasEq(_) => None,
164+
WhereClause::LifetimeOutlives(..) => None,
163165
})
164166
})
165167
.collect::<Vec<_>>()

chalk-solve/src/coinductive_goal.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ impl<I: Interner> IsCoinductive<I> for Goal<I> {
2424
|| db.trait_datum(tr.trait_id).is_coinductive_trait()
2525
}
2626
WhereClause::AliasEq(..) => false,
27+
WhereClause::LifetimeOutlives(..) => false,
2728
},
2829
GoalData::DomainGoal(DomainGoal::WellFormed(WellFormed::Trait(..))) => true,
2930
GoalData::Quantified(QuantifierKind::ForAll, goal) => {

0 commit comments

Comments
 (0)