Fix default annotation for spend's optional datum and mint argument.
When there's no type annotation in a validator handler signature, we provide default annotation to help the type-checker. However, for spend's datum and mint policy_id, those annotations mustn't be `Data`, but rather Option<Data> and Bytearray. Without that, when no annotation are provided, the compiler infer invalid types and fails with incongruous errors.
This commit is contained in:
parent
0510ca58f7
commit
4003343444
|
@ -266,6 +266,16 @@ pub struct Function<T, Expr, Arg> {
|
|||
pub on_test_failure: OnTestFailure,
|
||||
}
|
||||
|
||||
impl<T, Expr, Arg> Function<T, Expr, Arg> {
|
||||
pub fn is_spend(&self) -> bool {
|
||||
self.name == HANDLER_SPEND
|
||||
}
|
||||
|
||||
pub fn is_mint(&self) -> bool {
|
||||
self.name == HANDLER_MINT
|
||||
}
|
||||
}
|
||||
|
||||
impl TypedFunction {
|
||||
pub fn find_node(&self, byte_index: usize) -> Option<Located<'_>> {
|
||||
self.arguments
|
||||
|
@ -279,10 +289,6 @@ impl TypedFunction {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn is_spend(&self) -> bool {
|
||||
self.name == HANDLER_SPEND
|
||||
}
|
||||
|
||||
pub fn has_valid_purpose_name(&self) -> bool {
|
||||
self.name == HANDLER_SPEND
|
||||
|| self.name == HANDLER_PUBLISH
|
||||
|
@ -1245,6 +1251,15 @@ impl Annotation {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn option(inner: Annotation) -> Self {
|
||||
Annotation::Constructor {
|
||||
name: "Option".to_string(),
|
||||
module: None,
|
||||
location: inner.location(),
|
||||
arguments: vec![inner],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_logically_equal(&self, other: &Annotation) -> bool {
|
||||
match self {
|
||||
Annotation::Constructor {
|
||||
|
|
|
@ -1275,10 +1275,9 @@ impl<'a> Environment<'a> {
|
|||
location,
|
||||
end_position: _,
|
||||
}) if kind.is_validator() => {
|
||||
let default_annotation = |mut arg: UntypedArg| {
|
||||
let default_annotation = |mut arg: UntypedArg, ann: Annotation| {
|
||||
if arg.annotation.is_none() {
|
||||
arg.annotation = Some(Annotation::data(arg.location));
|
||||
|
||||
arg.annotation = Some(ann);
|
||||
arg
|
||||
} else {
|
||||
arg
|
||||
|
@ -1287,12 +1286,29 @@ impl<'a> Environment<'a> {
|
|||
|
||||
let mut handler_names = vec![];
|
||||
|
||||
let params_len = params.len();
|
||||
|
||||
for handler in handlers {
|
||||
let temp_params: Vec<UntypedArg> = params
|
||||
.iter()
|
||||
.cloned()
|
||||
.chain(handler.arguments.clone())
|
||||
.map(default_annotation)
|
||||
.enumerate()
|
||||
.map(|(ix, arg)| {
|
||||
let is_datum = handler.is_spend() && ix == params_len;
|
||||
let is_mint_policy = handler.is_mint() && ix == params_len + 1;
|
||||
let location = arg.location;
|
||||
default_annotation(
|
||||
arg,
|
||||
if is_datum {
|
||||
Annotation::option(Annotation::data(location))
|
||||
} else if is_mint_policy {
|
||||
Annotation::bytearray(location)
|
||||
} else {
|
||||
Annotation::data(location)
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
handler_names.push(handler.name.clone());
|
||||
|
@ -1312,7 +1328,10 @@ impl<'a> Environment<'a> {
|
|||
.iter()
|
||||
.cloned()
|
||||
.chain(fallback.arguments.clone())
|
||||
.map(default_annotation)
|
||||
.map(|arg| {
|
||||
let location = arg.location;
|
||||
default_annotation(arg, Annotation::data(location))
|
||||
})
|
||||
.collect();
|
||||
|
||||
self.register_function(
|
||||
|
|
Loading…
Reference in New Issue