From 07122aaa88925c1a9d9db0bc30517e4b2b3c55af Mon Sep 17 00:00:00 2001 From: rvcas Date: Mon, 11 Dec 2023 18:27:08 -0500 Subject: [PATCH] feat: allow importing off validators in validators/tests/* --- crates/aiken-lang/src/tests/check.rs | 19 --------- crates/aiken-lang/src/tipo/environment.rs | 43 ++++++++++++++++++-- crates/aiken-lang/src/tipo/error.rs | 8 ---- crates/aiken-lang/src/tipo/infer.rs | 48 ++--------------------- 4 files changed, 43 insertions(+), 75 deletions(-) diff --git a/crates/aiken-lang/src/tests/check.rs b/crates/aiken-lang/src/tests/check.rs index afffe4ea..1163b02f 100644 --- a/crates/aiken-lang/src/tests/check.rs +++ b/crates/aiken-lang/src/tests/check.rs @@ -66,25 +66,6 @@ fn validator_illegal_return_type() { )) } -#[test] -fn validator_useless_pub() { - let source_code = r#" - type Datum { - thing: Int - } - - validator { - pub fn foo(_d: Datum, _r, _c) { - True - } - } - "#; - - let (warnings, _) = check_validator(parse(source_code)).unwrap(); - - assert!(matches!(warnings[0], Warning::PubInValidatorModule { .. })) -} - #[test] fn validator_illegal_arity() { let source_code = r#" diff --git a/crates/aiken-lang/src/tipo/environment.rs b/crates/aiken-lang/src/tipo/environment.rs index afc7da76..a96715b5 100644 --- a/crates/aiken-lang/src/tipo/environment.rs +++ b/crates/aiken-lang/src/tipo/environment.rs @@ -33,6 +33,7 @@ pub struct Environment<'a> { /// Accessors defined in the current module pub accessors: HashMap, pub current_module: &'a String, + pub current_kind: &'a ModuleKind, /// entity_usages is a stack of scopes. When an entity is created it is /// added to the top scope. When an entity is used we crawl down the scope /// stack for an entity with that name and mark it as used. @@ -244,12 +245,44 @@ impl<'a> Environment<'a> { can_error, }) } + Definition::Validator(Validator { + doc, + end_position, + fun, + other_fun, + location, + params, + }) => { + let Definition::Fn(fun) = + self.generalise_definition(Definition::Fn(fun), module_name) + else { + unreachable!() + }; + + let other_fun = other_fun.map(|other_fun| { + let Definition::Fn(other_fun) = + self.generalise_definition(Definition::Fn(other_fun), module_name) + else { + unreachable!() + }; + + other_fun + }); + + Definition::Validator(Validator { + doc, + end_position, + fun, + other_fun, + location, + params, + }) + } definition @ (Definition::TypeAlias { .. } | Definition::DataType { .. } | Definition::Use { .. } | Definition::Test { .. } - | Definition::Validator { .. } | Definition::ModuleConstant { .. }) => definition, } } @@ -600,6 +633,7 @@ impl<'a> Environment<'a> { pub fn new( id_gen: IdGenerator, current_module: &'a String, + current_kind: &'a ModuleKind, importable_modules: &'a HashMap, warnings: &'a mut Vec, ) -> Self { @@ -622,6 +656,7 @@ impl<'a> Environment<'a> { importable_modules, imported_types: HashSet::new(), current_module, + current_kind, warnings, entity_usages: vec![HashMap::new()], } @@ -677,7 +712,9 @@ impl<'a> Environment<'a> { imported_modules: self.imported_modules.keys().cloned().collect(), })?; - if module_info.kind.is_validator() { + if module_info.kind.is_validator() + && (self.current_kind.is_lib() || !self.current_module.starts_with("tests")) + { return Err(Error::ValidatorImported { location: *location, name, @@ -1086,7 +1123,7 @@ impl<'a> Environment<'a> { &fun.location, )?; - if !fun.public && kind.is_lib() { + if !fun.public { self.init_usage(fun.name.clone(), EntityKind::PrivateFunction, fun.location); } } diff --git a/crates/aiken-lang/src/tipo/error.rs b/crates/aiken-lang/src/tipo/error.rs index 8113298b..8afd2a73 100644 --- a/crates/aiken-lang/src/tipo/error.rs +++ b/crates/aiken-lang/src/tipo/error.rs @@ -1363,13 +1363,6 @@ pub enum Warning { location: Span, }, - #[error("I found a public definition in a validator module.\nDefinitions in validator modules do not need to be public.\n")] - #[diagnostic(code("redundant::pub"))] - PubInValidatorModule { - #[label] - location: Span, - }, - #[error("I found a when expression with a single clause.")] #[diagnostic( code("single_when_clause"), @@ -1607,7 +1600,6 @@ impl ExtraData for Warning { Warning::AllFieldsRecordUpdate { .. } | Warning::ImplicitlyDiscardedResult { .. } | Warning::NoFieldsRecordUpdate { .. } - | Warning::PubInValidatorModule { .. } | Warning::SingleConstructorExpect { .. } | Warning::SingleWhenClause { .. } | Warning::Todo { .. } diff --git a/crates/aiken-lang/src/tipo/infer.rs b/crates/aiken-lang/src/tipo/infer.rs index 82484968..782540ce 100644 --- a/crates/aiken-lang/src/tipo/infer.rs +++ b/crates/aiken-lang/src/tipo/infer.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use crate::{ ast::{ ArgName, DataType, Definition, Function, Layer, ModuleConstant, ModuleKind, - RecordConstructor, RecordConstructorArg, Span, Tracing, TypeAlias, TypedDefinition, + RecordConstructor, RecordConstructorArg, Tracing, TypeAlias, TypedDefinition, TypedFunction, TypedModule, UntypedDefinition, UntypedModule, Use, Validator, }, builtins, @@ -19,8 +19,6 @@ use super::{ TypeInfo, ValueConstructor, ValueConstructorVariant, }; -const PUB_OFFSET: usize = 3; - impl UntypedModule { pub fn infer( mut self, @@ -33,7 +31,7 @@ impl UntypedModule { ) -> Result { let name = self.name.clone(); let docs = std::mem::take(&mut self.docs); - let mut environment = Environment::new(id_gen.clone(), &name, modules, warnings); + let mut environment = Environment::new(id_gen.clone(), &name, &kind, modules, warnings); let mut type_names = HashMap::with_capacity(self.definitions.len()); let mut value_names = HashMap::with_capacity(self.definitions.len()); @@ -82,7 +80,7 @@ impl UntypedModule { for def in consts.into_iter().chain(not_consts) { let definition = - infer_definition(def, &name, &mut hydrators, &mut environment, tracing, kind)?; + infer_definition(def, &name, &mut hydrators, &mut environment, tracing)?; definitions.push(definition); } @@ -148,7 +146,6 @@ fn infer_definition( hydrators: &mut HashMap, environment: &mut Environment<'_>, tracing: Tracing, - kind: ModuleKind, ) -> Result { match def { Definition::Fn(Function { @@ -163,15 +160,6 @@ fn infer_definition( can_error, .. }) => { - if public && kind.is_validator() { - environment.warnings.push(Warning::PubInValidatorModule { - location: Span { - start: location.start, - end: location.start + PUB_OFFSET, - }, - }) - } - let preregistered_fn = environment .get_variable(&name) .expect("Could not find preregistered type for function"); @@ -306,7 +294,6 @@ fn infer_definition( hydrators, environment, tracing, - kind, )? else { unreachable!( @@ -357,7 +344,6 @@ fn infer_definition( hydrators, environment, tracing, - kind, )? else { unreachable!( @@ -419,7 +405,6 @@ fn infer_definition( hydrators, environment, tracing, - kind, )? { environment.unify(f.return_type.clone(), builtins::bool(), f.location, false)?; @@ -438,15 +423,6 @@ fn infer_definition( annotation, .. }) => { - if public && kind.is_validator() { - environment.warnings.push(Warning::PubInValidatorModule { - location: Span { - start: location.start, - end: location.start + PUB_OFFSET, - }, - }) - } - let tipo = environment .get_type_constructor(&None, &alias, location) .expect("Could not find existing type for type alias") @@ -474,15 +450,6 @@ fn infer_definition( constructors: untyped_constructors, .. }) => { - if public && kind.is_validator() { - environment.warnings.push(Warning::PubInValidatorModule { - location: Span { - start: location.start, - end: location.start + PUB_OFFSET, - }, - }) - } - let constructors = untyped_constructors .into_iter() .map( @@ -617,15 +584,6 @@ fn infer_definition( value, .. }) => { - if public && kind.is_validator() { - environment.warnings.push(Warning::PubInValidatorModule { - location: Span { - start: location.start, - end: location.start + PUB_OFFSET, - }, - }) - } - let typed_expr = ExprTyper::new(environment, tracing).infer_const(&annotation, *value)?;