fix: comments in record patterns closes #946
This commit is contained in:
parent
c16bd06e97
commit
7f38b55c1c
|
@ -1243,7 +1243,7 @@ pub enum Pattern<Constructor, Type> {
|
||||||
arguments: Vec<CallArg<Self>>,
|
arguments: Vec<CallArg<Self>>,
|
||||||
module: Option<String>,
|
module: Option<String>,
|
||||||
constructor: Constructor,
|
constructor: Constructor,
|
||||||
with_spread: bool,
|
spread_location: Option<Span>,
|
||||||
tipo: Type,
|
tipo: Type,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1273,6 +1273,15 @@ impl<A, B> Pattern<A, B> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn with_spread(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
Pattern::Constructor {
|
||||||
|
spread_location, ..
|
||||||
|
} => spread_location.is_some(),
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns `true` if the pattern is [`Discard`].
|
/// Returns `true` if the pattern is [`Discard`].
|
||||||
///
|
///
|
||||||
/// [`Discard`]: Pattern::Discard
|
/// [`Discard`]: Pattern::Discard
|
||||||
|
@ -1295,7 +1304,7 @@ impl UntypedPattern {
|
||||||
name: "True".to_string(),
|
name: "True".to_string(),
|
||||||
arguments: vec![],
|
arguments: vec![],
|
||||||
constructor: (),
|
constructor: (),
|
||||||
with_spread: false,
|
spread_location: None,
|
||||||
tipo: (),
|
tipo: (),
|
||||||
module: None,
|
module: None,
|
||||||
is_record: false,
|
is_record: false,
|
||||||
|
|
|
@ -1068,7 +1068,7 @@ impl<'comments> Formatter<'comments> {
|
||||||
name: &'a str,
|
name: &'a str,
|
||||||
args: &'a [CallArg<UntypedPattern>],
|
args: &'a [CallArg<UntypedPattern>],
|
||||||
module: &'a Option<String>,
|
module: &'a Option<String>,
|
||||||
with_spread: bool,
|
spread_location: Option<Span>,
|
||||||
is_record: bool,
|
is_record: bool,
|
||||||
) -> Document<'a> {
|
) -> Document<'a> {
|
||||||
fn is_breakable(expr: &UntypedPattern) -> bool {
|
fn is_breakable(expr: &UntypedPattern) -> bool {
|
||||||
|
@ -1086,7 +1086,7 @@ impl<'comments> Formatter<'comments> {
|
||||||
None => name.to_doc(),
|
None => name.to_doc(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if args.is_empty() && with_spread {
|
if args.is_empty() && spread_location.is_some() {
|
||||||
if is_record {
|
if is_record {
|
||||||
name.append(" { .. }")
|
name.append(" { .. }")
|
||||||
// TODO: not possible
|
// TODO: not possible
|
||||||
|
@ -1095,11 +1095,16 @@ impl<'comments> Formatter<'comments> {
|
||||||
}
|
}
|
||||||
} else if args.is_empty() {
|
} else if args.is_empty() {
|
||||||
name
|
name
|
||||||
} else if with_spread {
|
} else if let Some(spread_location) = spread_location {
|
||||||
|
let args = args
|
||||||
|
.iter()
|
||||||
|
.map(|a| self.pattern_call_arg(a))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let wrapped_args = if is_record {
|
let wrapped_args = if is_record {
|
||||||
wrap_fields_with_spread(args.iter().map(|a| self.pattern_call_arg(a)))
|
self.wrap_fields_with_spread(args, spread_location)
|
||||||
} else {
|
} else {
|
||||||
wrap_args_with_spread(args.iter().map(|a| self.pattern_call_arg(a)))
|
self.wrap_args_with_spread(args, spread_location)
|
||||||
};
|
};
|
||||||
|
|
||||||
name.append(wrapped_args)
|
name.append(wrapped_args)
|
||||||
|
@ -1120,6 +1125,48 @@ impl<'comments> Formatter<'comments> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn wrap_fields_with_spread<'a, I>(&mut self, args: I, spread_location: Span) -> Document<'a>
|
||||||
|
where
|
||||||
|
I: IntoIterator<Item = Document<'a>>,
|
||||||
|
{
|
||||||
|
let mut args = args.into_iter().peekable();
|
||||||
|
if args.peek().is_none() {
|
||||||
|
return "()".to_doc();
|
||||||
|
}
|
||||||
|
|
||||||
|
let comments = self.pop_comments(spread_location.start);
|
||||||
|
|
||||||
|
break_(" {", " { ")
|
||||||
|
.append(join(args, break_(",", ", ")))
|
||||||
|
.append(break_(",", ", "))
|
||||||
|
.append(commented("..".to_doc(), comments))
|
||||||
|
.nest(INDENT)
|
||||||
|
.append(break_("", " "))
|
||||||
|
.append("}")
|
||||||
|
.group()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn wrap_args_with_spread<'a, I>(&mut self, args: I, spread_location: Span) -> Document<'a>
|
||||||
|
where
|
||||||
|
I: IntoIterator<Item = Document<'a>>,
|
||||||
|
{
|
||||||
|
let mut args = args.into_iter().peekable();
|
||||||
|
if args.peek().is_none() {
|
||||||
|
return "()".to_doc();
|
||||||
|
}
|
||||||
|
|
||||||
|
let comments = self.pop_comments(spread_location.start);
|
||||||
|
|
||||||
|
break_("(", "(")
|
||||||
|
.append(join(args, break_(",", ", ")))
|
||||||
|
.append(break_(",", ", "))
|
||||||
|
.append(commented("..".to_doc(), comments))
|
||||||
|
.nest(INDENT)
|
||||||
|
.append(break_(",", ""))
|
||||||
|
.append(")")
|
||||||
|
.group()
|
||||||
|
}
|
||||||
|
|
||||||
fn call<'a>(&mut self, fun: &'a UntypedExpr, args: &'a [CallArg<UntypedExpr>]) -> Document<'a> {
|
fn call<'a>(&mut self, fun: &'a UntypedExpr, args: &'a [CallArg<UntypedExpr>]) -> Document<'a> {
|
||||||
let is_constr = match fun {
|
let is_constr = match fun {
|
||||||
UntypedExpr::Var { name, .. } => name[0..1].chars().all(|c| c.is_uppercase()),
|
UntypedExpr::Var { name, .. } => name[0..1].chars().all(|c| c.is_uppercase()),
|
||||||
|
@ -1821,26 +1868,31 @@ impl<'comments> Formatter<'comments> {
|
||||||
name,
|
name,
|
||||||
arguments: args,
|
arguments: args,
|
||||||
module,
|
module,
|
||||||
with_spread,
|
spread_location,
|
||||||
is_record,
|
is_record,
|
||||||
..
|
..
|
||||||
} => self.pattern_constructor(name, args, module, *with_spread, *is_record),
|
} => self.pattern_constructor(name, args, module, *spread_location, *is_record),
|
||||||
};
|
};
|
||||||
commented(doc, comments)
|
commented(doc, comments)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pattern_call_arg<'a>(&mut self, arg: &'a CallArg<UntypedPattern>) -> Document<'a> {
|
fn pattern_call_arg<'a>(&mut self, arg: &'a CallArg<UntypedPattern>) -> Document<'a> {
|
||||||
|
let comments = self.pop_comments(arg.location.start);
|
||||||
|
|
||||||
if let (UntypedPattern::Var { name, .. }, Some(label)) = (&arg.value, &arg.label) {
|
if let (UntypedPattern::Var { name, .. }, Some(label)) = (&arg.value, &arg.label) {
|
||||||
if name == label {
|
if name == label {
|
||||||
return self.pattern(&arg.value);
|
return self.pattern(&arg.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
arg.label
|
let doc = arg
|
||||||
|
.label
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|s| s.to_doc().append(": "))
|
.map(|s| s.to_doc().append(": "))
|
||||||
.unwrap_or_else(nil)
|
.unwrap_or_else(nil)
|
||||||
.append(self.pattern(&arg.value))
|
.append(self.pattern(&arg.value));
|
||||||
|
|
||||||
|
commented(doc, comments)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clause_guard_bin_op<'a>(
|
pub fn clause_guard_bin_op<'a>(
|
||||||
|
@ -2029,44 +2081,6 @@ where
|
||||||
.append(line())
|
.append(line())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wrap_args_with_spread<'a, I>(args: I) -> Document<'a>
|
|
||||||
where
|
|
||||||
I: IntoIterator<Item = Document<'a>>,
|
|
||||||
{
|
|
||||||
let mut args = args.into_iter().peekable();
|
|
||||||
if args.peek().is_none() {
|
|
||||||
return "()".to_doc();
|
|
||||||
}
|
|
||||||
|
|
||||||
break_("(", "(")
|
|
||||||
.append(join(args, break_(",", ", ")))
|
|
||||||
.append(break_(",", ", "))
|
|
||||||
.append("..")
|
|
||||||
.nest(INDENT)
|
|
||||||
.append(break_(",", ""))
|
|
||||||
.append(")")
|
|
||||||
.group()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn wrap_fields_with_spread<'a, I>(args: I) -> Document<'a>
|
|
||||||
where
|
|
||||||
I: IntoIterator<Item = Document<'a>>,
|
|
||||||
{
|
|
||||||
let mut args = args.into_iter().peekable();
|
|
||||||
if args.peek().is_none() {
|
|
||||||
return "()".to_doc();
|
|
||||||
}
|
|
||||||
|
|
||||||
break_(" {", " { ")
|
|
||||||
.append(join(args, break_(",", ", ")))
|
|
||||||
.append(break_(",", ", "))
|
|
||||||
.append("..")
|
|
||||||
.nest(INDENT)
|
|
||||||
.append(break_("", " "))
|
|
||||||
.append("}")
|
|
||||||
.group()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn list<'a>(elements: Document<'a>, length: usize, tail: Option<Document<'a>>) -> Document<'a> {
|
fn list<'a>(elements: Document<'a>, length: usize, tail: Option<Document<'a>>) -> Document<'a> {
|
||||||
if length == 0 {
|
if length == 0 {
|
||||||
return match tail {
|
return match tail {
|
||||||
|
|
|
@ -23,7 +23,7 @@ Test(
|
||||||
arguments: [],
|
arguments: [],
|
||||||
module: None,
|
module: None,
|
||||||
constructor: (),
|
constructor: (),
|
||||||
with_spread: false,
|
spread_location: None,
|
||||||
tipo: (),
|
tipo: (),
|
||||||
},
|
},
|
||||||
annotation: None,
|
annotation: None,
|
||||||
|
|
|
@ -30,7 +30,7 @@ Assignment {
|
||||||
],
|
],
|
||||||
module: None,
|
module: None,
|
||||||
constructor: (),
|
constructor: (),
|
||||||
with_spread: false,
|
spread_location: None,
|
||||||
tipo: (),
|
tipo: (),
|
||||||
},
|
},
|
||||||
annotation: None,
|
annotation: None,
|
||||||
|
|
|
@ -29,7 +29,7 @@ Assignment {
|
||||||
arguments: [],
|
arguments: [],
|
||||||
module: None,
|
module: None,
|
||||||
constructor: (),
|
constructor: (),
|
||||||
with_spread: false,
|
spread_location: None,
|
||||||
tipo: (),
|
tipo: (),
|
||||||
},
|
},
|
||||||
annotation: None,
|
annotation: None,
|
||||||
|
|
|
@ -41,7 +41,7 @@ Assignment {
|
||||||
arguments: [],
|
arguments: [],
|
||||||
module: None,
|
module: None,
|
||||||
constructor: (),
|
constructor: (),
|
||||||
with_spread: false,
|
spread_location: None,
|
||||||
tipo: (),
|
tipo: (),
|
||||||
},
|
},
|
||||||
annotation: None,
|
annotation: None,
|
||||||
|
|
|
@ -20,7 +20,7 @@ Assignment {
|
||||||
arguments: [],
|
arguments: [],
|
||||||
module: None,
|
module: None,
|
||||||
constructor: (),
|
constructor: (),
|
||||||
with_spread: false,
|
spread_location: None,
|
||||||
tipo: (),
|
tipo: (),
|
||||||
},
|
},
|
||||||
annotation: None,
|
annotation: None,
|
||||||
|
|
|
@ -19,7 +19,9 @@ When {
|
||||||
arguments: [],
|
arguments: [],
|
||||||
module: None,
|
module: None,
|
||||||
constructor: (),
|
constructor: (),
|
||||||
with_spread: true,
|
spread_location: Some(
|
||||||
|
21..23,
|
||||||
|
),
|
||||||
tipo: (),
|
tipo: (),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -46,7 +48,9 @@ When {
|
||||||
arguments: [],
|
arguments: [],
|
||||||
module: None,
|
module: None,
|
||||||
constructor: (),
|
constructor: (),
|
||||||
with_spread: true,
|
spread_location: Some(
|
||||||
|
40..42,
|
||||||
|
),
|
||||||
tipo: (),
|
tipo: (),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -19,7 +19,9 @@ When {
|
||||||
arguments: [],
|
arguments: [],
|
||||||
module: None,
|
module: None,
|
||||||
constructor: (),
|
constructor: (),
|
||||||
with_spread: true,
|
spread_location: Some(
|
||||||
|
21..23,
|
||||||
|
),
|
||||||
tipo: (),
|
tipo: (),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -19,7 +19,9 @@ When {
|
||||||
arguments: [],
|
arguments: [],
|
||||||
module: None,
|
module: None,
|
||||||
constructor: (),
|
constructor: (),
|
||||||
with_spread: true,
|
spread_location: Some(
|
||||||
|
21..23,
|
||||||
|
),
|
||||||
tipo: (),
|
tipo: (),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -39,7 +41,9 @@ When {
|
||||||
arguments: [],
|
arguments: [],
|
||||||
module: None,
|
module: None,
|
||||||
constructor: (),
|
constructor: (),
|
||||||
with_spread: true,
|
spread_location: Some(
|
||||||
|
40..42,
|
||||||
|
),
|
||||||
tipo: (),
|
tipo: (),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use chumsky::prelude::*;
|
use chumsky::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{CallArg, UntypedPattern},
|
ast::{CallArg, Span, UntypedPattern},
|
||||||
parser::{error::ParseError, token::Token},
|
parser::{error::ParseError, token::Token},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -10,23 +10,26 @@ pub fn parser(
|
||||||
) -> impl Parser<Token, UntypedPattern, Error = ParseError> + '_ {
|
) -> impl Parser<Token, UntypedPattern, Error = ParseError> + '_ {
|
||||||
select! {Token::UpName { name } => name}
|
select! {Token::UpName { name } => name}
|
||||||
.then(args(expression))
|
.then(args(expression))
|
||||||
.map_with_span(|(name, (arguments, with_spread, is_record)), location| {
|
.map_with_span(
|
||||||
UntypedPattern::Constructor {
|
|(name, (arguments, spread_location, is_record)), location| {
|
||||||
is_record,
|
UntypedPattern::Constructor {
|
||||||
location,
|
is_record,
|
||||||
name,
|
location,
|
||||||
arguments,
|
name,
|
||||||
module: None,
|
arguments,
|
||||||
constructor: (),
|
module: None,
|
||||||
with_spread,
|
constructor: (),
|
||||||
tipo: (),
|
spread_location,
|
||||||
}
|
tipo: (),
|
||||||
})
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn args(
|
pub(crate) fn args(
|
||||||
expression: Recursive<'_, Token, UntypedPattern, ParseError>,
|
expression: Recursive<'_, Token, UntypedPattern, ParseError>,
|
||||||
) -> impl Parser<Token, (Vec<CallArg<UntypedPattern>>, bool, bool), Error = ParseError> + '_ {
|
) -> impl Parser<Token, (Vec<CallArg<UntypedPattern>>, Option<Span>, bool), Error = ParseError> + '_
|
||||||
|
{
|
||||||
let record_constructor_pattern_arg_parser = choice((
|
let record_constructor_pattern_arg_parser = choice((
|
||||||
select! {Token::Name {name} => name}
|
select! {Token::Name {name} => name}
|
||||||
.then_ignore(just(Token::Colon))
|
.then_ignore(just(Token::Colon))
|
||||||
|
@ -49,8 +52,9 @@ pub(crate) fn args(
|
||||||
.allow_trailing()
|
.allow_trailing()
|
||||||
.then(
|
.then(
|
||||||
just(Token::DotDot)
|
just(Token::DotDot)
|
||||||
.then_ignore(just(Token::Comma).or_not())
|
|
||||||
.ignored()
|
.ignored()
|
||||||
|
.map_with_span(|_spread, span| span)
|
||||||
|
.then_ignore(just(Token::Comma).or_not())
|
||||||
.or_not(),
|
.or_not(),
|
||||||
)
|
)
|
||||||
.delimited_by(just(Token::LeftBrace), just(Token::RightBrace));
|
.delimited_by(just(Token::LeftBrace), just(Token::RightBrace));
|
||||||
|
@ -66,8 +70,9 @@ pub(crate) fn args(
|
||||||
.allow_trailing()
|
.allow_trailing()
|
||||||
.then(
|
.then(
|
||||||
just(Token::DotDot)
|
just(Token::DotDot)
|
||||||
.then_ignore(just(Token::Comma).or_not())
|
|
||||||
.ignored()
|
.ignored()
|
||||||
|
.map_with_span(|_spread, span| span)
|
||||||
|
.then_ignore(just(Token::Comma).or_not())
|
||||||
.or_not(),
|
.or_not(),
|
||||||
)
|
)
|
||||||
.delimited_by(just(Token::LeftParen), just(Token::RightParen));
|
.delimited_by(just(Token::LeftParen), just(Token::RightParen));
|
||||||
|
@ -79,8 +84,8 @@ pub(crate) fn args(
|
||||||
.or_not()
|
.or_not()
|
||||||
.map(|opt_args| {
|
.map(|opt_args| {
|
||||||
opt_args
|
opt_args
|
||||||
.map(|((a, b), c)| (a, b.is_some(), c))
|
.map(|((a, b), c)| (a, b, c))
|
||||||
.unwrap_or_else(|| (vec![], false, false))
|
.unwrap_or_else(|| (vec![], None, false))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,6 @@ Constructor {
|
||||||
arguments: [],
|
arguments: [],
|
||||||
module: None,
|
module: None,
|
||||||
constructor: (),
|
constructor: (),
|
||||||
with_spread: false,
|
spread_location: None,
|
||||||
tipo: (),
|
tipo: (),
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,6 @@ Constructor {
|
||||||
"module",
|
"module",
|
||||||
),
|
),
|
||||||
constructor: (),
|
constructor: (),
|
||||||
with_spread: false,
|
spread_location: None,
|
||||||
tipo: (),
|
tipo: (),
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,6 @@ Constructor {
|
||||||
],
|
],
|
||||||
module: None,
|
module: None,
|
||||||
constructor: (),
|
constructor: (),
|
||||||
with_spread: false,
|
spread_location: None,
|
||||||
tipo: (),
|
tipo: (),
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,6 @@ Constructor {
|
||||||
],
|
],
|
||||||
module: None,
|
module: None,
|
||||||
constructor: (),
|
constructor: (),
|
||||||
with_spread: false,
|
spread_location: None,
|
||||||
tipo: (),
|
tipo: (),
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,6 @@ Constructor {
|
||||||
],
|
],
|
||||||
module: None,
|
module: None,
|
||||||
constructor: (),
|
constructor: (),
|
||||||
with_spread: false,
|
spread_location: None,
|
||||||
tipo: (),
|
tipo: (),
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,8 @@ Constructor {
|
||||||
],
|
],
|
||||||
module: None,
|
module: None,
|
||||||
constructor: (),
|
constructor: (),
|
||||||
with_spread: true,
|
spread_location: Some(
|
||||||
|
9..11,
|
||||||
|
),
|
||||||
tipo: (),
|
tipo: (),
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ Pair {
|
||||||
arguments: [],
|
arguments: [],
|
||||||
module: None,
|
module: None,
|
||||||
constructor: (),
|
constructor: (),
|
||||||
with_spread: false,
|
spread_location: None,
|
||||||
tipo: (),
|
tipo: (),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ pub fn parser(
|
||||||
.or_not(),
|
.or_not(),
|
||||||
)
|
)
|
||||||
.map_with_span(|(name, opt_pattern), span| {
|
.map_with_span(|(name, opt_pattern), span| {
|
||||||
if let Some((c_name, (arguments, with_spread, is_record))) = opt_pattern {
|
if let Some((c_name, (arguments, spread_location, is_record))) = opt_pattern {
|
||||||
UntypedPattern::Constructor {
|
UntypedPattern::Constructor {
|
||||||
is_record,
|
is_record,
|
||||||
location: span,
|
location: span,
|
||||||
|
@ -26,7 +26,7 @@ pub fn parser(
|
||||||
arguments,
|
arguments,
|
||||||
module: Some(name),
|
module: Some(name),
|
||||||
constructor: (),
|
constructor: (),
|
||||||
with_spread,
|
spread_location,
|
||||||
tipo: (),
|
tipo: (),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -749,6 +749,24 @@ fn format_int_uint() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn preserve_comment_in_record() {
|
||||||
|
assert_format!(
|
||||||
|
r#"
|
||||||
|
fn foo() {
|
||||||
|
let Output {
|
||||||
|
// something
|
||||||
|
address: own_address,
|
||||||
|
// value: own_value,
|
||||||
|
..
|
||||||
|
} = own_output
|
||||||
|
|
||||||
|
own_address
|
||||||
|
}
|
||||||
|
"#
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn fail_expr() {
|
fn fail_expr() {
|
||||||
assert_format!(
|
assert_format!(
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
source: crates/aiken-lang/src/tests/format.rs
|
||||||
|
description: "Code:\n\nfn foo() {\n let Output {\n // something\n address: own_address,\n // value: own_value,\n ..\n } = own_output\n\n own_address\n}\n"
|
||||||
|
---
|
||||||
|
fn foo() {
|
||||||
|
let Output {
|
||||||
|
// something
|
||||||
|
address: own_address,
|
||||||
|
// value: own_value,
|
||||||
|
..
|
||||||
|
} = own_output
|
||||||
|
|
||||||
|
own_address
|
||||||
|
}
|
|
@ -732,7 +732,7 @@ Perhaps, try the following:
|
||||||
, constructor = name
|
, constructor = name
|
||||||
.if_supports_color(Stdout, |s| s.bright_blue())
|
.if_supports_color(Stdout, |s| s.bright_blue())
|
||||||
.if_supports_color(Stdout, |s| s.bold())
|
.if_supports_color(Stdout, |s| s.bold())
|
||||||
, suggestion = suggest_constructor_pattern(name, args, module, *with_spread)
|
, suggestion = suggest_constructor_pattern(name, args, module, *spread_location)
|
||||||
))]
|
))]
|
||||||
UnexpectedLabeledArgInPattern {
|
UnexpectedLabeledArgInPattern {
|
||||||
#[label]
|
#[label]
|
||||||
|
@ -741,7 +741,7 @@ Perhaps, try the following:
|
||||||
name: String,
|
name: String,
|
||||||
args: Vec<CallArg<UntypedPattern>>,
|
args: Vec<CallArg<UntypedPattern>>,
|
||||||
module: Option<String>,
|
module: Option<String>,
|
||||||
with_spread: bool,
|
spread_location: Option<Span>,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("I discovered a regular let assignment with multiple patterns.\n")]
|
#[error("I discovered a regular let assignment with multiple patterns.\n")]
|
||||||
|
@ -1210,7 +1210,7 @@ fn suggest_pattern(
|
||||||
Some(format!(
|
Some(format!(
|
||||||
"Try instead: {}",
|
"Try instead: {}",
|
||||||
Formatter::new()
|
Formatter::new()
|
||||||
.pattern_constructor(name, given, module, true, is_record)
|
.pattern_constructor(name, given, module, Some(Span::empty()), is_record)
|
||||||
.to_pretty_string(70),
|
.to_pretty_string(70),
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
|
@ -1239,7 +1239,7 @@ fn suggest_constructor_pattern(
|
||||||
name: &str,
|
name: &str,
|
||||||
args: &[CallArg<UntypedPattern>],
|
args: &[CallArg<UntypedPattern>],
|
||||||
module: &Option<String>,
|
module: &Option<String>,
|
||||||
with_spread: bool,
|
spread_location: Option<Span>,
|
||||||
) -> String {
|
) -> String {
|
||||||
let fixed_args = args
|
let fixed_args = args
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -1251,7 +1251,7 @@ fn suggest_constructor_pattern(
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
Formatter::new()
|
Formatter::new()
|
||||||
.pattern_constructor(name, &fixed_args, module, with_spread, false)
|
.pattern_constructor(name, &fixed_args, module, spread_location, false)
|
||||||
.to_pretty_string(70)
|
.to_pretty_string(70)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -558,7 +558,7 @@ pub(super) fn simplify(
|
||||||
arguments,
|
arguments,
|
||||||
location,
|
location,
|
||||||
tipo,
|
tipo,
|
||||||
with_spread,
|
spread_location,
|
||||||
constructor: super::PatternConstructor::Record { name, .. },
|
constructor: super::PatternConstructor::Record { name, .. },
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
|
@ -589,7 +589,7 @@ pub(super) fn simplify(
|
||||||
args.push(simplify(environment, &argument.value)?);
|
args.push(simplify(environment, &argument.value)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
if *with_spread {
|
if spread_location.is_some() {
|
||||||
for _ in 0..(arity - arguments.len()) {
|
for _ in 0..(arity - arguments.len()) {
|
||||||
args.push(Pattern::Wildcard)
|
args.push(Pattern::Wildcard)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2608,7 +2608,7 @@ fn assert_assignment(expr: TypedExpr) -> Result<TypedExpr, Error> {
|
||||||
},
|
},
|
||||||
arguments: vec![],
|
arguments: vec![],
|
||||||
module: None,
|
module: None,
|
||||||
with_spread: false,
|
spread_location: None,
|
||||||
tipo: void(),
|
tipo: void(),
|
||||||
},
|
},
|
||||||
kind: AssignmentKind::let_(),
|
kind: AssignmentKind::let_(),
|
||||||
|
|
|
@ -344,7 +344,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
|
||||||
module,
|
module,
|
||||||
name,
|
name,
|
||||||
arguments: mut pattern_args,
|
arguments: mut pattern_args,
|
||||||
with_spread,
|
spread_location,
|
||||||
is_record,
|
is_record,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
|
@ -360,7 +360,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
|
||||||
match cons.field_map() {
|
match cons.field_map() {
|
||||||
// The fun has a field map so labelled arguments may be present and need to be reordered.
|
// The fun has a field map so labelled arguments may be present and need to be reordered.
|
||||||
Some(field_map) => {
|
Some(field_map) => {
|
||||||
if with_spread {
|
if spread_location.is_some() {
|
||||||
// Using the spread operator when you have already provided variables for all of the
|
// Using the spread operator when you have already provided variables for all of the
|
||||||
// record's fields throws an error
|
// record's fields throws an error
|
||||||
if pattern_args.len() == field_map.arity {
|
if pattern_args.len() == field_map.arity {
|
||||||
|
@ -416,7 +416,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
args: pattern_args.clone(),
|
args: pattern_args.clone(),
|
||||||
module: module.clone(),
|
module: module.clone(),
|
||||||
with_spread,
|
spread_location,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.unwrap_or(Ok(()))?,
|
.unwrap_or(Ok(()))?,
|
||||||
|
@ -445,7 +445,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
|
||||||
|
|
||||||
match instantiated_constructor_type.deref() {
|
match instantiated_constructor_type.deref() {
|
||||||
Type::Fn { args, ret, .. } => {
|
Type::Fn { args, ret, .. } => {
|
||||||
if with_spread && has_no_fields {
|
if spread_location.is_some() && has_no_fields {
|
||||||
if pattern_args.len() == args.len() {
|
if pattern_args.len() == args.len() {
|
||||||
return Err(Error::UnnecessarySpreadOperator {
|
return Err(Error::UnnecessarySpreadOperator {
|
||||||
location: Span {
|
location: Span {
|
||||||
|
@ -502,7 +502,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
|
||||||
name,
|
name,
|
||||||
arguments: pattern_args,
|
arguments: pattern_args,
|
||||||
constructor,
|
constructor,
|
||||||
with_spread,
|
spread_location,
|
||||||
tipo: instantiated_constructor_type,
|
tipo: instantiated_constructor_type,
|
||||||
is_record,
|
is_record,
|
||||||
})
|
})
|
||||||
|
@ -533,7 +533,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
|
||||||
name,
|
name,
|
||||||
arguments: vec![],
|
arguments: vec![],
|
||||||
constructor,
|
constructor,
|
||||||
with_spread,
|
spread_location,
|
||||||
tipo: instantiated_constructor_type,
|
tipo: instantiated_constructor_type,
|
||||||
is_record,
|
is_record,
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue