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,
|
||||
name,
|
||||
args,
|
||||
..
|
||||
opaque,
|
||||
alias: _,
|
||||
} => {
|
||||
if let Type::App {
|
||||
public: public2,
|
||||
module: module2,
|
||||
name: name2,
|
||||
args: args2,
|
||||
..
|
||||
opaque: opaque2,
|
||||
alias: _,
|
||||
} = other
|
||||
{
|
||||
name == name2
|
||||
&& module == module2
|
||||
&& public == public2
|
||||
&& opaque == opaque2
|
||||
&& args.iter().zip(args2).all(|(left, right)| left == right)
|
||||
} else {
|
||||
false
|
||||
|
@ -104,7 +107,7 @@ impl PartialEq for Type {
|
|||
if let Type::Fn {
|
||||
args: args2,
|
||||
ret: ret2,
|
||||
..
|
||||
alias: _,
|
||||
} = other
|
||||
{
|
||||
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 {
|
||||
elems.iter().zip(elems2).all(|(left, right)| left == right)
|
||||
} else {
|
||||
|
@ -121,8 +124,12 @@ impl PartialEq for Type {
|
|||
}
|
||||
}
|
||||
|
||||
Type::Var { tipo, .. } => {
|
||||
if let Type::Var { tipo: tipo2, .. } = other {
|
||||
Type::Var { tipo, alias: _ } => {
|
||||
if let Type::Var {
|
||||
tipo: tipo2,
|
||||
alias: _,
|
||||
} = other
|
||||
{
|
||||
tipo == tipo2
|
||||
} else {
|
||||
false
|
||||
|
@ -157,7 +164,7 @@ impl Type {
|
|||
module,
|
||||
name,
|
||||
args,
|
||||
..
|
||||
alias: _,
|
||||
} => Type::App {
|
||||
public,
|
||||
opaque,
|
||||
|
@ -166,9 +173,13 @@ impl Type {
|
|||
args,
|
||||
alias,
|
||||
},
|
||||
Type::Fn { args, ret, .. } => Type::Fn { args, ret, alias },
|
||||
Type::Var { tipo, .. } => Type::Var { tipo, alias },
|
||||
Type::Tuple { elems, .. } => Type::Tuple { elems, alias },
|
||||
Type::Fn {
|
||||
args,
|
||||
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::Unbound { .. } => vec![],
|
||||
var => {
|
||||
vec![Type::Var {
|
||||
tipo: RefCell::new(var.clone()).into(),
|
||||
alias: None,
|
||||
}
|
||||
.into()]
|
||||
vec![
|
||||
Type::Var {
|
||||
tipo: RefCell::new(var.clone()).into(),
|
||||
alias: None,
|
||||
}
|
||||
.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 {
|
||||
Err(Error::IncorrectFunctionCallArity {
|
||||
expected: args.len(),
|
||||
|
@ -730,7 +735,7 @@ impl<'a> Environment<'a> {
|
|||
as_name,
|
||||
unqualified,
|
||||
location,
|
||||
..
|
||||
package: _,
|
||||
}) => {
|
||||
let name = module.join("/");
|
||||
|
||||
|
@ -765,7 +770,6 @@ impl<'a> Environment<'a> {
|
|||
name,
|
||||
location,
|
||||
as_name,
|
||||
..
|
||||
} in unqualified
|
||||
{
|
||||
let mut type_imported = false;
|
||||
|
@ -990,7 +994,8 @@ impl<'a> Environment<'a> {
|
|||
parameters,
|
||||
location,
|
||||
constructors,
|
||||
..
|
||||
doc: _,
|
||||
typed_parameters: _,
|
||||
}) => {
|
||||
assert_unique_type_name(names, name, location)?;
|
||||
|
||||
|
@ -1037,7 +1042,8 @@ impl<'a> Environment<'a> {
|
|||
parameters: args,
|
||||
alias: name,
|
||||
annotation: resolved_type,
|
||||
..
|
||||
doc: _,
|
||||
tipo: _,
|
||||
}) => {
|
||||
assert_unique_type_name(names, name, location)?;
|
||||
|
||||
|
@ -1178,7 +1184,9 @@ impl<'a> Environment<'a> {
|
|||
fun,
|
||||
other_fun,
|
||||
params,
|
||||
..
|
||||
doc: _,
|
||||
location: _,
|
||||
end_position: _,
|
||||
}) if kind.is_validator() => {
|
||||
let default_annotation = |mut arg: UntypedArg| {
|
||||
if arg.annotation.is_none() {
|
||||
|
@ -1256,7 +1264,10 @@ impl<'a> Environment<'a> {
|
|||
opaque,
|
||||
name,
|
||||
constructors,
|
||||
..
|
||||
doc: _,
|
||||
location: _,
|
||||
parameters: _,
|
||||
typed_parameters: _,
|
||||
}) => {
|
||||
let mut hydrator = hydrators
|
||||
.remove(name)
|
||||
|
@ -1299,7 +1310,8 @@ impl<'a> Environment<'a> {
|
|||
label,
|
||||
annotation,
|
||||
location,
|
||||
..
|
||||
tipo: _,
|
||||
doc: _,
|
||||
},
|
||||
) 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.
|
||||
if let Type::Var { tipo, .. } = t2.deref() {
|
||||
if let TypeVar::Link { tipo, .. } = tipo.borrow().deref() {
|
||||
return self.unify(t1, tipo.clone(), location, allow_cast);
|
||||
if let Type::Var { tipo, alias } = t2.deref() {
|
||||
if let TypeVar::Link { tipo } = tipo.borrow().deref() {
|
||||
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 {
|
||||
Unify(Rc<Type>),
|
||||
CouldNotUnify,
|
||||
|
@ -1403,7 +1420,9 @@ impl<'a> Environment<'a> {
|
|||
}
|
||||
|
||||
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 } => {
|
||||
unify_unbound_type(t2.clone(), *id, location)?;
|
||||
|
@ -1411,7 +1430,7 @@ impl<'a> Environment<'a> {
|
|||
}
|
||||
|
||||
TypeVar::Generic { id } => {
|
||||
if let Type::Var { tipo, .. } = t2.deref() {
|
||||
if let Type::Var { tipo, alias: _ } = t2.deref() {
|
||||
if tipo.borrow().is_unbound() {
|
||||
*tipo.borrow_mut() = TypeVar::Generic { id: *id };
|
||||
return Ok(());
|
||||
|
@ -1451,13 +1470,17 @@ impl<'a> Environment<'a> {
|
|||
module: m1,
|
||||
name: n1,
|
||||
args: args1,
|
||||
..
|
||||
public: _,
|
||||
opaque: _,
|
||||
alias: _,
|
||||
},
|
||||
Type::App {
|
||||
module: m2,
|
||||
name: n2,
|
||||
args: args2,
|
||||
..
|
||||
public: _,
|
||||
opaque: _,
|
||||
alias: _,
|
||||
},
|
||||
) if m1 == m2 && n1 == n2 && args1.len() == args2.len() => {
|
||||
for (a, b) in args1.iter().zip(args2) {
|
||||
|
@ -1470,9 +1493,16 @@ impl<'a> Environment<'a> {
|
|||
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) {
|
||||
unify_enclosed_type(
|
||||
t1.clone(),
|
||||
|
@ -1487,12 +1517,12 @@ impl<'a> Environment<'a> {
|
|||
Type::Fn {
|
||||
args: args1,
|
||||
ret: retrn1,
|
||||
..
|
||||
alias: _,
|
||||
},
|
||||
Type::Fn {
|
||||
args: args2,
|
||||
ret: retrn2,
|
||||
..
|
||||
alias: _,
|
||||
},
|
||||
) if args1.len() == args2.len() => {
|
||||
for (a, b) in args1.iter().zip(args2) {
|
||||
|
@ -1678,10 +1708,14 @@ pub enum EntityKind {
|
|||
/// could cause naively-implemented type checking to diverge.
|
||||
/// While traversing the type tree.
|
||||
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() {
|
||||
TypeVar::Link { tipo, .. } => {
|
||||
return unify_unbound_type(tipo.clone(), own_id, location);
|
||||
TypeVar::Link { tipo } => {
|
||||
return unify_unbound_type(
|
||||
Type::with_alias(tipo.clone(), alias.clone()),
|
||||
own_id,
|
||||
location,
|
||||
);
|
||||
}
|
||||
|
||||
TypeVar::Unbound { id } => {
|
||||
|
@ -1702,7 +1736,14 @@ fn unify_unbound_type(tipo: Rc<Type>, own_id: u64, location: Span) -> Result<(),
|
|||
}
|
||||
|
||||
match tipo.deref() {
|
||||
Type::App { args, .. } => {
|
||||
Type::App {
|
||||
args,
|
||||
module: _,
|
||||
name: _,
|
||||
public: _,
|
||||
alias: _,
|
||||
opaque: _,
|
||||
} => {
|
||||
for arg in args {
|
||||
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(())
|
||||
}
|
||||
|
||||
Type::Fn { args, ret, .. } => {
|
||||
Type::Fn {
|
||||
args,
|
||||
ret,
|
||||
alias: _,
|
||||
} => {
|
||||
for arg in args {
|
||||
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)
|
||||
}
|
||||
|
||||
Type::Tuple { elems, .. } => {
|
||||
Type::Tuple { elems, alias: _ } => {
|
||||
for elem in elems {
|
||||
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> {
|
||||
if let Type::Var { tipo, .. } = t.deref() {
|
||||
if let Type::Var { tipo, alias } = t.deref() {
|
||||
if let TypeVar::Link { tipo } = tipo.borrow().deref() {
|
||||
return tipo.clone();
|
||||
return Type::with_alias(tipo.clone(), alias.clone());
|
||||
}
|
||||
}
|
||||
t
|
||||
|
|
|
@ -211,10 +211,12 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
match expr {
|
||||
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 {
|
||||
location, value, ..
|
||||
location,
|
||||
value,
|
||||
base: _,
|
||||
} => Ok(self.infer_uint(value, location)),
|
||||
|
||||
UntypedExpr::Sequence {
|
||||
|
@ -222,13 +224,9 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
location,
|
||||
} => self.infer_seq(location, expressions),
|
||||
|
||||
UntypedExpr::Tuple {
|
||||
location, elems, ..
|
||||
} => self.infer_tuple(elems, location),
|
||||
UntypedExpr::Tuple { location, elems } => self.infer_tuple(elems, location),
|
||||
|
||||
UntypedExpr::String {
|
||||
location, value, ..
|
||||
} => Ok(self.infer_string(value, location)),
|
||||
UntypedExpr::String { location, value } => Ok(self.infer_string(value, location)),
|
||||
|
||||
UntypedExpr::LogicalOpChain {
|
||||
kind,
|
||||
|
@ -244,7 +242,6 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
arguments: args,
|
||||
body,
|
||||
return_annotation,
|
||||
..
|
||||
} => self.infer_fn(
|
||||
args,
|
||||
&[],
|
||||
|
@ -265,7 +262,6 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
patterns,
|
||||
value,
|
||||
kind,
|
||||
..
|
||||
} => {
|
||||
// at this point due to backpassing rewrites,
|
||||
// patterns is guaranteed to have one item
|
||||
|
@ -295,14 +291,12 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
location,
|
||||
elements,
|
||||
tail,
|
||||
..
|
||||
} => self.infer_list(elements, tail, location),
|
||||
|
||||
UntypedExpr::Call {
|
||||
location,
|
||||
fun,
|
||||
arguments: args,
|
||||
..
|
||||
} => self.infer_call(*fun, args, location),
|
||||
|
||||
UntypedExpr::BinOp {
|
||||
|
@ -310,21 +304,18 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
name,
|
||||
left,
|
||||
right,
|
||||
..
|
||||
} => self.infer_binop(name, *left, *right, location),
|
||||
|
||||
UntypedExpr::FieldAccess {
|
||||
location,
|
||||
label,
|
||||
container,
|
||||
..
|
||||
} => self.infer_field_access(*container, label, location),
|
||||
|
||||
UntypedExpr::TupleIndex {
|
||||
location,
|
||||
index,
|
||||
tuple,
|
||||
..
|
||||
} => self.infer_tuple_index(*tuple, index, location),
|
||||
|
||||
UntypedExpr::ByteArray {
|
||||
|
@ -334,7 +325,9 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
} => self.infer_bytearray(bytes, preferred_format, location),
|
||||
|
||||
UntypedExpr::CurvePoint {
|
||||
location, point, ..
|
||||
location,
|
||||
point,
|
||||
preferred_format: _,
|
||||
} => self.infer_curve_point(*point, location),
|
||||
|
||||
UntypedExpr::RecordUpdate {
|
||||
|
@ -578,7 +571,10 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
ValueConstructorVariant::Record {
|
||||
field_map: Some(field_map),
|
||||
constructors_count,
|
||||
..
|
||||
name: _,
|
||||
arity: _,
|
||||
location: _,
|
||||
module: _,
|
||||
} => (field_map, *constructors_count),
|
||||
_ => {
|
||||
return Err(Error::RecordUpdateInvalidConstructor {
|
||||
|
@ -704,7 +700,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
Ok(record_access) => Ok(record_access),
|
||||
|
||||
Err(err) => match container {
|
||||
UntypedExpr::Var { name, location, .. } => {
|
||||
UntypedExpr::Var { name, location } => {
|
||||
let module_access =
|
||||
self.infer_module_access(&name, label, &location, access_location);
|
||||
|
||||
|
@ -894,7 +890,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
annotation,
|
||||
location,
|
||||
doc,
|
||||
..
|
||||
tipo: _,
|
||||
} = arg;
|
||||
|
||||
let tipo = annotation
|
||||
|
@ -1087,7 +1083,8 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
(
|
||||
Type::Fn {
|
||||
args: expected_arguments,
|
||||
..
|
||||
ret: _,
|
||||
alias: _,
|
||||
},
|
||||
UntypedExpr::Fn {
|
||||
arguments,
|
||||
|
@ -1095,7 +1092,6 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
return_annotation,
|
||||
location,
|
||||
fn_style,
|
||||
..
|
||||
},
|
||||
) if fn_style != FnStyle::Capture && expected_arguments.len() == arguments.len() => {
|
||||
self.infer_fn(
|
||||
|
@ -1398,9 +1394,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
base,
|
||||
}),
|
||||
|
||||
Constant::String {
|
||||
location, value, ..
|
||||
} => Ok(Constant::String { location, value }),
|
||||
Constant::String { location, value } => Ok(Constant::String { location, value }),
|
||||
|
||||
Constant::ByteArray {
|
||||
location,
|
||||
|
@ -1748,7 +1742,6 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
value,
|
||||
kind,
|
||||
patterns,
|
||||
..
|
||||
} = breakpoint
|
||||
else {
|
||||
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
|
||||
// (which is perhaps something we should support?).
|
||||
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));
|
||||
}
|
||||
_ => {
|
||||
|
@ -1806,7 +1801,11 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
}
|
||||
|
||||
match *value {
|
||||
UntypedExpr::Call { fun, arguments, .. } => {
|
||||
UntypedExpr::Call {
|
||||
fun,
|
||||
arguments,
|
||||
location: _,
|
||||
} => {
|
||||
let mut new_arguments = Vec::new();
|
||||
new_arguments.extend(arguments);
|
||||
new_arguments.push(CallArg {
|
||||
|
@ -1832,7 +1831,8 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
fn_style,
|
||||
ref arguments,
|
||||
ref return_annotation,
|
||||
..
|
||||
location: _,
|
||||
body: _,
|
||||
} => {
|
||||
let return_annotation = return_annotation.clone();
|
||||
|
||||
|
@ -1891,7 +1891,10 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
breakpoint = Some(expression);
|
||||
}
|
||||
UntypedExpr::Assignment {
|
||||
patterns, location, ..
|
||||
patterns,
|
||||
location,
|
||||
value: _,
|
||||
kind: _,
|
||||
} if patterns.len() > 1 => {
|
||||
return Err(Error::UnexpectedMultiPatternAssignment {
|
||||
arrow: patterns
|
||||
|
@ -2012,7 +2015,10 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
let tuple = self.infer(tuple)?;
|
||||
|
||||
let tipo = match *tuple.tipo() {
|
||||
Type::Tuple { ref elems, .. } => {
|
||||
Type::Tuple {
|
||||
ref elems,
|
||||
alias: _,
|
||||
} => {
|
||||
let size = elems.len();
|
||||
if index >= size {
|
||||
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> {
|
||||
match t.deref() {
|
||||
Type::App { args, .. } => {
|
||||
Type::App {
|
||||
args,
|
||||
name: _,
|
||||
module: _,
|
||||
public: _,
|
||||
opaque: _,
|
||||
alias: _,
|
||||
} => {
|
||||
if t.is_ml_result() {
|
||||
return Err(Error::IllegalTypeInData {
|
||||
tipo: t.clone(),
|
||||
|
@ -2356,7 +2369,7 @@ pub fn ensure_serialisable(allow_fn: bool, t: Rc<Type>, location: Span) -> Resul
|
|||
Ok(())
|
||||
}
|
||||
|
||||
Type::Tuple { elems, .. } => {
|
||||
Type::Tuple { elems, alias: _ } => {
|
||||
elems
|
||||
.iter()
|
||||
.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(())
|
||||
}
|
||||
|
||||
Type::Fn { args, ret, .. } => {
|
||||
Type::Fn {
|
||||
args,
|
||||
ret,
|
||||
alias: _,
|
||||
} => {
|
||||
if !allow_fn {
|
||||
return Err(Error::IllegalTypeInData {
|
||||
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)
|
||||
}
|
||||
|
||||
Type::Var { tipo, .. } => match tipo.borrow().deref() {
|
||||
Type::Var { tipo, alias } => match tipo.borrow().deref() {
|
||||
TypeVar::Unbound { .. } => 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 {
|
||||
name,
|
||||
is_validator_param,
|
||||
..
|
||||
label: _,
|
||||
location: _,
|
||||
} if *is_validator_param => {
|
||||
environment.insert_variable(
|
||||
name.to_string(),
|
||||
|
@ -383,7 +384,9 @@ fn infer_definition(
|
|||
.get_mut(&f.name)
|
||||
.expect("Could not find preregistered type for test");
|
||||
if let Type::Fn {
|
||||
ref ret, ref alias, ..
|
||||
ref ret,
|
||||
ref alias,
|
||||
args: _,
|
||||
} = scope.tipo.as_ref()
|
||||
{
|
||||
scope.tipo = Rc::new(Type::Fn {
|
||||
|
@ -425,7 +428,11 @@ fn infer_definition(
|
|||
arguments: match typed_via {
|
||||
Some((via, tipo)) => {
|
||||
let Arg {
|
||||
arg_name, location, ..
|
||||
arg_name,
|
||||
location,
|
||||
annotation: _,
|
||||
doc: _,
|
||||
tipo: _,
|
||||
} = typed_f
|
||||
.arguments
|
||||
.first()
|
||||
|
@ -457,7 +464,7 @@ fn infer_definition(
|
|||
alias,
|
||||
parameters,
|
||||
annotation,
|
||||
..
|
||||
tipo: _,
|
||||
}) => {
|
||||
let tipo = environment
|
||||
.get_type_constructor(&None, &alias, location)
|
||||
|
@ -484,7 +491,7 @@ fn infer_definition(
|
|||
name,
|
||||
parameters,
|
||||
constructors: untyped_constructors,
|
||||
..
|
||||
typed_parameters: _,
|
||||
}) => {
|
||||
let constructors = untyped_constructors
|
||||
.into_iter()
|
||||
|
@ -514,7 +521,7 @@ fn infer_definition(
|
|||
annotation,
|
||||
location,
|
||||
doc,
|
||||
..
|
||||
tipo: _,
|
||||
},
|
||||
t,
|
||||
)| {
|
||||
|
@ -561,7 +568,14 @@ fn infer_definition(
|
|||
};
|
||||
|
||||
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() {
|
||||
return Err(Error::FunctionTypeInData {
|
||||
location: *location,
|
||||
|
@ -585,7 +599,7 @@ fn infer_definition(
|
|||
module,
|
||||
as_name,
|
||||
unqualified,
|
||||
..
|
||||
package: _,
|
||||
}) => {
|
||||
let name = module.join("/");
|
||||
|
||||
|
@ -616,7 +630,7 @@ fn infer_definition(
|
|||
annotation,
|
||||
public,
|
||||
value,
|
||||
..
|
||||
tipo: _,
|
||||
}) => {
|
||||
let typed_expr =
|
||||
ExprTyper::new(environment, lines, tracing).infer_const(&annotation, *value)?;
|
||||
|
@ -672,7 +686,7 @@ fn infer_function(
|
|||
return_annotation,
|
||||
end_position,
|
||||
can_error,
|
||||
..
|
||||
return_type: _,
|
||||
} = f;
|
||||
|
||||
let preregistered_fn = environment
|
||||
|
@ -773,9 +787,18 @@ fn infer_fuzzer(
|
|||
};
|
||||
|
||||
match tipo.borrow() {
|
||||
Type::Fn { ret, .. } => match ret.borrow() {
|
||||
Type::Fn {
|
||||
ret,
|
||||
args: _,
|
||||
alias: _,
|
||||
} => match ret.borrow() {
|
||||
Type::App {
|
||||
module, name, args, ..
|
||||
module,
|
||||
name,
|
||||
args,
|
||||
public: _,
|
||||
opaque: _,
|
||||
alias: _,
|
||||
} if module.is_empty() && name == "Option" && args.len() == 1 => {
|
||||
match args.first().expect("args.len() == 1").borrow() {
|
||||
Type::Tuple { elems, .. } if elems.len() == 2 => {
|
||||
|
@ -805,10 +828,13 @@ fn infer_fuzzer(
|
|||
_ => Err(could_not_unify()),
|
||||
},
|
||||
|
||||
Type::Var { tipo, .. } => match &*tipo.deref().borrow() {
|
||||
TypeVar::Link { tipo } => {
|
||||
infer_fuzzer(environment, expected_inner_type, tipo, location)
|
||||
}
|
||||
Type::Var { tipo, alias } => match &*tipo.deref().borrow() {
|
||||
TypeVar::Link { tipo } => infer_fuzzer(
|
||||
environment,
|
||||
expected_inner_type,
|
||||
&Type::with_alias(tipo.clone(), alias.clone()),
|
||||
location,
|
||||
),
|
||||
_ => Err(Error::GenericLeftAtBoundary {
|
||||
location: *location,
|
||||
}),
|
||||
|
@ -821,7 +847,12 @@ fn infer_fuzzer(
|
|||
fn annotate_fuzzer(tipo: &Type, location: &Span) -> Result<Annotation, Error> {
|
||||
match tipo {
|
||||
Type::App {
|
||||
name, module, args, ..
|
||||
name,
|
||||
module,
|
||||
args,
|
||||
public: _,
|
||||
opaque: _,
|
||||
alias: _,
|
||||
} => {
|
||||
let arguments = args
|
||||
.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
|
||||
.iter()
|
||||
.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),
|
||||
_ => Err(Error::GenericLeftAtBoundary {
|
||||
location: *location,
|
||||
|
|
Loading…
Reference in New Issue