diff --git a/crates/aiken-project/src/blueprint/error.rs b/crates/aiken-project/src/blueprint/error.rs index 27c7d5f4..cb53916b 100644 --- a/crates/aiken-project/src/blueprint/error.rs +++ b/crates/aiken-project/src/blueprint/error.rs @@ -6,7 +6,7 @@ use aiken_lang::ast::Span; use miette::{Diagnostic, NamedSource}; use owo_colors::{OwoColorize, Stream::Stdout}; use std::fmt::Debug; -use uplc::ast::{DeBruijn, Term}; +use uplc::ast::Constant; #[derive(Debug, thiserror::Error, Diagnostic)] pub enum Error { @@ -48,12 +48,12 @@ pub enum Error { ))] ParameterizedValidator { n: usize }, - #[error("I failed to infer what should be the schema of a given parameter to apply.")] + #[error("I stumble upon something else than a constant when I expected one.")] #[diagnostic(code("aiken:blueprint::apply::malformed::argument"))] #[diagnostic(help( - "I couldn't figure out the schema corresponding to a term you've given. Here's a possible hint about why I failed: {hint}" + "Parameters applied to blueprints must be constant; they cannot be lambdas or delayed terms." ))] - UnableToInferArgumentSchema { hint: String }, + NonConstantParameter, #[error("I couldn't find a definition corresponding to a reference.")] #[diagnostic(code("aiken::blueprint::apply::unknown::reference"))] @@ -70,10 +70,7 @@ pub enum Error { serde_json::to_string_pretty(&schema).unwrap().if_supports_color(Stdout, |s| s.green()), term.to_pretty().if_supports_color(Stdout, |s| s.red()), ))] - SchemaMismatch { - schema: Schema, - term: Term, - }, + SchemaMismatch { schema: Schema, term: Constant }, #[error( "I discovered a discrepancy of elements between a given tuple and its declared schema." diff --git a/crates/aiken-project/src/blueprint/parameter.rs b/crates/aiken-project/src/blueprint/parameter.rs index fe682077..4e127490 100644 --- a/crates/aiken-project/src/blueprint/parameter.rs +++ b/crates/aiken-project/src/blueprint/parameter.rs @@ -3,7 +3,7 @@ use super::{ error::Error, schema::{Annotated, Constructor, Data, Declaration, Items, Schema}, }; -use std::{iter, ops::Deref, rc::Rc}; +use std::{iter, ops::Deref}; use uplc::{ ast::{Constant, Data as UplcData, DeBruijn, Term}, PlutusData, @@ -17,8 +17,6 @@ pub struct Parameter { pub schema: Reference, } -type Instance = Term; - impl From for Parameter { fn from(schema: Reference) -> Parameter { Parameter { @@ -32,7 +30,7 @@ impl Parameter { pub fn validate( &self, definitions: &Definitions>, - term: &Instance, + term: &Term, ) -> Result<(), Error> { let schema = &definitions .lookup(&self.schema) @@ -44,14 +42,18 @@ impl Parameter { })? .annotated; - validate_schema(schema, definitions, term) + if let Term::Constant(constant) = term { + validate_schema(schema, definitions, constant) + } else { + Err(Error::NonConstantParameter) + } } } fn validate_schema( schema: &Schema, definitions: &Definitions>, - term: &Instance, + term: &Constant, ) -> Result<(), Error> { match schema { Schema::Data(data) => validate_data(data, definitions, term), @@ -135,7 +137,7 @@ fn validate_schema( fn validate_data( data: &Data, definitions: &Definitions>, - term: &Instance, + term: &Constant, ) -> Result<(), Error> { match data { Data::Opaque => expect_data(term), @@ -267,11 +269,9 @@ fn validate_data( } } -fn expect_data(term: &Instance) -> Result<(), Error> { - if let Term::Constant(constant) = term { - if matches!(constant.deref(), Constant::Data(..)) { - return Ok(()); - } +fn expect_data(term: &Constant) -> Result<(), Error> { + if matches!(term, Constant::Data(..)) { + return Ok(()); } Err(Error::SchemaMismatch { @@ -280,12 +280,10 @@ fn expect_data(term: &Instance) -> Result<(), Error> { }) } -fn expect_data_integer(term: &Instance) -> Result<(), Error> { - if let Term::Constant(constant) = term { - if let Constant::Data(data) = constant.deref() { - if matches!(data, PlutusData::BigInt(..)) { - return Ok(()); - } +fn expect_data_integer(term: &Constant) -> Result<(), Error> { + if let Constant::Data(data) = term { + if matches!(data, PlutusData::BigInt(..)) { + return Ok(()); } } @@ -295,12 +293,10 @@ fn expect_data_integer(term: &Instance) -> Result<(), Error> { }) } -fn expect_data_bytes(term: &Instance) -> Result<(), Error> { - if let Term::Constant(constant) = term { - if let Constant::Data(data) = constant.deref() { - if matches!(data, PlutusData::BoundedBytes(..)) { - return Ok(()); - } +fn expect_data_bytes(term: &Constant) -> Result<(), Error> { + if let Constant::Data(data) = term { + if matches!(data, PlutusData::BoundedBytes(..)) { + return Ok(()); } } @@ -310,14 +306,12 @@ fn expect_data_bytes(term: &Instance) -> Result<(), Error> { }) } -fn expect_data_list(term: &Instance) -> Result, Error> { - if let Term::Constant(constant) = term { - if let Constant::Data(PlutusData::Array(elems)) = constant.deref() { - return Ok(elems - .iter() - .map(|elem| Term::Constant(Rc::new(Constant::Data(elem.to_owned())))) - .collect()); - } +fn expect_data_list(term: &Constant) -> Result, Error> { + if let Constant::Data(PlutusData::Array(elems)) = term { + return Ok(elems + .iter() + .map(|elem| Constant::Data(elem.to_owned())) + .collect()); } let inner_schema = Items::One(Declaration::Inline(Box::new(Data::Opaque))); @@ -328,19 +322,12 @@ fn expect_data_list(term: &Instance) -> Result, Error> { }) } -fn expect_data_map(term: &Instance) -> Result, Error> { - if let Term::Constant(constant) = term { - if let Constant::Data(PlutusData::Map(pairs)) = constant.deref() { - return Ok(pairs - .iter() - .map(|(k, v)| { - ( - Term::Constant(Rc::new(Constant::Data(k.to_owned()))), - Term::Constant(Rc::new(Constant::Data(v.to_owned()))), - ) - }) - .collect()); - } +fn expect_data_map(term: &Constant) -> Result, Error> { + if let Constant::Data(PlutusData::Map(pairs)) = term { + return Ok(pairs + .iter() + .map(|(k, v)| (Constant::Data(k.to_owned()), Constant::Data(v.to_owned()))) + .collect()); } let key_schema = Declaration::Inline(Box::new(Data::Opaque)); @@ -352,18 +339,15 @@ fn expect_data_map(term: &Instance) -> Result, Error> }) } -fn expect_data_constr(term: &Instance, index: usize) -> Result, Error> { - if let Term::Constant(constant) = term { - if let Constant::Data(PlutusData::Constr(constr)) = constant.deref() { - if let PlutusData::Constr(expected) = UplcData::constr(index as u64, vec![]) { - if expected.tag == constr.tag && expected.any_constructor == constr.any_constructor - { - return Ok(constr - .fields - .iter() - .map(|field| Term::Constant(Rc::new(Constant::Data(field.to_owned())))) - .collect()); - } +fn expect_data_constr(term: &Constant, index: usize) -> Result, Error> { + if let Constant::Data(PlutusData::Constr(constr)) = term { + if let PlutusData::Constr(expected) = UplcData::constr(index as u64, vec![]) { + if expected.tag == constr.tag && expected.any_constructor == constr.any_constructor { + return Ok(constr + .fields + .iter() + .map(|field| Constant::Data(field.to_owned())) + .collect()); } } } @@ -378,11 +362,9 @@ fn expect_data_constr(term: &Instance, index: usize) -> Result, Er }) } -fn expect_unit(term: &Instance) -> Result<(), Error> { - if let Term::Constant(constant) = term { - if matches!(constant.deref(), Constant::Unit) { - return Ok(()); - } +fn expect_unit(term: &Constant) -> Result<(), Error> { + if matches!(term, Constant::Unit) { + return Ok(()); } Err(Error::SchemaMismatch { @@ -391,11 +373,9 @@ fn expect_unit(term: &Instance) -> Result<(), Error> { }) } -fn expect_integer(term: &Instance) -> Result<(), Error> { - if let Term::Constant(constant) = term { - if matches!(constant.deref(), Constant::Integer(..)) { - return Ok(()); - } +fn expect_integer(term: &Constant) -> Result<(), Error> { + if matches!(term, Constant::Integer(..)) { + return Ok(()); } Err(Error::SchemaMismatch { @@ -404,11 +384,9 @@ fn expect_integer(term: &Instance) -> Result<(), Error> { }) } -fn expect_bytes(term: &Instance) -> Result<(), Error> { - if let Term::Constant(constant) = term { - if matches!(constant.deref(), Constant::ByteString(..)) { - return Ok(()); - } +fn expect_bytes(term: &Constant) -> Result<(), Error> { + if matches!(term, Constant::ByteString(..)) { + return Ok(()); } Err(Error::SchemaMismatch { @@ -417,11 +395,9 @@ fn expect_bytes(term: &Instance) -> Result<(), Error> { }) } -fn expect_string(term: &Instance) -> Result<(), Error> { - if let Term::Constant(constant) = term { - if matches!(constant.deref(), Constant::String(..)) { - return Ok(()); - } +fn expect_string(term: &Constant) -> Result<(), Error> { + if matches!(term, Constant::String(..)) { + return Ok(()); } Err(Error::SchemaMismatch { @@ -430,11 +406,9 @@ fn expect_string(term: &Instance) -> Result<(), Error> { }) } -fn expect_boolean(term: &Instance) -> Result<(), Error> { - if let Term::Constant(constant) = term { - if matches!(constant.deref(), Constant::Bool(..)) { - return Ok(()); - } +fn expect_boolean(term: &Constant) -> Result<(), Error> { + if matches!(term, Constant::Bool(..)) { + return Ok(()); } Err(Error::SchemaMismatch { @@ -443,11 +417,9 @@ fn expect_boolean(term: &Instance) -> Result<(), Error> { }) } -fn expect_pair(term: &Instance) -> Result<(Instance, Instance), Error> { - if let Term::Constant(constant) = term { - if let Constant::ProtoPair(_, _, left, right) = constant.deref() { - return Ok((Term::Constant(left.clone()), Term::Constant(right.clone()))); - } +fn expect_pair(term: &Constant) -> Result<(Constant, Constant), Error> { + if let Constant::ProtoPair(_, _, left, right) = term { + return Ok((left.deref().clone(), right.deref().clone())); } let left_schema = Declaration::Inline(Box::new(Schema::Data(Data::Opaque))); @@ -459,14 +431,9 @@ fn expect_pair(term: &Instance) -> Result<(Instance, Instance), Error> { }) } -fn expect_list(term: &Instance) -> Result, Error> { - if let Term::Constant(constant) = term { - if let Constant::ProtoList(_, elems) = constant.deref() { - return Ok(elems - .iter() - .map(|elem| Term::Constant(Rc::new(elem.to_owned()))) - .collect()); - } +fn expect_list(term: &Constant) -> Result, Error> { + if let Constant::ProtoList(_, elems) = term { + return Ok(elems.to_owned()); } let inner_schema = Items::One(Declaration::Inline(Box::new(Schema::Data(Data::Opaque))));