Fix wrong use of 'UnknownVariable' instead of 'UnknownTypeConstructor'

While the feedback for human users is mostly the same, it does in fact
  matter for the LSP since the quickfix will be different depending on
  whether we look for a top-level identifier or if we look for a
  constructor.

  The typical case we see in the stdlib is the `VerificationKey` and
  `Script` constructors for `Credential`, often being mixed with
  their types counterparts in aiken/crypto!

Signed-off-by: KtorZ <matthias.benkort@gmail.com>
This commit is contained in:
KtorZ 2025-02-22 17:53:58 +01:00
parent a89694ed75
commit 9f24a5c577
No known key found for this signature in database
GPG Key ID: 33173CB6F77F4277
4 changed files with 38 additions and 10 deletions

View File

@ -1,5 +1,11 @@
# Changelog
## v1.1.15 - UNRELEASED
### Changed
- **aiken-lang**: fixed `UnknownTypeConstructor` wrongly reported as `UnknownVariable` (then messing up with LSP quickfix suggestions). @KtorZ
## v1.1.14 - 2025-02-21
### Changed

View File

@ -1357,6 +1357,10 @@ impl TypeConstructor {
public: true,
}
}
pub fn might_be(name: &str) -> bool {
name.chars().next().unwrap().is_uppercase()
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]

View File

@ -914,11 +914,7 @@ Perhaps, try the following:
suggest_neighbor(
name,
variables.iter(),
&if name.chars().next().unwrap().is_uppercase() {
suggest_import_constructor()
} else {
"Did you forget to import it?".to_string()
}
"Did you forget to import it?",
)
))]
UnknownVariable {

View File

@ -21,7 +21,9 @@ use crate::{
expr::{FnStyle, TypedExpr, UntypedExpr},
format,
parser::token::Base,
tipo::{fields::FieldMap, DefaultFunction, ModuleKind, PatternConstructor, TypeVar},
tipo::{
fields::FieldMap, DefaultFunction, ModuleKind, PatternConstructor, TypeConstructor, TypeVar,
},
IdGenerator,
};
use std::{
@ -2481,10 +2483,30 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
self.environment
.get_variable(name)
.cloned()
.ok_or_else(|| Error::UnknownVariable {
location: *location,
name: name.to_string(),
variables: self.environment.local_value_names(),
.ok_or_else(|| {
if TypeConstructor::might_be(name) {
Error::UnknownTypeConstructor {
location: *location,
name: name.to_string(),
constructors: self
.environment
.local_value_names()
.into_iter()
.filter(|s| TypeConstructor::might_be(s))
.collect::<Vec<_>>(),
}
} else {
Error::UnknownVariable {
location: *location,
name: name.to_string(),
variables: self
.environment
.local_value_names()
.into_iter()
.filter(|s| !TypeConstructor::might_be(s))
.collect::<Vec<_>>(),
}
}
})?;
if let ValueConstructorVariant::ModuleFn { name: fn_name, .. } =