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

default type of integer literals ignores type list in unions of integers #21331

Open
slaide opened this issue Feb 5, 2023 · 2 comments · May be fixed by #24250
Open

default type of integer literals ignores type list in unions of integers #21331

slaide opened this issue Feb 5, 2023 · 2 comments · May be fixed by #24250

Comments

@slaide
Copy link

slaide commented Feb 5, 2023

Description

i expect this code to pass, but it does not

let a : int8 | uint8 = 3
assert sizeof(a)==sizeof(int8) # this fails

making the type for the literal explicit fixes this

# case 1
let a : int8 | uint8 = 3.int # this fails to compile because int cannot be assigned to int8|uint8
assert sizeof(a)==sizeof(int8)
# case 2
let a : int8 | uint8 = 3.uint8
assert sizeof(a)==sizeof(int8) # now this passes

Nim Version

Nim Compiler Version 1.6.10 [Linux: amd64]
Compiled at 2022-11-21
Copyright (c) 2006-2021 by Andreas Rumpf

git hash: f151925
active boot switches: -d:release

Current Output

No response

Expected Output

No response

Possible Solution

No response

Additional Information

probably relevant unit tests

import std/unittest

test "type size mismatch for type possiblity #1":
    let a: int8|uint8 = 3
    check sizeof(a)==sizeof(int8)

test "type size mismatch for type possiblity #2":
    let a: int8|uint8 = 3
    check sizeof(a)==sizeof(uint8)

test "type size mismatch with negative sign on literal":
    let a: int8|uint8 = -3
    check sizeof(a)==sizeof(int8)

test "forcing integer literal type to match (signed)":
    let a: int8|uint8 = 3.int8
    check sizeof(a)==sizeof(int8)
    
test "forcing integer literal type to match (unsigned)":
    let a: int8|uint8 = 3.uint8
    check sizeof(a)==sizeof(uint8)

# the cases below will not compile (which is expected behaviour)

#test "forcing integer literal type to match (signed)":
#    let a: int8|uint8 = 3.int # compiler will display Error: type mismatch: got 'int' for 'int(3)' but expected 'int8 or uint8'
#    check sizeof(a)==sizeof(int8)
    
#test "forcing integer literal type to match (unsigned)":
#    let a: int8|uint8 = 3.uint # compiler will display Error: type mismatch: got 'uint' for 'uint(3)' but expected 'int8 or uint8'
#    check sizeof(a)==sizeof(uint8)

gives this output

/path/to/test.nim(5, 19): Check failed: sizeof(a) == sizeof(int8)
sizeof(a) was 8
sizeof(int8) was 1
[FAILED] type size mismatch for type possiblity #1
/path/to/test.nim(9, 19): Check failed: sizeof(a) == sizeof(uint8)
sizeof(a) was 8
sizeof(uint8) was 1
[FAILED] type size mismatch for type possiblity #2
/path/to/test.nim(13, 19): Check failed: sizeof(a) == sizeof(int8)
sizeof(a) was 8
sizeof(int8) was 1
[FAILED] type size mismatch with negative sign on literal
[OK] forcing integer literal type to match (signed)
[OK] forcing integer literal type to match (unsigned)
@metagn
Copy link
Collaborator

metagn commented Feb 6, 2023

The type of "3" is int literal 3, which matches both int8 and uint8, but this type gets turned into int as the type of the let variable. Demonstrated by:

let x: not int8 = 3
# Error: type mismatch: got 'int literal(3)' for '3' but expected 'not int8'

Maybe we can check if the type matches after the conversion from int literal to int, then it would say "got int but expected int8 | uint8".

Same issue #12552

@shirleyquirk
Copy link
Contributor

here's my version of this issue:

proc foo(b:byte) = echo b,typeof(b)

proc write(b:byte | seq[byte]) = 
  echo b,typeof(b)

proc read(b:byte | seq[byte]) = 
  when b is seq:
    for i in b:
      foo(i)
  else:
    foo(b)

foo(3) # 3byte
## this is great ergonomics and i love it

write(3) # 3int
## this is horrible, but i'd forgive if 
## this worked:
read(3) # type mismatch

passing through the lit to the next function down would be very nice.
but the current behaviour is not very nice.

ref #936

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 a pull request may close this issue.

3 participants