alloy-rs / core

High-performance, well-tested & documented core libraries for Ethereum, in Rust
https://alloy.rs
Apache License 2.0
763 stars 137 forks source link

[Bug] sol! macro cannot parse single-quoted strings #716

Closed CjS77 closed 2 weeks ago

CjS77 commented 3 weeks ago

Component

sol! macro

What version of Alloy are you on?

alloy = { version = "0.2.1", features = ["full", "rpc", "json-rpc", "signer-mnemonic", "signers", "serde", "transports", "transport-http"] }

Operating System

Linux

Describe the bug

This parses fine:

use alloy::sol;

sol!(
pragma solidity >=0.6.0;
import {Foo} from "bar.sol";
library Bar {}
);

This does not:

use alloy::sol;

sol!(
pragma solidity >=0.6.0;
import {Foo} from 'bar.sol';
library Bar {}
);
error: prefix `sol` is unknown
 --> defi-backend/src/aave/contracts.rs:5:24
  |
5 | import {Foo} from 'bar.sol';
  |                        ^^^ unknown prefix
  |
  = note: prefixed identifiers and literals are reserved since Rust 2021
help: if you meant to write a string literal, use double quotes
  |
5 | import {Foo} from "bar.sol";
  |                   ~       ~

Using double-quotes isn't always convenient, since the main use-case here is to import contracts from 3rd-party libraries with

sol!(
  "path/to/third-party/that-uses-single-quoted-strings/contract.sol"
)
mattsse commented 3 weeks ago

I believe the limitation is this

https://github.com/alloy-rs/core/blob/ea7f594b1560b25a767038f24cff7c7dd2f6b48a/crates/syn-solidity/src/item/import.rs#L283-L283

which doesn't support single quotes,

so we need to parse this manually

CjS77 commented 3 weeks ago

Yup, certainly a non-trivial fix.

But still technically a bug.

As a workaround, I'm using the JSON ABI in lieu of the contract code which is working fine.

CjS77 commented 3 weeks ago

RESS might be useful in helping with the heavy lifting of solidity (js) parsing.

In particular things like is_string.

Just a suggestion. I'll leave it here.

DaniPopes commented 2 weeks ago

This is not supported at the rust level. Proc macros get rust syntax tokens as input, and rust does not support single-quote literals longer than 1 character. See limitations in https://github.com/alloy-rs/core/tree/main/crates/syn-solidity