Skip to content

Commit a532519

Browse files
committed
Refactor LowerClause to permit multiple clauses
1 parent 869ff06 commit a532519

File tree

1 file changed

+44
-24
lines changed

1 file changed

+44
-24
lines changed

src/ir/lowering/mod.rs

+44-24
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::collections::BTreeMap;
33
use chalk_parse::ast::*;
44
use lalrpop_intern::intern;
55

6-
use cast::Cast;
6+
use cast::{Cast, Caster};
77
use errors::*;
88
use ir::{self, Anonymize, ToParameter};
99
use solve::SolverChoice;
@@ -205,7 +205,7 @@ impl LowerProgram for Program {
205205
impl_data.insert(item_id, d.lower_impl(&empty_env)?);
206206
}
207207
Item::Clause(ref clause) => {
208-
custom_clauses.push(clause.lower_clause(&empty_env)?);
208+
custom_clauses.extend(clause.lower_clause(&empty_env)?);
209209
}
210210
}
211211
}
@@ -412,12 +412,7 @@ trait LowerWhereClauseVec<T> {
412412

413413
impl LowerWhereClauseVec<ir::DomainGoal> for [WhereClause] {
414414
fn lower(&self, env: &Env) -> Result<Vec<ir::DomainGoal>> {
415-
self.iter()
416-
.flat_map(|wc| match wc.lower(env) {
417-
Ok(v) => v.into_iter().map(Ok).collect(),
418-
Err(e) => vec![Err(e)],
419-
})
420-
.collect()
415+
self.iter().flat_map(|wc| wc.lower(env).apply_result()).collect()
421416
}
422417
}
423418

@@ -519,7 +514,7 @@ impl LowerWhereClause<ir::LeafGoal> for WhereClause {
519514
| WhereClause::TraitRefFromEnv { .. }
520515
| WhereClause::Derefs { .. } => {
521516
let goals: Vec<ir::DomainGoal> = self.lower(env)?;
522-
goals.into_iter().map(|g| g.cast()).collect()
517+
goals.into_iter().casted().collect()
523518
}
524519
WhereClause::UnifyTys { ref a, ref b } => vec![ir::EqGoal {
525520
a: ir::ParameterKind::Ty(a.lower(env)?),
@@ -842,15 +837,13 @@ impl LowerImpl for Impl {
842837
}
843838

844839
trait LowerClause {
845-
fn lower_clause(&self, env: &Env) -> Result<ir::ProgramClause>;
840+
fn lower_clause(&self, env: &Env) -> Result<Vec<ir::ProgramClause>>;
846841
}
847842

848843
impl LowerClause for Clause {
849-
fn lower_clause(&self, env: &Env) -> Result<ir::ProgramClause> {
850-
let implication = env.in_binders(self.all_parameters(), |env| {
844+
fn lower_clause(&self, env: &Env) -> Result<Vec<ir::ProgramClause>> {
845+
let implications = env.in_binders(self.all_parameters(), |env| {
851846
let consequences: Vec<ir::DomainGoal> = self.consequence.lower(env)?;
852-
assert_eq!(1, consequences.len());
853-
let consequence = consequences.into_iter().next().unwrap();
854847

855848
let mut conditions: Vec<ir::Goal> = self.conditions
856849
.iter()
@@ -862,17 +855,27 @@ impl LowerClause for Clause {
862855
// therefore reverse.
863856
conditions.reverse();
864857

865-
Ok(ir::ProgramClauseImplication {
866-
consequence,
867-
conditions,
868-
})
858+
let implications = consequences
859+
.into_iter()
860+
.map(|consequence| ir::ProgramClauseImplication {
861+
consequence,
862+
conditions: conditions.clone(),
863+
})
864+
.collect::<Vec<_>>();
865+
Ok(implications)
869866
})?;
870867

871-
if implication.binders.is_empty() {
872-
Ok(ir::ProgramClause::Implies(implication.value))
873-
} else {
874-
Ok(ir::ProgramClause::ForAll(implication))
875-
}
868+
let clauses = implications
869+
.into_iter()
870+
.map(|implication: ir::Binders<ir::ProgramClauseImplication>| {
871+
if implication.binders.is_empty() {
872+
ir::ProgramClause::Implies(implication.value)
873+
} else {
874+
ir::ProgramClause::ForAll(implication)
875+
}
876+
})
877+
.collect();
878+
Ok(clauses)
876879
}
877880
}
878881

@@ -982,7 +985,8 @@ impl<'k> LowerGoal<Env<'k>> for Goal {
982985
// `if (FromEnv(T: Trait)) { ... /* this part is untouched */ ... }`.
983986
let where_clauses: Result<Vec<_>> =
984987
wc.into_iter()
985-
.map(|wc| Ok(wc.lower_clause(env)?.into_from_env_clause()))
988+
.flat_map(|wc| wc.lower_clause(env).apply_result())
989+
.map(|result| result.map(|wc| wc.into_from_env_clause()))
986990
.collect();
987991
Ok(Box::new(ir::Goal::Implies(where_clauses?, g.lower(env)?)))
988992
}
@@ -1025,3 +1029,19 @@ impl LowerQuantifiedGoal for Goal {
10251029
Ok(Box::new(ir::Goal::Quantified(quantifier_kind, subgoal)))
10261030
}
10271031
}
1032+
1033+
/// Lowers Result<Vec<T>> -> Vec<Result<T>>.
1034+
trait ApplyResult {
1035+
type Output;
1036+
fn apply_result(self) -> Self::Output;
1037+
}
1038+
1039+
impl<T> ApplyResult for Result<Vec<T>> {
1040+
type Output = Vec<Result<T>>;
1041+
fn apply_result(self) -> Self::Output {
1042+
match self {
1043+
Ok(v) => v.into_iter().map(Ok).collect(),
1044+
Err(e) => vec![Err(e)],
1045+
}
1046+
}
1047+
}

0 commit comments

Comments
 (0)