Skip to content

Commit 87cfd73

Browse files
committed
feat(rengine): drop BinOp resugaring in favor of FunctionApplications
1 parent 34a29ad commit 87cfd73

File tree

3 files changed

+43
-137
lines changed

3 files changed

+43
-137
lines changed

rust-engine/src/ast/resugared.rs

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,6 @@ pub enum ResugaredItemKind {}
2222
/// Resugared variants for expressions. This represent extra printing-only expressions, see [`super::ExprKind::Resugared`].
2323
#[derive_group_for_ast]
2424
pub enum ResugaredExprKind {
25-
/// Binary operations (identified by resugaring) of the form `f(e1, e2)`
26-
BinOp {
27-
/// The identifier of the operation (`f`)
28-
op: GlobalId,
29-
/// The left-hand side of the operation (`e1`)
30-
lhs: Expr,
31-
/// The right-hand side of the operation (`e2`)
32-
rhs: Expr,
33-
/// The generic arguments applied to the function.
34-
generic_args: Vec<GenericValue>,
35-
/// If the function requires generic bounds to be called, `bounds_impls`
36-
/// is a vector of impl. expressions for those bounds.
37-
bounds_impls: Vec<ImplExpr>,
38-
/// If we apply an associated function, contains the impl. expr used.
39-
trait_: Option<(ImplExpr, Vec<GenericValue>)>,
40-
},
4125
/// A function application recognized by the engine, with static arity.
4226
FunApp {
4327
/// The generic arguments applied to the function.

rust-engine/src/backends/lean.rs

Lines changed: 43 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,7 @@
55
//! source maps).
66
77
use super::prelude::*;
8-
use crate::resugarings::BinOp;
9-
10-
mod binops {
11-
pub use crate::names::rust_primitives::hax::machine_int::{add, div, mul, rem, shr, sub};
12-
pub use crate::names::rust_primitives::hax::{logical_op_and, logical_op_or};
13-
}
8+
use crate::resugarings;
149

1510
/// The Lean printer
1611
#[derive(Default)]
@@ -19,16 +14,7 @@ impl_doc_allocator_for!(LeanPrinter);
1914

2015
impl Printer for LeanPrinter {
2116
fn resugaring_phases() -> Vec<Box<dyn Resugaring>> {
22-
vec![Box::new(BinOp::new(&[
23-
binops::add(),
24-
binops::sub(),
25-
binops::mul(),
26-
binops::rem(),
27-
binops::div(),
28-
binops::shr(),
29-
binops::logical_op_and(),
30-
binops::logical_op_or(),
31-
]))]
17+
vec![Box::new(resugarings::FunctionApplications)]
3218
}
3319

3420
const NAME: &str = "Lean";
@@ -155,25 +141,7 @@ set_option linter.unusedVariables false
155141
unreachable!()
156142
}
157143
}
158-
ExprKind::App {
159-
head,
160-
args,
161-
generic_args,
162-
bounds_impls: _,
163-
trait_: _,
164-
} => {
165-
let generic_args = (!generic_args.is_empty()).then_some(
166-
docs![
167-
line!(),
168-
self.intersperse(generic_args, line!()).nest(INDENT)
169-
]
170-
.group(),
171-
);
172-
let args = (!args.is_empty()).then_some(
173-
docs![line!(), intersperse!(args, line!()).nest(INDENT)].group(),
174-
);
175-
docs!["← ", head, generic_args, args].parens().group()
176-
}
144+
ExprKind::App { .. } => unreachable!("See resugaring [FunctionApplications]"),
177145
ExprKind::Literal(literal) => docs![literal],
178146
ExprKind::Array(exprs) => {
179147
docs!["#v[", intersperse!(exprs, reflow!(", ")).nest(INDENT)].group()
@@ -254,38 +222,49 @@ set_option linter.unusedVariables false
254222
resugared_expr_kind: &'b ResugaredExprKind,
255223
) -> DocBuilder<'a, Self, A> {
256224
match resugared_expr_kind {
257-
ResugaredExprKind::BinOp {
258-
op,
259-
lhs,
260-
rhs,
261-
generic_args: _,
225+
ResugaredExprKind::FunApp {
226+
app,
227+
head,
228+
generic_args,
262229
bounds_impls: _,
263230
trait_: _,
264-
} => {
265-
let symbol = if op == &binops::add() {
266-
"+?"
267-
} else if op == &binops::sub() {
268-
"-?"
269-
} else if op == &binops::mul() {
270-
"*?"
271-
} else if op == &binops::div() {
272-
"/?"
273-
} else if op == &binops::rem() {
274-
"%?"
275-
} else if op == &binops::shr() {
276-
">>>?"
277-
} else if op == &binops::logical_op_and() {
278-
"&&"
279-
} else if op == &binops::logical_op_or() {
280-
"||"
281-
} else {
282-
unreachable!()
283-
};
284-
docs!["← ", lhs, softline!(), symbol, softline!(), rhs]
285-
.group()
286-
.parens()
231+
} => match app {
232+
FunApp::Binary(op, [lhs, rhs]) => {
233+
let op = match op {
234+
BinaryName::Add => "+?",
235+
BinaryName::Sub => "-?",
236+
BinaryName::Mul => "*?",
237+
BinaryName::Rem => "%?",
238+
BinaryName::Div => "/?",
239+
BinaryName::Shr => ">>>?",
240+
BinaryName::Shl => "<<<?",
241+
BinaryName::LogicalAnd => "&&",
242+
BinaryName::LogicalOr => "||",
243+
};
244+
// This monad lifting should be handled by a phase/resugaring, see
245+
// https://github.com/cryspen/hax/issues/1620
246+
Some(
247+
docs!["← ", lhs, softline!(), op, softline!(), rhs]
248+
.group()
249+
.parens(),
250+
)
251+
}
252+
_ => None,
287253
}
288-
_ => todo!(),
254+
.unwrap_or_else(|| {
255+
let args = app.args();
256+
let generic_args = (!generic_args.is_empty()).then_some(
257+
docs![
258+
line!(),
259+
self.intersperse(generic_args, line!()).nest(INDENT)
260+
]
261+
.group(),
262+
);
263+
let args = (!args.is_empty()).then_some(
264+
docs![line!(), intersperse!(args, line!()).nest(INDENT)].group(),
265+
);
266+
docs!["← ", head, generic_args, args].parens().group()
267+
}),
289268
}
290269
}
291270

rust-engine/src/resugarings.rs

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,10 @@
44
//! [`hax_rust_engine::ast::Resugaring`] for the definition of a
55
//! resugaring). Each backend defines its own set of resugaring phases.
66
7-
use crate::ast::identifiers::global_id::ExplicitDefId;
87
use crate::ast::resugared::*;
98
use crate::ast::visitors::*;
109
use crate::ast::*;
1110
use crate::printer::*;
12-
use std::collections::HashSet;
1311

1412
/// Rewrite every expression application node [`ExprKind::App`] into a
1513
/// [`ResugaredExprKind::App`]. [`ResugaredExprKind::App`] represent known
@@ -44,58 +42,3 @@ impl Resugaring for FunctionApplications {
4442
"function-applications".to_string()
4543
}
4644
}
47-
48-
/// Binop resugaring. Used to identify expressions of the form `(f e1 e2)` where
49-
/// `f` is a known identifier.
50-
pub struct BinOp {
51-
/// Stores a set of identifiers that should be resugared as binary
52-
/// operations. Usually, those identifiers come from the hax encoding. Each
53-
/// backend can select its own set of identifiers Typically, if the backend
54-
/// has a special support for addition, `known_ops` will contain
55-
/// `hax::machine::int::add`
56-
pub known_ops: HashSet<ExplicitDefId>,
57-
}
58-
59-
impl BinOp {
60-
/// Adds a new binary operation from a list of (hax-introduced) names
61-
pub fn new(known_ops: &[ExplicitDefId]) -> Self {
62-
Self {
63-
known_ops: HashSet::from_iter(known_ops.iter().cloned()),
64-
}
65-
}
66-
}
67-
68-
impl AstVisitorMut for BinOp {
69-
fn enter_expr_kind(&mut self, x: &mut ExprKind) {
70-
let ExprKind::App {
71-
head,
72-
args,
73-
generic_args,
74-
bounds_impls,
75-
trait_,
76-
}: &mut ExprKind = x
77-
else {
78-
return;
79-
};
80-
let ExprKind::GlobalId(id) = &*head.kind else {
81-
return;
82-
};
83-
let [lhs, rhs] = &args[..] else { return };
84-
if self.known_ops.iter().any(|defid| id == defid) {
85-
*x = ExprKind::Resugared(ResugaredExprKind::BinOp {
86-
op: id.clone(),
87-
lhs: lhs.clone(),
88-
rhs: rhs.clone(),
89-
generic_args: generic_args.clone(),
90-
bounds_impls: bounds_impls.clone(),
91-
trait_: trait_.clone(),
92-
});
93-
}
94-
}
95-
}
96-
97-
impl Resugaring for BinOp {
98-
fn name(&self) -> String {
99-
"binop".to_string()
100-
}
101-
}

0 commit comments

Comments
 (0)