-
Notifications
You must be signed in to change notification settings - Fork 6.1k
Immutable variables treated differently depending on type #15989
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
Comments
I can confirm that this is the current behavior. As to whether it's a bug - it's complicated. Integers and fixed byte arrays that have an initializer, which is a literal are intentionally considered pure. This does not apply to addresses or other value types (booleans, internal functions, contracts, enums, probably also UDVTs). This seems to have been introduced as a feature in 0.7.5 (#10240). The motivation in the request (#9554) was that it was not possible to define a pure getter in an interface and override it with an immutable state variable in a contract that implements it. It was concluded back then that immutables do not really fit the current notion of So it generally works as intended, but with one wrinkle. This seems to have been done with the assumption that having the initializer prevents the immutable from being reassigned later. We later decided to relax that limitation (#14240) and it's already partially lifted (#14304) - immutables can be reassigned in constructor. Not sure yet if that may have some weird consequences (it would probably be much worse if we allowed reassignments in functions), but this means that we need to reconsider whether we should scrap this feature before relaxing it further. |
I honestly don't understand why an address should be considered differently from a bytes20 or a uint160. This "maybe not a bug" is pushing us to cast objects that are clearly addresses to other types (of the same size) to work around issues. This is obfuscating the reality of the objects, overall decreassing readability and security of our code. |
If this is the intended rule there is no reason not to apply it to every type. But yes, I noticed what you point out, the original reasoning to justify making it pure doesn't hold any longer, which makes this a bug for a different reason. It was never the intention that this should compile: contract Test {
uint256 internal immutable _b = 0;
constructor() {
_b = block.number;
}
function b() external pure returns (uint256) {
return _b;
}
} And the fact that adding an explicit |
We discussed this on the Wednesday call:
|
Yeah, it seems like an artificial restriction. I don't think it was even meant to remain like this long term - #10240 looks to me like just a first quick step to address the immediate issue without opening it up too much and risking unforeseen issue, but also not closing the way for further extension.
True. This should definitely be considered a bug. Since
I mean, this "feature" is inherently unintuitive and hard to discover. Assuming we don't want to remove it. It would be better if it did not matter where the variable was initialized, only how, but the complexity of that and all the bugs around it is exactly why we decided to relax the restrictions on immutables. I'm not sure we can do anything else other than just document it though, assuming we want to keep it. |
BTW, this discussion has again brought the topic of Personally, I agree with @ekpyron's latest stance (#12829 (comment)) that we should make To be clear, this would still not really affect this issue. In construction context immutables are essentially variables so we have to fix it regardless. |
FWIW I think it would be fine to entirely disallow reading The underlying issue is that users prefer The fix to this situation is to ensure that |
Good point. I guess in all cases where we're fine making the immutable pure, it can syntactically be simply replaced with a constant. You can even use a public constant to solve the original override problem. It sounds like this is the direction we should have gone with this. |
Uh oh!
There was an error while loading. Please reload this page.
Description
An immutable variable that is initialized at declaration site can be used in
pure
context if it is of typeuint
but not if it is of typeaddress
.Environment
Steps to Reproduce
The text was updated successfully, but these errors were encountered: