diff --git a/crates/sol-types/tests/macros/sol/mod.rs b/crates/sol-types/tests/macros/sol/mod.rs index 2c15bac45..ec68ca1a7 100644 --- a/crates/sol-types/tests/macros/sol/mod.rs +++ b/crates/sol-types/tests/macros/sol/mod.rs @@ -1223,3 +1223,22 @@ fn mapping_getters() { let _ = TestIbc::channelsReturn { _0: 0u8, _1: 0u32, _2: 0u32, _3: bytes![], _4: String::new() }; } + +// https://github.com/alloy-rs/core/issues/829 +#[test] +fn bytes64() { + sol! { + struct bytes64 { + bytes32 a; + bytes32 b; + } + + function f(bytes64 x) public returns(bytes64 y) { + bytes64 z = x; + y = z; + } + } + + let x = bytes64 { a: B256::ZERO, b: B256::ZERO }; + assert_eq!(bytes64::abi_encode_packed(&x), alloy_primitives::B512::ZERO.as_slice()); +} diff --git a/crates/syn-solidity/src/expr/mod.rs b/crates/syn-solidity/src/expr/mod.rs index 8ca87ffe2..f777a05c6 100644 --- a/crates/syn-solidity/src/expr/mod.rs +++ b/crates/syn-solidity/src/expr/mod.rs @@ -222,9 +222,11 @@ impl Expr { input.parse().map(Self::Delete) } else if lookahead.peek(Ident::peek_any) { let ident = input.call(Ident::parse_any)?; - match Type::parse_ident(ident.clone()) { - Ok(ty) if !ty.is_custom() => ty.parse_payable(input).map(Self::Type), - _ => Ok(Self::Ident(ident.into())), + let ty = Type::parse_ident(ident.clone()).parse_payable(input); + if ty.is_custom() { + Ok(Self::Ident(ident.into())) + } else { + Ok(Self::Type(ty)) } } else { Err(lookahead.error()) diff --git a/crates/syn-solidity/src/type/mod.rs b/crates/syn-solidity/src/type/mod.rs index f8f00656c..94caa1b75 100644 --- a/crates/syn-solidity/src/type/mod.rs +++ b/crates/syn-solidity/src/type/mod.rs @@ -228,7 +228,11 @@ impl Type { /// keyword separately. /// /// [ref]: https://docs.soliditylang.org/en/latest/grammar.html#a4.SolidityParser.elementaryTypeName - pub fn parse_ident(ident: Ident) -> Result { + pub fn parse_ident(ident: Ident) -> Self { + Self::try_parse_ident(ident.clone()).unwrap_or_else(|_| Self::custom(ident)) + } + + pub fn try_parse_ident(ident: Ident) -> Result { let span = ident.span(); let s = ident.to_string(); let ret = match s.as_str() { @@ -271,11 +275,11 @@ impl Type { /// Parses the `payable` keyword from the input stream if this type is an /// address. - pub fn parse_payable(mut self, input: ParseStream<'_>) -> Result { + pub fn parse_payable(mut self, input: ParseStream<'_>) -> Self { if let Self::Address(_, opt @ None) = &mut self { - *opt = input.parse()?; + *opt = input.parse().unwrap(); } - Ok(self) + self } /// Returns whether this type is ABI-encoded as a single EVM word (32 bytes). @@ -478,7 +482,7 @@ impl Type { input.parse().map(Self::Custom) } else if input.peek(Ident::peek_any) { let ident = input.call(Ident::parse_any)?; - Self::parse_ident(ident)?.parse_payable(input) + Ok(Self::parse_ident(ident).parse_payable(input)) } else { Err(input.error( "expected a Solidity type: \