Skip to content

Fix integer.create and fromstring type definitions#2540

Open
tapple wants to merge 2 commits into
luau-lang:masterfrom
tapple:integer-definitions
Open

Fix integer.create and fromstring type definitions#2540
tapple wants to merge 2 commits into
luau-lang:masterfrom
tapple:integer-definitions

Conversation

@tapple

@tapple tapple commented Jul 11, 2026

Copy link
Copy Markdown

integer.create and integer.fromstring can return nil, but the embedded type definitions don't reflect that:

> integer.create(5.4)
nil
> integer.fromstring("w")
nil

The embedded definitions also mismatch the integer RFC, where they are both documented to return integer?, and not integer.


Example program to demonstrate why this is a problem:

--!strict
local function add_ints(a: string, b: string): integer
    return integer.add(integer.fromstring(a), integer.fromstring(b))
end
return add_ints("1.1", "2.2")

This program really needs to check that it's not adding nil numbers:

$ luau integer-bug.luau 
./integer-bug.luau:3: invalid argument #1 to 'add' (integer expected, got nil)
stacktrace:
[C] function add
./integer-bug.luau:3 function add_ints
./integer-bug.luau:5

But the typechecker doesn't notice

$ luau-analyze integer-bug.luau 
# no errors

After this change, the typechecker also gives a warning:

$ luau-analyze integer-bug.luau 
./integer-bug.luau(3,24): TypeError: Expected this to be 'integer', but got 'integer?'; 
the 2nd component of the union is `nil`, which is not a subtype of `integer`
./integer-bug.luau(3,24): TypeError: Expected this to be 'integer', but got 'nil'

I don't expect this change will need a FFlag, as integers are still experimental, but I'll add one if requested

@tapple tapple changed the title Fix integer.create and fromstring type definitions Fix integer.create and fromstring type definitions Jul 11, 2026
@vegorov-rbx

Copy link
Copy Markdown
Collaborator

This change will require a separate flag.

@vegorov-rbx

Copy link
Copy Markdown
Collaborator

Can you share the motivation behind this change?

@tapple

tapple commented Jul 13, 2026

Copy link
Copy Markdown
Author

@vegorov-rbx

  1. I updated the description with an example of what this fixes
  2. I wrapped this change in a FFlag

@tommyscholly

Copy link
Copy Markdown
Contributor

While being the correct type in theory, I find this would make working with integers worse. For instance:

local one = integer.create(1)
local two = integer.create(2)

integer.add(one, two) -- this would now be a type error

@tapple

tapple commented Jul 13, 2026

Copy link
Copy Markdown
Author

While being the correct type in theory, I find this would make working with integers worse. For instance:

If you know you're doing it right, you can typecast for zero runtime overhead:

 local one = integer.create(1) :: integer

perhaps a magic type function could be added to integer.create so that it typechecks as integer if it's argument is any of the following expressions:

  • //
  • math.floor
  • math.ciel
  • math.modf
  • math.random(number, number?)
  • #
  • string.len
  • buffer.readi*
  • bit32.*

I think integer.fromstring should always typecheck as integer? though, regardless of what happens to integer.create

Also, maybe integer.create should not be @checked. wait no that wouldn't help. it would have to be all the other integer functions that were not @checked, and that would be worse.

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.

3 participants