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:
KtorZ 2024-03-13 10:03:08 +01:00 committed by rvcas
parent 7af4ef53ab
commit 3820d2af14
No known key found for this signature in database
GPG Key ID: C09B64E263F7D68C
4 changed files with 208 additions and 98 deletions

View File

@ -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![
tipo: RefCell::new(var.clone()).into(), Type::Var {
alias: None, tipo: RefCell::new(var.clone()).into(),
} alias: None,
.into()] }
.into(),
]
} }
} }
} }

View File

@ -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

View File

@ -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,
),
}, },
} }
} }

View File

@ -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,