feat: return err if data type contains functions
Due to how PlutusData works it doesn't make sense to allow user defined types to contain functions. ``` type Foo { bar: fn(Int) -> Int } ``` The above definition will now return an error.
This commit is contained in:
parent
95c9be5c52
commit
b69c1f66d7
|
@ -73,6 +73,10 @@ impl Type {
|
||||||
matches!(self, Self::Var { tipo } if tipo.borrow().is_unbound())
|
matches!(self, Self::Var { tipo } if tipo.borrow().is_unbound())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_function(&self) -> bool {
|
||||||
|
matches!(self, Self::Fn { .. })
|
||||||
|
}
|
||||||
|
|
||||||
pub fn return_type(&self) -> Option<Arc<Self>> {
|
pub fn return_type(&self) -> Option<Arc<Self>> {
|
||||||
match self {
|
match self {
|
||||||
Self::Fn { ret, .. } => Some(ret.clone()),
|
Self::Fn { ret, .. } => Some(ret.clone()),
|
||||||
|
|
|
@ -47,6 +47,9 @@ pub enum Error {
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
#[error("I found a data type that has a function type in it. This is not allowed.")]
|
||||||
|
FunctionTypeInData { location: Span },
|
||||||
|
|
||||||
#[error("I saw a {} fields in a context where there should be {}.\n", given.purple(), expected.purple())]
|
#[error("I saw a {} fields in a context where there should be {}.\n", given.purple(), expected.purple())]
|
||||||
IncorrectFieldsArity {
|
IncorrectFieldsArity {
|
||||||
location: Span,
|
location: Span,
|
||||||
|
@ -365,6 +368,7 @@ impl Diagnostic for Error {
|
||||||
Self::DuplicateField { .. } => Some(Box::new("duplicate_field")),
|
Self::DuplicateField { .. } => Some(Box::new("duplicate_field")),
|
||||||
Self::DuplicateName { .. } => Some(Box::new("duplicate_name")),
|
Self::DuplicateName { .. } => Some(Box::new("duplicate_name")),
|
||||||
Self::DuplicateTypeName { .. } => Some(Box::new("duplicate_type_name")),
|
Self::DuplicateTypeName { .. } => Some(Box::new("duplicate_type_name")),
|
||||||
|
Self::FunctionTypeInData { .. } => Some(Box::new("function_type_in_data")),
|
||||||
Self::IncorrectFieldsArity { .. } => Some(Box::new("incorrect_fields_arity")),
|
Self::IncorrectFieldsArity { .. } => Some(Box::new("incorrect_fields_arity")),
|
||||||
Self::IncorrectFunctionCallArity { .. } => Some(Box::new("incorrect_fn_arity")),
|
Self::IncorrectFunctionCallArity { .. } => Some(Box::new("incorrect_fn_arity")),
|
||||||
Self::IncorrectPatternArity { .. } => Some(Box::new("incorrect_pattern_arity")),
|
Self::IncorrectPatternArity { .. } => Some(Box::new("incorrect_pattern_arity")),
|
||||||
|
@ -478,6 +482,8 @@ impl Diagnostic for Error {
|
||||||
, cannot = "cannot".red()
|
, cannot = "cannot".red()
|
||||||
})),
|
})),
|
||||||
|
|
||||||
|
Self::FunctionTypeInData { .. } => Some(Box::new("Data types can't have functions in them due to how Plutus Data works.")),
|
||||||
|
|
||||||
Self::IncorrectFieldsArity { .. } => None,
|
Self::IncorrectFieldsArity { .. } => None,
|
||||||
|
|
||||||
Self::IncorrectFunctionCallArity { expected, .. } => Some(Box::new(formatdoc! {
|
Self::IncorrectFunctionCallArity { expected, .. } => Some(Box::new(formatdoc! {
|
||||||
|
@ -1134,6 +1140,9 @@ impl Diagnostic for Error {
|
||||||
Self::DuplicateTypeName { location, .. } => Some(Box::new(
|
Self::DuplicateTypeName { location, .. } => Some(Box::new(
|
||||||
vec![LabeledSpan::new_with_span(None, *location)].into_iter(),
|
vec![LabeledSpan::new_with_span(None, *location)].into_iter(),
|
||||||
)),
|
)),
|
||||||
|
Self::FunctionTypeInData { location } => Some(Box::new(
|
||||||
|
vec![LabeledSpan::new_with_span(None, *location)].into_iter(),
|
||||||
|
)),
|
||||||
Self::IncorrectFieldsArity { location, .. } => Some(Box::new(
|
Self::IncorrectFieldsArity { location, .. } => Some(Box::new(
|
||||||
vec![LabeledSpan::new_with_span(None, *location)].into_iter(),
|
vec![LabeledSpan::new_with_span(None, *location)].into_iter(),
|
||||||
)),
|
)),
|
||||||
|
@ -1262,6 +1271,7 @@ impl Diagnostic for Error {
|
||||||
Self::DuplicateField { .. } => None,
|
Self::DuplicateField { .. } => None,
|
||||||
Self::DuplicateName { .. } => None,
|
Self::DuplicateName { .. } => None,
|
||||||
Self::DuplicateTypeName { .. } => None,
|
Self::DuplicateTypeName { .. } => None,
|
||||||
|
Self::FunctionTypeInData { .. } => None,
|
||||||
Self::IncorrectFieldsArity { .. } => Some(Box::new(
|
Self::IncorrectFieldsArity { .. } => Some(Box::new(
|
||||||
"https://aiken-lang.org/language-tour/custom-types",
|
"https://aiken-lang.org/language-tour/custom-types",
|
||||||
)),
|
)),
|
||||||
|
|
|
@ -281,10 +281,10 @@ fn infer_definition(
|
||||||
opaque,
|
opaque,
|
||||||
name,
|
name,
|
||||||
parameters,
|
parameters,
|
||||||
constructors,
|
constructors: untyped_constructors,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
let constructors = constructors
|
let constructors = untyped_constructors
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(
|
.map(
|
||||||
|RecordConstructor {
|
|RecordConstructor {
|
||||||
|
@ -346,7 +346,7 @@ fn infer_definition(
|
||||||
.parameters
|
.parameters
|
||||||
.clone();
|
.clone();
|
||||||
|
|
||||||
Ok(Definition::DataType(DataType {
|
let typed_data = DataType {
|
||||||
doc,
|
doc,
|
||||||
location,
|
location,
|
||||||
public,
|
public,
|
||||||
|
@ -355,7 +355,19 @@ fn infer_definition(
|
||||||
parameters,
|
parameters,
|
||||||
constructors,
|
constructors,
|
||||||
typed_parameters,
|
typed_parameters,
|
||||||
}))
|
};
|
||||||
|
|
||||||
|
for constr in &typed_data.constructors {
|
||||||
|
for RecordConstructorArg { tipo, location, .. } in &constr.arguments {
|
||||||
|
if tipo.is_function() {
|
||||||
|
return Err(Error::FunctionTypeInData {
|
||||||
|
location: *location,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Definition::DataType(typed_data))
|
||||||
}
|
}
|
||||||
|
|
||||||
Definition::Use(Use {
|
Definition::Use(Use {
|
||||||
|
|
Loading…
Reference in New Issue