From cad69d46f008e96909282921ce79fca6d2fe9b5a Mon Sep 17 00:00:00 2001 From: Oleksandr Zarudnyi Date: Wed, 4 Dec 2024 23:34:58 +0800 Subject: [PATCH] docs: remaining CLI endpoints (#219) --- docs/src/02-command-line-interface.md | 317 +++++++++++++++++- docs/src/04-combined-json.md | 21 +- docs/src/05-linker.md | 6 +- docs/src/guides/01-sanitizers.md | 6 +- era-compiler-solidity/src/build_eravm/mod.rs | 19 +- era-compiler-solidity/src/build_evm/mod.rs | 23 +- era-compiler-solidity/src/zksolc/arguments.rs | 47 +-- era-compiler-solidity/src/zksolc/main.rs | 12 + era-compiler-solidity/tests/cli/llvm_ir.rs | 14 + era-compiler-solidity/tests/common/const.rs | 4 + .../data/contracts/llvm_ir/LinkerError.ll | 6 + .../standard_json/output/error/collectable.rs | 26 +- era-solc/src/standard_json/output/mod.rs | 16 +- 13 files changed, 414 insertions(+), 103 deletions(-) create mode 100644 era-compiler-solidity/tests/data/contracts/llvm_ir/LinkerError.ll diff --git a/docs/src/02-command-line-interface.md b/docs/src/02-command-line-interface.md index 883ba416..0edf31b8 100644 --- a/docs/src/02-command-line-interface.md +++ b/docs/src/02-command-line-interface.md @@ -89,6 +89,26 @@ Visit [the *solc* documentation](https://docs.soliditylang.org/en/latest/using-t +### `--libraries` + +Specifies the libraries to link with compiled contracts. The option accepts multiple string arguments. The safest way is to wrap each argument in single quotes, and separate them with a space. + +The specifier has the following format: `:=`. + +Usage: + +```bash +zksolc './Simple.sol' --bin --libraries 'Simple.sol:Test=0x1234567890abcdef1234567890abcdef12345678' +``` + +There are two ways of linking libraries: +1. At compile time, immediately after the contract is compiled. +2. At deploy time (a.k.a. post-compile time), right before the contract is deployed. + +The use case above describes linking at compile time. For linking at deploy time, see the [linker documentation](./05-linker.md). + + + ### `--base-path`, `--include-path`, `--allow-paths` These options are used to specify Solidity import resolution settings. They are not used by *zksolc* and only passed through to *solc* like import remappings. @@ -97,7 +117,6 @@ Visit [the *solc* documentation](https://docs.soliditylang.org/en/latest/path-re - ### `--asm` Enables the output of contract assembly. The assembly format depends on the [*--target*](#--target) architecture the contract is compiled for. @@ -152,7 +171,87 @@ Output: ```text ======= Simple.sol:Simple ======= Metadata: -{"llvm_options":[],"optimizer_settings":{"is_debug_logging_enabled":false,"is_fallback_to_size_enabled":false,"is_verify_each_enabled":false,"level_back_end":"Aggressive","level_middle_end":"Aggressive","level_middle_end_size":"Zero"},"solc_version":"","solc_zkvm_edition":null,"source_metadata":{...},"zk_version":""} +{"llvm_options":[],"optimizer_settings":{"is_debug_logging_enabled":false,"is_fallback_to_size_enabled":false,"is_verify_each_enabled":false,"level_back_end":"Aggressive","level_middle_end":"Aggressive","level_middle_end_size":"Zero"},"solc_version":"x.y.z","solc_zkvm_edition":null,"source_metadata":{...},"zk_version":"x.y.z"} +``` + + + +### `--output-dir` + +Specifies the output directory for build artifacts. Can only be used with [basic CLI](#basic-cli) and [combined JSON](./04-combined-json.md) modes. + +Usage in basic CLI mode: + +```bash +zksolc './Simple.sol' --bin --asm --metadata --output-dir './build/' +ls './build/Simple.sol' +``` + +Output: + +```text +Compiler run successful. Artifact(s) can be found in directory "build". +... +Test.zasm Test.zbin Test_meta.json +``` + +Usage in combined JSON mode: + +```bash +zksolc './Simple.sol' --combined-json 'bin,asm,metadata' --output-dir './build/' +ls './build/' +``` + +Output: + +```text +Compiler run successful. Artifact(s) can be found in directory "build". +... +combined.json +``` + + + +### `--overwrite` + +Overwrites the output files if they already exist in the output directory. By default, *zksolc* does not overwrite existing files. + +Can only be used in combination with the [`--output-dir`](#--output-dir) option. + +Usage: + +```bash +zksolc './Simple.sol' --combined-json 'bin,asm,metadata' --output-dir './build/' --overwrite +``` + +If the `--overwrite` option is not specified and the output files already exist, *zksolc* will print an error message and exit: + +```text +Error: Refusing to overwrite an existing file "build/combined.json" (use --overwrite to force). +``` + + + +### `--version` + +Prints the version of *zksolc* and the hash of the LLVM commit it was built with. + +Usage: + +```bash +zksolc --version +``` + + + +### `--help` + +Prints the help message. + +Usage: + +```bash +zksolc --help ``` @@ -177,6 +276,90 @@ For the combined JSON mode usage, see the [Combined JSON](./04-combined-json.md) +### `--optimization / -O` + +Sets the optimization level of the LLVM optimizer. Available values are: + +| Level | Meaning | Hints | +|:-----:|:----------------------------:|:------------------------------------------------:| +| 0 | No optimization | Best compilation speed: for active development +| 1 | Performance: basic | For optimization research +| 2 | Performance: default | For optimization research +| 3 | Performance: aggressive | Default value. Best performance: for production +| s | Size: default | For optimization research +| z | Size: aggressive | Best size: for contracts with size constraints + +For most cases, it is fine to use the default value of `3`. You should only use the level `z` if you are ready to deliberately sacrifice performance and optimize for size. + +> Large contracts may hit the EraVM or EVM bytecode size limit. In this case, it is recommended to use the [`--fallback-Oz`](#--fallback-oz) option rather than set the `z` level. + + + +### `--fallback-Oz` + +Sets the optimization level to `z` for contracts that failed to compile due to overrunning the bytecode size constraints. + +Under the hood, this option automatically triggers recompilation of contracts with level `z`. Contracts that were successfully compiled with [the original `--optimization` setting](#--optimization---o) are not recompiled. + +> It is recommended to have this option always enabled to prevent compilation failures due to bytecode size constraints. There are no known downsides to using this option. + + + +### `--enable-eravm-extensions` + +Enables the EraVM extensions. + +If this flag is set, calls to addresses `0xFFFF` and below are substituted by special EraVM instructions. + +In the Yul mode, the `verbatim_*` instruction family becomes available. + +The full list of EraVM extensions will be documented soon. + +Usage: + +```bash +zksolc './Simple.sol' --bin --enable-eravm-extensions +``` + + + +### `--llvm-options` + +Specifies additional options for the LLVM framework. The argument must be a single quoted string following a `=` separator. + +Usage: + +```bash +zksolc './Simple.sol' --bin --llvm-options='-eravm-jump-table-density-threshold=10' +``` + +> The `--llvm-options` option is experimental and must only be used by experienced users. All supported options will be documented in the future. + + + +### `--codegen` + +Specifies the *solc* codegen. The following values are allowed: + +| Value | Description | Hints | +|:-----:|:----------------------------:|:----------------------------------:| +| evmla | EVM legacy assembly | *solc* default for EVM/L1 | +| yul | Yul a.k.a. IR | *zksolc* default for ZKsync | + +> *solc* uses the `evmla` codegen by default. However, *zksolc* uses the `yul` codegen by default for historical reasons. +> Codegens are not equivalent and may lead to different behavior in production. +> Make sure that this option is set to `evmla` if you want your contracts to behave as they would on L1. +> For codegen differences, visit the [solc IR breaking changes page](https://docs.soliditylang.org/en/latest/ir-breaking-changes.html). +> *zksolc* is going to switch to the `evmla` codegen by default in the future in order to have more parity with L1. + +Usage: + +```bash +zksolc './Simple.sol' --bin --codegen 'evmla' +``` + + + ### `--evm-version` Specifies the EVM version *solc* will produce artifacts for. Only artifacts such as Yul and EVM assembly are known to be affected by this option. For instance, if the EVM version is set to *cancun*, then Yul and EVM assembly may contain `MCOPY` instructions. @@ -248,6 +431,34 @@ zksolc './Simple.sol' --bin --metadata-literal +### `--suppress-errors` + +Tells the compiler to suppress specified errors. The option accepts multiple string arguments, so make sure they are properly separated by whitespace. + +Only one error can be suppressed with this option: [`sendtransfer`](https://docs.zksync.io/build/developer-reference/best-practices#use-call-over-send-or-transfer). + +Usage: + +```bash +zksolc './Simple.sol' --bin --suppress-errors 'sendtransfer' +``` + + + +### `--suppress-warnings` + +Tells the compiler to suppress specified warnings. The option accepts multiple string arguments, so make sure they are properly separated by whitespace. + +Only one warning can be suppressed with this option: [`txorigin`](https://docs.zksync.io/build/tooling/foundry/migration-guide/testing#origin-address). + +Usage: + +```bash +zksolc './Simple.sol' --bin --suppress-warnings 'txorigin' +``` + + + ## Multi-Language Support *zksolc* supports input in multiple programming languages: @@ -335,6 +546,37 @@ Binary: +## Multi-Target Support + +*zksolc* is an LLVM-based compiler toolchain, so it is easily extensible to support multiple target architectures. The following targets are supported: + +- `eravm` — [EraVM](https://docs.zksync.io/zk-stack/components/zksync-evm) (default). +- `evm` — [EVM](https://ethereum.org/en/developers/docs/evm/) (under development and only available for testing). + +### `--target` + +Specifies the target architecture for the compiled contract. + +
+The --target option is experimental and must be passed as a CLI argument in all modes including combined JSON and standard JSON. +
+ +Usage: + +```bash +zksolc Simple.sol --bin --target evm +``` + +Output: + +```text +======= Simple.sol:Simple ======= +Binary: +0000008003000039000000400030043f0000000100200190000000130000c13d... +``` + + + ## Integrated Tooling *zksolc* includes several tools provided by the LLVM framework out of the box, such as disassembler and linker. The following sections describe the usage of these tools. @@ -391,39 +633,78 @@ File `input.zbin` disassembly: -## Multi-Target Support +### `--link` -*zksolc* is an LLVM-based compiler toolchain, so it is easily extensible to support multiple target architectures. The following targets are supported: +Enables the linker mode. -- `eravm` — [EraVM](https://docs.zksync.io/zk-stack/components/zksync-evm) (default). -- `evm` — [EVM](https://ethereum.org/en/developers/docs/evm/) (under development and only available for testing). +For the linker usage, visit [the linker documentation](./05-linker.md). -### `--target` -Specifies the target architecture for the compiled contract. -
-The --target option is experimental and must be passed as a CLI argument in all modes including combined JSON and standard JSON. -
+## Debugging + + + +### `--debug-output-dir` + +Specifies the directory to store intermediate build artifacts. The artifacts can be useful for debugging and research. + +The directory is created if it does not exist. If artifacts are already present in the directory, they are overwritten. + +The intermediate build artifacts can be: + +| Name | Codegen | File extension | +|:---------------:|:---------------:|:----------------:| +| EVM assembly | evmla | *evmla* | +| EthIR | evmla | *ethir* | +| Yul | yul | *yul* | +| LLVM IR | evmla, yul | *ll* | +| EraVM assembly | evmla, yul | *zasm* | Usage: ```bash -zksolc Simple.sol --bin --target evm +zksolc './Simple.sol' --bin --debug-output-dir './debug/' +ls './debug/' ``` Output: ```text -======= Simple.sol:Simple ======= -Binary: -0000008003000039000000400030043f0000000100200190000000130000c13d... +Compiler run successful. No output requested. Use flags --metadata, --asm, --bin. +... +Simple.sol.C.runtime.optimized.ll +Simple.sol.C.runtime.unoptimized.ll +Simple.sol.C.yul +Simple.sol.C.zasm +Simple.sol.Test.runtime.optimized.ll +Simple.sol.Test.runtime.unoptimized.ll +Simple.sol.Test.yul +Simple.sol.Test.zasm ``` +The output file name is constructed as follows: `...`. -### `--link` -Enables the linker mode. +### `--llvm-verify-each` + +Enables the verification of the LLVM IR after each optimization pass. This option is useful for debugging and research purposes. -For the linker usage, visit [the linker documentation](./05-linker.md). \ No newline at end of file +Usage: + +```bash +zksolc './Simple.sol' --bin --llvm-verify-each +``` + + + +### `--llvm-debug-logging` + +Enables the debug logging of the LLVM IR optimization passes. This option is useful for debugging and research purposes. + +Usage: + +```bash +zksolc './Simple.sol' --bin --llvm-debug-logging +``` \ No newline at end of file diff --git a/docs/src/04-combined-json.md b/docs/src/04-combined-json.md index 8d6ac475..a8bf5187 100644 --- a/docs/src/04-combined-json.md +++ b/docs/src/04-combined-json.md @@ -9,20 +9,21 @@ Combined JSON is an I/O mode designed to provide a middle-ground experience betw To use combined JSON, pass the `--combined-json` flag to *zksolc* with the desired comma-separated output selectors: ```shell -zksolc './MyContract.sol' --combined-json ast,abi,metadata +zksolc './MyContract.sol' --combined-json 'ast,abi,metadata' ``` The following selectors are supported: -| Selector | Description | Type | -|:-----------------------:|:-------------------------------------------:|:-------------------------:| -| **ast** | AST of the source file | JSON | -| **abi** | Solidity ABI | JSON | -| **hashes** | Solidity function hashes | JSON | -| **storage-layout** | Solidity storage layout | JSON | -| **metadata** | Metadata | Stringified JSON | -| **devdoc** | Developer documentation | JSON (NatSpec) | -| **userdoc** | User documentation | JSON (NatSpec) | +| Selector | Description | Type | +|:-----------------------------:|:------------------------------------------:|:-------------------------:| +| **ast** | AST of the source file | JSON | +| **abi** | Solidity ABI | JSON | +| **hashes** | Solidity function hashes | JSON | +| **storage-layout** | Solidity storage layout | JSON | +| **transient-storage-layout** | Solidity transientstorage layout | JSON | +| **metadata** | Metadata | Stringified JSON | +| **devdoc** | Developer documentation | JSON (NatSpec) | +| **userdoc** | User documentation | JSON (NatSpec) |
It is only possible to use Combined JSON with Solidity input, so the path to solc must be always provided to *zksolc*. diff --git a/docs/src/05-linker.md b/docs/src/05-linker.md index ad27f581..f68474b3 100644 --- a/docs/src/05-linker.md +++ b/docs/src/05-linker.md @@ -4,13 +4,15 @@ For unlinked bytecode, the ZKsync compiler toolchain uses [an ELF wrapper](https://en.wikipedia.org/wiki/Executable_and_Linkable_Format), which is the standard in the LLVM framework. ELF-wrapped bytecode cannot be deployed to the blockchain as-is; all library references must first be resolved. Once they are resolved, the ELF wrapper is stripped, leaving only the raw bytecode ready for deployment. This approach also results in unlinked and linked bytecode differing in size. -> When compiling to EraVM, provide all build artifacts to the linker. Unlike EVM ones, EraVM dependencies are linked using the bytecode hash, so if you simply provide all the bytecode files of your project, the linker will automatically resolve all dependencies. +> When compiling to EraVM, provide all build artifacts to the linker. Unlike EVM ones, EraVM dependencies are linked using the bytecode hash, so the linker must be able to derive the bytecode hash of all contracts in order to automatically resolve all dependencies. The *zksolc* linker can be used in several ways: - [JSON Protocol](#json-protocol) - [Basic CLI](#basic-cli) + + ## JSON Protocol This mode is suitable for integration with tooling such as Foundry. The linker features its own JSON protocol with input and output formats which are described in [input](#input) and [output](#output) sections below. @@ -78,6 +80,8 @@ cat './input.json' | zksolc --link --standard-json } ``` + + ## Basic CLI This mode is suitable for experiments and quick checks. Linking is done in several steps: diff --git a/docs/src/guides/01-sanitizers.md b/docs/src/guides/01-sanitizers.md index 861cdad7..042b8aa3 100644 --- a/docs/src/guides/01-sanitizers.md +++ b/docs/src/guides/01-sanitizers.md @@ -29,8 +29,8 @@ You can check the LLVM version used by `rustc` by running the following command ## Build steps The general steps to have a sanitizer enabled build include: -1. Build LLVM ("backend") with the required sanitizer enabled. -2. Build ZKsync solidity Rust code ("frontend") with the LLVM build from the previous step. +1. Build the LLVM framework with the required sanitizer enabled. +2. Build `zksolc` with the LLVM build from the previous step. Please, follow the common [installation instructions](../01-installation.md#building-from-source) until the `zksync-llvm build` step. @@ -52,7 +52,7 @@ For example:
```shell -zksync-llvm build --sansitizer=Address \ +zksync-llvm build --sanitizer=Address \ --extra-args '\-DCMAKE_C_COMPILER=/opt/homebrew/opt/llvm/bin/clang' \ '\-DCMAKE_CXX_COMPILER=/opt/homebrew/opt/llvm/bin/clang++' ``` diff --git a/era-compiler-solidity/src/build_eravm/mod.rs b/era-compiler-solidity/src/build_eravm/mod.rs index 93418c43..52c9d9df 100644 --- a/era-compiler-solidity/src/build_eravm/mod.rs +++ b/era-compiler-solidity/src/build_eravm/mod.rs @@ -310,19 +310,20 @@ impl era_solc::CollectableError for Build { errors.extend( self.messages .iter() - .filter(|message| message.r#type == "Error"), + .filter(|message| message.severity == "error"), ); errors } - fn warnings(&self) -> Vec<&era_solc::StandardJsonOutputError> { - self.messages + fn take_warnings(&mut self) -> Vec { + let warnings = self + .messages .iter() - .filter(|message| message.r#type == "Warning") - .collect() - } - - fn remove_warnings(&mut self) { - self.messages.retain(|message| message.r#type != "Warning"); + .filter(|message| message.severity == "warning") + .cloned() + .collect(); + self.messages + .retain(|message| message.severity != "warning"); + warnings } } diff --git a/era-compiler-solidity/src/build_evm/mod.rs b/era-compiler-solidity/src/build_evm/mod.rs index b4d3f1fc..f94a9f72 100644 --- a/era-compiler-solidity/src/build_evm/mod.rs +++ b/era-compiler-solidity/src/build_evm/mod.rs @@ -31,11 +31,11 @@ impl Build { /// A shortcut constructor. /// pub fn new( - contracts: BTreeMap>, + results: BTreeMap>, messages: &mut Vec, ) -> Self { Self { - results: contracts, + results, messages: std::mem::take(messages), } } @@ -198,19 +198,20 @@ impl era_solc::CollectableError for Build { errors.extend( self.messages .iter() - .filter(|message| message.r#type == "Error"), + .filter(|message| message.severity == "error"), ); errors } - fn warnings(&self) -> Vec<&era_solc::StandardJsonOutputError> { - self.messages + fn take_warnings(&mut self) -> Vec { + let warnings = self + .messages .iter() - .filter(|message| message.r#type == "Warning") - .collect() - } - - fn remove_warnings(&mut self) { - self.messages.retain(|message| message.r#type != "Warning"); + .filter(|message| message.severity == "warning") + .cloned() + .collect(); + self.messages + .retain(|message| message.severity != "warning"); + warnings } } diff --git a/era-compiler-solidity/src/zksolc/arguments.rs b/era-compiler-solidity/src/zksolc/arguments.rs index a807b914..f6a9b6f7 100644 --- a/era-compiler-solidity/src/zksolc/arguments.rs +++ b/era-compiler-solidity/src/zksolc/arguments.rs @@ -64,16 +64,11 @@ pub struct Arguments { pub fallback_to_optimizing_for_size: bool, /// Pass arbitary space-separated options to LLVM. - /// The argument must be a single quoted string following a `=` separator. + /// The argument must be a single-quoted string following a `=` separator. /// Example: `--llvm-options='-eravm-jump-table-density-threshold=10'`. #[arg(long)] pub llvm_options: Option, - /// Deprecated. - /// The `solc` optimizer is not used by `zksolc` anymore. - #[arg(long)] - pub disable_solc_optimizer: bool, - /// Specify the path to a `solc` executable. /// Solidity mode: if not provided, `solc` is also searched in `${PATH}`. /// Yul mode: `solc` is optional for additional Yul validation, as `zksolc` has limited Yul verification capabilities. @@ -111,12 +106,6 @@ pub struct Arguments { #[arg(short, long)] pub threads: Option, - /// Switch to missing deployable libraries detection mode. - /// Only available for standard JSON input/output mode. - /// Contracts are not compiled in this mode, and all compilation artifacts are not included. - #[arg(long)] - pub detect_missing_libraries: bool, - /// Switch to Yul mode. /// Only one input Yul file is allowed. /// Cannot be used with combined and standard JSON modes. @@ -154,17 +143,6 @@ pub struct Arguments { #[arg(long)] pub codegen: Option, - /// Forcibly switch to EVM legacy assembly codegen. - /// It is useful for older revisions of `solc` 0.8, where Yul was considered highly experimental - /// and contained more bugs than today. - /// Deprecated: use `--codegen` instead. - #[arg(long)] - pub force_evmla: bool, - - /// Deprecated: use `--enable-eravm-extensions` instead. - #[arg(long)] - pub system_mode: bool, - /// Enable EraVM extensions. /// In this mode, calls to addresses `0xFFFF` and below are substituted by special EraVM instructions. /// In the Yul mode, the `verbatim_*` instruction family becomes available. @@ -223,6 +201,29 @@ pub struct Arguments { /// Only for usage from within the compiler. #[arg(long)] pub recursive_process: bool, + + /// Switch to missing deployable libraries detection mode. + /// Only available for standard JSON input/output mode. + /// Contracts are not compiled in this mode, and all compilation artifacts are not included. + /// Deprecated: missing libraries are now always returned in standard JSON output. + #[arg(long)] + pub detect_missing_libraries: bool, + + /// Forcibly switch to EVM legacy assembly codegen. + /// It is useful for older revisions of `solc` 0.8, where Yul was considered highly experimental + /// and contained more bugs than today. + /// Deprecated: use `--codegen` instead. + #[arg(long)] + pub force_evmla: bool, + + /// Deprecated: use `--enable-eravm-extensions` instead. + #[arg(long)] + pub system_mode: bool, + + /// Deprecated. + /// The `solc` optimizer is not used by `zksolc` anymore. + #[arg(long)] + pub disable_solc_optimizer: bool, } impl Arguments { diff --git a/era-compiler-solidity/src/zksolc/main.rs b/era-compiler-solidity/src/zksolc/main.rs index cd898e2d..2fafe761 100644 --- a/era-compiler-solidity/src/zksolc/main.rs +++ b/era-compiler-solidity/src/zksolc/main.rs @@ -27,6 +27,18 @@ fn main() -> anyhow::Result<()> { let is_standard_json = arguments.standard_json.is_some(); let mut messages = arguments.validate(); if messages.iter().all(|error| error.severity != "error") { + if !is_standard_json { + std::io::stderr() + .write_all( + messages + .drain(..) + .map(|error| error.to_string()) + .collect::>() + .join("\n") + .as_bytes(), + ) + .expect("Stderr writing error"); + } if let Err(error) = main_inner(arguments, &mut messages) { messages.push(era_solc::StandardJsonOutputError::new_error( error, None, None, diff --git a/era-compiler-solidity/tests/cli/llvm_ir.rs b/era-compiler-solidity/tests/cli/llvm_ir.rs index 5e2860cd..63c28b3e 100644 --- a/era-compiler-solidity/tests/cli/llvm_ir.rs +++ b/era-compiler-solidity/tests/cli/llvm_ir.rs @@ -47,6 +47,20 @@ fn with_llvm_ir_invalid(target: Target) -> anyhow::Result<()> { Ok(()) } +#[test_case(Target::EraVM)] +fn with_llvm_ir_linker_error(target: Target) -> anyhow::Result<()> { + common::setup()?; + + let args = &["--llvm-ir", common::TEST_LLVM_IR_CONTRACT_LINKER_ERROR_PATH]; + + let result = cli::execute_zksolc_with_target(args, target)?; + result.failure().stderr(predicate::str::contains( + "ld.lld: error: undefined symbol: foo", + )); + + Ok(()) +} + #[test_case(Target::EraVM)] #[test_case(Target::EVM)] fn with_wrong_input_format(target: Target) -> anyhow::Result<()> { diff --git a/era-compiler-solidity/tests/common/const.rs b/era-compiler-solidity/tests/common/const.rs index 7b75e365..119c4d9c 100644 --- a/era-compiler-solidity/tests/common/const.rs +++ b/era-compiler-solidity/tests/common/const.rs @@ -78,6 +78,10 @@ pub const TEST_LLVM_IR_CONTRACT_EVM_PATH: &str = "tests/data/contracts/llvm_ir/T /// A test input file. pub const TEST_LLVM_IR_CONTRACT_INVALID_PATH: &str = "tests/data/contracts/llvm_ir/Invalid.ll"; +/// A test input file. +pub const TEST_LLVM_IR_CONTRACT_LINKER_ERROR_PATH: &str = + "tests/data/contracts/llvm_ir/LinkerError.ll"; + /// A test input file. pub const TEST_ERAVM_ASSEMBLY_CONTRACT_PATH: &str = "tests/data/contracts/eravm_assembly/Test.zasm"; diff --git a/era-compiler-solidity/tests/data/contracts/llvm_ir/LinkerError.ll b/era-compiler-solidity/tests/data/contracts/llvm_ir/LinkerError.ll new file mode 100644 index 00000000..0132a286 --- /dev/null +++ b/era-compiler-solidity/tests/data/contracts/llvm_ir/LinkerError.ll @@ -0,0 +1,6 @@ +target datalayout = "E-p:256:256-i256:256:256-S32-a:256:256" +declare void @foo() +define void @glob() nounwind { + call void @foo() + ret void +} \ No newline at end of file diff --git a/era-solc/src/standard_json/output/error/collectable.rs b/era-solc/src/standard_json/output/error/collectable.rs index fe68b723..9de71d93 100644 --- a/era-solc/src/standard_json/output/error/collectable.rs +++ b/era-solc/src/standard_json/output/error/collectable.rs @@ -19,14 +19,9 @@ pub trait Collectable { fn errors(&self) -> Vec<&Error>; /// - /// Returns warnings as a list. + /// Extracts warnings from the list of messages. /// - fn warnings(&self) -> Vec<&Error>; - - /// - /// Removes warnings from the list of messages. - /// - fn remove_warnings(&mut self); + fn take_warnings(&mut self) -> Vec; /// /// Checks if there is at least one error. @@ -35,13 +30,6 @@ pub trait Collectable { !self.errors().is_empty() } - /// - /// Checks if there is at least one warning. - /// - fn has_warnings(&self) -> bool { - !self.warnings().is_empty() - } - /// /// Collects errors into one message and bails, if there is at least one error. /// @@ -85,21 +73,19 @@ pub trait Collectable { /// Removes warnings from the list of messages and prints them to stderr. /// fn take_and_write_warnings(&mut self) { - if !self.has_warnings() { + let warnings = self.take_warnings(); + if warnings.is_empty() { return; } - writeln!( std::io::stderr(), "{}", - self.warnings() - .iter() + warnings + .into_iter() .map(|error| error.to_string()) .collect::>() .join("\n") ) .expect("Stderr writing error"); - - self.remove_warnings(); } } diff --git a/era-solc/src/standard_json/output/mod.rs b/era-solc/src/standard_json/output/mod.rs index 9344648f..c8a85217 100644 --- a/era-solc/src/standard_json/output/mod.rs +++ b/era-solc/src/standard_json/output/mod.rs @@ -223,14 +223,14 @@ impl CollectableError for Output { .collect() } - fn warnings(&self) -> Vec<&JsonOutputError> { - self.errors + fn take_warnings(&mut self) -> Vec { + let warnings = self + .errors .iter() - .filter(|error| error.severity == "warning") - .collect() - } - - fn remove_warnings(&mut self) { - self.errors.retain(|error| error.severity != "warning"); + .filter(|message| message.severity == "warning") + .cloned() + .collect(); + self.errors.retain(|message| message.severity != "warning"); + warnings } }