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

ntuple doesn't handle Int32s well during struct Construction. #57271

Open
ghyatzo opened this issue Feb 5, 2025 · 5 comments
Open

ntuple doesn't handle Int32s well during struct Construction. #57271

ghyatzo opened this issue Feb 5, 2025 · 5 comments
Labels
error messages Better, more actionable error messages types and dispatch Types, subtyping and method dispatch

Comments

@ghyatzo
Copy link
Contributor

ghyatzo commented Feb 5, 2025

MWE:

struct MyStruct{N}
    x::NTuple{N, Symbol}
end

function MyStruct()
    N = rand(2:4) % Int32 #<- the important bit is the cast to Int32
    x = ntuple(N) do i
        rand([:A, :B, :C, :D])
    end

    MyStruct{N}(x)
end

incurs into a:

ERROR: ArgumentError: cannot convert a value to Union{} for assignment
Stacktrace:
 [1] convert(T::Core.TypeofBottom, x::Tuple{Symbol, Symbol})
   @ Base .\essentials.jl:455
 [2] MyStruct{2}(x::Tuple{Symbol, Symbol})
   @ Main .\REPL[5]:2
 [3] MyStruct()
   @ Main .\REPL[6]:7
 [4] top-level scope
   @ REPL[7]:1

Also fails with an inner constructor.

Versioninfo:

Julia Version 1.11.3
Commit d63adeda50 (2025-01-21 19:42 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: 16 × AMD Ryzen 7 5825U with Radeon Graphics
  WORD_SIZE: 64
  LLVM: libLLVM-16.0.6 (ORCJIT, znver3)
Threads: 8 default, 0 interactive, 6 GC (on 16 virtual cores)
Environment:
  JULIA_NUM_THREADS = 8
  JULIA_PKG_DEVDIR = C:\Users\camillo.schenone\Dev\+Julia
@vtjnash vtjnash added the error messages Better, more actionable error messages label Feb 5, 2025
@adienes
Copy link
Contributor

adienes commented Feb 5, 2025

what should the error message be here? probably ERROR: TypeError: in Vararg, in count, expected Int64, got a value of type Int32 ?

@jakobnissen
Copy link
Contributor

This may be related, and is not just a problem with error messages:

julia> struct Foo{N}
           x::NTuple{N, Int}
           Foo() = new{Int32(1)}()
       end

julia> Foo()
Foo{1}(#undef)

@nsajko
Copy link
Contributor

nsajko commented Feb 5, 2025

Related: #57189. Fixing it would make the stack trace here more informative.

@JeffBezanson
Copy link
Member

Prior to v1.3 this gave an error when the type was constructed. Now, we let you form the type but the field type that didn't work is Union{}. I believe it was a8c8377.

IIRC, this was done to fix a soundness issue where failing to construct a type led subtyping to conclude the type was uninhabited, and so field types could affect the subtype relation even though they really shouldn't. I don't have a specific example of the problem at hand unfortunately.

I agree this is not ideal. Jameson had a helpful idea in the commit message:

    It might be possible to instead store this error, and rethrow it when someone
    tries to construct a (partially initialized) copy of the type and/or when the
    user (but not inference or introspection tools) tries to examine the fieldtype
    of the object. But I think this extra complexity (and additional failure cases
    to consider) isn't worthwhile to add.

I think another option is to examine the error when we print it, and reconstruct the problem by trying to instantiate each field type and seeing if it fails, so we can give that information to the user.

@JeffBezanson JeffBezanson added the types and dispatch Types, subtyping and method dispatch label Feb 5, 2025
@vtjnash
Copy link
Member

vtjnash commented Feb 6, 2025

It wasn't exactly correctness but rather that we don't compute fieldtypes eagerly anymore, so we cannot throw an exception at the time that we instantiated that type. To expound upon Jeff's noted improvement: we could potentially inject a bit of code at the start of each new call which checks if the fields are actually all inhabited and throw a better exception if we see that it is not

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
error messages Better, more actionable error messages types and dispatch Types, subtyping and method dispatch
Projects
None yet
Development

No branches or pull requests

6 participants