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

Type of integer constant is ignored during folding of literal ops #2830

Closed
tserg opened this issue Apr 30, 2022 · 8 comments
Closed

Type of integer constant is ignored during folding of literal ops #2830

tserg opened this issue Apr 30, 2022 · 8 comments

Comments

@tserg
Copy link
Collaborator

tserg commented Apr 30, 2022

Version Information

  • vyper Version (output of vyper --version): 0.3.3
  • OS: Linux
  • Python Version (output of python --version): 3.8.5

What's your issue about?

Please include information like:

This contract compiles when it should throw a typechecking error.

a: constant(uint16) = 200

@external
def foo() -> int16:
	return a - 201

How can it be fixed?

Annotate the folded nodes with the original type information.

@tserg
Copy link
Collaborator Author

tserg commented Apr 30, 2022

This also compiles, when it should not:

a: constant(uint16) = 200
b: constant(int248) = 100

@external
def foo() -> int16:
    return a - b

@tserg
Copy link
Collaborator Author

tserg commented Apr 30, 2022

This also compiles, when it should not:

a: constant(uint8) = 255
b: constant(uint8) = 1

@external
def foo() -> uint8:
	return a + b

[UPDATE - this now throws an InvalidType as of 0.3.7]

@tserg
Copy link
Collaborator Author

tserg commented May 1, 2022

Another example:

a: constant(int8) = 25
b: constant(uint8) = 38

@external
def foo() -> bool:
	return a < b

@tserg tserg changed the title Type of integer constant is ignored after folding Type of integer constant is ignored during folding of literal ops May 2, 2022
@trocher
Copy link
Contributor

trocher commented Feb 15, 2023

Might be redundant with your examples, but I got this one which is compiling:

a:constant(uint256)=1
b:constant(uint16)=a+0

Where this one does not:

a:constant(uint256)=1
b:constant(uint16)=a

@tserg
Copy link
Collaborator Author

tserg commented Feb 16, 2023

Might be redundant with your examples, but I got this one which is compiling:

a:constant(uint256)=1
b:constant(uint16)=a+0

Where this one does not:

a:constant(uint256)=1
b:constant(uint16)=a

Cool! I will add both examples as test cases to #3201.

@ToonVanHove
Copy link
Contributor

As a side note, this also causes some funky stuff when used as array index:

CONST: constant(int128) = 1

@external
def foo():
    array: uint256[10] = empty(uint256[10])
    a: int128 = 1

    array[a + CONST] = 20

When compiled this results in an AssertionError that is supposed to be unreachable.

@trocher
Copy link
Contributor

trocher commented Feb 18, 2023

As a side note, this also causes some funky stuff when used as array index:

CONST: constant(int128) = 1

@external
def foo():
    array: uint256[10] = empty(uint256[10])
    a: int128 = 1

    array[a + CONST] = 20

When compiled this results in an AssertionError that is supposed to be unreachable.

Interesting, for this one it seems that the typechecker allows a + CONST to be any integer types but when annotating a + CONST is given type uint256, it annotate a with its int128 type but visit_Constant annotates CONST with the uint256 obtained from the subscript's value type and does not care about its annotation obtained from folding..

@charles-cooper
Copy link
Member

i think this was solved during recent refactoring of constant folding (see #3669 and #3719). @ToonVanHove @trocher please reopen if there are still any issues.

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