diff --git a/src/can/operator.rs b/src/can/operator.rs index 97160b421d..f1ec619ef8 100644 --- a/src/can/operator.rs +++ b/src/can/operator.rs @@ -199,7 +199,32 @@ pub fn desugar<'a>(arena: &'a Bump, loc_expr: &'a Located>) -> &'a Loca let value = match loc_op.value { Pizza => { // Rewrite the Pizza operator into an Apply - panic!("TODO desugar |> operator into an Apply"); + + match &right.value { + Apply(function, arguments, _called_via) => { + let mut args = Vec::with_capacity_in(1 + arguments.len(), arena); + + args.push(left); + + for arg in arguments { + args.push(arg); + } + + Apply(function, args, CalledVia::BinOp(Pizza)) + } + expr => { + // e.g. `1 |> (if b then (\a -> a) else (\c -> c))` + let mut args = Vec::with_capacity_in(1, arena); + args.push(*arena.alloc(left)); + + let function = arena.alloc(Located { + value: expr.clone(), + region: right.region, + }); + + Apply(function, args, CalledVia::BinOp(Pizza)) + } + } } binop => { // This is a normal binary operator like (+), so desugar it @@ -207,8 +232,8 @@ pub fn desugar<'a>(arena: &'a Bump, loc_expr: &'a Located>) -> &'a Loca let (module_parts, name) = desugar_binop(binop, arena); let mut args = Vec::with_capacity_in(2, arena); - args.push(*arena.alloc(left)); - args.push(*arena.alloc(right)); + args.push(left); + args.push(right); let loc_expr = arena.alloc(Located { value: Expr::Var(module_parts, name), diff --git a/tests/test_infer.rs b/tests/test_infer.rs index df3805b73f..26f31a9af1 100644 --- a/tests/test_infer.rs +++ b/tests/test_infer.rs @@ -505,6 +505,31 @@ mod test_infer { ); } + #[test] + fn pizza_desugar() { + infer_eq( + indoc!( + r#" + 1 |> (\a -> a) + "# + ), + "Int", + ); + } + + #[test] + fn pizza_desugar_two_arguments() { + infer_eq( + indoc!( + r#" + always = \a b -> a + + 1 |> always "foo" + "# + ), + "Int", + ); + } // #[test] // fn identity() { // infer_eq(