Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: update solang-parser #4661

Merged
merged 16 commits into from
Apr 18, 2023
Merged

Conversation

DaniPopes
Copy link
Member

@DaniPopes DaniPopes commented Mar 29, 2023

Motivation

Relevant changes:

Waiting on solang-parser v0.2.4 release, draft until then.

Blocked by gakonst/ethers-rs#2334 and an Ethers release.

Solution

@DaniPopes DaniPopes marked this pull request as draft March 29, 2023 04:41
Copy link
Member

@mattsse mattsse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome!
love that we could simplify this

lgtm, pending release

@mattsse mattsse added the Cmd-forge-fmt Command: forge fmt label Apr 1, 2023
@DaniPopes
Copy link
Member Author

DaniPopes commented Apr 7, 2023

Looks like 2 different errors in tests (CI):

  1. IfStatement/original.sol: looks like a previous bug, where the if statement on line 89 wasn't getting inlined?
  2. InlineDisable/original.sol: brackets get removed on empty blocks when disabled inline, I cannot figure out where this happens

cc @rkrasiuk @jpopesculian pls advise

@mattsse mattsse marked this pull request as ready for review April 12, 2023 21:48
@mattsse
Copy link
Member

mattsse commented Apr 12, 2023

@rkrasiuk please take a look at the failing tests, this is now a blocker for any PR that needs new ethers release

@mattsse mattsse requested a review from rkrasiuk April 12, 2023 21:53
@rkrasiuk
Copy link
Collaborator

@DaniPopes thanks for the update, you are an OG! looking at failing tests rn

@rkrasiuk
Copy link
Collaborator

regarding 2, i narrowed it down to the line below

return_source_if_disabled!(self, func.loc());

not sure yet under which circumstances the location is invalid, tried changing it to

return_source_if_disabled!(self, func.loc().with_end(body.loc().end()));

but that results in different errors 🤷‍♂️

@mattsse
Copy link
Member

mattsse commented Apr 15, 2023

I've added a smaller repro IfStatement2 and tracked it down to:

  1. _ => self.visit_block(stmt.loc(), &mut vec![stmt], attempt_single_line, true),
    called with FunctionCall(execute())
  2. and the fits_on_single fires here:
    if fits_on_single {

but couldn't make any additional progress because not familiar with the assumptions here, could please take another look at the visit_block function?

@DaniPopes
Copy link
Member Author

Isn't (1) the intended behaviour? visit_block gets called with (true, true) so the single stmt gets inlined because it fits

@mattsse
Copy link
Member

mattsse commented Apr 15, 2023

Isn't (1) the intended behaviour?

yes, was just pointing out the callgraph

so the single stmt gets inlined because it fits

yes, but I didn't before, so something changed here

@DaniPopes
Copy link
Member Author

DaniPopes commented Apr 15, 2023

The old manual implementation of .loc() for FunctionDefinition includes the block, while solang-parser's actual parser excludes it. This breaks an internal assumption that there is only whitespace between item[n].loc().end() and item[n + 1].loc().start()

In Formatter::write_lined_visitable, last_byte_written gets assigned to item.loc().end(), and unwritten_whitespace returns the wrong value which includes the block:

TRACE SU:function: forge_fmt::formatter: BEFORE: "<OMITTED>\n\n// forgefmt: disable-start\n\n"
TRACE SU:function: forge_fmt::formatter: AFTER:  "<OMITTED>\n\n// forgefmt: disable-start\n\nfunction test1() {}"
TRACE SU: forge_fmt::formatter: Unwritten whitespace: "{}\n\n"
TRACE SU:function: forge_fmt::formatter: BEFORE: "<OMITTED>\n\n// forgefmt: disable-start\n\nfunction test1() {}{}\n\n"

Should we revert to the old manual trait with just the special case for FunctionDefinition?

@mattsse
Copy link
Member

mattsse commented Apr 16, 2023

Should we revert to the old manual trait with just the special case for FunctionDefinition?

this sounds reasonable, would give us a bit more flexibility

@DaniPopes
Copy link
Member Author

Done, this fixes point number 2.

Number 1 is fixed with:

diff --git a/fmt/testdata/IfStatement/fmt.sol b/fmt/testdata/IfStatement/fmt.sol
index 4c430108..cb2f8874 100644
--- a/fmt/testdata/IfStatement/fmt.sol
+++ b/fmt/testdata/IfStatement/fmt.sol
@@ -104,9 +104,7 @@ contract IfStatement {
             execute();
         }
 
-        if (condition && ((condition || anotherLongCondition))) {
-            execute();
-        }
+        if (condition && ((condition || anotherLongCondition))) execute();
 
         // if statement
         if (condition) execute();
diff --git a/fmt/testdata/IfStatement2/fmt.sol b/fmt/testdata/IfStatement2/fmt.sol
index f9c27b1f..10ae4360 100644
--- a/fmt/testdata/IfStatement2/fmt.sol
+++ b/fmt/testdata/IfStatement2/fmt.sol
@@ -2,8 +2,6 @@ contract IfStatement {
     function test() external {
         bool anotherLongCondition;
 
-        if (condition && ((condition || anotherLongCondition))) {
-            execute();
-        }
+        if (condition && ((condition || anotherLongCondition))) execute();
     }
 }

But I guess the question here is still why did this change.

Comment on lines +160 to 167
/// Casts the current `W` writer as a `String` reference. Should only be used for debugging.
#[allow(dead_code)]
unsafe fn buf_contents(&self) -> &String {
match &self.temp_bufs[..] {
[] => unsafe { *(&self.buf.w as *const W as *const &mut String) },
[.., buf] => &buf.w,
}
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Used inline with trace!("{}", self.buf_contents())

This avoids adding fmt::Debug bounds everywhere, makes debugging faster. LMK if this should be removed.

fn visit_parser_error(&mut self, loc: Loc) -> Result<()> {
Err(FormatterError::InvalidParsedItem(loc))
}
}

#[cfg(test)]
mod tests {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved to ../tests/it/formatter.rs

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

diff in: 815e1d8

@DaniPopes
Copy link
Member Author

Some failing anvil test unrelated

@mattsse
Copy link
Member

mattsse commented Apr 17, 2023

merged the anvil issue from master,

failures:
formatter::IfStatement
formatter::IfStatement2

still fails though

@DaniPopes
Copy link
Member Author

DaniPopes commented Apr 17, 2023

yep honestly i don't know why, i think it's fine just keeping the change by patching the tests

@mattsse
Copy link
Member

mattsse commented Apr 17, 2023

fine with that, can reiterate when we receive feedback, but this pr is now blocking for a while

@DaniPopes

This comment was marked as resolved.

Copy link
Member

@mattsse mattsse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm!

@mattsse mattsse merged commit a9ad3ae into foundry-rs:master Apr 18, 2023
@DaniPopes DaniPopes deleted the feat/update-solang branch April 18, 2023 10:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Cmd-forge-fmt Command: forge fmt
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants