diff --git a/crates/aiken-lang/src/tipo.rs b/crates/aiken-lang/src/tipo.rs index 574c7167..fad2f08e 100644 --- a/crates/aiken-lang/src/tipo.rs +++ b/crates/aiken-lang/src/tipo.rs @@ -22,6 +22,8 @@ mod pattern; mod pipe; pub mod pretty; +pub use environment::collapse_links; + #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] pub struct TypeAliasAnnotation { pub alias: String, @@ -1099,13 +1101,11 @@ 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()] } } } diff --git a/crates/aiken-lang/src/tipo/environment.rs b/crates/aiken-lang/src/tipo/environment.rs index 2c8c70cd..5de5d162 100644 --- a/crates/aiken-lang/src/tipo/environment.rs +++ b/crates/aiken-lang/src/tipo/environment.rs @@ -1967,7 +1967,7 @@ pub(super) fn assert_no_labeled_arguments(args: &[CallArg]) -> Option<(Spa None } -pub(super) fn collapse_links(t: Rc) -> Rc { +pub fn collapse_links(t: Rc) -> Rc { if let Type::Var { tipo, alias } = t.deref() { if let TypeVar::Link { tipo } = tipo.borrow().deref() { return Type::with_alias(tipo.clone(), alias.clone()); diff --git a/crates/aiken-project/src/blueprint/validator.rs b/crates/aiken-project/src/blueprint/validator.rs index 113bcb23..4fb070ac 100644 --- a/crates/aiken-project/src/blueprint/validator.rs +++ b/crates/aiken-project/src/blueprint/validator.rs @@ -10,7 +10,7 @@ use aiken_lang::{ ast::{well_known, Annotation, TypedArg, TypedFunction, TypedValidator}, gen_uplc::CodeGenerator, plutus_version::PlutusVersion, - tipo::Type, + tipo::{collapse_links, Type}, }; use miette::NamedSource; use serde; @@ -126,12 +126,16 @@ impl Validator { .map(|datum| { match datum.tipo.as_ref() { Type::App { module: module_name, name, args, .. } if module_name.is_empty() && name == well_known::OPTION => { + let Some(Annotation::Constructor { arguments, .. }) = datum.annotation.as_ref() else { + panic!("Datum isn't an option but should be; this should have been caught by the type-checker!"); + }; + Annotated::from_type( modules.into(), tipo_or_annotation(module, &TypedArg { arg_name: datum.arg_name.clone(), location: datum.location, - annotation: datum.annotation.clone(), + annotation: arguments.first().cloned(), doc: datum.doc.clone(), is_validator_param: datum.is_validator_param, tipo: args.first().expect("Option always have a single type argument.").clone() @@ -204,7 +208,7 @@ impl Validator { } pub fn tipo_or_annotation<'a>(module: &'a CheckedModule, arg: &'a TypedArg) -> &'a Type { - match *arg.tipo.borrow() { + match collapse_links(arg.tipo.clone()).borrow() { Type::App { module: ref module_name, name: ref type_name,