mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-18 07:11:53 +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
|
// 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/>.
|
// 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 leo_span::{sym, Span, Symbol};
|
||||||
|
|
||||||
use crate::Type::Composite;
|
use crate::Type::Composite;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use snarkvm::{
|
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},
|
prelude::{Network, ValueType},
|
||||||
synthesizer::program::{ClosureCore, CommandTrait, FunctionCore, InstructionTrait},
|
synthesizer::program::{ClosureCore, CommandTrait, FunctionCore, InstructionTrait},
|
||||||
};
|
};
|
||||||
@ -246,26 +267,32 @@ impl FunctionStub {
|
|||||||
is_async: true,
|
is_async: true,
|
||||||
variant: Variant::Transition,
|
variant: Variant::Transition,
|
||||||
identifier: Identifier::new(name, Default::default()),
|
identifier: Identifier::new(name, Default::default()),
|
||||||
input: function.finalize_logic().unwrap().inputs().iter().enumerate().map(|(index, input)| {
|
input: function
|
||||||
Input::Internal(FunctionInput {
|
.finalize_logic()
|
||||||
identifier: Identifier::new(Symbol::intern(&format!("a{}", index + 1)), Default::default()),
|
.unwrap()
|
||||||
mode: Mode::Public,
|
.inputs()
|
||||||
type_: match input.finalize_type() {
|
.iter()
|
||||||
PlaintextFinalizeType(val) => Type::from_snarkvm(&val, name),
|
.enumerate()
|
||||||
FutureFinalizeType(_) => Type::Future(Default::default()),
|
.map(|(index, input)| {
|
||||||
},
|
Input::Internal(FunctionInput {
|
||||||
span: Default::default(),
|
identifier: Identifier::new(Symbol::intern(&format!("a{}", index + 1)), Default::default()),
|
||||||
id: 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 {
|
output: vec![Output::Internal(FunctionOutput {
|
||||||
mode: Mode::Public,
|
mode: Mode::Public,
|
||||||
type_: Type::Future(FutureType { inputs: None} ),
|
type_: Type::Future(FutureType { inputs: None }),
|
||||||
span: Default::default(),
|
span: Default::default(),
|
||||||
id: 0,
|
id: 0,
|
||||||
})
|
})],
|
||||||
],
|
output_type: Type::Future(FutureType { inputs: None }),
|
||||||
output_type: Type::Future(FutureType { inputs: None}),
|
|
||||||
span: Default::default(),
|
span: Default::default(),
|
||||||
id: 0,
|
id: 0,
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
//! A stub contains function templates as well as definitions for mappings, structs, records, and constants.
|
//! 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 mod function_stub;
|
||||||
pub use function_stub::*;
|
pub use function_stub::*;
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// 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/>.
|
// 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 itertools::Itertools;
|
||||||
use leo_span::Symbol;
|
use leo_span::Symbol;
|
||||||
@ -98,9 +98,9 @@ impl Type {
|
|||||||
}
|
}
|
||||||
(Type::Future(left), Type::Future(right)) if left.inputs.len() == right.inputs.len() => left
|
(Type::Future(left), Type::Future(right)) if left.inputs.len() == right.inputs.len() => left
|
||||||
.inputs()
|
.inputs()
|
||||||
.iter()
|
.iter()
|
||||||
.zip_eq(right.inputs().iter())
|
.zip_eq(right.inputs().iter())
|
||||||
.all(|(left_type, right_type)| left_type.eq_flat(right_type)),
|
.all(|(left_type, right_type)| left_type.eq_flat(right_type)),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,8 +149,14 @@ impl<'a> Compiler<'a> {
|
|||||||
|
|
||||||
/// Runs the type checker pass.
|
/// Runs the type checker pass.
|
||||||
pub fn type_checker_pass(&'a self, symbol_table: SymbolTable) -> Result<(SymbolTable, StructGraph, CallGraph)> {
|
pub fn type_checker_pass(&'a self, symbol_table: SymbolTable) -> Result<(SymbolTable, StructGraph, CallGraph)> {
|
||||||
let (symbol_table, struct_graph, call_graph) =
|
let (symbol_table, struct_graph, call_graph) = TypeChecker::do_pass((
|
||||||
TypeChecker::do_pass((&self.ast, self.handler, symbol_table, &self.type_table))?;
|
&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 {
|
if self.compiler_options.output.type_checked_symbol_table {
|
||||||
self.write_symbol_table_to_json("type_checked_symbol_table.json", &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 {
|
pub struct BuildOptions {
|
||||||
/// Whether to enable dead code elimination.
|
/// Whether to enable dead code elimination.
|
||||||
pub dce_enabled: bool,
|
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)]
|
#[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 {
|
impl From<BuildOptions> for CompilerOptions {
|
||||||
fn from(options: BuildOptions) -> Self {
|
fn from(options: BuildOptions) -> Self {
|
||||||
let mut out_options = 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 {
|
output: OutputOptions {
|
||||||
symbol_table_spans_enabled: options.enable_symbol_table_spans,
|
symbol_table_spans_enabled: options.enable_symbol_table_spans,
|
||||||
initial_symbol_table: options.enable_initial_symbol_table_snapshot,
|
initial_symbol_table: options.enable_initial_symbol_table_snapshot,
|
||||||
|
@ -160,4 +160,8 @@ pub struct BuildOptions {
|
|||||||
pub enable_inlined_ast_snapshot: bool,
|
pub enable_inlined_ast_snapshot: bool,
|
||||||
#[clap(long, help = "Writes AST snapshot of the dead code eliminated (DCE) AST.")]
|
#[clap(long, help = "Writes AST snapshot of the dead code eliminated (DCE) AST.")]
|
||||||
pub enable_dce_ast_snapshot: bool,
|
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