Refactor 'is_capture' field on function expressions.

Refactored into an enum to make it easier to extend with a new variant to support binary operators.
This commit is contained in:
KtorZ 2023-06-17 07:26:46 +02:00
parent 93135cebbb
commit ba911d48ea
No known key found for this signature in database
GPG Key ID: 33173CB6F77F4277
5 changed files with 38 additions and 21 deletions

View File

@ -399,6 +399,13 @@ impl TypedExpr {
} }
} }
// Represent how a function was written so that we can format it back.
#[derive(Debug, Clone, PartialEq, Copy)]
pub enum FnStyle {
Plain,
Capture,
}
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub enum UntypedExpr { pub enum UntypedExpr {
Int { Int {
@ -424,7 +431,7 @@ pub enum UntypedExpr {
Fn { Fn {
location: Span, location: Span,
is_capture: bool, fn_style: FnStyle,
arguments: Vec<Arg<()>>, arguments: Vec<Arg<()>>,
body: Box<Self>, body: Box<Self>,
return_annotation: Option<Annotation>, return_annotation: Option<Annotation>,

View File

@ -8,7 +8,7 @@ use crate::{
Use, Validator, CAPTURE_VARIABLE, Use, Validator, CAPTURE_VARIABLE,
}, },
docvec, docvec,
expr::{UntypedExpr, DEFAULT_ERROR_STR, DEFAULT_TODO_STR}, expr::{FnStyle, UntypedExpr, DEFAULT_ERROR_STR, DEFAULT_TODO_STR},
parser::{ parser::{
extra::{Comment, ModuleExtra}, extra::{Comment, ModuleExtra},
token::Base, token::Base,
@ -768,12 +768,13 @@ impl<'comments> Formatter<'comments> {
UntypedExpr::UnOp { value, op, .. } => self.un_op(value, op), UntypedExpr::UnOp { value, op, .. } => self.un_op(value, op),
UntypedExpr::Fn { UntypedExpr::Fn {
is_capture: true, fn_style: FnStyle::Capture,
body, body,
.. ..
} => self.fn_capture(body), } => self.fn_capture(body),
UntypedExpr::Fn { UntypedExpr::Fn {
fn_style: FnStyle::Plain,
return_annotation, return_annotation,
arguments: args, arguments: args,
body, body,
@ -1093,7 +1094,7 @@ impl<'comments> Formatter<'comments> {
let comments = self.pop_comments(expr.location().start); let comments = self.pop_comments(expr.location().start);
let doc = match expr { let doc = match expr {
UntypedExpr::Fn { UntypedExpr::Fn {
is_capture: true, fn_style: FnStyle::Capture,
body, body,
.. ..
} => self.pipe_capture_right_hand_side(body), } => self.pipe_capture_right_hand_side(body),

View File

@ -935,7 +935,7 @@ pub fn expr_parser(
arguments, arguments,
body: Box::new(body), body: Box::new(body),
location: span, location: span,
is_capture: false, fn_style: expr::FnStyle::Plain,
return_annotation, return_annotation,
}, },
); );
@ -1205,7 +1205,7 @@ pub fn expr_parser(
} else { } else {
expr::UntypedExpr::Fn { expr::UntypedExpr::Fn {
location: call.location(), location: call.location(),
is_capture: true, fn_style: expr::FnStyle::Capture,
arguments: holes, arguments: holes,
body: Box::new(call), body: Box::new(call),
return_annotation: None, return_annotation: None,

View File

@ -1369,7 +1369,7 @@ fn anonymous_function() {
location: Span::new((), 25..67), location: Span::new((), 25..67),
value: Box::new(expr::UntypedExpr::Fn { value: Box::new(expr::UntypedExpr::Fn {
location: Span::new((), 39..67), location: Span::new((), 39..67),
is_capture: false, fn_style: expr::FnStyle::Plain,
arguments: vec![ast::Arg { arguments: vec![ast::Arg {
arg_name: ast::ArgName::Named { arg_name: ast::ArgName::Named {
label: "a".to_string(), label: "a".to_string(),
@ -1547,7 +1547,7 @@ fn call() {
location: Span::new((), 37..82), location: Span::new((), 37..82),
value: Box::new(expr::UntypedExpr::Fn { value: Box::new(expr::UntypedExpr::Fn {
location: Span::new((), 53..82), location: Span::new((), 53..82),
is_capture: true, fn_style: expr::FnStyle::Capture,
arguments: vec![ast::Arg { arguments: vec![ast::Arg {
arg_name: ast::ArgName::Named { arg_name: ast::ArgName::Named {
label: "_capture__0".to_string(), label: "_capture__0".to_string(),
@ -1574,7 +1574,7 @@ fn call() {
location: Span::new((), 65..81), location: Span::new((), 65..81),
value: expr::UntypedExpr::Fn { value: expr::UntypedExpr::Fn {
location: Span::new((), 65..81), location: Span::new((), 65..81),
is_capture: false, fn_style: expr::FnStyle::Plain,
arguments: vec![ast::Arg { arguments: vec![ast::Arg {
arg_name: ast::ArgName::Named { arg_name: ast::ArgName::Named {
label: "y".to_string(), label: "y".to_string(),

View File

@ -12,7 +12,7 @@ use crate::{
UntypedRecordUpdateArg, UntypedRecordUpdateArg,
}, },
builtins::{bool, byte_array, function, int, list, string, tuple}, builtins::{bool, byte_array, function, int, list, string, tuple},
expr::{TypedExpr, UntypedExpr}, expr::{FnStyle, TypedExpr, UntypedExpr},
format, format,
tipo::fields::FieldMap, tipo::fields::FieldMap,
}; };
@ -220,12 +220,19 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
UntypedExpr::Fn { UntypedExpr::Fn {
location, location,
is_capture, fn_style,
arguments: args, arguments: args,
body, body,
return_annotation, return_annotation,
.. ..
} => self.infer_fn(args, &[], *body, is_capture, return_annotation, location), } => self.infer_fn(
args,
&[],
*body,
fn_style == FnStyle::Capture,
return_annotation,
location,
),
UntypedExpr::If { UntypedExpr::If {
location, location,
@ -1011,17 +1018,19 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
body, body,
return_annotation, return_annotation,
location, location,
is_capture: false, fn_style,
.. ..
}, },
) if expected_arguments.len() == arguments.len() => self.infer_fn( ) if fn_style != FnStyle::Capture && expected_arguments.len() == arguments.len() => {
arguments, self.infer_fn(
expected_arguments, arguments,
*body, expected_arguments,
false, *body,
return_annotation, false,
location, return_annotation,
), location,
)
}
// Otherwise just perform normal type inference. // Otherwise just perform normal type inference.
(_, value) => self.infer(value), (_, value) => self.infer(value),