Handle opaque single-variant-single-field special case.

This commit is contained in:
KtorZ 2023-01-29 10:33:50 +01:00
parent aaa8cba0cf
commit 2523816813
No known key found for this signature in database
GPG Key ID: 33173CB6F77F4277
2 changed files with 63 additions and 13 deletions

View File

@ -160,12 +160,19 @@ impl Annotated<Schema> {
let generic = let generic =
Annotated::from_type(modules, args.get(0).unwrap(), type_parameters)?; Annotated::from_type(modules, args.get(0).unwrap(), type_parameters)?;
let generic = match generic.annotated { // NOTE: Lists of 2-tuples are treated as Maps. This is an oddity we inherit
// from the PlutusTx / LedgerApi Haskell codebase, which encodes some elements
// as such. We don't have a concept of language maps in Aiken, so we simply
// make all types abide by this convention.
let data = match generic.annotated {
Schema::Pair(left, right) => Data::Map(Box::new(left), Box::new(right)), Schema::Pair(left, right) => Data::Map(Box::new(left), Box::new(right)),
_ => generic.into_data(type_info)?.annotated, _ => {
let inner = generic.into_data(type_info)?.annotated;
Data::List(Box::new(inner))
}
}; };
Ok(Schema::Data(Some(Data::List(Box::new(generic)))).into()) Ok(Schema::Data(Some(data)).into())
} }
_ => Err(Error::UnsupportedType { _ => Err(Error::UnsupportedType {
@ -284,6 +291,17 @@ impl Data {
variants.push(variant); variants.push(variant);
} }
// NOTE: Opaque data-types with a single variant and a single field are transparent, they
// are erased completely at compilation time.
if data_type.opaque {
if let [variant] = &variants[..] {
if let [field] = &variant.annotated.fields[..] {
return Ok(field.annotated.clone());
}
}
}
Ok(Data::AnyOf(variants)) Ok(Data::AnyOf(variants))
} }
} }

View File

@ -531,7 +531,7 @@ mod test {
} }
#[test] #[test]
fn validator_phantom_and_opaque_types() { fn validator_phantom_types() {
assert_validator( assert_validator(
r#" r#"
type Dict<key, value> { type Dict<key, value> {
@ -559,8 +559,6 @@ mod test {
"fields": [ "fields": [
{ {
"title": "inner", "title": "inner",
"dataType": "list",
"items": {
"dataType": "map", "dataType": "map",
"keys": { "keys": {
"dataType": "bytes" "dataType": "bytes"
@ -569,7 +567,6 @@ mod test {
"dataType": "integer" "dataType": "integer"
} }
} }
}
] ]
} }
] ]
@ -579,4 +576,39 @@ mod test {
), ),
); );
} }
#[test]
fn validator_opaque_types() {
assert_validator(
r#"
pub opaque type Dict<key, value> {
inner: List<(ByteArray, value)>
}
type UUID { UUID }
fn mint(redeemer: Dict<UUID, Int>, ctx: Void) {
True
}
"#,
json!(
{
"title": "test_module",
"purpose": "mint",
"hash": "da4a98cee05a17be402b07c414d59bf894c9ebd0487186417121de8f",
"redeemer": {
"title": "Dict",
"dataType": "map",
"keys": {
"dataType": "bytes"
},
"values": {
"dataType": "integer"
}
},
"compiledCode": "581d010000210872656465656d657200210363747800533357349445261601"
}
),
);
}
} }