feat: fix some tests and add a failing one
This commit is contained in:
parent
9127dcdd6e
commit
e71470747f
|
@ -1267,7 +1267,7 @@ pub fn prelude_data_types(id_gen: &IdGenerator) -> IndexMap<DataTypeKey, TypedDa
|
||||||
pub fn int() -> Rc<Type> {
|
pub fn int() -> Rc<Type> {
|
||||||
Rc::new(Type::App {
|
Rc::new(Type::App {
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
name: INT.to_string(),
|
name: INT.to_string(),
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
args: vec![],
|
args: vec![],
|
||||||
|
@ -1278,7 +1278,7 @@ pub fn int() -> Rc<Type> {
|
||||||
pub fn data() -> Rc<Type> {
|
pub fn data() -> Rc<Type> {
|
||||||
Rc::new(Type::App {
|
Rc::new(Type::App {
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
name: DATA.to_string(),
|
name: DATA.to_string(),
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
args: vec![],
|
args: vec![],
|
||||||
|
@ -1290,7 +1290,7 @@ pub fn byte_array() -> Rc<Type> {
|
||||||
Rc::new(Type::App {
|
Rc::new(Type::App {
|
||||||
args: vec![],
|
args: vec![],
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
name: BYTE_ARRAY.to_string(),
|
name: BYTE_ARRAY.to_string(),
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
alias: None,
|
alias: None,
|
||||||
|
@ -1300,7 +1300,7 @@ pub fn byte_array() -> Rc<Type> {
|
||||||
pub fn g1_element() -> Rc<Type> {
|
pub fn g1_element() -> Rc<Type> {
|
||||||
Rc::new(Type::App {
|
Rc::new(Type::App {
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
name: G1_ELEMENT.to_string(),
|
name: G1_ELEMENT.to_string(),
|
||||||
args: vec![],
|
args: vec![],
|
||||||
|
@ -1311,7 +1311,7 @@ pub fn g1_element() -> Rc<Type> {
|
||||||
pub fn g2_element() -> Rc<Type> {
|
pub fn g2_element() -> Rc<Type> {
|
||||||
Rc::new(Type::App {
|
Rc::new(Type::App {
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
name: G2_ELEMENT.to_string(),
|
name: G2_ELEMENT.to_string(),
|
||||||
args: vec![],
|
args: vec![],
|
||||||
|
@ -1322,7 +1322,7 @@ pub fn g2_element() -> Rc<Type> {
|
||||||
pub fn miller_loop_result() -> Rc<Type> {
|
pub fn miller_loop_result() -> Rc<Type> {
|
||||||
Rc::new(Type::App {
|
Rc::new(Type::App {
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
name: MILLER_LOOP_RESULT.to_string(),
|
name: MILLER_LOOP_RESULT.to_string(),
|
||||||
args: vec![],
|
args: vec![],
|
||||||
|
@ -1338,7 +1338,7 @@ pub fn bool() -> Rc<Type> {
|
||||||
Rc::new(Type::App {
|
Rc::new(Type::App {
|
||||||
args: vec![],
|
args: vec![],
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
name: BOOL.to_string(),
|
name: BOOL.to_string(),
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
alias: None,
|
alias: None,
|
||||||
|
@ -1349,7 +1349,7 @@ pub fn prng() -> Rc<Type> {
|
||||||
Rc::new(Type::App {
|
Rc::new(Type::App {
|
||||||
args: vec![],
|
args: vec![],
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
name: PRNG.to_string(),
|
name: PRNG.to_string(),
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
alias: None,
|
alias: None,
|
||||||
|
@ -1400,7 +1400,7 @@ pub fn fuzzer(a: Rc<Type>) -> Rc<Type> {
|
||||||
pub fn list(t: Rc<Type>) -> Rc<Type> {
|
pub fn list(t: Rc<Type>) -> Rc<Type> {
|
||||||
Rc::new(Type::App {
|
Rc::new(Type::App {
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
name: LIST.to_string(),
|
name: LIST.to_string(),
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
args: vec![t],
|
args: vec![t],
|
||||||
|
@ -1412,7 +1412,7 @@ pub fn string() -> Rc<Type> {
|
||||||
Rc::new(Type::App {
|
Rc::new(Type::App {
|
||||||
args: vec![],
|
args: vec![],
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
name: STRING.to_string(),
|
name: STRING.to_string(),
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
alias: None,
|
alias: None,
|
||||||
|
@ -1423,7 +1423,7 @@ pub fn void() -> Rc<Type> {
|
||||||
Rc::new(Type::App {
|
Rc::new(Type::App {
|
||||||
args: vec![],
|
args: vec![],
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
name: VOID.to_string(),
|
name: VOID.to_string(),
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
alias: None,
|
alias: None,
|
||||||
|
@ -1433,7 +1433,7 @@ pub fn void() -> Rc<Type> {
|
||||||
pub fn option(a: Rc<Type>) -> Rc<Type> {
|
pub fn option(a: Rc<Type>) -> Rc<Type> {
|
||||||
Rc::new(Type::App {
|
Rc::new(Type::App {
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
name: OPTION.to_string(),
|
name: OPTION.to_string(),
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
args: vec![a],
|
args: vec![a],
|
||||||
|
@ -1444,7 +1444,7 @@ pub fn option(a: Rc<Type>) -> Rc<Type> {
|
||||||
pub fn ordering() -> Rc<Type> {
|
pub fn ordering() -> Rc<Type> {
|
||||||
Rc::new(Type::App {
|
Rc::new(Type::App {
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
name: ORDERING.to_string(),
|
name: ORDERING.to_string(),
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
args: vec![],
|
args: vec![],
|
||||||
|
@ -1475,7 +1475,7 @@ pub fn unbound_var(id: u64) -> Rc<Type> {
|
||||||
pub fn wrapped_redeemer(redeemer: Rc<Type>) -> Rc<Type> {
|
pub fn wrapped_redeemer(redeemer: Rc<Type>) -> Rc<Type> {
|
||||||
Rc::new(Type::App {
|
Rc::new(Type::App {
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
name: REDEEMER_WRAPPER.to_string(),
|
name: REDEEMER_WRAPPER.to_string(),
|
||||||
args: vec![redeemer],
|
args: vec![redeemer],
|
||||||
|
|
|
@ -1858,7 +1858,7 @@ fn forbid_expect_into_nested_opaque_in_record_without_typecasting() {
|
||||||
|
|
||||||
type Foo { foo: Thing }
|
type Foo { foo: Thing }
|
||||||
|
|
||||||
fn bar(thing: Thing) {
|
fn bar(thing: Foo) {
|
||||||
expect Foo { foo: Thing { inner } } : Foo = thing
|
expect Foo { foo: Thing { inner } } : Foo = thing
|
||||||
Void
|
Void
|
||||||
}
|
}
|
||||||
|
@ -1905,3 +1905,18 @@ fn forbid_expect_into_nested_opaque_in_list() {
|
||||||
Err((_, Error::ExpectOnOpaqueType { .. }))
|
Err((_, Error::ExpectOnOpaqueType { .. }))
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn allow_expect_on_var_patterns_that_are_opaque() {
|
||||||
|
let source_code = r#"
|
||||||
|
opaque type Thing { inner: Int }
|
||||||
|
|
||||||
|
fn bar(a: Option<Thing>) {
|
||||||
|
expect Some(thing) = a
|
||||||
|
|
||||||
|
thing.inner
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
|
||||||
|
assert!(check(parse(source_code)).is_ok())
|
||||||
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ pub enum Type {
|
||||||
///
|
///
|
||||||
App {
|
App {
|
||||||
public: bool,
|
public: bool,
|
||||||
opaque: bool,
|
contains_opaque: bool,
|
||||||
module: String,
|
module: String,
|
||||||
name: String,
|
name: String,
|
||||||
args: Vec<Rc<Type>>,
|
args: Vec<Rc<Type>>,
|
||||||
|
@ -81,7 +81,7 @@ impl PartialEq for Type {
|
||||||
module,
|
module,
|
||||||
name,
|
name,
|
||||||
args,
|
args,
|
||||||
opaque,
|
contains_opaque: opaque,
|
||||||
alias: _,
|
alias: _,
|
||||||
} => {
|
} => {
|
||||||
if let Type::App {
|
if let Type::App {
|
||||||
|
@ -89,7 +89,7 @@ impl PartialEq for Type {
|
||||||
module: module2,
|
module: module2,
|
||||||
name: name2,
|
name: name2,
|
||||||
args: args2,
|
args: args2,
|
||||||
opaque: opaque2,
|
contains_opaque: opaque2,
|
||||||
alias: _,
|
alias: _,
|
||||||
} = other
|
} = other
|
||||||
{
|
{
|
||||||
|
@ -160,14 +160,14 @@ impl Type {
|
||||||
Rc::new(match self {
|
Rc::new(match self {
|
||||||
Type::App {
|
Type::App {
|
||||||
public,
|
public,
|
||||||
opaque,
|
contains_opaque: opaque,
|
||||||
module,
|
module,
|
||||||
name,
|
name,
|
||||||
args,
|
args,
|
||||||
alias: _,
|
alias: _,
|
||||||
} => Type::App {
|
} => Type::App {
|
||||||
public,
|
public,
|
||||||
opaque,
|
contains_opaque: opaque,
|
||||||
module,
|
module,
|
||||||
name,
|
name,
|
||||||
args,
|
args,
|
||||||
|
@ -195,17 +195,30 @@ impl Type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_or_holds_opaque(&self) -> bool {
|
pub fn contains_opaque(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Type::Var { tipo, .. } => tipo.borrow().is_or_holds_opaque(),
|
Type::Var { tipo, .. } => tipo.borrow().is_or_holds_opaque(),
|
||||||
Type::App { opaque, args, .. } => {
|
Type::App {
|
||||||
*opaque || args.iter().any(|arg| arg.is_or_holds_opaque())
|
contains_opaque: opaque,
|
||||||
}
|
args,
|
||||||
Type::Tuple { elems, .. } => elems.iter().any(|elem| elem.is_or_holds_opaque()),
|
..
|
||||||
|
} => *opaque || args.iter().any(|arg| arg.contains_opaque()),
|
||||||
|
Type::Tuple { elems, .. } => elems.iter().any(|elem| elem.contains_opaque()),
|
||||||
Type::Fn { .. } => false,
|
Type::Fn { .. } => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_opaque(&mut self, opaque: bool) {
|
||||||
|
match self {
|
||||||
|
Type::App {
|
||||||
|
contains_opaque, ..
|
||||||
|
} => {
|
||||||
|
*contains_opaque = opaque;
|
||||||
|
}
|
||||||
|
Type::Fn { .. } | Type::Var { .. } | Type::Tuple { .. } => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_unbound(&self) -> bool {
|
pub fn is_unbound(&self) -> bool {
|
||||||
matches!(self, Self::Var { tipo, .. } if tipo.borrow().is_unbound())
|
matches!(self, Self::Var { tipo, .. } if tipo.borrow().is_unbound())
|
||||||
}
|
}
|
||||||
|
@ -511,7 +524,7 @@ impl Type {
|
||||||
*tipo.borrow_mut() = TypeVar::Link {
|
*tipo.borrow_mut() = TypeVar::Link {
|
||||||
tipo: Rc::new(Self::App {
|
tipo: Rc::new(Self::App {
|
||||||
public,
|
public,
|
||||||
opaque,
|
contains_opaque: opaque,
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
module: module.to_owned(),
|
module: module.to_owned(),
|
||||||
args: args.clone(),
|
args: args.clone(),
|
||||||
|
@ -666,7 +679,7 @@ pub fn convert_opaque_type(
|
||||||
match t.as_ref() {
|
match t.as_ref() {
|
||||||
Type::App {
|
Type::App {
|
||||||
public,
|
public,
|
||||||
opaque,
|
contains_opaque: opaque,
|
||||||
module,
|
module,
|
||||||
name,
|
name,
|
||||||
args,
|
args,
|
||||||
|
@ -679,7 +692,7 @@ pub fn convert_opaque_type(
|
||||||
}
|
}
|
||||||
Type::App {
|
Type::App {
|
||||||
public: *public,
|
public: *public,
|
||||||
opaque: *opaque,
|
contains_opaque: *opaque,
|
||||||
module: module.clone(),
|
module: module.clone(),
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
args: new_args,
|
args: new_args,
|
||||||
|
@ -754,7 +767,7 @@ pub fn find_and_replace_generics(
|
||||||
Type::App {
|
Type::App {
|
||||||
args,
|
args,
|
||||||
public,
|
public,
|
||||||
opaque,
|
contains_opaque: opaque,
|
||||||
module,
|
module,
|
||||||
name,
|
name,
|
||||||
alias,
|
alias,
|
||||||
|
@ -767,7 +780,7 @@ pub fn find_and_replace_generics(
|
||||||
let t = Type::App {
|
let t = Type::App {
|
||||||
args: new_args,
|
args: new_args,
|
||||||
public: *public,
|
public: *public,
|
||||||
opaque: *opaque,
|
contains_opaque: *opaque,
|
||||||
module: module.clone(),
|
module: module.clone(),
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
alias: alias.clone(),
|
alias: alias.clone(),
|
||||||
|
@ -851,7 +864,7 @@ impl TypeVar {
|
||||||
|
|
||||||
pub fn is_or_holds_opaque(&self) -> bool {
|
pub fn is_or_holds_opaque(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::Link { tipo } => tipo.is_or_holds_opaque(),
|
Self::Link { tipo } => tipo.contains_opaque(),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -981,13 +994,11 @@ 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![
|
vec![Type::Var {
|
||||||
Type::Var {
|
|
||||||
tipo: RefCell::new(var.clone()).into(),
|
tipo: RefCell::new(var.clone()).into(),
|
||||||
alias: None,
|
alias: None,
|
||||||
}
|
}
|
||||||
.into(),
|
.into()]
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -301,6 +301,25 @@ impl<'a> Environment<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_type_constructor_mut(
|
||||||
|
&mut self,
|
||||||
|
name: &str,
|
||||||
|
location: Span,
|
||||||
|
) -> Result<&mut TypeConstructor, Error> {
|
||||||
|
let types = self.module_types.keys().map(|t| t.to_string()).collect();
|
||||||
|
|
||||||
|
let constructor = self
|
||||||
|
.module_types
|
||||||
|
.get_mut(name)
|
||||||
|
.ok_or_else(|| Error::UnknownType {
|
||||||
|
location,
|
||||||
|
name: name.to_string(),
|
||||||
|
types,
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(constructor)
|
||||||
|
}
|
||||||
|
|
||||||
/// Lookup a type in the current scope.
|
/// Lookup a type in the current scope.
|
||||||
pub fn get_type_constructor(
|
pub fn get_type_constructor(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -551,7 +570,7 @@ impl<'a> Environment<'a> {
|
||||||
match t.deref() {
|
match t.deref() {
|
||||||
Type::App {
|
Type::App {
|
||||||
public,
|
public,
|
||||||
opaque,
|
contains_opaque: opaque,
|
||||||
name,
|
name,
|
||||||
module,
|
module,
|
||||||
args,
|
args,
|
||||||
|
@ -564,7 +583,7 @@ impl<'a> Environment<'a> {
|
||||||
|
|
||||||
Rc::new(Type::App {
|
Rc::new(Type::App {
|
||||||
public: *public,
|
public: *public,
|
||||||
opaque: *opaque,
|
contains_opaque: *opaque,
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
module: module.clone(),
|
module: module.clone(),
|
||||||
alias: alias.clone(),
|
alias: alias.clone(),
|
||||||
|
@ -1006,7 +1025,7 @@ impl<'a> Environment<'a> {
|
||||||
|
|
||||||
let tipo = Rc::new(Type::App {
|
let tipo = Rc::new(Type::App {
|
||||||
public: *public,
|
public: *public,
|
||||||
opaque: *opaque,
|
contains_opaque: *opaque,
|
||||||
module: module.to_owned(),
|
module: module.to_owned(),
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
args: parameters.clone(),
|
args: parameters.clone(),
|
||||||
|
@ -1471,7 +1490,7 @@ impl<'a> Environment<'a> {
|
||||||
name: n1,
|
name: n1,
|
||||||
args: args1,
|
args: args1,
|
||||||
public: _,
|
public: _,
|
||||||
opaque: _,
|
contains_opaque: _,
|
||||||
alias: _,
|
alias: _,
|
||||||
},
|
},
|
||||||
Type::App {
|
Type::App {
|
||||||
|
@ -1479,7 +1498,7 @@ impl<'a> Environment<'a> {
|
||||||
name: n2,
|
name: n2,
|
||||||
args: args2,
|
args: args2,
|
||||||
public: _,
|
public: _,
|
||||||
opaque: _,
|
contains_opaque: _,
|
||||||
alias: _,
|
alias: _,
|
||||||
},
|
},
|
||||||
) if m1 == m2 && n1 == n2 && args1.len() == args2.len() => {
|
) if m1 == m2 && n1 == n2 && args1.len() == args2.len() => {
|
||||||
|
@ -1742,7 +1761,7 @@ fn unify_unbound_type(tipo: Rc<Type>, own_id: u64, location: Span) -> Result<(),
|
||||||
name: _,
|
name: _,
|
||||||
public: _,
|
public: _,
|
||||||
alias: _,
|
alias: _,
|
||||||
opaque: _,
|
contains_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)?
|
||||||
|
@ -1906,7 +1925,7 @@ pub(crate) fn generalise(t: Rc<Type>, ctx_level: usize) -> Rc<Type> {
|
||||||
|
|
||||||
Type::App {
|
Type::App {
|
||||||
public,
|
public,
|
||||||
opaque,
|
contains_opaque: opaque,
|
||||||
module,
|
module,
|
||||||
name,
|
name,
|
||||||
args,
|
args,
|
||||||
|
@ -1919,7 +1938,7 @@ pub(crate) fn generalise(t: Rc<Type>, ctx_level: usize) -> Rc<Type> {
|
||||||
|
|
||||||
Rc::new(Type::App {
|
Rc::new(Type::App {
|
||||||
public: *public,
|
public: *public,
|
||||||
opaque: *opaque,
|
contains_opaque: *opaque,
|
||||||
module: module.clone(),
|
module: module.clone(),
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
args,
|
args,
|
||||||
|
|
|
@ -976,11 +976,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
kind.is_let(),
|
kind.is_let(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// FIXME: This check is insufficient as we need to also assert the type
|
if kind.is_expect() && value_typ.contains_opaque() {
|
||||||
// definition itself since there might be nested opaque types on the rhs.
|
|
||||||
//
|
|
||||||
// For that, we must lookup
|
|
||||||
if kind.is_expect() && value_typ.is_or_holds_opaque() {
|
|
||||||
return Err(Error::ExpectOnOpaqueType { location });
|
return Err(Error::ExpectOnOpaqueType { location });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2347,7 +2343,7 @@ pub fn ensure_serialisable(allow_fn: bool, t: Rc<Type>, location: Span) -> Resul
|
||||||
name: _,
|
name: _,
|
||||||
module: _,
|
module: _,
|
||||||
public: _,
|
public: _,
|
||||||
opaque: _,
|
contains_opaque: _,
|
||||||
alias: _,
|
alias: _,
|
||||||
} => {
|
} => {
|
||||||
if t.is_ml_result() {
|
if t.is_ml_result() {
|
||||||
|
|
|
@ -89,6 +89,7 @@ impl UntypedModule {
|
||||||
&self.lines,
|
&self.lines,
|
||||||
tracing,
|
tracing,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
definitions.push(definition);
|
definitions.push(definition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -495,60 +496,62 @@ fn infer_definition(
|
||||||
}) => {
|
}) => {
|
||||||
let constructors = untyped_constructors
|
let constructors = untyped_constructors
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(
|
.map(|constructor| {
|
||||||
|RecordConstructor {
|
|
||||||
location,
|
|
||||||
name,
|
|
||||||
arguments: args,
|
|
||||||
doc,
|
|
||||||
sugar,
|
|
||||||
}| {
|
|
||||||
let preregistered_fn = environment
|
let preregistered_fn = environment
|
||||||
.get_variable(&name)
|
.get_variable(&constructor.name)
|
||||||
.expect("Could not find preregistered type for function");
|
.expect("Could not find preregistered type for function");
|
||||||
|
|
||||||
let preregistered_type = preregistered_fn.tipo.clone();
|
let preregistered_type = preregistered_fn.tipo.clone();
|
||||||
|
|
||||||
let args = if let Some((args_types, _return_type)) =
|
let args = preregistered_type.function_types().map_or(
|
||||||
preregistered_type.function_types()
|
Ok(vec![]),
|
||||||
{
|
|(args_types, _return_type)| {
|
||||||
args.into_iter()
|
constructor
|
||||||
|
.arguments
|
||||||
|
.into_iter()
|
||||||
.zip(&args_types)
|
.zip(&args_types)
|
||||||
.map(
|
.map(|(arg, t)| {
|
||||||
|(
|
if t.is_function() {
|
||||||
RecordConstructorArg {
|
return Err(Error::FunctionTypeInData {
|
||||||
label,
|
location: arg.location,
|
||||||
annotation,
|
});
|
||||||
location,
|
|
||||||
doc,
|
|
||||||
tipo: _,
|
|
||||||
},
|
|
||||||
t,
|
|
||||||
)| {
|
|
||||||
RecordConstructorArg {
|
|
||||||
label,
|
|
||||||
annotation,
|
|
||||||
location,
|
|
||||||
tipo: t.clone(),
|
|
||||||
doc,
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
)
|
|
||||||
.collect()
|
|
||||||
} else {
|
|
||||||
vec![]
|
|
||||||
};
|
|
||||||
|
|
||||||
RecordConstructor {
|
if t.is_ml_result() {
|
||||||
location,
|
return Err(Error::IllegalTypeInData {
|
||||||
name,
|
location: arg.location,
|
||||||
arguments: args,
|
tipo: t.clone(),
|
||||||
doc,
|
});
|
||||||
sugar,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if t.contains_opaque() {
|
||||||
|
let parent = environment
|
||||||
|
.get_type_constructor_mut(&name, location)?;
|
||||||
|
|
||||||
|
Rc::make_mut(&mut parent.tipo).set_opaque(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(RecordConstructorArg {
|
||||||
|
label: arg.label,
|
||||||
|
annotation: arg.annotation,
|
||||||
|
location: arg.location,
|
||||||
|
doc: arg.doc,
|
||||||
|
tipo: t.clone(),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
},
|
},
|
||||||
)
|
)?;
|
||||||
.collect();
|
|
||||||
|
Ok(RecordConstructor {
|
||||||
|
location: constructor.location,
|
||||||
|
name: constructor.name,
|
||||||
|
arguments: args,
|
||||||
|
doc: constructor.doc,
|
||||||
|
sugar: constructor.sugar,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect::<Result<_, Error>>()?;
|
||||||
|
|
||||||
let typed_parameters = environment
|
let typed_parameters = environment
|
||||||
.get_type_constructor(&None, &name, location)
|
.get_type_constructor(&None, &name, location)
|
||||||
|
@ -797,7 +800,7 @@ fn infer_fuzzer(
|
||||||
name,
|
name,
|
||||||
args,
|
args,
|
||||||
public: _,
|
public: _,
|
||||||
opaque: _,
|
contains_opaque: _,
|
||||||
alias: _,
|
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() {
|
||||||
|
@ -851,7 +854,7 @@ fn annotate_fuzzer(tipo: &Type, location: &Span) -> Result<Annotation, Error> {
|
||||||
module,
|
module,
|
||||||
args,
|
args,
|
||||||
public: _,
|
public: _,
|
||||||
opaque: _,
|
contains_opaque: _,
|
||||||
alias: _,
|
alias: _,
|
||||||
} => {
|
} => {
|
||||||
let arguments = args
|
let arguments = args
|
||||||
|
|
|
@ -154,6 +154,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
|
||||||
location,
|
location,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Pattern::Discard { name, location })
|
Ok(Pattern::Discard { name, location })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -368,7 +368,7 @@ mod tests {
|
||||||
module: "whatever".to_string(),
|
module: "whatever".to_string(),
|
||||||
name: "Int".to_string(),
|
name: "Int".to_string(),
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
args: vec![],
|
args: vec![],
|
||||||
alias: None
|
alias: None
|
||||||
},
|
},
|
||||||
|
@ -379,14 +379,14 @@ mod tests {
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
name: "Pair".to_string(),
|
name: "Pair".to_string(),
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
alias: None,
|
alias: None,
|
||||||
args: vec![
|
args: vec![
|
||||||
Rc::new(Type::App {
|
Rc::new(Type::App {
|
||||||
module: "whatever".to_string(),
|
module: "whatever".to_string(),
|
||||||
name: "Int".to_string(),
|
name: "Int".to_string(),
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
args: vec![],
|
args: vec![],
|
||||||
alias: None
|
alias: None
|
||||||
}),
|
}),
|
||||||
|
@ -394,7 +394,7 @@ mod tests {
|
||||||
module: "whatever".to_string(),
|
module: "whatever".to_string(),
|
||||||
name: "Bool".to_string(),
|
name: "Bool".to_string(),
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
args: vec![],
|
args: vec![],
|
||||||
alias: None
|
alias: None
|
||||||
}),
|
}),
|
||||||
|
@ -410,7 +410,7 @@ mod tests {
|
||||||
module: "whatever".to_string(),
|
module: "whatever".to_string(),
|
||||||
name: "Int".to_string(),
|
name: "Int".to_string(),
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
alias: None,
|
alias: None,
|
||||||
}),
|
}),
|
||||||
Rc::new(Type::App {
|
Rc::new(Type::App {
|
||||||
|
@ -418,7 +418,7 @@ mod tests {
|
||||||
module: "whatever".to_string(),
|
module: "whatever".to_string(),
|
||||||
name: "Bool".to_string(),
|
name: "Bool".to_string(),
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
alias: None,
|
alias: None,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
@ -427,7 +427,7 @@ mod tests {
|
||||||
module: "whatever".to_string(),
|
module: "whatever".to_string(),
|
||||||
name: "Bool".to_string(),
|
name: "Bool".to_string(),
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
alias: None,
|
alias: None,
|
||||||
}),
|
}),
|
||||||
alias: None,
|
alias: None,
|
||||||
|
@ -444,7 +444,7 @@ mod tests {
|
||||||
module: "whatever".to_string(),
|
module: "whatever".to_string(),
|
||||||
name: "Int".to_string(),
|
name: "Int".to_string(),
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
}),
|
}),
|
||||||
})),
|
})),
|
||||||
},
|
},
|
||||||
|
@ -487,7 +487,7 @@ mod tests {
|
||||||
Type::Fn {
|
Type::Fn {
|
||||||
args: vec![Rc::new(Type::App {
|
args: vec![Rc::new(Type::App {
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
name: "PRNG".to_string(),
|
name: "PRNG".to_string(),
|
||||||
args: vec![],
|
args: vec![],
|
||||||
|
@ -495,14 +495,14 @@ mod tests {
|
||||||
})],
|
})],
|
||||||
ret: Rc::new(Type::App {
|
ret: Rc::new(Type::App {
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
name: "Option".to_string(),
|
name: "Option".to_string(),
|
||||||
args: vec![Rc::new(Type::Tuple {
|
args: vec![Rc::new(Type::Tuple {
|
||||||
elems: vec![
|
elems: vec![
|
||||||
Rc::new(Type::App {
|
Rc::new(Type::App {
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
name: "PRNG".to_string(),
|
name: "PRNG".to_string(),
|
||||||
args: vec![],
|
args: vec![],
|
||||||
|
@ -510,7 +510,7 @@ mod tests {
|
||||||
}),
|
}),
|
||||||
Rc::new(Type::App {
|
Rc::new(Type::App {
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
name: "Bool".to_string(),
|
name: "Bool".to_string(),
|
||||||
args: vec![],
|
args: vec![],
|
||||||
|
@ -561,7 +561,7 @@ mod tests {
|
||||||
Type::Fn {
|
Type::Fn {
|
||||||
args: vec![Rc::new(Type::App {
|
args: vec![Rc::new(Type::App {
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
name: "PRNG".to_string(),
|
name: "PRNG".to_string(),
|
||||||
args: vec![],
|
args: vec![],
|
||||||
|
@ -569,14 +569,14 @@ mod tests {
|
||||||
})],
|
})],
|
||||||
ret: Rc::new(Type::App {
|
ret: Rc::new(Type::App {
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
name: "Option".to_string(),
|
name: "Option".to_string(),
|
||||||
args: vec![Rc::new(Type::Tuple {
|
args: vec![Rc::new(Type::Tuple {
|
||||||
elems: vec![
|
elems: vec![
|
||||||
Rc::new(Type::App {
|
Rc::new(Type::App {
|
||||||
public: true,
|
public: true,
|
||||||
opaque: false,
|
contains_opaque: false,
|
||||||
module: "".to_string(),
|
module: "".to_string(),
|
||||||
name: "PRNG".to_string(),
|
name: "PRNG".to_string(),
|
||||||
args: vec![],
|
args: vec![],
|
||||||
|
|
Loading…
Reference in New Issue