Skip to content

feat(lint): add UnsafeTypecast lint #11046

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

Merged
merged 32 commits into from
Aug 15, 2025

Conversation

TropicalDog17
Copy link
Contributor

Motivation

Closes #11029

Solution

PR Checklist

  • Added Tests
  • Added Documentation
  • Breaking changes

@0xClandestine
Copy link
Contributor

Any updates, can update the tests for you if needed @TropicalDog17

@TropicalDog17
Copy link
Contributor Author

Hi @0xClandestine, I've updated the test, but not sure how to emit a helpful fix for the lint, can you help me on that? Thank a lot!

@0xrusowsky
Copy link
Contributor

Hi @0xClandestine, I've updated the test, but not sure how to emit a helpful fix for the lint, can you help me on that? Thank a lot!

maybe in this case a warning is enough, and no fix suggestion is required, but you could tell them to consider adding an explicit check like:

if (a > type(uint32).max) revert TypecastOverflow();

Copy link
Contributor

@0xrusowsky 0xrusowsky left a comment

Choose a reason for hiding this comment

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

please address the feedback

Comment on lines 91 to 97
solar_ast::LitKind::Number(num) => {
if is_negative_number_literal(num) {
Some(hir::ElementaryType::Int(solar_ast::TypeSize::ZERO))
} else {
Some(hir::ElementaryType::UInt(solar_ast::TypeSize::ZERO))
}
}
Copy link
Contributor

@0xrusowsky 0xrusowsky Jul 23, 2025

Choose a reason for hiding this comment

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

the compiler performs checks when assigning literal values, i think it is safe to remove this check, which would also remove the need of the bigint dep.

Please return None and add a comment explaining the reason why


Assigning values which cannot fit into the type gives a compiler error. For example:
uint8 foo = 300;

The largest value an uint8 can hold is (2 8) - 1 = 255. So, the compiler says:
value 300 does not fit into type uint8

ref: https://solang.readthedocs.io/en/latest/language/types.html

}

/// Infers the elementary type of a source expression.
/// For cast chains, returns the ultimate source type, not intermediate cast results.
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we check intermediate casts for cast chains? I think that's why this isn't throwing:

    function _addInt128(uint64 a, int128 b) internal pure returns (uint64) {
        return uint64(uint128(int128(uint128(a)) + b));
    }

Copy link
Contributor

Choose a reason for hiding this comment

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

Would suggest adding a test, you can also reproduce using the following commands:

foundryup --pr 11046
git clone https://github.com/Layr-Labs/eigenlayer-contracts.git
git checkout 44ece6d  
forge lint src/contracts/core/AllocationManager.sol --only-lint unsafe-typecast

Copy link
Contributor

Choose a reason for hiding this comment

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

good call, fixed to support cast chains.
do you expect any other cases not covered by the unit tests?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is a good start. Will make another small pr in the future if anything else comes to mind.

@0xrusowsky 0xrusowsky dismissed stale reviews from grandizzy and themself via 6fc6866 July 31, 2025 07:13
@0xClandestine
Copy link
Contributor

Sick! Ty, will review this evening sorry for the delay.

Copy link
Contributor

@0xClandestine 0xClandestine left a comment

Choose a reason for hiding this comment

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

Some nits for coverage and readability, and a false positive was found. Will throw together a gist with my suggested changes.

EDIT: https://gist.github.com/0xClandestine/06adf9eeba08ca08661d97fba035e542

@0xrusowsky
Copy link
Contributor

@TropicalDog17 can you address the feedback provided by @0xClandestine pls?

@mattsse
Copy link
Member

mattsse commented Aug 14, 2025

what's missing here @0xrusowsky

@0xrusowsky
Copy link
Contributor

the fix is shortsighted and will still yield false positives + clippy needs to be addressed.

i'll take over to bring it to the finish line

@0xrusowsky
Copy link
Contributor

0xrusowsky commented Aug 14, 2025

@0xClandestine can you do a final pass on the unit tests and the stderr outputs please? everything should be good now, based on the feedback u gave

cc: @mattsse @grandizzy for rust checks

Copy link
Contributor

@0xClandestine 0xClandestine left a comment

Choose a reason for hiding this comment

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

LGTM

grandizzy
grandizzy previously approved these changes Aug 14, 2025
Copy link
Collaborator

@grandizzy grandizzy left a comment

Choose a reason for hiding this comment

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

lgtm, small optional nit

return false;
};

for source_ty in source_types {
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit can nicely write as

    source_types
        .iter()
        .any(|source_ty| is_unsafe_elementary_typecast(source_ty, target_type))

Copy link
Collaborator

@grandizzy grandizzy left a comment

Choose a reason for hiding this comment

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

lgtm, thank you! @0xrusowsky I believe only docs pr remaining to be done here

@0xrusowsky
Copy link
Contributor

i'll make sure docs are added and merge

@0xrusowsky 0xrusowsky enabled auto-merge (squash) August 15, 2025 05:03
@0xrusowsky 0xrusowsky merged commit 1186156 into foundry-rs:master Aug 15, 2025
22 checks passed
@github-project-automation github-project-automation bot moved this to Done in Foundry Aug 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

feat(forge-lint): add UnsafeTypecast lint
5 participants