mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-17 23:02:47 +03:00
Add compiler flags for configuring await checker in nested conditionals
This commit is contained in:
parent
5a499937e6
commit
cfee45da8f
@ -14,14 +14,35 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{Annotation, CompositeType, External, Function, FunctionInput, FunctionOutput, Identifier, Input, Mode, Node, NodeID, Output, ProgramId, TupleType, Type, Variant, FutureType};
|
||||
use crate::{
|
||||
Annotation,
|
||||
CompositeType,
|
||||
External,
|
||||
Function,
|
||||
FunctionInput,
|
||||
FunctionOutput,
|
||||
FutureType,
|
||||
Identifier,
|
||||
Input,
|
||||
Mode,
|
||||
Node,
|
||||
NodeID,
|
||||
Output,
|
||||
ProgramId,
|
||||
TupleType,
|
||||
Type,
|
||||
Variant,
|
||||
};
|
||||
use leo_span::{sym, Span, Symbol};
|
||||
|
||||
use crate::Type::Composite;
|
||||
use itertools::Itertools;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use snarkvm::{
|
||||
console::program::{RegisterType::{ExternalRecord, Future, Plaintext, Record}, FinalizeType::{Future as FutureFinalizeType, Plaintext as PlaintextFinalizeType}},
|
||||
console::program::{
|
||||
FinalizeType::{Future as FutureFinalizeType, Plaintext as PlaintextFinalizeType},
|
||||
RegisterType::{ExternalRecord, Future, Plaintext, Record},
|
||||
},
|
||||
prelude::{Network, ValueType},
|
||||
synthesizer::program::{ClosureCore, CommandTrait, FunctionCore, InstructionTrait},
|
||||
};
|
||||
@ -246,26 +267,32 @@ impl FunctionStub {
|
||||
is_async: true,
|
||||
variant: Variant::Transition,
|
||||
identifier: Identifier::new(name, Default::default()),
|
||||
input: function.finalize_logic().unwrap().inputs().iter().enumerate().map(|(index, input)| {
|
||||
Input::Internal(FunctionInput {
|
||||
identifier: Identifier::new(Symbol::intern(&format!("a{}", index + 1)), Default::default()),
|
||||
mode: Mode::Public,
|
||||
type_: match input.finalize_type() {
|
||||
PlaintextFinalizeType(val) => Type::from_snarkvm(&val, name),
|
||||
FutureFinalizeType(_) => Type::Future(Default::default()),
|
||||
},
|
||||
span: Default::default(),
|
||||
id: Default::default(),
|
||||
input: function
|
||||
.finalize_logic()
|
||||
.unwrap()
|
||||
.inputs()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, input)| {
|
||||
Input::Internal(FunctionInput {
|
||||
identifier: Identifier::new(Symbol::intern(&format!("a{}", index + 1)), Default::default()),
|
||||
mode: Mode::Public,
|
||||
type_: match input.finalize_type() {
|
||||
PlaintextFinalizeType(val) => Type::from_snarkvm(&val, name),
|
||||
FutureFinalizeType(_) => Type::Future(Default::default()),
|
||||
},
|
||||
span: Default::default(),
|
||||
id: Default::default(),
|
||||
})
|
||||
})
|
||||
}).collect_vec(),
|
||||
.collect_vec(),
|
||||
output: vec![Output::Internal(FunctionOutput {
|
||||
mode: Mode::Public,
|
||||
type_: Type::Future(FutureType { inputs: None} ),
|
||||
type_: Type::Future(FutureType { inputs: None }),
|
||||
span: Default::default(),
|
||||
id: 0,
|
||||
})
|
||||
],
|
||||
output_type: Type::Future(FutureType { inputs: None}),
|
||||
})],
|
||||
output_type: Type::Future(FutureType { inputs: None }),
|
||||
span: Default::default(),
|
||||
id: 0,
|
||||
}
|
||||
|
@ -16,8 +16,6 @@
|
||||
|
||||
//! A stub contains function templates as well as definitions for mappings, structs, records, and constants.
|
||||
|
||||
pub mod finalize_stub;
|
||||
pub use finalize_stub::*;
|
||||
pub mod function_stub;
|
||||
pub use function_stub::*;
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{common, ArrayType, CompositeType, Identifier, IntegerType, MappingType, TupleType, FutureType};
|
||||
use crate::{common, ArrayType, CompositeType, FutureType, Identifier, IntegerType, MappingType, TupleType};
|
||||
|
||||
use itertools::Itertools;
|
||||
use leo_span::Symbol;
|
||||
@ -98,9 +98,9 @@ impl Type {
|
||||
}
|
||||
(Type::Future(left), Type::Future(right)) if left.inputs.len() == right.inputs.len() => left
|
||||
.inputs()
|
||||
.iter()
|
||||
.zip_eq(right.inputs().iter())
|
||||
.all(|(left_type, right_type)| left_type.eq_flat(right_type)),
|
||||
.iter()
|
||||
.zip_eq(right.inputs().iter())
|
||||
.all(|(left_type, right_type)| left_type.eq_flat(right_type)),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -149,8 +149,14 @@ impl<'a> Compiler<'a> {
|
||||
|
||||
/// Runs the type checker pass.
|
||||
pub fn type_checker_pass(&'a self, symbol_table: SymbolTable) -> Result<(SymbolTable, StructGraph, CallGraph)> {
|
||||
let (symbol_table, struct_graph, call_graph) =
|
||||
TypeChecker::do_pass((&self.ast, self.handler, symbol_table, &self.type_table))?;
|
||||
let (symbol_table, struct_graph, call_graph) = TypeChecker::do_pass((
|
||||
&self.ast,
|
||||
self.handler,
|
||||
symbol_table,
|
||||
&self.type_table,
|
||||
self.compiler_options.build.conditional_block_max_depth,
|
||||
self.compiler_options.build.disable_conditional_branch_type_checking,
|
||||
))?;
|
||||
if self.compiler_options.output.type_checked_symbol_table {
|
||||
self.write_symbol_table_to_json("type_checked_symbol_table.json", &symbol_table)?;
|
||||
}
|
||||
|
@ -28,6 +28,10 @@ pub struct CompilerOptions {
|
||||
pub struct BuildOptions {
|
||||
/// Whether to enable dead code elimination.
|
||||
pub dce_enabled: bool,
|
||||
/// Max depth to type check nested conditionals.
|
||||
pub conditional_block_max_depth: usize,
|
||||
/// Whether to disable type checking for nested conditionals.
|
||||
pub disable_conditional_branch_type_checking: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
|
40
errors/src/errors/type_checker/type_checker_warning.rs
Normal file
40
errors/src/errors/type_checker/type_checker_warning.rs
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright (C) 2019-2023 Aleo Systems Inc.
|
||||
// This file is part of the Leo library.
|
||||
|
||||
// The Leo library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// The Leo library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::create_messages;
|
||||
|
||||
use std::fmt::Display;
|
||||
|
||||
create_messages!(
|
||||
/// ParserWarning enum that represents all the warnings for the `leo-parser` crate.
|
||||
TypeCheckerWarning,
|
||||
code_mask: 2000i32,
|
||||
code_prefix: "TYC",
|
||||
|
||||
@formatted
|
||||
some_paths_do_not_await_all_futures {
|
||||
args: (num_total_paths: impl Display, num_unawaited_paths: impl Display),
|
||||
msg: format!("Not all paths through the function await all futures. {num_unawaited_paths}/{num_total_paths} paths contain at least one future that is never awaited."),
|
||||
help: Some("Ex: `f.await()` to await a future. Remove this warning by including the `--disable-conditional-branch-type-checking` flag.".to_string()),
|
||||
}
|
||||
|
||||
@formatted
|
||||
some_paths_contain_duplicate_future_awaits {
|
||||
args: (num_total_paths: impl Display, num_duplicate_await_paths: impl Display),
|
||||
msg: format!("Some paths through the function contain duplicate future awaits. {num_duplicate_await_paths}/{num_total_paths} paths contain at least one future that is awaited more than once."),
|
||||
help: Some("Look at the times `.await()` is called, and try to reduce redundancies. Remove this warning by including the `--disable-conditional-branch-type-checking` flag.".to_string()),
|
||||
}
|
||||
);
|
@ -39,7 +39,11 @@ type CurrentNetwork = Testnet3;
|
||||
impl From<BuildOptions> for CompilerOptions {
|
||||
fn from(options: BuildOptions) -> Self {
|
||||
let mut out_options = Self {
|
||||
build: leo_compiler::BuildOptions { dce_enabled: options.enable_dce },
|
||||
build: leo_compiler::BuildOptions {
|
||||
dce_enabled: options.enable_dce,
|
||||
conditional_block_max_depth: options.conditional_block_max_depth,
|
||||
disable_conditional_branch_type_checking: options.disable_conditional_branch_type_checking,
|
||||
},
|
||||
output: OutputOptions {
|
||||
symbol_table_spans_enabled: options.enable_symbol_table_spans,
|
||||
initial_symbol_table: options.enable_initial_symbol_table_snapshot,
|
||||
|
@ -160,4 +160,8 @@ pub struct BuildOptions {
|
||||
pub enable_inlined_ast_snapshot: bool,
|
||||
#[clap(long, help = "Writes AST snapshot of the dead code eliminated (DCE) AST.")]
|
||||
pub enable_dce_ast_snapshot: bool,
|
||||
#[clap(long, help = "Max depth to type check nested conditionals.", default_value = "10")]
|
||||
pub conditional_block_max_depth: usize,
|
||||
#[clap(long, help = "Disable type checking of nested conditional branches in finalize scope.")]
|
||||
pub disable_conditional_branch_type_checking: bool,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user