fix: allow spread operator on positional constructors closes #677
This commit is contained in:
parent
d5820bb20a
commit
6ce30bd949
|
@ -981,6 +981,46 @@ fn list_pattern_6() {
|
|||
assert!(check(parse(source_code)).is_ok())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn spread_with_positional_constr_args() {
|
||||
let source_code = r#"
|
||||
type Redeemer {
|
||||
First(Int)
|
||||
Second
|
||||
}
|
||||
|
||||
fn foo(redeemer: Redeemer) {
|
||||
when redeemer is {
|
||||
First(..) -> True
|
||||
Second -> True
|
||||
}
|
||||
}
|
||||
"#;
|
||||
assert!(check(parse(source_code)).is_ok())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unnecessary_spread_with_positional_constr_args() {
|
||||
let source_code = r#"
|
||||
type Redeemer {
|
||||
First(Int)
|
||||
Second
|
||||
}
|
||||
|
||||
fn foo(redeemer: Redeemer) {
|
||||
when redeemer is {
|
||||
First(x, ..) -> True
|
||||
Second -> True
|
||||
}
|
||||
}
|
||||
"#;
|
||||
|
||||
assert!(matches!(
|
||||
check(parse(source_code)),
|
||||
Err((_, Error::UnnecessarySpreadOperator { .. }))
|
||||
))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn trace_strings() {
|
||||
let source_code = r#"
|
||||
|
|
|
@ -314,6 +314,8 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
|
|||
self.environment
|
||||
.get_value_constructor(module.as_ref(), &name, location)?;
|
||||
|
||||
let has_no_fields = cons.field_map().is_none();
|
||||
|
||||
match cons.field_map() {
|
||||
// The fun has a field map so labelled arguments may be present and need to be reordered.
|
||||
Some(field_map) => {
|
||||
|
@ -399,8 +401,37 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
|
|||
&mut HashMap::new(),
|
||||
self.hydrator,
|
||||
);
|
||||
|
||||
match instantiated_constructor_type.deref() {
|
||||
Type::Fn { args, ret } => {
|
||||
if with_spread && has_no_fields {
|
||||
if pattern_args.len() == args.len() {
|
||||
return Err(Error::UnnecessarySpreadOperator {
|
||||
location: Span {
|
||||
start: location.end - 3,
|
||||
end: location.end - 1,
|
||||
},
|
||||
arity: args.len(),
|
||||
});
|
||||
}
|
||||
|
||||
while pattern_args.len() < args.len() {
|
||||
let location = Span {
|
||||
start: location.end - 3,
|
||||
end: location.end - 1,
|
||||
};
|
||||
|
||||
pattern_args.push(CallArg {
|
||||
value: Pattern::Discard {
|
||||
name: "_".to_string(),
|
||||
location,
|
||||
},
|
||||
location,
|
||||
label: None,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if args.len() == pattern_args.len() {
|
||||
let pattern_args = pattern_args
|
||||
.into_iter()
|
||||
|
|
Loading…
Reference in New Issue