mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-20 15:27:45 +03:00
Merge pull request #5421 from roc-lang/agu-z/record-builder-colon-arrow
New Record Builder `: <-` syntax
This commit is contained in:
commit
57336e3de1
@ -503,7 +503,7 @@ fn record_builder_arg<'a>(
|
||||
RecordBuilderField::Value(label, spaces, expr) => {
|
||||
break AssignedField::RequiredValue(label, spaces, expr)
|
||||
}
|
||||
RecordBuilderField::ApplyValue(label, spaces, expr) => {
|
||||
RecordBuilderField::ApplyValue(label, _, _, expr) => {
|
||||
apply_field_names.push(label);
|
||||
apply_exprs.push(expr);
|
||||
|
||||
@ -515,7 +515,7 @@ fn record_builder_arg<'a>(
|
||||
},
|
||||
});
|
||||
|
||||
break AssignedField::RequiredValue(label, spaces, var);
|
||||
break AssignedField::RequiredValue(label, &[], var);
|
||||
}
|
||||
RecordBuilderField::LabelOnly(label) => break AssignedField::LabelOnly(label),
|
||||
RecordBuilderField::SpaceBefore(sub_field, _) => {
|
||||
|
@ -669,8 +669,8 @@ mod test_can {
|
||||
|
||||
succeed {
|
||||
a: 1,
|
||||
b <- apply "b",
|
||||
c <- apply "c",
|
||||
b: <- apply "b",
|
||||
c: <- apply "c",
|
||||
d
|
||||
}
|
||||
"#
|
||||
@ -783,7 +783,7 @@ mod test_can {
|
||||
number = "42"
|
||||
|
||||
succeed {
|
||||
number <- parse number,
|
||||
number: <- parse number,
|
||||
raw: number,
|
||||
}
|
||||
"#
|
||||
@ -818,8 +818,8 @@ mod test_can {
|
||||
let src = indoc!(
|
||||
r#"
|
||||
succeed
|
||||
{ a <- apply "a" }
|
||||
{ b <- apply "b" }
|
||||
{ a: <- apply "a" }
|
||||
{ b: <- apply "b" }
|
||||
"#
|
||||
);
|
||||
let arena = Bump::new();
|
||||
@ -843,7 +843,7 @@ mod test_can {
|
||||
fn hanging_record_builder() {
|
||||
let src = indoc!(
|
||||
r#"
|
||||
{ a <- apply "a" }
|
||||
{ a: <- apply "a" }
|
||||
"#
|
||||
);
|
||||
let arena = Bump::new();
|
||||
|
@ -505,7 +505,7 @@ impl<'a> Formattable for RecordBuilderField<'a> {
|
||||
|
||||
fn format_with_options(&self, buf: &mut Buf, _parens: Parens, newlines: Newlines, indent: u16) {
|
||||
// we abuse the `Newlines` type to decide between multiline or single-line layout
|
||||
format_record_builder_field_help(self, buf, indent, 0, newlines == Newlines::Yes);
|
||||
format_record_builder_field_help(self, buf, indent, newlines == Newlines::Yes);
|
||||
}
|
||||
}
|
||||
|
||||
@ -513,8 +513,9 @@ fn is_multiline_record_builder_field_help(afield: &RecordBuilderField<'_>) -> bo
|
||||
use self::RecordBuilderField::*;
|
||||
|
||||
match afield {
|
||||
Value(_, spaces, ann) | ApplyValue(_, spaces, ann) => {
|
||||
!spaces.is_empty() || ann.value.is_multiline()
|
||||
Value(_, spaces, ann) => !spaces.is_empty() || ann.value.is_multiline(),
|
||||
ApplyValue(_, colon_spaces, arrow_spaces, ann) => {
|
||||
!colon_spaces.is_empty() || !arrow_spaces.is_empty() || ann.value.is_multiline()
|
||||
}
|
||||
LabelOnly(_) => false,
|
||||
SpaceBefore(_, _) | SpaceAfter(_, _) => true,
|
||||
@ -526,7 +527,6 @@ fn format_record_builder_field_help(
|
||||
zelf: &RecordBuilderField,
|
||||
buf: &mut Buf,
|
||||
indent: u16,
|
||||
separator_spaces: usize,
|
||||
is_multiline: bool,
|
||||
) {
|
||||
use self::RecordBuilderField::*;
|
||||
@ -544,12 +544,11 @@ fn format_record_builder_field_help(
|
||||
fmt_spaces(buf, spaces.iter(), indent);
|
||||
}
|
||||
|
||||
buf.spaces(separator_spaces);
|
||||
buf.push(':');
|
||||
buf.spaces(1);
|
||||
ann.value.format(buf, indent);
|
||||
}
|
||||
ApplyValue(name, spaces, ann) => {
|
||||
ApplyValue(name, colon_spaces, arrow_spaces, ann) => {
|
||||
if is_multiline {
|
||||
buf.newline();
|
||||
buf.indent(indent);
|
||||
@ -557,12 +556,17 @@ fn format_record_builder_field_help(
|
||||
|
||||
buf.push_str(name.value);
|
||||
|
||||
if !spaces.is_empty() {
|
||||
fmt_spaces(buf, spaces.iter(), indent);
|
||||
if !colon_spaces.is_empty() {
|
||||
fmt_spaces(buf, colon_spaces.iter(), indent);
|
||||
}
|
||||
|
||||
buf.spaces(separator_spaces);
|
||||
buf.push(':');
|
||||
buf.spaces(1);
|
||||
|
||||
if !arrow_spaces.is_empty() {
|
||||
fmt_spaces(buf, arrow_spaces.iter(), indent);
|
||||
}
|
||||
|
||||
buf.push_str("<-");
|
||||
buf.spaces(1);
|
||||
ann.value.format(buf, indent);
|
||||
@ -577,22 +581,10 @@ fn format_record_builder_field_help(
|
||||
}
|
||||
SpaceBefore(sub_field, spaces) => {
|
||||
fmt_comments_only(buf, spaces.iter(), NewlineAt::Bottom, indent);
|
||||
format_record_builder_field_help(
|
||||
sub_field,
|
||||
buf,
|
||||
indent,
|
||||
separator_spaces,
|
||||
is_multiline,
|
||||
);
|
||||
format_record_builder_field_help(sub_field, buf, indent, is_multiline);
|
||||
}
|
||||
SpaceAfter(sub_field, spaces) => {
|
||||
format_record_builder_field_help(
|
||||
sub_field,
|
||||
buf,
|
||||
indent,
|
||||
separator_spaces,
|
||||
is_multiline,
|
||||
);
|
||||
format_record_builder_field_help(sub_field, buf, indent, is_multiline);
|
||||
fmt_comments_only(buf, spaces.iter(), NewlineAt::Bottom, indent);
|
||||
}
|
||||
Malformed(raw) => {
|
||||
|
@ -228,7 +228,10 @@ impl<'a> Formattable for Expr<'a> {
|
||||
a.extract_spaces().item.is_multiline()
|
||||
&& matches!(
|
||||
a.value.extract_spaces().item,
|
||||
Expr::Tuple(_) | Expr::List(_) | Expr::Record(_)
|
||||
Expr::Tuple(_)
|
||||
| Expr::List(_)
|
||||
| Expr::Record(_)
|
||||
| Expr::RecordBuilder(_)
|
||||
)
|
||||
&& a.extract_spaces().before == [CommentOrNewline::Newline]
|
||||
})
|
||||
@ -560,7 +563,11 @@ pub(crate) fn format_sq_literal(buf: &mut Buf, s: &str) {
|
||||
fn is_outdentable(expr: &Expr) -> bool {
|
||||
matches!(
|
||||
expr.extract_spaces().item,
|
||||
Expr::Tuple(_) | Expr::List(_) | Expr::Record(_) | Expr::Closure(..)
|
||||
Expr::Tuple(_)
|
||||
| Expr::List(_)
|
||||
| Expr::Record(_)
|
||||
| Expr::RecordBuilder(_)
|
||||
| Expr::Closure(..)
|
||||
)
|
||||
}
|
||||
|
||||
@ -1537,25 +1544,45 @@ fn format_record_builder_field_multiline(
|
||||
|
||||
buf.push_str(separator_prefix);
|
||||
buf.push_str(":");
|
||||
|
||||
if ann.value.is_multiline() {
|
||||
buf.newline();
|
||||
ann.value.format(buf, indent + INDENT);
|
||||
} else {
|
||||
buf.spaces(1);
|
||||
ann.value.format(buf, indent);
|
||||
}
|
||||
|
||||
buf.push(',');
|
||||
}
|
||||
ApplyValue(name, spaces, ann) => {
|
||||
ApplyValue(name, colon_spaces, arrow_spaces, ann) => {
|
||||
buf.newline();
|
||||
buf.indent(indent);
|
||||
buf.push_str(name.value);
|
||||
|
||||
if !spaces.is_empty() {
|
||||
fmt_spaces(buf, spaces.iter(), indent);
|
||||
if !colon_spaces.is_empty() {
|
||||
fmt_spaces(buf, colon_spaces.iter(), indent);
|
||||
buf.indent(indent);
|
||||
}
|
||||
|
||||
buf.push_str(separator_prefix);
|
||||
buf.push(':');
|
||||
buf.spaces(1);
|
||||
|
||||
if !arrow_spaces.is_empty() {
|
||||
fmt_spaces(buf, arrow_spaces.iter(), indent);
|
||||
buf.indent(indent + INDENT);
|
||||
}
|
||||
|
||||
buf.push_str("<-");
|
||||
|
||||
if ann.value.is_multiline() {
|
||||
buf.newline();
|
||||
ann.value.format(buf, indent + INDENT);
|
||||
} else {
|
||||
buf.spaces(1);
|
||||
ann.value.format(buf, indent);
|
||||
}
|
||||
buf.push(',');
|
||||
}
|
||||
LabelOnly(name) => {
|
||||
|
@ -620,12 +620,13 @@ impl<'a> RemoveSpaces<'a> for RecordBuilderField<'a> {
|
||||
match *self {
|
||||
RecordBuilderField::Value(a, _, c) => RecordBuilderField::Value(
|
||||
a.remove_spaces(arena),
|
||||
arena.alloc([]),
|
||||
&[],
|
||||
arena.alloc(c.remove_spaces(arena)),
|
||||
),
|
||||
RecordBuilderField::ApplyValue(a, _, c) => RecordBuilderField::ApplyValue(
|
||||
RecordBuilderField::ApplyValue(a, _, _, c) => RecordBuilderField::ApplyValue(
|
||||
a.remove_spaces(arena),
|
||||
arena.alloc([]),
|
||||
&[],
|
||||
&[],
|
||||
arena.alloc(c.remove_spaces(arena)),
|
||||
),
|
||||
RecordBuilderField::LabelOnly(a) => {
|
||||
|
@ -694,8 +694,13 @@ pub enum RecordBuilderField<'a> {
|
||||
// A field with a value, e.g. `{ name: "blah" }`
|
||||
Value(Loc<&'a str>, &'a [CommentOrNewline<'a>], &'a Loc<Expr<'a>>),
|
||||
|
||||
// A field with a function we can apply to build part of the record, e.g. `{ name <- apply getName }`
|
||||
ApplyValue(Loc<&'a str>, &'a [CommentOrNewline<'a>], &'a Loc<Expr<'a>>),
|
||||
// A field with a function we can apply to build part of the record, e.g. `{ name: <- apply getName }`
|
||||
ApplyValue(
|
||||
Loc<&'a str>,
|
||||
&'a [CommentOrNewline<'a>],
|
||||
&'a [CommentOrNewline<'a>],
|
||||
&'a Loc<Expr<'a>>,
|
||||
),
|
||||
|
||||
// A label with no value, e.g. `{ name }` (this is sugar for { name: name })
|
||||
LabelOnly(Loc<&'a str>),
|
||||
@ -1615,9 +1620,8 @@ impl<'a, T: Malformed> Malformed for AssignedField<'a, T> {
|
||||
impl<'a> Malformed for RecordBuilderField<'a> {
|
||||
fn is_malformed(&self) -> bool {
|
||||
match self {
|
||||
RecordBuilderField::Value(_, _, expr) | RecordBuilderField::ApplyValue(_, _, expr) => {
|
||||
expr.is_malformed()
|
||||
}
|
||||
RecordBuilderField::Value(_, _, expr)
|
||||
| RecordBuilderField::ApplyValue(_, _, _, expr) => expr.is_malformed(),
|
||||
RecordBuilderField::LabelOnly(_) => false,
|
||||
RecordBuilderField::SpaceBefore(field, _)
|
||||
| RecordBuilderField::SpaceAfter(field, _) => field.is_malformed(),
|
||||
|
@ -2539,7 +2539,12 @@ pub enum RecordField<'a> {
|
||||
LabelOnly(Loc<&'a str>),
|
||||
SpaceBefore(&'a RecordField<'a>, &'a [CommentOrNewline<'a>]),
|
||||
SpaceAfter(&'a RecordField<'a>, &'a [CommentOrNewline<'a>]),
|
||||
ApplyValue(Loc<&'a str>, &'a [CommentOrNewline<'a>], &'a Loc<Expr<'a>>),
|
||||
ApplyValue(
|
||||
Loc<&'a str>,
|
||||
&'a [CommentOrNewline<'a>],
|
||||
&'a [CommentOrNewline<'a>],
|
||||
&'a Loc<Expr<'a>>,
|
||||
),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -2554,7 +2559,7 @@ impl<'a> RecordField<'a> {
|
||||
|
||||
loop {
|
||||
match current {
|
||||
RecordField::ApplyValue(_, _, _) => break true,
|
||||
RecordField::ApplyValue(_, _, _, _) => break true,
|
||||
RecordField::SpaceBefore(field, _) | RecordField::SpaceAfter(field, _) => {
|
||||
current = *field;
|
||||
}
|
||||
@ -2580,7 +2585,7 @@ impl<'a> RecordField<'a> {
|
||||
|
||||
RecordField::LabelOnly(loc_label) => Ok(LabelOnly(loc_label)),
|
||||
|
||||
RecordField::ApplyValue(_, _, _) => Err(FoundApplyValue),
|
||||
RecordField::ApplyValue(_, _, _, _) => Err(FoundApplyValue),
|
||||
|
||||
RecordField::SpaceBefore(field, spaces) => {
|
||||
let assigned_field = field.to_assigned_field(arena)?;
|
||||
@ -2611,8 +2616,8 @@ impl<'a> RecordField<'a> {
|
||||
|
||||
RecordField::LabelOnly(loc_label) => Ok(LabelOnly(loc_label)),
|
||||
|
||||
RecordField::ApplyValue(loc_label, spaces, loc_expr) => {
|
||||
Ok(ApplyValue(loc_label, spaces, loc_expr))
|
||||
RecordField::ApplyValue(loc_label, colon_spaces, arrow_spaces, loc_expr) => {
|
||||
Ok(ApplyValue(loc_label, colon_spaces, arrow_spaces, loc_expr))
|
||||
}
|
||||
|
||||
RecordField::SpaceBefore(field, spaces) => {
|
||||
@ -2642,36 +2647,33 @@ impl<'a> Spaceable<'a> for RecordField<'a> {
|
||||
pub fn record_field<'a>() -> impl Parser<'a, RecordField<'a>, ERecord<'a>> {
|
||||
use RecordField::*;
|
||||
|
||||
enum AssignKind {
|
||||
Required,
|
||||
Optional,
|
||||
Apply,
|
||||
}
|
||||
|
||||
use AssignKind::*;
|
||||
|
||||
map_with_arena!(
|
||||
and!(
|
||||
specialize(|_, pos| ERecord::Field(pos), loc!(lowercase_ident())),
|
||||
and!(
|
||||
spaces(),
|
||||
optional(and!(
|
||||
one_of!(
|
||||
map!(word1(b':', ERecord::Colon), |_| Required),
|
||||
map!(word1(b'?', ERecord::QuestionMark), |_| Optional),
|
||||
map!(word2(b'<', b'-', ERecord::Arrow), |_| Apply),
|
||||
),
|
||||
optional(either!(
|
||||
and!(word1(b':', ERecord::Colon), record_field_expr()),
|
||||
and!(
|
||||
word1(b'?', ERecord::QuestionMark),
|
||||
spaces_before(specialize_ref(ERecord::Expr, loc_expr(false)))
|
||||
)
|
||||
))
|
||||
)
|
||||
),
|
||||
|arena: &'a bumpalo::Bump, (loc_label, (spaces, opt_loc_val))| {
|
||||
match opt_loc_val {
|
||||
Some((Required, loc_val)) => RequiredValue(loc_label, spaces, arena.alloc(loc_val)),
|
||||
Some(Either::First((_, RecordFieldExpr::Value(loc_val)))) => {
|
||||
RequiredValue(loc_label, spaces, arena.alloc(loc_val))
|
||||
}
|
||||
|
||||
Some((Optional, loc_val)) => OptionalValue(loc_label, spaces, arena.alloc(loc_val)),
|
||||
Some(Either::First((_, RecordFieldExpr::Apply(arrow_spaces, loc_val)))) => {
|
||||
ApplyValue(loc_label, spaces, arrow_spaces, arena.alloc(loc_val))
|
||||
}
|
||||
|
||||
Some((Apply, loc_val)) => ApplyValue(loc_label, spaces, arena.alloc(loc_val)),
|
||||
Some(Either::Second((_, loc_val))) => {
|
||||
OptionalValue(loc_label, spaces, arena.alloc(loc_val))
|
||||
}
|
||||
|
||||
// If no value was provided, record it as a Var.
|
||||
// Canonicalize will know what to do with a Var later.
|
||||
@ -2687,6 +2689,40 @@ pub fn record_field<'a>() -> impl Parser<'a, RecordField<'a>, ERecord<'a>> {
|
||||
)
|
||||
}
|
||||
|
||||
enum RecordFieldExpr<'a> {
|
||||
Apply(&'a [CommentOrNewline<'a>], Loc<Expr<'a>>),
|
||||
Value(Loc<Expr<'a>>),
|
||||
}
|
||||
|
||||
fn record_field_expr<'a>() -> impl Parser<'a, RecordFieldExpr<'a>, ERecord<'a>> {
|
||||
map_with_arena!(
|
||||
and!(
|
||||
spaces(),
|
||||
either!(
|
||||
and!(
|
||||
word2(b'<', b'-', ERecord::Arrow),
|
||||
spaces_before(specialize_ref(ERecord::Expr, loc_expr(false)))
|
||||
),
|
||||
specialize_ref(ERecord::Expr, loc_expr(false))
|
||||
)
|
||||
),
|
||||
|arena: &'a bumpalo::Bump, (spaces, either)| {
|
||||
match either {
|
||||
Either::First((_, loc_expr)) => RecordFieldExpr::Apply(spaces, loc_expr),
|
||||
Either::Second(loc_expr) => RecordFieldExpr::Value({
|
||||
if spaces.is_empty() {
|
||||
loc_expr
|
||||
} else {
|
||||
arena
|
||||
.alloc(loc_expr.value)
|
||||
.with_spaces_before(spaces, loc_expr.region)
|
||||
}
|
||||
}),
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fn record_updateable_identifier<'a>() -> impl Parser<'a, Expr<'a>, ERecord<'a>> {
|
||||
specialize(
|
||||
|_, pos| ERecord::Updateable(pos),
|
||||
|
@ -1930,19 +1930,19 @@ mod test_fmt {
|
||||
fn record_builder() {
|
||||
expr_formats_same(indoc!(
|
||||
r#"
|
||||
{ a: 1, b <- get "b" |> batch, c <- get "c" |> batch, d }
|
||||
{ a: 1, b: <- get "b" |> batch, c: <- get "c" |> batch, d }
|
||||
"#
|
||||
));
|
||||
|
||||
expr_formats_to(
|
||||
indoc!(
|
||||
r#"
|
||||
{ a: 1, b <- get "b" |> batch, c <- get "c" |> batch }
|
||||
{ a: 1, b: <- get "b" |> batch, c:<- get "c" |> batch }
|
||||
"#
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
{ a: 1, b <- get "b" |> batch, c <- get "c" |> batch }
|
||||
{ a: 1, b: <- get "b" |> batch, c: <- get "c" |> batch }
|
||||
"#
|
||||
),
|
||||
);
|
||||
@ -1951,8 +1951,8 @@ mod test_fmt {
|
||||
r#"
|
||||
{
|
||||
a: 1,
|
||||
b <- get "b" |> batch,
|
||||
c <- get "c" |> batch,
|
||||
b: <- get "b" |> batch,
|
||||
c: <- get "c" |> batch,
|
||||
d,
|
||||
}
|
||||
"#
|
||||
@ -1961,16 +1961,16 @@ mod test_fmt {
|
||||
expr_formats_to(
|
||||
indoc!(
|
||||
r#"
|
||||
{ a: 1, b <- get "b" |> batch,
|
||||
c <- get "c" |> batch, d }
|
||||
{ a: 1, b: <- get "b" |> batch,
|
||||
c: <- get "c" |> batch, d }
|
||||
"#
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
{
|
||||
a: 1,
|
||||
b <- get "b" |> batch,
|
||||
c <- get "c" |> batch,
|
||||
b: <- get "b" |> batch,
|
||||
c: <- get "c" |> batch,
|
||||
d,
|
||||
}
|
||||
"#
|
||||
@ -1979,20 +1979,92 @@ mod test_fmt {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiline_record_builder_func_arg() {
|
||||
fn multiline_record_builder_field() {
|
||||
expr_formats_to(
|
||||
indoc!(
|
||||
r#"
|
||||
succeed { a: get "a" |> batch,
|
||||
b: get "b" |> batch,
|
||||
succeed {
|
||||
a: <- get "a" |> map (\x -> x * 2)
|
||||
|> batch,
|
||||
b: <- get "b" |> batch,
|
||||
c: items
|
||||
|> List.map \x -> x * 2
|
||||
}
|
||||
"#
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
succeed {
|
||||
a: get "a" |> batch,
|
||||
b: get "b" |> batch,
|
||||
a: <-
|
||||
get "a"
|
||||
|> map (\x -> x * 2)
|
||||
|> batch,
|
||||
b: <- get "b" |> batch,
|
||||
c:
|
||||
items
|
||||
|> List.map \x -> x * 2,
|
||||
}
|
||||
"#
|
||||
),
|
||||
);
|
||||
|
||||
expr_formats_same(indoc!(
|
||||
r#"
|
||||
succeed {
|
||||
a: # I like to comment in weird places
|
||||
<- get "a" |> batch,
|
||||
b: <- get "b" |> batch,
|
||||
}
|
||||
"#
|
||||
));
|
||||
|
||||
expr_formats_same(indoc!(
|
||||
r#"
|
||||
succeed {
|
||||
a:
|
||||
# I like to comment in weird places
|
||||
<- get "a" |> batch,
|
||||
b: <- get "b" |> batch,
|
||||
}
|
||||
"#
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn outdentable_record_builders() {
|
||||
expr_formats_to(
|
||||
indoc!(
|
||||
r#"
|
||||
succeed { a: <- get "a" |> batch,
|
||||
b: <- get "b" |> batch,
|
||||
}
|
||||
"#
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
succeed {
|
||||
a: <- get "a" |> batch,
|
||||
b: <- get "b" |> batch,
|
||||
}
|
||||
"#
|
||||
),
|
||||
);
|
||||
|
||||
expr_formats_to(
|
||||
indoc!(
|
||||
r#"
|
||||
succeed
|
||||
{
|
||||
a: <- get "a" |> batch,
|
||||
b: <- get "b" |> batch,
|
||||
}
|
||||
"#
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
succeed {
|
||||
a: <- get "a" |> batch,
|
||||
b: <- get "b" |> batch,
|
||||
}
|
||||
"#
|
||||
),
|
||||
@ -2004,15 +2076,15 @@ mod test_fmt {
|
||||
expr_formats_to(
|
||||
indoc!(
|
||||
r#"
|
||||
succeed { a <- get "a" }
|
||||
{ b <- get "b" }
|
||||
succeed { a: <- get "a" }
|
||||
{ b: <- get "b" }
|
||||
"#
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
succeed
|
||||
{ a <- get "a" }
|
||||
{ b <- get "b" }
|
||||
{ a: <- get "a" }
|
||||
{ b: <- get "b" }
|
||||
"#
|
||||
),
|
||||
);
|
||||
|
@ -1189,10 +1189,8 @@ fn to_expr_report<'b>(
|
||||
CalledVia::RecordBuilder => {
|
||||
alloc.concat([
|
||||
alloc.tip(),
|
||||
alloc.reflow("Replace "),
|
||||
alloc.reflow("Remove "),
|
||||
alloc.keyword("<-"),
|
||||
alloc.reflow(" with "),
|
||||
alloc.keyword(":"),
|
||||
alloc.reflow(" to assign the field directly.")
|
||||
])
|
||||
}
|
||||
|
@ -10184,7 +10184,7 @@ I recommend using camelCase. It's the standard style in Roc code!
|
||||
indoc!(
|
||||
r#"
|
||||
{
|
||||
a <- apply "a",
|
||||
a: <- apply "a",
|
||||
b,
|
||||
c ? "optional"
|
||||
}
|
||||
@ -10200,7 +10200,7 @@ I recommend using camelCase. It's the standard style in Roc code!
|
||||
2│
|
||||
3│ main =
|
||||
4│ {
|
||||
5│ a <- apply "a",
|
||||
5│ a: <- apply "a",
|
||||
6│ b,
|
||||
7│ c ? "optional"
|
||||
^^^^^^^^^^^^^^
|
||||
@ -10214,7 +10214,7 @@ I recommend using camelCase. It's the standard style in Roc code!
|
||||
indoc!(
|
||||
r#"
|
||||
{ rec &
|
||||
a <- apply "a",
|
||||
a: <- apply "a",
|
||||
b: 3
|
||||
}
|
||||
"#
|
||||
@ -10229,8 +10229,8 @@ I recommend using camelCase. It's the standard style in Roc code!
|
||||
2│
|
||||
3│ main =
|
||||
4│ { rec &
|
||||
5│ a <- apply "a",
|
||||
^^^^^^^^^^^^^^
|
||||
5│ a: <- apply "a",
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
Record builders cannot be updated like records.
|
||||
"###
|
||||
@ -10241,8 +10241,8 @@ I recommend using camelCase. It's the standard style in Roc code!
|
||||
indoc!(
|
||||
r#"
|
||||
succeed
|
||||
{ a <- apply "a" }
|
||||
{ b <- apply "b" }
|
||||
{ a: <- apply "a" }
|
||||
{ b: <- apply "b" }
|
||||
"#
|
||||
),
|
||||
@r###"
|
||||
@ -10251,8 +10251,8 @@ I recommend using camelCase. It's the standard style in Roc code!
|
||||
This function is applied to multiple record builders:
|
||||
|
||||
4│> succeed
|
||||
5│> { a <- apply "a" }
|
||||
6│> { b <- apply "b" }
|
||||
5│> { a: <- apply "a" }
|
||||
6│> { b: <- apply "b" }
|
||||
|
||||
Note: Functions can only take at most one record builder!
|
||||
|
||||
@ -10265,7 +10265,7 @@ I recommend using camelCase. It's the standard style in Roc code!
|
||||
unapplied_record_builder,
|
||||
indoc!(
|
||||
r#"
|
||||
{ a <- apply "a" }
|
||||
{ a: <- apply "a" }
|
||||
"#
|
||||
),
|
||||
@r###"
|
||||
@ -10273,8 +10273,8 @@ I recommend using camelCase. It's the standard style in Roc code!
|
||||
|
||||
This record builder was not applied to a function:
|
||||
|
||||
4│ { a <- apply "a" }
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
4│ { a: <- apply "a" }
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
However, we need a function to construct the record.
|
||||
|
||||
@ -10289,7 +10289,7 @@ I recommend using camelCase. It's the standard style in Roc code!
|
||||
succeed = \_ -> crash ""
|
||||
|
||||
succeed {
|
||||
a <- "a",
|
||||
a: <- "a",
|
||||
}
|
||||
"#
|
||||
),
|
||||
@ -10298,10 +10298,10 @@ I recommend using camelCase. It's the standard style in Roc code!
|
||||
|
||||
This value is not a function, but it was given 1 argument:
|
||||
|
||||
7│ a <- "a",
|
||||
7│ a: <- "a",
|
||||
^^^
|
||||
|
||||
Tip: Replace `<-` with `:` to assign the field directly.
|
||||
Tip: Remove `<-` to assign the field directly.
|
||||
"###
|
||||
);
|
||||
|
||||
@ -10320,7 +10320,7 @@ I recommend using camelCase. It's the standard style in Roc code!
|
||||
// get = \_ -> @Decode {}
|
||||
|
||||
// succeed {
|
||||
// a <- get "a",
|
||||
// a: <- get "a",
|
||||
// # missing |> apply ^
|
||||
// }
|
||||
// "#
|
||||
@ -10330,7 +10330,7 @@ I recommend using camelCase. It's the standard style in Roc code!
|
||||
|
||||
// This value is an opaque type, so it cannot be called with an argument:
|
||||
|
||||
// 12│ a <- get "a",
|
||||
// 12│ a: <- get "a",
|
||||
// ^^^^^^^
|
||||
|
||||
// Hint: Did you mean to apply it to a function first?
|
||||
|
Loading…
Reference in New Issue
Block a user