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,