From c66d07a54cdee9c32d99cb56462d99e53c363157 Mon Sep 17 00:00:00 2001 From: rvcas Date: Sun, 15 Jan 2023 12:11:16 -0500 Subject: [PATCH] feat: validator fns no longer need to be public If the function doesn't match a script purpose and is unused then it will till present as a warning. --- crates/aiken-lang/src/lib.rs | 6 +++ crates/aiken-lang/src/tipo/environment.rs | 7 ++-- crates/aiken-lang/src/tipo/error.rs | 6 +++ crates/aiken-lang/src/tipo/infer.rs | 45 +++++++++++++++++++++-- crates/aiken-project/src/lib.rs | 7 +--- crates/aiken-project/src/module.rs | 6 --- 6 files changed, 59 insertions(+), 18 deletions(-) diff --git a/crates/aiken-lang/src/lib.rs b/crates/aiken-lang/src/lib.rs index ccff969e..63826de2 100644 --- a/crates/aiken-lang/src/lib.rs +++ b/crates/aiken-lang/src/lib.rs @@ -30,5 +30,11 @@ impl IdGenerator { } } +pub const SPEND: &str = "spend"; +pub const CERT: &str = "cert"; +pub const MINT: &str = "mint"; +pub const WITHDRAW: &str = "withdraw"; +pub const VALIDATOR_NAMES: [&str; 4] = [SPEND, CERT, MINT, WITHDRAW]; + #[cfg(test)] mod tests; diff --git a/crates/aiken-lang/src/tipo/environment.rs b/crates/aiken-lang/src/tipo/environment.rs index 0680eab3..7b4dba93 100644 --- a/crates/aiken-lang/src/tipo/environment.rs +++ b/crates/aiken-lang/src/tipo/environment.rs @@ -8,13 +8,13 @@ use itertools::Itertools; use crate::{ ast::{ - Annotation, CallArg, DataType, Definition, Function, ModuleConstant, Pattern, + Annotation, CallArg, DataType, Definition, Function, ModuleConstant, ModuleKind, Pattern, RecordConstructor, RecordConstructorArg, Span, TypeAlias, TypedDefinition, UnqualifiedImport, UntypedDefinition, Use, PIPE_VARIABLE, }, builtins::{self, function, generic_var, tuple, unbound_var}, tipo::fields::FieldMap, - IdGenerator, + IdGenerator, VALIDATOR_NAMES, }; use super::{ @@ -993,6 +993,7 @@ impl<'a> Environment<'a> { module_name: &String, hydrators: &mut HashMap, names: &mut HashMap<&'a str, &'a Span>, + kind: ModuleKind, ) -> Result<(), Error> { match def { Definition::Fn(Function { @@ -1051,7 +1052,7 @@ impl<'a> Environment<'a> { tipo, ); - if !public { + if !public && (kind.is_lib() || !VALIDATOR_NAMES.contains(&name.as_str())) { self.init_usage(name.clone(), EntityKind::PrivateFunction, *location); } } diff --git a/crates/aiken-lang/src/tipo/error.rs b/crates/aiken-lang/src/tipo/error.rs index 50e8fb96..5473be14 100644 --- a/crates/aiken-lang/src/tipo/error.rs +++ b/crates/aiken-lang/src/tipo/error.rs @@ -1389,6 +1389,12 @@ 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")] + PubInValidatorModule { + #[label] + location: Span, + }, + #[error("I found a record update with no fields; effectively updating nothing.\n")] #[diagnostic(url("https://aiken-lang.org/language-tour/custom-types#record-updates"))] NoFieldsRecordUpdate { diff --git a/crates/aiken-lang/src/tipo/infer.rs b/crates/aiken-lang/src/tipo/infer.rs index 4cce3df4..88af0cf5 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::{ DataType, Definition, Function, Layer, ModuleConstant, ModuleKind, RecordConstructor, - RecordConstructorArg, TypeAlias, TypedDefinition, TypedModule, UntypedDefinition, + RecordConstructorArg, Span, TypeAlias, TypedDefinition, TypedModule, UntypedDefinition, UntypedModule, Use, }, builtins, @@ -57,7 +57,7 @@ impl UntypedModule { // Register values so they can be used in functions earlier in the module. for def in self.definitions() { - environment.register_values(def, &name, &mut hydrators, &mut value_names)?; + environment.register_values(def, &name, &mut hydrators, &mut value_names, kind)?; } // Infer the types of each definition in the module @@ -79,7 +79,7 @@ impl UntypedModule { } for def in consts.into_iter().chain(not_consts) { - let definition = infer_definition(def, &name, &mut hydrators, &mut environment)?; + let definition = infer_definition(def, &name, &mut hydrators, &mut environment, kind)?; definitions.push(definition); } @@ -145,6 +145,7 @@ fn infer_definition( module_name: &String, hydrators: &mut HashMap, environment: &mut Environment<'_>, + kind: ModuleKind, ) -> Result { match def { Definition::Fn(Function { @@ -158,6 +159,15 @@ fn infer_definition( end_position, .. }) => { + if public && kind.is_validator() { + environment.warnings.push(Warning::PubInValidatorModule { + location: Span { + start: location.start, + end: location.start + 3, + }, + }) + } + let preregistered_fn = environment .get_variable(&name) .expect("Could not find preregistered type for function"); @@ -239,7 +249,7 @@ fn infer_definition( Definition::Test(f) => { if let Definition::Fn(f) = - infer_definition(Definition::Fn(f), module_name, hydrators, environment)? + infer_definition(Definition::Fn(f), module_name, hydrators, environment, kind)? { environment.unify(f.return_type.clone(), builtins::bool(), f.location)?; Ok(Definition::Test(f)) @@ -257,6 +267,15 @@ fn infer_definition( annotation, .. }) => { + if public && kind.is_validator() { + environment.warnings.push(Warning::PubInValidatorModule { + location: Span { + start: location.start, + end: location.start + 3, + }, + }) + } + let tipo = environment .get_type_constructor(&None, &alias, location) .expect("Could not find existing type for type alias") @@ -284,6 +303,15 @@ fn infer_definition( constructors: untyped_constructors, .. }) => { + if public && kind.is_validator() { + environment.warnings.push(Warning::PubInValidatorModule { + location: Span { + start: location.start, + end: location.start + 3, + }, + }) + } + let constructors = untyped_constructors .into_iter() .map( @@ -417,6 +445,15 @@ fn infer_definition( value, .. }) => { + if public && kind.is_validator() { + environment.warnings.push(Warning::PubInValidatorModule { + location: Span { + start: location.start, + end: location.start + 3, + }, + }) + } + let typed_expr = ExprTyper::new(environment).infer_const(&annotation, *value)?; let tipo = typed_expr.tipo(); diff --git a/crates/aiken-project/src/lib.rs b/crates/aiken-project/src/lib.rs index 5035a261..009f47ad 100644 --- a/crates/aiken-project/src/lib.rs +++ b/crates/aiken-project/src/lib.rs @@ -17,7 +17,7 @@ use aiken_lang::{ builtins::{self, generic_var}, tipo::TypeInfo, uplc::CodeGenerator, - IdGenerator, + IdGenerator, CERT, MINT, SPEND, VALIDATOR_NAMES, WITHDRAW, }; use deps::UseManifest; use miette::NamedSource; @@ -44,10 +44,7 @@ use uplc::{ use crate::{ config::Config, error::{Error, Warning}, - module::{ - CheckedModule, CheckedModules, ParsedModule, ParsedModules, CERT, MINT, SPEND, - VALIDATOR_NAMES, WITHDRAW, - }, + module::{CheckedModule, CheckedModules, ParsedModule, ParsedModules}, telemetry::Event, }; diff --git a/crates/aiken-project/src/module.rs b/crates/aiken-project/src/module.rs index 5d8658fc..7c440e5e 100644 --- a/crates/aiken-project/src/module.rs +++ b/crates/aiken-project/src/module.rs @@ -207,12 +207,6 @@ fn find_cycle( false } -pub const SPEND: &str = "spend"; -pub const CERT: &str = "cert"; -pub const MINT: &str = "mint"; -pub const WITHDRAW: &str = "withdraw"; -pub const VALIDATOR_NAMES: [&str; 4] = [SPEND, CERT, MINT, WITHDRAW]; - #[derive(Debug, Clone)] pub struct CheckedModule { pub name: String,