diff --git a/crates/aiken-lang/src/tipo/environment.rs b/crates/aiken-lang/src/tipo/environment.rs index 4548bc7a..96805465 100644 --- a/crates/aiken-lang/src/tipo/environment.rs +++ b/crates/aiken-lang/src/tipo/environment.rs @@ -91,20 +91,36 @@ impl<'a> Environment<'a> { pub fn find_module(&self, fragments: &[String], location: Span) -> Result<&'a TypeInfo, Error> { let mut name = fragments.join("/"); - if name == ast::ENV_MODULE { + let is_env = name == ast::ENV_MODULE; + + if is_env { name = self .target_env .unwrap_or(ast::DEFAULT_ENV_MODULE) .to_string() } - self.importable_modules - .get(&name) - .ok_or_else(|| Error::UnknownModule { - location, - name, - imported_modules: self.imported_modules.keys().cloned().collect(), - }) + self.importable_modules.get(&name).ok_or_else(|| { + if is_env { + Error::UnknownEnvironment { + name, + known_environments: self + .importable_modules + .values() + .filter_map(|m| match m.kind { + ModuleKind::Env => Some(m.name.clone()), + ModuleKind::Lib | ModuleKind::Validator => None, + }) + .collect(), + } + } else { + Error::UnknownModule { + location, + name, + known_modules: self.importable_modules.keys().cloned().collect(), + } + } + }) } pub fn close_scope(&mut self, data: ScopeResetData) { @@ -373,7 +389,7 @@ impl<'a> Environment<'a> { .ok_or_else(|| Error::UnknownModule { location, name: name.to_string(), - imported_modules: self + known_modules: self .importable_modules .keys() .map(|t| t.to_string()) @@ -419,7 +435,7 @@ impl<'a> Environment<'a> { .get(m) .ok_or_else(|| Error::UnknownModule { name: m.to_string(), - imported_modules: self + known_modules: self .importable_modules .keys() .map(|t| t.to_string()) @@ -1726,7 +1742,7 @@ impl<'a> Environment<'a> { .ok_or_else(|| Error::UnknownModule { location, name: name.to_string(), - imported_modules: self + known_modules: self .importable_modules .keys() .map(|t| t.to_string()) diff --git a/crates/aiken-lang/src/tipo/error.rs b/crates/aiken-lang/src/tipo/error.rs index 6601d380..81ed0519 100644 --- a/crates/aiken-lang/src/tipo/error.rs +++ b/crates/aiken-lang/src/tipo/error.rs @@ -751,13 +751,39 @@ Perhaps, try the following: #[diagnostic(code("unknown::module"))] #[diagnostic(help( "{}", - suggest_neighbor(name, imported_modules.iter(), "Did you forget to add a package as dependency?") + suggest_neighbor(name, known_modules.iter(), "Did you forget to add a package as dependency?") ))] UnknownModule { #[label] location: Span, name: String, - imported_modules: Vec, + known_modules: Vec, + }, + + #[error( + "I couldn't find any module for the environment: '{}'\n", + name.if_supports_color(Stdout, |s| s.purple()) + )] + #[diagnostic(code("unknown::environment"))] + #[diagnostic(help( + "{}{}", + if known_environments.is_empty() { + String::new() + } else { + format!( + "I know about the following environments:\n{}\n\n", + known_environments + .iter() + .map(|s| format!("─▶ {}", s.if_supports_color(Stdout, |s| s.purple()))) + .collect::>() + .join("\n") + ) + }, + suggest_neighbor(name, known_environments.iter(), "Did you forget to define this environment?") + ))] + UnknownEnvironment { + name: String, + known_environments: Vec, }, #[error( @@ -1066,6 +1092,7 @@ impl ExtraData for Error { | Error::UnknownModuleType { .. } | Error::UnknownModuleValue { .. } | Error::UnknownRecordField { .. } + | Error::UnknownEnvironment { .. } | Error::UnnecessarySpreadOperator { .. } | Error::UpdateMultiConstructorType { .. } | Error::ValidatorImported { .. } diff --git a/crates/aiken-lang/src/tipo/expr.rs b/crates/aiken-lang/src/tipo/expr.rs index 9219de88..f6ceb1a1 100644 --- a/crates/aiken-lang/src/tipo/expr.rs +++ b/crates/aiken-lang/src/tipo/expr.rs @@ -956,9 +956,9 @@ impl<'a, 'b> ExprTyper<'a, 'b> { .ok_or_else(|| Error::UnknownModule { name: module_alias.to_string(), location: *module_location, - imported_modules: self + known_modules: self .environment - .imported_modules + .importable_modules .keys() .map(|t| t.to_string()) .collect(), @@ -2327,9 +2327,9 @@ impl<'a, 'b> ExprTyper<'a, 'b> { .ok_or_else(|| Error::UnknownModule { location: *location, name: module_name.to_string(), - imported_modules: self + known_modules: self .environment - .imported_modules + .importable_modules .keys() .map(|t| t.to_string()) .collect(),