Remove potentially problematic use of ".." in pattern-match
Discard pattern are _dangerous_ is used recklessly. The problem comes from maintenance and when adding new fields. We usually don't get any compiler warnings which may lead to missing spots and confusing behaviors. So I have, in some cases, inline discard to explicitly list all fields. That's a bit more cumbersome to write but hopefully will catch a few things for us in the future.
This commit is contained in:
parent
7af4ef53ab
commit
3820d2af14
|
@ -81,19 +81,22 @@ impl PartialEq for Type {
|
||||||
module,
|
module,
|
||||||
name,
|
name,
|
||||||
args,
|
args,
|
||||||
..
|
opaque,
|
||||||
|
alias: _,
|
||||||
} => {
|
} => {
|
||||||
if let Type::App {
|
if let Type::App {
|
||||||
public: public2,
|
public: public2,
|
||||||
module: module2,
|
module: module2,
|
||||||
name: name2,
|
name: name2,
|
||||||
args: args2,
|
args: args2,
|
||||||
..
|
opaque: opaque2,
|
||||||
|
alias: _,
|
||||||
} = other
|
} = other
|
||||||
{
|
{
|
||||||
name == name2
|
name == name2
|
||||||
&& module == module2
|
&& module == module2
|
||||||
&& public == public2
|
&& public == public2
|
||||||
|
&& opaque == opaque2
|
||||||
&& args.iter().zip(args2).all(|(left, right)| left == right)
|
&& args.iter().zip(args2).all(|(left, right)| left == right)
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
@ -104,7 +107,7 @@ impl PartialEq for Type {
|
||||||
if let Type::Fn {
|
if let Type::Fn {
|
||||||
args: args2,
|
args: args2,
|
||||||
ret: ret2,
|
ret: ret2,
|
||||||
..
|
alias: _,
|
||||||
} = other
|
} = other
|
||||||
{
|
{
|
||||||
ret == ret2 && args.iter().zip(args2).all(|(left, right)| left == right)
|
ret == ret2 && args.iter().zip(args2).all(|(left, right)| left == right)
|
||||||
|
@ -113,7 +116,7 @@ impl PartialEq for Type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::Tuple { elems, .. } => {
|
Type::Tuple { elems, alias: _ } => {
|
||||||
if let Type::Tuple { elems: elems2, .. } = other {
|
if let Type::Tuple { elems: elems2, .. } = other {
|
||||||
elems.iter().zip(elems2).all(|(left, right)| left == right)
|
elems.iter().zip(elems2).all(|(left, right)| left == right)
|
||||||
} else {
|
} else {
|
||||||
|
@ -121,8 +124,12 @@ impl PartialEq for Type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::Var { tipo, .. } => {
|
Type::Var { tipo, alias: _ } => {
|
||||||
if let Type::Var { tipo: tipo2, .. } = other {
|
if let Type::Var {
|
||||||
|
tipo: tipo2,
|
||||||
|
alias: _,
|
||||||
|
} = other
|
||||||
|
{
|
||||||
tipo == tipo2
|
tipo == tipo2
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
@ -157,7 +164,7 @@ impl Type {
|
||||||
module,
|
module,
|
||||||
name,
|
name,
|
||||||
args,
|
args,
|
||||||
..
|
alias: _,
|
||||||
} => Type::App {
|
} => Type::App {
|
||||||
public,
|
public,
|
||||||
opaque,
|
opaque,
|
||||||
|
@ -166,9 +173,13 @@ impl Type {
|
||||||
args,
|
args,
|
||||||
alias,
|
alias,
|
||||||
},
|
},
|
||||||
Type::Fn { args, ret, .. } => Type::Fn { args, ret, alias },
|
Type::Fn {
|
||||||
Type::Var { tipo, .. } => Type::Var { tipo, alias },
|
args,
|
||||||
Type::Tuple { elems, .. } => Type::Tuple { elems, alias },
|
ret,
|
||||||
|
alias: _,
|
||||||
|
} => Type::Fn { args, ret, alias },
|
||||||
|
Type::Var { tipo, alias: _ } => Type::Var { tipo, alias },
|
||||||
|
Type::Tuple { elems, alias: _ } => Type::Tuple { elems, alias },
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -959,11 +970,13 @@ impl TypeVar {
|
||||||
Self::Link { tipo } => tipo.get_inner_types(),
|
Self::Link { tipo } => tipo.get_inner_types(),
|
||||||
Self::Unbound { .. } => vec![],
|
Self::Unbound { .. } => vec![],
|
||||||
var => {
|
var => {
|
||||||
vec![Type::Var {
|
vec![
|
||||||
|
Type::Var {
|
||||||
tipo: RefCell::new(var.clone()).into(),
|
tipo: RefCell::new(var.clone()).into(),
|
||||||
alias: None,
|
alias: None,
|
||||||
}
|
}
|
||||||
.into()]
|
.into(),
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,7 +145,12 @@ impl<'a> Environment<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Type::Fn { args, ret, .. } = tipo.deref() {
|
if let Type::Fn {
|
||||||
|
args,
|
||||||
|
ret,
|
||||||
|
alias: _,
|
||||||
|
} = tipo.deref()
|
||||||
|
{
|
||||||
return if args.len() != arity {
|
return if args.len() != arity {
|
||||||
Err(Error::IncorrectFunctionCallArity {
|
Err(Error::IncorrectFunctionCallArity {
|
||||||
expected: args.len(),
|
expected: args.len(),
|
||||||
|
@ -730,7 +735,7 @@ impl<'a> Environment<'a> {
|
||||||
as_name,
|
as_name,
|
||||||
unqualified,
|
unqualified,
|
||||||
location,
|
location,
|
||||||
..
|
package: _,
|
||||||
}) => {
|
}) => {
|
||||||
let name = module.join("/");
|
let name = module.join("/");
|
||||||
|
|
||||||
|
@ -765,7 +770,6 @@ impl<'a> Environment<'a> {
|
||||||
name,
|
name,
|
||||||
location,
|
location,
|
||||||
as_name,
|
as_name,
|
||||||
..
|
|
||||||
} in unqualified
|
} in unqualified
|
||||||
{
|
{
|
||||||
let mut type_imported = false;
|
let mut type_imported = false;
|
||||||
|
@ -990,7 +994,8 @@ impl<'a> Environment<'a> {
|
||||||
parameters,
|
parameters,
|
||||||
location,
|
location,
|
||||||
constructors,
|
constructors,
|
||||||
..
|
doc: _,
|
||||||
|
typed_parameters: _,
|
||||||
}) => {
|
}) => {
|
||||||
assert_unique_type_name(names, name, location)?;
|
assert_unique_type_name(names, name, location)?;
|
||||||
|
|
||||||
|
@ -1037,7 +1042,8 @@ impl<'a> Environment<'a> {
|
||||||
parameters: args,
|
parameters: args,
|
||||||
alias: name,
|
alias: name,
|
||||||
annotation: resolved_type,
|
annotation: resolved_type,
|
||||||
..
|
doc: _,
|
||||||
|
tipo: _,
|
||||||
}) => {
|
}) => {
|
||||||
assert_unique_type_name(names, name, location)?;
|
assert_unique_type_name(names, name, location)?;
|
||||||
|
|
||||||
|
@ -1178,7 +1184,9 @@ impl<'a> Environment<'a> {
|
||||||
fun,
|
fun,
|
||||||
other_fun,
|
other_fun,
|
||||||
params,
|
params,
|
||||||
..
|
doc: _,
|
||||||
|
location: _,
|
||||||
|
end_position: _,
|
||||||
}) if kind.is_validator() => {
|
}) if kind.is_validator() => {
|
||||||
let default_annotation = |mut arg: UntypedArg| {
|
let default_annotation = |mut arg: UntypedArg| {
|
||||||
if arg.annotation.is_none() {
|
if arg.annotation.is_none() {
|
||||||
|
@ -1256,7 +1264,10 @@ impl<'a> Environment<'a> {
|
||||||
opaque,
|
opaque,
|
||||||
name,
|
name,
|
||||||
constructors,
|
constructors,
|
||||||
..
|
doc: _,
|
||||||
|
location: _,
|
||||||
|
parameters: _,
|
||||||
|
typed_parameters: _,
|
||||||
}) => {
|
}) => {
|
||||||
let mut hydrator = hydrators
|
let mut hydrator = hydrators
|
||||||
.remove(name)
|
.remove(name)
|
||||||
|
@ -1299,7 +1310,8 @@ impl<'a> Environment<'a> {
|
||||||
label,
|
label,
|
||||||
annotation,
|
annotation,
|
||||||
location,
|
location,
|
||||||
..
|
tipo: _,
|
||||||
|
doc: _,
|
||||||
},
|
},
|
||||||
) in constructor.arguments.iter().enumerate()
|
) in constructor.arguments.iter().enumerate()
|
||||||
{
|
{
|
||||||
|
@ -1389,13 +1401,18 @@ impl<'a> Environment<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collapse right hand side type links. Left hand side will be collapsed in the next block.
|
// Collapse right hand side type links. Left hand side will be collapsed in the next block.
|
||||||
if let Type::Var { tipo, .. } = t2.deref() {
|
if let Type::Var { tipo, alias } = t2.deref() {
|
||||||
if let TypeVar::Link { tipo, .. } = tipo.borrow().deref() {
|
if let TypeVar::Link { tipo } = tipo.borrow().deref() {
|
||||||
return self.unify(t1, tipo.clone(), location, allow_cast);
|
return self.unify(
|
||||||
|
t1,
|
||||||
|
Type::with_alias(tipo.clone(), alias.clone()),
|
||||||
|
location,
|
||||||
|
allow_cast,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Type::Var { tipo, .. } = t1.deref() {
|
if let Type::Var { tipo, alias } = t1.deref() {
|
||||||
enum Action {
|
enum Action {
|
||||||
Unify(Rc<Type>),
|
Unify(Rc<Type>),
|
||||||
CouldNotUnify,
|
CouldNotUnify,
|
||||||
|
@ -1403,7 +1420,9 @@ impl<'a> Environment<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let action = match tipo.borrow().deref() {
|
let action = match tipo.borrow().deref() {
|
||||||
TypeVar::Link { tipo } => Action::Unify(tipo.clone()),
|
TypeVar::Link { tipo } => {
|
||||||
|
Action::Unify(Type::with_alias(tipo.clone(), alias.clone()))
|
||||||
|
}
|
||||||
|
|
||||||
TypeVar::Unbound { id } => {
|
TypeVar::Unbound { id } => {
|
||||||
unify_unbound_type(t2.clone(), *id, location)?;
|
unify_unbound_type(t2.clone(), *id, location)?;
|
||||||
|
@ -1411,7 +1430,7 @@ impl<'a> Environment<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeVar::Generic { id } => {
|
TypeVar::Generic { id } => {
|
||||||
if let Type::Var { tipo, .. } = t2.deref() {
|
if let Type::Var { tipo, alias: _ } = t2.deref() {
|
||||||
if tipo.borrow().is_unbound() {
|
if tipo.borrow().is_unbound() {
|
||||||
*tipo.borrow_mut() = TypeVar::Generic { id: *id };
|
*tipo.borrow_mut() = TypeVar::Generic { id: *id };
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
@ -1451,13 +1470,17 @@ impl<'a> Environment<'a> {
|
||||||
module: m1,
|
module: m1,
|
||||||
name: n1,
|
name: n1,
|
||||||
args: args1,
|
args: args1,
|
||||||
..
|
public: _,
|
||||||
|
opaque: _,
|
||||||
|
alias: _,
|
||||||
},
|
},
|
||||||
Type::App {
|
Type::App {
|
||||||
module: m2,
|
module: m2,
|
||||||
name: n2,
|
name: n2,
|
||||||
args: args2,
|
args: args2,
|
||||||
..
|
public: _,
|
||||||
|
opaque: _,
|
||||||
|
alias: _,
|
||||||
},
|
},
|
||||||
) if m1 == m2 && n1 == n2 && args1.len() == args2.len() => {
|
) if m1 == m2 && n1 == n2 && args1.len() == args2.len() => {
|
||||||
for (a, b) in args1.iter().zip(args2) {
|
for (a, b) in args1.iter().zip(args2) {
|
||||||
|
@ -1470,9 +1493,16 @@ impl<'a> Environment<'a> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
(Type::Tuple { elems: elems1, .. }, Type::Tuple { elems: elems2, .. })
|
(
|
||||||
if elems1.len() == elems2.len() =>
|
Type::Tuple {
|
||||||
{
|
elems: elems1,
|
||||||
|
alias: _,
|
||||||
|
},
|
||||||
|
Type::Tuple {
|
||||||
|
elems: elems2,
|
||||||
|
alias: _,
|
||||||
|
},
|
||||||
|
) if elems1.len() == elems2.len() => {
|
||||||
for (a, b) in elems1.iter().zip(elems2) {
|
for (a, b) in elems1.iter().zip(elems2) {
|
||||||
unify_enclosed_type(
|
unify_enclosed_type(
|
||||||
t1.clone(),
|
t1.clone(),
|
||||||
|
@ -1487,12 +1517,12 @@ impl<'a> Environment<'a> {
|
||||||
Type::Fn {
|
Type::Fn {
|
||||||
args: args1,
|
args: args1,
|
||||||
ret: retrn1,
|
ret: retrn1,
|
||||||
..
|
alias: _,
|
||||||
},
|
},
|
||||||
Type::Fn {
|
Type::Fn {
|
||||||
args: args2,
|
args: args2,
|
||||||
ret: retrn2,
|
ret: retrn2,
|
||||||
..
|
alias: _,
|
||||||
},
|
},
|
||||||
) if args1.len() == args2.len() => {
|
) if args1.len() == args2.len() => {
|
||||||
for (a, b) in args1.iter().zip(args2) {
|
for (a, b) in args1.iter().zip(args2) {
|
||||||
|
@ -1678,10 +1708,14 @@ pub enum EntityKind {
|
||||||
/// could cause naively-implemented type checking to diverge.
|
/// could cause naively-implemented type checking to diverge.
|
||||||
/// While traversing the type tree.
|
/// While traversing the type tree.
|
||||||
fn unify_unbound_type(tipo: Rc<Type>, own_id: u64, location: Span) -> Result<(), Error> {
|
fn unify_unbound_type(tipo: Rc<Type>, own_id: u64, location: Span) -> Result<(), Error> {
|
||||||
if let Type::Var { tipo, .. } = tipo.deref() {
|
if let Type::Var { tipo, alias } = tipo.deref() {
|
||||||
let new_value = match tipo.borrow().deref() {
|
let new_value = match tipo.borrow().deref() {
|
||||||
TypeVar::Link { tipo, .. } => {
|
TypeVar::Link { tipo } => {
|
||||||
return unify_unbound_type(tipo.clone(), own_id, location);
|
return unify_unbound_type(
|
||||||
|
Type::with_alias(tipo.clone(), alias.clone()),
|
||||||
|
own_id,
|
||||||
|
location,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeVar::Unbound { id } => {
|
TypeVar::Unbound { id } => {
|
||||||
|
@ -1702,7 +1736,14 @@ fn unify_unbound_type(tipo: Rc<Type>, own_id: u64, location: Span) -> Result<(),
|
||||||
}
|
}
|
||||||
|
|
||||||
match tipo.deref() {
|
match tipo.deref() {
|
||||||
Type::App { args, .. } => {
|
Type::App {
|
||||||
|
args,
|
||||||
|
module: _,
|
||||||
|
name: _,
|
||||||
|
public: _,
|
||||||
|
alias: _,
|
||||||
|
opaque: _,
|
||||||
|
} => {
|
||||||
for arg in args {
|
for arg in args {
|
||||||
unify_unbound_type(arg.clone(), own_id, location)?
|
unify_unbound_type(arg.clone(), own_id, location)?
|
||||||
}
|
}
|
||||||
|
@ -1710,7 +1751,11 @@ fn unify_unbound_type(tipo: Rc<Type>, own_id: u64, location: Span) -> Result<(),
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::Fn { args, ret, .. } => {
|
Type::Fn {
|
||||||
|
args,
|
||||||
|
ret,
|
||||||
|
alias: _,
|
||||||
|
} => {
|
||||||
for arg in args {
|
for arg in args {
|
||||||
unify_unbound_type(arg.clone(), own_id, location)?;
|
unify_unbound_type(arg.clone(), own_id, location)?;
|
||||||
}
|
}
|
||||||
|
@ -1718,7 +1763,7 @@ fn unify_unbound_type(tipo: Rc<Type>, own_id: u64, location: Span) -> Result<(),
|
||||||
unify_unbound_type(ret.clone(), own_id, location)
|
unify_unbound_type(ret.clone(), own_id, location)
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::Tuple { elems, .. } => {
|
Type::Tuple { elems, alias: _ } => {
|
||||||
for elem in elems {
|
for elem in elems {
|
||||||
unify_unbound_type(elem.clone(), own_id, location)?
|
unify_unbound_type(elem.clone(), own_id, location)?
|
||||||
}
|
}
|
||||||
|
@ -1805,9 +1850,9 @@ pub(super) fn assert_no_labeled_arguments<A>(args: &[CallArg<A>]) -> Option<(Spa
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn collapse_links(t: Rc<Type>) -> Rc<Type> {
|
pub(super) fn collapse_links(t: Rc<Type>) -> Rc<Type> {
|
||||||
if let Type::Var { tipo, .. } = t.deref() {
|
if let Type::Var { tipo, alias } = t.deref() {
|
||||||
if let TypeVar::Link { tipo } = tipo.borrow().deref() {
|
if let TypeVar::Link { tipo } = tipo.borrow().deref() {
|
||||||
return tipo.clone();
|
return Type::with_alias(tipo.clone(), alias.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t
|
t
|
||||||
|
|
|
@ -211,10 +211,12 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
match expr {
|
match expr {
|
||||||
UntypedExpr::ErrorTerm { location } => Ok(self.infer_error_term(location)),
|
UntypedExpr::ErrorTerm { location } => Ok(self.infer_error_term(location)),
|
||||||
|
|
||||||
UntypedExpr::Var { location, name, .. } => self.infer_var(name, location),
|
UntypedExpr::Var { location, name } => self.infer_var(name, location),
|
||||||
|
|
||||||
UntypedExpr::UInt {
|
UntypedExpr::UInt {
|
||||||
location, value, ..
|
location,
|
||||||
|
value,
|
||||||
|
base: _,
|
||||||
} => Ok(self.infer_uint(value, location)),
|
} => Ok(self.infer_uint(value, location)),
|
||||||
|
|
||||||
UntypedExpr::Sequence {
|
UntypedExpr::Sequence {
|
||||||
|
@ -222,13 +224,9 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
location,
|
location,
|
||||||
} => self.infer_seq(location, expressions),
|
} => self.infer_seq(location, expressions),
|
||||||
|
|
||||||
UntypedExpr::Tuple {
|
UntypedExpr::Tuple { location, elems } => self.infer_tuple(elems, location),
|
||||||
location, elems, ..
|
|
||||||
} => self.infer_tuple(elems, location),
|
|
||||||
|
|
||||||
UntypedExpr::String {
|
UntypedExpr::String { location, value } => Ok(self.infer_string(value, location)),
|
||||||
location, value, ..
|
|
||||||
} => Ok(self.infer_string(value, location)),
|
|
||||||
|
|
||||||
UntypedExpr::LogicalOpChain {
|
UntypedExpr::LogicalOpChain {
|
||||||
kind,
|
kind,
|
||||||
|
@ -244,7 +242,6 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
arguments: args,
|
arguments: args,
|
||||||
body,
|
body,
|
||||||
return_annotation,
|
return_annotation,
|
||||||
..
|
|
||||||
} => self.infer_fn(
|
} => self.infer_fn(
|
||||||
args,
|
args,
|
||||||
&[],
|
&[],
|
||||||
|
@ -265,7 +262,6 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
patterns,
|
patterns,
|
||||||
value,
|
value,
|
||||||
kind,
|
kind,
|
||||||
..
|
|
||||||
} => {
|
} => {
|
||||||
// at this point due to backpassing rewrites,
|
// at this point due to backpassing rewrites,
|
||||||
// patterns is guaranteed to have one item
|
// patterns is guaranteed to have one item
|
||||||
|
@ -295,14 +291,12 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
location,
|
location,
|
||||||
elements,
|
elements,
|
||||||
tail,
|
tail,
|
||||||
..
|
|
||||||
} => self.infer_list(elements, tail, location),
|
} => self.infer_list(elements, tail, location),
|
||||||
|
|
||||||
UntypedExpr::Call {
|
UntypedExpr::Call {
|
||||||
location,
|
location,
|
||||||
fun,
|
fun,
|
||||||
arguments: args,
|
arguments: args,
|
||||||
..
|
|
||||||
} => self.infer_call(*fun, args, location),
|
} => self.infer_call(*fun, args, location),
|
||||||
|
|
||||||
UntypedExpr::BinOp {
|
UntypedExpr::BinOp {
|
||||||
|
@ -310,21 +304,18 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
name,
|
name,
|
||||||
left,
|
left,
|
||||||
right,
|
right,
|
||||||
..
|
|
||||||
} => self.infer_binop(name, *left, *right, location),
|
} => self.infer_binop(name, *left, *right, location),
|
||||||
|
|
||||||
UntypedExpr::FieldAccess {
|
UntypedExpr::FieldAccess {
|
||||||
location,
|
location,
|
||||||
label,
|
label,
|
||||||
container,
|
container,
|
||||||
..
|
|
||||||
} => self.infer_field_access(*container, label, location),
|
} => self.infer_field_access(*container, label, location),
|
||||||
|
|
||||||
UntypedExpr::TupleIndex {
|
UntypedExpr::TupleIndex {
|
||||||
location,
|
location,
|
||||||
index,
|
index,
|
||||||
tuple,
|
tuple,
|
||||||
..
|
|
||||||
} => self.infer_tuple_index(*tuple, index, location),
|
} => self.infer_tuple_index(*tuple, index, location),
|
||||||
|
|
||||||
UntypedExpr::ByteArray {
|
UntypedExpr::ByteArray {
|
||||||
|
@ -334,7 +325,9 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
} => self.infer_bytearray(bytes, preferred_format, location),
|
} => self.infer_bytearray(bytes, preferred_format, location),
|
||||||
|
|
||||||
UntypedExpr::CurvePoint {
|
UntypedExpr::CurvePoint {
|
||||||
location, point, ..
|
location,
|
||||||
|
point,
|
||||||
|
preferred_format: _,
|
||||||
} => self.infer_curve_point(*point, location),
|
} => self.infer_curve_point(*point, location),
|
||||||
|
|
||||||
UntypedExpr::RecordUpdate {
|
UntypedExpr::RecordUpdate {
|
||||||
|
@ -578,7 +571,10 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
ValueConstructorVariant::Record {
|
ValueConstructorVariant::Record {
|
||||||
field_map: Some(field_map),
|
field_map: Some(field_map),
|
||||||
constructors_count,
|
constructors_count,
|
||||||
..
|
name: _,
|
||||||
|
arity: _,
|
||||||
|
location: _,
|
||||||
|
module: _,
|
||||||
} => (field_map, *constructors_count),
|
} => (field_map, *constructors_count),
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::RecordUpdateInvalidConstructor {
|
return Err(Error::RecordUpdateInvalidConstructor {
|
||||||
|
@ -704,7 +700,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
Ok(record_access) => Ok(record_access),
|
Ok(record_access) => Ok(record_access),
|
||||||
|
|
||||||
Err(err) => match container {
|
Err(err) => match container {
|
||||||
UntypedExpr::Var { name, location, .. } => {
|
UntypedExpr::Var { name, location } => {
|
||||||
let module_access =
|
let module_access =
|
||||||
self.infer_module_access(&name, label, &location, access_location);
|
self.infer_module_access(&name, label, &location, access_location);
|
||||||
|
|
||||||
|
@ -894,7 +890,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
annotation,
|
annotation,
|
||||||
location,
|
location,
|
||||||
doc,
|
doc,
|
||||||
..
|
tipo: _,
|
||||||
} = arg;
|
} = arg;
|
||||||
|
|
||||||
let tipo = annotation
|
let tipo = annotation
|
||||||
|
@ -1087,7 +1083,8 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
(
|
(
|
||||||
Type::Fn {
|
Type::Fn {
|
||||||
args: expected_arguments,
|
args: expected_arguments,
|
||||||
..
|
ret: _,
|
||||||
|
alias: _,
|
||||||
},
|
},
|
||||||
UntypedExpr::Fn {
|
UntypedExpr::Fn {
|
||||||
arguments,
|
arguments,
|
||||||
|
@ -1095,7 +1092,6 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
return_annotation,
|
return_annotation,
|
||||||
location,
|
location,
|
||||||
fn_style,
|
fn_style,
|
||||||
..
|
|
||||||
},
|
},
|
||||||
) if fn_style != FnStyle::Capture && expected_arguments.len() == arguments.len() => {
|
) if fn_style != FnStyle::Capture && expected_arguments.len() == arguments.len() => {
|
||||||
self.infer_fn(
|
self.infer_fn(
|
||||||
|
@ -1398,9 +1394,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
base,
|
base,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
Constant::String {
|
Constant::String { location, value } => Ok(Constant::String { location, value }),
|
||||||
location, value, ..
|
|
||||||
} => Ok(Constant::String { location, value }),
|
|
||||||
|
|
||||||
Constant::ByteArray {
|
Constant::ByteArray {
|
||||||
location,
|
location,
|
||||||
|
@ -1748,7 +1742,6 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
value,
|
value,
|
||||||
kind,
|
kind,
|
||||||
patterns,
|
patterns,
|
||||||
..
|
|
||||||
} = breakpoint
|
} = breakpoint
|
||||||
else {
|
else {
|
||||||
unreachable!("backpass misuse: breakpoint isn't an Assignment ?!");
|
unreachable!("backpass misuse: breakpoint isn't an Assignment ?!");
|
||||||
|
@ -1776,7 +1769,9 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
// in front of the continuation sequence. This is because we do not support patterns in function argument
|
// in front of the continuation sequence. This is because we do not support patterns in function argument
|
||||||
// (which is perhaps something we should support?).
|
// (which is perhaps something we should support?).
|
||||||
match pattern {
|
match pattern {
|
||||||
Pattern::Var { name, .. } | Pattern::Discard { name, .. } if kind.is_let() => {
|
Pattern::Var { name, location: _ } | Pattern::Discard { name, location: _ }
|
||||||
|
if kind.is_let() =>
|
||||||
|
{
|
||||||
names.push((name.clone(), annotation));
|
names.push((name.clone(), annotation));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -1806,7 +1801,11 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
}
|
}
|
||||||
|
|
||||||
match *value {
|
match *value {
|
||||||
UntypedExpr::Call { fun, arguments, .. } => {
|
UntypedExpr::Call {
|
||||||
|
fun,
|
||||||
|
arguments,
|
||||||
|
location: _,
|
||||||
|
} => {
|
||||||
let mut new_arguments = Vec::new();
|
let mut new_arguments = Vec::new();
|
||||||
new_arguments.extend(arguments);
|
new_arguments.extend(arguments);
|
||||||
new_arguments.push(CallArg {
|
new_arguments.push(CallArg {
|
||||||
|
@ -1832,7 +1831,8 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
fn_style,
|
fn_style,
|
||||||
ref arguments,
|
ref arguments,
|
||||||
ref return_annotation,
|
ref return_annotation,
|
||||||
..
|
location: _,
|
||||||
|
body: _,
|
||||||
} => {
|
} => {
|
||||||
let return_annotation = return_annotation.clone();
|
let return_annotation = return_annotation.clone();
|
||||||
|
|
||||||
|
@ -1891,7 +1891,10 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
breakpoint = Some(expression);
|
breakpoint = Some(expression);
|
||||||
}
|
}
|
||||||
UntypedExpr::Assignment {
|
UntypedExpr::Assignment {
|
||||||
patterns, location, ..
|
patterns,
|
||||||
|
location,
|
||||||
|
value: _,
|
||||||
|
kind: _,
|
||||||
} if patterns.len() > 1 => {
|
} if patterns.len() > 1 => {
|
||||||
return Err(Error::UnexpectedMultiPatternAssignment {
|
return Err(Error::UnexpectedMultiPatternAssignment {
|
||||||
arrow: patterns
|
arrow: patterns
|
||||||
|
@ -2012,7 +2015,10 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
let tuple = self.infer(tuple)?;
|
let tuple = self.infer(tuple)?;
|
||||||
|
|
||||||
let tipo = match *tuple.tipo() {
|
let tipo = match *tuple.tipo() {
|
||||||
Type::Tuple { ref elems, .. } => {
|
Type::Tuple {
|
||||||
|
ref elems,
|
||||||
|
alias: _,
|
||||||
|
} => {
|
||||||
let size = elems.len();
|
let size = elems.len();
|
||||||
if index >= size {
|
if index >= size {
|
||||||
Err(Error::TupleIndexOutOfBound {
|
Err(Error::TupleIndexOutOfBound {
|
||||||
|
@ -2341,7 +2347,14 @@ fn assert_assignment(expr: TypedExpr) -> Result<TypedExpr, Error> {
|
||||||
|
|
||||||
pub fn ensure_serialisable(allow_fn: bool, t: Rc<Type>, location: Span) -> Result<(), Error> {
|
pub fn ensure_serialisable(allow_fn: bool, t: Rc<Type>, location: Span) -> Result<(), Error> {
|
||||||
match t.deref() {
|
match t.deref() {
|
||||||
Type::App { args, .. } => {
|
Type::App {
|
||||||
|
args,
|
||||||
|
name: _,
|
||||||
|
module: _,
|
||||||
|
public: _,
|
||||||
|
opaque: _,
|
||||||
|
alias: _,
|
||||||
|
} => {
|
||||||
if t.is_ml_result() {
|
if t.is_ml_result() {
|
||||||
return Err(Error::IllegalTypeInData {
|
return Err(Error::IllegalTypeInData {
|
||||||
tipo: t.clone(),
|
tipo: t.clone(),
|
||||||
|
@ -2356,7 +2369,7 @@ pub fn ensure_serialisable(allow_fn: bool, t: Rc<Type>, location: Span) -> Resul
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::Tuple { elems, .. } => {
|
Type::Tuple { elems, alias: _ } => {
|
||||||
elems
|
elems
|
||||||
.iter()
|
.iter()
|
||||||
.map(|e| ensure_serialisable(false, e.clone(), location))
|
.map(|e| ensure_serialisable(false, e.clone(), location))
|
||||||
|
@ -2365,7 +2378,11 @@ pub fn ensure_serialisable(allow_fn: bool, t: Rc<Type>, location: Span) -> Resul
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::Fn { args, ret, .. } => {
|
Type::Fn {
|
||||||
|
args,
|
||||||
|
ret,
|
||||||
|
alias: _,
|
||||||
|
} => {
|
||||||
if !allow_fn {
|
if !allow_fn {
|
||||||
return Err(Error::IllegalTypeInData {
|
return Err(Error::IllegalTypeInData {
|
||||||
tipo: t.clone(),
|
tipo: t.clone(),
|
||||||
|
@ -2380,10 +2397,14 @@ pub fn ensure_serialisable(allow_fn: bool, t: Rc<Type>, location: Span) -> Resul
|
||||||
ensure_serialisable(allow_fn, ret.clone(), location)
|
ensure_serialisable(allow_fn, ret.clone(), location)
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::Var { tipo, .. } => match tipo.borrow().deref() {
|
Type::Var { tipo, alias } => match tipo.borrow().deref() {
|
||||||
TypeVar::Unbound { .. } => Ok(()),
|
TypeVar::Unbound { .. } => Ok(()),
|
||||||
TypeVar::Generic { .. } => Ok(()),
|
TypeVar::Generic { .. } => Ok(()),
|
||||||
TypeVar::Link { tipo } => ensure_serialisable(allow_fn, tipo.clone(), location),
|
TypeVar::Link { tipo } => ensure_serialisable(
|
||||||
|
allow_fn,
|
||||||
|
Type::with_alias(tipo.clone(), alias.clone()),
|
||||||
|
location,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -197,7 +197,8 @@ fn infer_definition(
|
||||||
ArgName::Named {
|
ArgName::Named {
|
||||||
name,
|
name,
|
||||||
is_validator_param,
|
is_validator_param,
|
||||||
..
|
label: _,
|
||||||
|
location: _,
|
||||||
} if *is_validator_param => {
|
} if *is_validator_param => {
|
||||||
environment.insert_variable(
|
environment.insert_variable(
|
||||||
name.to_string(),
|
name.to_string(),
|
||||||
|
@ -383,7 +384,9 @@ fn infer_definition(
|
||||||
.get_mut(&f.name)
|
.get_mut(&f.name)
|
||||||
.expect("Could not find preregistered type for test");
|
.expect("Could not find preregistered type for test");
|
||||||
if let Type::Fn {
|
if let Type::Fn {
|
||||||
ref ret, ref alias, ..
|
ref ret,
|
||||||
|
ref alias,
|
||||||
|
args: _,
|
||||||
} = scope.tipo.as_ref()
|
} = scope.tipo.as_ref()
|
||||||
{
|
{
|
||||||
scope.tipo = Rc::new(Type::Fn {
|
scope.tipo = Rc::new(Type::Fn {
|
||||||
|
@ -425,7 +428,11 @@ fn infer_definition(
|
||||||
arguments: match typed_via {
|
arguments: match typed_via {
|
||||||
Some((via, tipo)) => {
|
Some((via, tipo)) => {
|
||||||
let Arg {
|
let Arg {
|
||||||
arg_name, location, ..
|
arg_name,
|
||||||
|
location,
|
||||||
|
annotation: _,
|
||||||
|
doc: _,
|
||||||
|
tipo: _,
|
||||||
} = typed_f
|
} = typed_f
|
||||||
.arguments
|
.arguments
|
||||||
.first()
|
.first()
|
||||||
|
@ -457,7 +464,7 @@ fn infer_definition(
|
||||||
alias,
|
alias,
|
||||||
parameters,
|
parameters,
|
||||||
annotation,
|
annotation,
|
||||||
..
|
tipo: _,
|
||||||
}) => {
|
}) => {
|
||||||
let tipo = environment
|
let tipo = environment
|
||||||
.get_type_constructor(&None, &alias, location)
|
.get_type_constructor(&None, &alias, location)
|
||||||
|
@ -484,7 +491,7 @@ fn infer_definition(
|
||||||
name,
|
name,
|
||||||
parameters,
|
parameters,
|
||||||
constructors: untyped_constructors,
|
constructors: untyped_constructors,
|
||||||
..
|
typed_parameters: _,
|
||||||
}) => {
|
}) => {
|
||||||
let constructors = untyped_constructors
|
let constructors = untyped_constructors
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -514,7 +521,7 @@ fn infer_definition(
|
||||||
annotation,
|
annotation,
|
||||||
location,
|
location,
|
||||||
doc,
|
doc,
|
||||||
..
|
tipo: _,
|
||||||
},
|
},
|
||||||
t,
|
t,
|
||||||
)| {
|
)| {
|
||||||
|
@ -561,7 +568,14 @@ fn infer_definition(
|
||||||
};
|
};
|
||||||
|
|
||||||
for constr in &typed_data.constructors {
|
for constr in &typed_data.constructors {
|
||||||
for RecordConstructorArg { tipo, location, .. } in &constr.arguments {
|
for RecordConstructorArg {
|
||||||
|
tipo,
|
||||||
|
location,
|
||||||
|
doc: _,
|
||||||
|
label: _,
|
||||||
|
annotation: _,
|
||||||
|
} in &constr.arguments
|
||||||
|
{
|
||||||
if tipo.is_function() {
|
if tipo.is_function() {
|
||||||
return Err(Error::FunctionTypeInData {
|
return Err(Error::FunctionTypeInData {
|
||||||
location: *location,
|
location: *location,
|
||||||
|
@ -585,7 +599,7 @@ fn infer_definition(
|
||||||
module,
|
module,
|
||||||
as_name,
|
as_name,
|
||||||
unqualified,
|
unqualified,
|
||||||
..
|
package: _,
|
||||||
}) => {
|
}) => {
|
||||||
let name = module.join("/");
|
let name = module.join("/");
|
||||||
|
|
||||||
|
@ -616,7 +630,7 @@ fn infer_definition(
|
||||||
annotation,
|
annotation,
|
||||||
public,
|
public,
|
||||||
value,
|
value,
|
||||||
..
|
tipo: _,
|
||||||
}) => {
|
}) => {
|
||||||
let typed_expr =
|
let typed_expr =
|
||||||
ExprTyper::new(environment, lines, tracing).infer_const(&annotation, *value)?;
|
ExprTyper::new(environment, lines, tracing).infer_const(&annotation, *value)?;
|
||||||
|
@ -672,7 +686,7 @@ fn infer_function(
|
||||||
return_annotation,
|
return_annotation,
|
||||||
end_position,
|
end_position,
|
||||||
can_error,
|
can_error,
|
||||||
..
|
return_type: _,
|
||||||
} = f;
|
} = f;
|
||||||
|
|
||||||
let preregistered_fn = environment
|
let preregistered_fn = environment
|
||||||
|
@ -773,9 +787,18 @@ fn infer_fuzzer(
|
||||||
};
|
};
|
||||||
|
|
||||||
match tipo.borrow() {
|
match tipo.borrow() {
|
||||||
Type::Fn { ret, .. } => match ret.borrow() {
|
Type::Fn {
|
||||||
|
ret,
|
||||||
|
args: _,
|
||||||
|
alias: _,
|
||||||
|
} => match ret.borrow() {
|
||||||
Type::App {
|
Type::App {
|
||||||
module, name, args, ..
|
module,
|
||||||
|
name,
|
||||||
|
args,
|
||||||
|
public: _,
|
||||||
|
opaque: _,
|
||||||
|
alias: _,
|
||||||
} if module.is_empty() && name == "Option" && args.len() == 1 => {
|
} if module.is_empty() && name == "Option" && args.len() == 1 => {
|
||||||
match args.first().expect("args.len() == 1").borrow() {
|
match args.first().expect("args.len() == 1").borrow() {
|
||||||
Type::Tuple { elems, .. } if elems.len() == 2 => {
|
Type::Tuple { elems, .. } if elems.len() == 2 => {
|
||||||
|
@ -805,10 +828,13 @@ fn infer_fuzzer(
|
||||||
_ => Err(could_not_unify()),
|
_ => Err(could_not_unify()),
|
||||||
},
|
},
|
||||||
|
|
||||||
Type::Var { tipo, .. } => match &*tipo.deref().borrow() {
|
Type::Var { tipo, alias } => match &*tipo.deref().borrow() {
|
||||||
TypeVar::Link { tipo } => {
|
TypeVar::Link { tipo } => infer_fuzzer(
|
||||||
infer_fuzzer(environment, expected_inner_type, tipo, location)
|
environment,
|
||||||
}
|
expected_inner_type,
|
||||||
|
&Type::with_alias(tipo.clone(), alias.clone()),
|
||||||
|
location,
|
||||||
|
),
|
||||||
_ => Err(Error::GenericLeftAtBoundary {
|
_ => Err(Error::GenericLeftAtBoundary {
|
||||||
location: *location,
|
location: *location,
|
||||||
}),
|
}),
|
||||||
|
@ -821,7 +847,12 @@ fn infer_fuzzer(
|
||||||
fn annotate_fuzzer(tipo: &Type, location: &Span) -> Result<Annotation, Error> {
|
fn annotate_fuzzer(tipo: &Type, location: &Span) -> Result<Annotation, Error> {
|
||||||
match tipo {
|
match tipo {
|
||||||
Type::App {
|
Type::App {
|
||||||
name, module, args, ..
|
name,
|
||||||
|
module,
|
||||||
|
args,
|
||||||
|
public: _,
|
||||||
|
opaque: _,
|
||||||
|
alias: _,
|
||||||
} => {
|
} => {
|
||||||
let arguments = args
|
let arguments = args
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -839,7 +870,7 @@ fn annotate_fuzzer(tipo: &Type, location: &Span) -> Result<Annotation, Error> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::Tuple { elems, .. } => {
|
Type::Tuple { elems, alias: _ } => {
|
||||||
let elems = elems
|
let elems = elems
|
||||||
.iter()
|
.iter()
|
||||||
.map(|arg| annotate_fuzzer(arg, location))
|
.map(|arg| annotate_fuzzer(arg, location))
|
||||||
|
@ -850,7 +881,7 @@ fn annotate_fuzzer(tipo: &Type, location: &Span) -> Result<Annotation, Error> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::Var { tipo, .. } => match &*tipo.deref().borrow() {
|
Type::Var { tipo, alias: _ } => match &*tipo.deref().borrow() {
|
||||||
TypeVar::Link { tipo } => annotate_fuzzer(tipo, location),
|
TypeVar::Link { tipo } => annotate_fuzzer(tipo, location),
|
||||||
_ => Err(Error::GenericLeftAtBoundary {
|
_ => Err(Error::GenericLeftAtBoundary {
|
||||||
location: *location,
|
location: *location,
|
||||||
|
|
Loading…
Reference in New Issue