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,
|
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 {
|
impl TypedFunction {
|
||||||
pub fn find_node(&self, byte_index: usize) -> Option<Located<'_>> {
|
pub fn find_node(&self, byte_index: usize) -> Option<Located<'_>> {
|
||||||
self.arguments
|
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 {
|
pub fn has_valid_purpose_name(&self) -> bool {
|
||||||
self.name == HANDLER_SPEND
|
self.name == HANDLER_SPEND
|
||||||
|| self.name == HANDLER_PUBLISH
|
|| 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 {
|
pub fn is_logically_equal(&self, other: &Annotation) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Annotation::Constructor {
|
Annotation::Constructor {
|
||||||
|
|
|
@ -1275,10 +1275,9 @@ impl<'a> Environment<'a> {
|
||||||
location,
|
location,
|
||||||
end_position: _,
|
end_position: _,
|
||||||
}) if kind.is_validator() => {
|
}) if kind.is_validator() => {
|
||||||
let default_annotation = |mut arg: UntypedArg| {
|
let default_annotation = |mut arg: UntypedArg, ann: Annotation| {
|
||||||
if arg.annotation.is_none() {
|
if arg.annotation.is_none() {
|
||||||
arg.annotation = Some(Annotation::data(arg.location));
|
arg.annotation = Some(ann);
|
||||||
|
|
||||||
arg
|
arg
|
||||||
} else {
|
} else {
|
||||||
arg
|
arg
|
||||||
|
@ -1287,12 +1286,29 @@ impl<'a> Environment<'a> {
|
||||||
|
|
||||||
let mut handler_names = vec![];
|
let mut handler_names = vec![];
|
||||||
|
|
||||||
|
let params_len = params.len();
|
||||||
|
|
||||||
for handler in handlers {
|
for handler in handlers {
|
||||||
let temp_params: Vec<UntypedArg> = params
|
let temp_params: Vec<UntypedArg> = params
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.cloned()
|
||||||
.chain(handler.arguments.clone())
|
.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();
|
.collect();
|
||||||
|
|
||||||
handler_names.push(handler.name.clone());
|
handler_names.push(handler.name.clone());
|
||||||
|
@ -1312,7 +1328,10 @@ impl<'a> Environment<'a> {
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.cloned()
|
||||||
.chain(fallback.arguments.clone())
|
.chain(fallback.arguments.clone())
|
||||||
.map(default_annotation)
|
.map(|arg| {
|
||||||
|
let location = arg.location;
|
||||||
|
default_annotation(arg, Annotation::data(location))
|
||||||
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
self.register_function(
|
self.register_function(
|
||||||
|
|
Loading…
Reference in New Issue