Better errors when using unknown data-type constructor.
## Before ``` × Checking ╰─▶ Unknown variable Finite ╭─[../stdlib/validators/tmp.ak:10:1] 10 │ let now = when context.transaction.validity_range.lower_bound.bound_type is { 11 │ Finite { t } -> t · ──────────── 12 │ NegativeInfinity -> 0 ╰──── ``` ## After ``` × Type-checking ╰─▶ Unknown data-type constructor 'Finite' ╭─[../stdlib/validators/tmp.ak:10:1] 10 │ let now = when context.transaction.validity_range.lower_bound.bound_type is { 11 │ Finite { t } -> t · ──────────── 12 │ NegativeInfinity -> 0 ╰──── help: Did you forget to import it? Data-type constructors are not automatically imported, even if their type is imported. So, if a module `aiken/pet` defines the following type: ┍━ aiken/pet.ak ━━━━━━━━ │ pub type Pet { │ Cat │ Dog │ } You must import its constructors explicitly to use them, or prefix them with the module's name. ┍━ foo.ak ━━━━━━━━ │ use aiken/pet.{Pet, Dog} │ │ fn foo(pet : Pet) { │ when pet is { │ pet.Cat -> // ... │ Dog -> // ... │ } │ } ```
This commit is contained in:
parent
2aa4429231
commit
0682781460
|
@ -315,10 +315,20 @@ impl<'a> Environment<'a> {
|
||||||
location: Span,
|
location: Span,
|
||||||
) -> Result<&ValueConstructor, Error> {
|
) -> Result<&ValueConstructor, Error> {
|
||||||
match module {
|
match module {
|
||||||
None => self.scope.get(name).ok_or_else(|| Error::UnknownVariable {
|
None => self.scope.get(name).ok_or_else(|| {
|
||||||
name: name.to_string(),
|
if name.chars().into_iter().next().unwrap().is_uppercase() {
|
||||||
variables: self.local_value_names(),
|
Error::UnknownTypeConstructor {
|
||||||
location,
|
name: name.to_string(),
|
||||||
|
variables: self.local_value_names(),
|
||||||
|
location,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Error::UnknownVariable {
|
||||||
|
name: name.to_string(),
|
||||||
|
variables: self.local_value_names(),
|
||||||
|
location,
|
||||||
|
}
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
Some(m) => {
|
Some(m) => {
|
||||||
|
|
|
@ -225,6 +225,40 @@ pub enum Error {
|
||||||
variables: Vec<String>,
|
variables: Vec<String>,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
#[error("Unknown data-type constructor '{name}'\n")]
|
||||||
|
#[diagnostic(help(
|
||||||
|
r#"Did you forget to import it?
|
||||||
|
|
||||||
|
Data-type constructors are not automatically imported, even if their type is
|
||||||
|
imported. So, if a module `aiken/pet` defines the following type:
|
||||||
|
|
||||||
|
┍━ aiken/pet.ak ━━━━━━━━
|
||||||
|
│ pub type Pet {{
|
||||||
|
│ Cat
|
||||||
|
│ Dog
|
||||||
|
│ }}
|
||||||
|
|
||||||
|
You must import its constructors explicitly to use them, or prefix them
|
||||||
|
with the module's name.
|
||||||
|
|
||||||
|
┍━ foo.ak ━━━━━━━━
|
||||||
|
│ use aiken/pet.{{Pet, Dog}}
|
||||||
|
│
|
||||||
|
│ fn foo(pet : Pet) {{
|
||||||
|
│ when pet is {{
|
||||||
|
│ pet.Cat -> // ...
|
||||||
|
│ Dog -> // ...
|
||||||
|
│ }}
|
||||||
|
│ }}
|
||||||
|
"#
|
||||||
|
))]
|
||||||
|
UnknownTypeConstructor {
|
||||||
|
#[label]
|
||||||
|
location: Span,
|
||||||
|
name: String,
|
||||||
|
variables: Vec<String>,
|
||||||
|
},
|
||||||
|
|
||||||
#[error("Unnecessary spread operator\n")]
|
#[error("Unnecessary spread operator\n")]
|
||||||
UnnecessarySpreadOperator {
|
UnnecessarySpreadOperator {
|
||||||
#[label]
|
#[label]
|
||||||
|
|
|
@ -74,7 +74,7 @@ pub enum Error {
|
||||||
error: Box<ParseError>,
|
error: Box<ParseError>,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("Checking")]
|
#[error("Type-checking")]
|
||||||
Type {
|
Type {
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
src: String,
|
src: String,
|
||||||
|
|
Loading…
Reference in New Issue