Skip to content

Constant evaluator support for member constants #16056

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

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from

Conversation

matheusaaguiar
Copy link
Collaborator

Fix #16055.

@matheusaaguiar matheusaaguiar self-assigned this May 18, 2025
@matheusaaguiar matheusaaguiar force-pushed the constantEvaluatorSupportForMemberAccess branch 2 times, most recently from 93d7f5a to 78e1d3e Compare May 19, 2025 04:41
@matheusaaguiar matheusaaguiar marked this pull request as ready for review May 19, 2025 04:41
@matheusaaguiar matheusaaguiar force-pushed the constantEvaluatorSupportForMemberAccess branch from 1e7955b to 985b03f Compare May 20, 2025 15:13
Copy link
Member

@clonker clonker left a comment

Choose a reason for hiding this comment

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

I am not sure if there aren't any unwanted side-effects hiding in this. Looks good to me generally, though!

@matheusaaguiar matheusaaguiar force-pushed the constantEvaluatorSupportForMemberAccess branch from ad3f23a to 7fa4363 Compare May 22, 2025 22:26
clonker
clonker previously approved these changes May 23, 2025
Copy link
Member

@clonker clonker left a comment

Choose a reason for hiding this comment

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

LGTM aside from the typo

@matheusaaguiar matheusaaguiar force-pushed the constantEvaluatorSupportForMemberAccess branch 2 times, most recently from e596763 to d5beb9e Compare May 23, 2025 14:35
@matheusaaguiar matheusaaguiar force-pushed the constantEvaluatorSupportForMemberAccess branch from d5beb9e to 9d5f93f Compare June 4, 2025 13:57
Copy link

This pull request is stale because it has been open for 14 days with no activity.
It will be closed in 7 days unless the stale label is removed.

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

github-actions bot commented Jul 9, 2025

This pull request is stale because it has been open for 14 days with no activity.
It will be closed in 7 days unless the stale label is removed.

@github-actions github-actions bot added the stale The issue/PR was marked as stale because it has been open for too long. label Jul 9, 2025
@matheusaaguiar matheusaaguiar removed the stale The issue/PR was marked as stale because it has been open for too long. label Jul 9, 2025
@matheusaaguiar matheusaaguiar force-pushed the constantEvaluatorSupportForMemberAccess branch 3 times, most recently from 66a8367 to a1c8007 Compare July 10, 2025 15:16
clonker
clonker previously approved these changes Jul 10, 2025
@matheusaaguiar matheusaaguiar force-pushed the constantEvaluatorSupportForMemberAccess branch from a1c8007 to 1145d25 Compare July 14, 2025 12:33
Copy link
Member

@cameel cameel left a comment

Choose a reason for hiding this comment

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

Actually, there are some problems here.

Comment on lines 415 to 417
if (auto const* parentIdentifier = dynamic_cast<Identifier const*>(&_memberAccess.expression()))
{
if (auto const* contract = dynamic_cast<ContractDefinition const*>(parentIdentifier->annotation().referencedDeclaration))
Copy link
Member

Choose a reason for hiding this comment

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

This does not cover all relevant cases. I think it will break at least on these:

  • m.CONST (expression is a module)
  • (C).CONST (expression is not an identifier)
  • m.C.CONST (member access on a member access)

Especially the first and the third one are not far fetched at all.

These are probably not all cases either. I can also think about a few more that are now disallowed due to our previous changes in implicit conversions:

  • [C][0].CONST
  • (true ? C : C).CONST

Copy link
Member

Choose a reason for hiding this comment

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

This should really be possible to implement in a more general way, without handling all those cases one by one. Have you tried getting the constant definition via _memberAccess.annotation().referencedDeclaration?

Copy link
Collaborator Author

@matheusaaguiar matheusaaguiar Jul 15, 2025

Choose a reason for hiding this comment

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

The problem is that constant evaluation is done "on demand" whenever it is needed, so in some (most?) cases information like referencedDeclaration may not be present and will only be calculated later.
For example, in the case of array sizes, the expression will be evaluated during the DeclarationTypeChecker step and referencedDeclaration is resolved later when TypeChecker step runs.
On the other hand, in the case of the custom storage layout of the contract, the evaluation would occur during the same step and information like referencedDeclaration would be available.
I ended up focusing only in the simplest use of contract constants, and then later was considering handling modules in a different PR to not hold this one back.
I am not sure about expressions like (true ? C : C).CONST, I think maybe it kinda falls out of scope, because currently the constant evaluator can't handle them, so it would not be able to yield C as the "result" there...

Copy link
Member

@cameel cameel Jul 14, 2025

Choose a reason for hiding this comment

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

We need more tests. At least:

  • Access to a non-constant member should produce an appropriate error.
  • Member access that is not a top-level expression in array size, e.g. a[1 + C.CONST + 2].
  • Nesting: member access to a constant whose value contains member access as well.
  • Cycles: Two member access constants using each other as values (should be an error).

Especially the last one looks worrying. I just found #12928 (comment), which may be the reason we had this limitation to begin with. If that's the case, then properly solving this may require deeper changes to analysis phases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Compile-time evaluation of member constants
3 participants