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

Error when array length is an expression involving only literals and type conversions: Invalid array length, expected integer literal or constant expression #12832

Closed
bshastry opened this issue Mar 22, 2022 · 15 comments
Labels
closed due inactivity The issue/PR was automatically closed due to inactivity. documentation 📖 stale The issue/PR was marked as stale because it has been open for too long.

Comments

@bshastry
Copy link
Contributor

contract C {
  function f() external {
    uint[uint256((((((77203342890060379470995536562582626741748008201257474317563024391158357352195 ** uint152(1020873840434952056135838088180821062407121094)) >> 56910752605302543330500802966993239962334264168338881516084502707322707229319) ** 82705070667290639185515540116081796374718317434275556705609245196574547402355) + 66683721687286726833199636002753785367603597234526287466620826223496546038896) & 87485231878771483395216945770994664543542803176944483799433554461795287649940))] memory x;
  }
}

throws the said error although the length literal is an integer literal and a constant expression.

@chriseth
Copy link
Contributor

I think the issue is that the constant is too large - we should improve the error message.

@bshastry
Copy link
Contributor Author

I think the issue is that the constant is too large - we should improve the error message.

contract C {
  function ()[uint8(5)] x;
}

also errors similarly. But here there is something else wrong.

@bshastry
Copy link
Contributor Author

On debugging, it looks like the constant evaluator does not evaluate explicitly typed constant literals like uint8(1).

@bshastry
Copy link
Contributor Author

Minor update: This error is also encountered when statically defined array size is a compile-time constant but is not in a form that will be evaluated as such because it is not of a RationalNumberType e.g., bool[uint8(1)] x;

@StrongerXi
Copy link
Contributor

Minor update: This error is also encountered when statically defined array size is a compile-time constant but is not in a form that will be evaluated as such because it is not of a RationalNumberType e.g., bool[uint8(1)] x;

I believe this should be dealt with in ConstantEvaluator.cpp. Indeed it's not visiting such AST variant at the moment. We can raise another issue if needed, and I can send a PR for that.

@cameel
Copy link
Member

cameel commented Apr 1, 2022

The constant is definitely too large. We don't really support exponentiation in arbitrary precision with such large numbers. If you remove explicit conversions, you get this error message:

Error: Operator ** not compatible with types int_const 7720...(69 digits omitted)...2195 and int_const 1020...(38 digits omitted)...1094

And you don't even need numbers that large to get this error. You'd get it even with something like 10 ** 5000.

Minor update: This error is also encountered when statically defined array size is a compile-time constant but is not in a form that will be evaluated as such because it is not of a RationalNumberType e.g., bool[uint8(1)] x;

I think it's by design. It seems to be the same kind of issue as #12677. I.e. expressions stop being treated as compile-time constants once you convert to a limited-precision type. It's not ideal but at least does not look like a bug to me.

I think we should just properly document what is considered a "constant expression" or a "compile-time constant" and maybe also adjust the error message to be clearer about that.

@cameel cameel changed the title [TypeChecker] Invalid array length, expected integer literal or constant expression Error when array length is an expression involving only literals and type conversions:Invalid array length, expected integer literal or constant expression Apr 1, 2022
@cameel cameel changed the title Error when array length is an expression involving only literals and type conversions:Invalid array length, expected integer literal or constant expression Error when array length is an expression involving only literals and type conversions: Invalid array length, expected integer literal or constant expression Apr 1, 2022
@StrongerXi
Copy link
Contributor

I believe this can be closed by #12885

@cameel
Copy link
Member

cameel commented Apr 7, 2022

Two things we might still want to do as a part of this:

  • Explicitly say in the docs that adding a type conversion currently makes a literal non-usable as a compile-time constant?
  • Adjust the message you get when the length is a literal but with an explicit conversion?
    uint[uint(1)] valid_size_invalid_expr1;
    // TypeError 5462: (22-29): Invalid array length, expected integer literal or constant expression.
    uint(1) can reasonably be interpreted as a constant expression and the message does not clear that up.

What do you think?

@StrongerXi
Copy link
Contributor

Explicitly say in the docs that adding a type conversion currently makes a literal non-usable as a compile-time constant

I think that'll be a a good temporary workaround before we fully address the second thing.

Adjust the message you get when the length is a literal but with an explicit conversion?
...
uint(1) can reasonably be interpreted as a constant expression and the message does not clear that up.

I do think we should make the constant evaluator more aggressive by stripping away type conversion for applicable constants. With the limited context I have, that seems to address the issue at its root. Also similar things are suggested in another thread.

I'd gladly try sending a PR for this, if we think it's worth attempting and viable.

@cameel
Copy link
Member

cameel commented Apr 12, 2022

I do think we should make the constant evaluator more aggressive by stripping away type conversion for applicable constants.

We can't just strip the conversion. It may affect the value (e.g. casting uint to uint16 or negative int to uint). What we could do would be to extend the constant expression evaluation to cover these but I'm not sure if it'll be that simple. I think this is in scope for #3157, though it's not explicitly listed there so I added a comment.

I think issue I think we should just update docs/messages and close it, leaving evaluation for #3157.

@StrongerXi
Copy link
Contributor

We can't just strip the conversion. It may affect the value (e.g. casting uint to uint16 or negative int to uint). What we could do would be to extend the constant expression evaluation to cover these but I'm not sure if it'll be that simple. I think this is in scope for #3157, though it's not explicitly listed there so I added a comment.

You are right, I'll look into #3157.

I think issue I think we should just update docs/messages and close it, leaving evaluation for #3157.

Agree!

@cameel
Copy link
Member

cameel commented Apr 14, 2022

You are right, I'll look into #3157.

It's a rather big task. Compile-time evaluation is something we've been discussing for a while now. It's on our roadmap but we're not even decided on all details yet.

Are you interested in getting that specific feature implemented in the compiler or are you just looking for a good task to contribute in general? If it's the latter, I can find you a better defined task. If the former, you should really come to one of our team calls and join the design discussion on that topic (note that the next few calls might be a bit sparsely attended due to Devconnect though).

@StrongerXi
Copy link
Contributor

Thanks for the info! I'd say for now I'm just looking for a small tasks to contribute in general. If you can give me some pointers, I'll try to pick them up when possible:).

@github-actions
Copy link

This issue has been marked as stale due to inactivity for the last 90 days.
It will be automatically closed in 7 days.

@github-actions github-actions bot added the stale The issue/PR was marked as stale because it has been open for too long. label Mar 24, 2023
@github-actions
Copy link

github-actions bot commented Apr 1, 2023

Hi everyone! This issue has been automatically closed due to inactivity.
If you think this issue is still relevant in the latest Solidity version and you have something to contribute, feel free to reopen.
However, unless the issue is a concrete proposal that can be implemented, we recommend starting a language discussion on the forum instead.

@github-actions github-actions bot added the closed due inactivity The issue/PR was automatically closed due to inactivity. label Apr 1, 2023
@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Apr 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed due inactivity The issue/PR was automatically closed due to inactivity. documentation 📖 stale The issue/PR was marked as stale because it has been open for too long.
Projects
None yet
Development

No branches or pull requests

4 participants