Skip to content

constructing a tuple from an iterator may fail when it's not supposed to #53182

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
nsajko opened this issue Feb 5, 2024 · 1 comment · May be fixed by #53265
Open

constructing a tuple from an iterator may fail when it's not supposed to #53182

nsajko opened this issue Feb 5, 2024 · 1 comment · May be fixed by #53265
Labels
bug Indicates an unexpected problem or unintended behavior collections Data structures holding multiple items, e.g. sets types and dispatch Types, subtyping and method dispatch

Comments

@nsajko
Copy link
Contributor

nsajko commented Feb 5, 2024

Constructing tuples is buggy because of how it depends on Base.tuple_type_tail:

julia> const A = Tuple{Val{T},T,T} where {T}
Tuple{Val{T}, T, T} where T

julia> const t = (Val(Any), 2, 2.0)
(Val{Any}(), 2, 2.0)

julia> const v = [Val(Any), 2, 2.0]
3-element Vector{Any}:
  Val{Any}()
 2
 2.0

julia> A(v)
ERROR: TypeError: in typeassert, expected Tuple{T, T} where T, got a value of type Tuple{Int64, Float64}
Stacktrace:
 [1] _totuple
   @ ./tuple.jl:474 [inlined]
 [2] _totuple
   @ ./tuple.jl:473 [inlined]
 [3] (Tuple{Val{T}, T, T} where T)(itr::Vector{Any})
   @ Base ./tuple.jl:455
 [4] top-level scope
   @ REPL[4]:1

julia> t isa A
true

julia> versioninfo()
Julia Version 1.11.0-DEV.1451
Commit f117a500ca9 (2024-02-01 15:38 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: 8 × AMD Ryzen 3 5300U with Radeon Graphics
  WORD_SIZE: 64
  LLVM: libLLVM-16.0.6 (ORCJIT, znver2)
Threads: 1 default, 0 interactive, 1 GC (on 8 virtual cores)

xref: #27736 (comment)

Working on a PR that should fix this by constructing tuples without relying on tuple_type_tail.

@nsajko nsajko added bug Indicates an unexpected problem or unintended behavior types and dispatch Types, subtyping and method dispatch collections Data structures holding multiple items, e.g. sets labels Feb 5, 2024
@vtjnash
Copy link
Member

vtjnash commented Feb 5, 2024

I have slowly tried to remove a lot of these calls in Base for that reason (in favor of fieldtypes, though fieldtypes can still suffer the same bug), so more work in that direction is probably good. We do have a predicate now (Base.widen_diagonal) to correct these types however as well in construction.

nsajko added a commit to nsajko/julia that referenced this issue Feb 9, 2024
Make tuple construction from overlong iterators throw instead of
truncating the input iterator.

Fixes JuliaLang#40495

Fixes JuliaLang#52657

Make tuple construction from known constant-length iterators inferrable
and prevent allocation.

Fixes JuliaLang#52993

Compute more accurate tuple element types in many cases using
`typeintersect`, with a fallback to the old behavior. This prevents
some cases of `convert` throwing due to ambiguity.

Instead of just calling `typeintersect` on the tuple types, do
`typeintersect` again once `fieldtype` computes the element type.

Fixes JuliaLang#53181

Separate the tuple construction from tuple element conversion, allowing
dropping the `tuple_type_tail` dependency.

Fixes JuliaLang#53182

Trying to construct a tuple from an infinite iterator now results in an
`ArgumentError` instead of in a `MethodError`.
@nsajko nsajko linked a pull request Feb 9, 2024 that will close this issue
nsajko added a commit to nsajko/julia that referenced this issue Feb 9, 2024
Make tuple construction from overlong iterators throw instead of
truncating the input iterator.

Fixes JuliaLang#40495

Fixes JuliaLang#52657

Make tuple construction from known constant-length iterators inferrable
and prevent allocation.

Fixes JuliaLang#52993

Compute more accurate tuple element types in many cases using
`typeintersect`, with a fallback to the old behavior. This prevents
some cases of `convert` throwing due to ambiguity.

Instead of just calling `typeintersect` on the tuple types, do
`typeintersect` again once `fieldtype` computes the element type.

Fixes JuliaLang#53181

Separate the tuple construction from tuple element conversion, allowing
dropping the `tuple_type_tail` dependency.

Fixes JuliaLang#53182

Trying to construct a tuple from an infinite iterator now throws an
`ArgumentError` instead of succeeding or throwing a `MethodError`.
nsajko added a commit to nsajko/julia that referenced this issue Feb 9, 2024
Make tuple construction from overlong iterators throw instead of
truncating the input iterator.

Fixes JuliaLang#40495

Fixes JuliaLang#52657

Make tuple construction from known constant-length iterators inferrable
and prevent allocation.

Fixes JuliaLang#52993

Compute more accurate tuple element types in many cases using
`typeintersect`, with a fallback to the old behavior. This prevents
some cases of `convert` throwing due to ambiguity.

Instead of just calling `typeintersect` on the tuple types, do
`typeintersect` again once `fieldtype` computes the element type.

Fixes JuliaLang#53181

Separate the tuple construction from tuple element conversion, allowing
dropping the `tuple_type_tail` dependency.

Fixes JuliaLang#53182

Trying to construct a tuple from an infinite iterator now throws an
`ArgumentError` instead of succeeding or throwing a `MethodError`.
nsajko added a commit to nsajko/julia that referenced this issue Feb 9, 2024
Make tuple construction from overlong iterators throw instead of
truncating the input iterator.

Fixes JuliaLang#40495

Fixes JuliaLang#52657

Make tuple construction from known constant-length iterators inferrable
and prevent allocation.

Fixes JuliaLang#52993

Compute more accurate tuple element types in many cases using
`typeintersect`, with a fallback to the old behavior. This prevents
some cases of `convert` throwing due to ambiguity.

Instead of just calling `typeintersect` on the tuple types, do
`typeintersect` again once `fieldtype` computes the element type.

Fixes JuliaLang#53181

Separate the tuple construction from tuple element conversion, allowing
dropping the `tuple_type_tail` dependency.

Fixes JuliaLang#53182

Trying to construct a tuple from an infinite iterator now throws an
`ArgumentError` instead of succeeding or throwing a `MethodError`.
nsajko added a commit to nsajko/julia that referenced this issue Feb 9, 2024
Make tuple construction from overlong iterators throw instead of
truncating the input iterator.

Trying to construct a tuple from an infinite iterator now throws an
`ArgumentError` instead of succeeding or throwing a `MethodError`.

Fixes JuliaLang#40495

Fixes JuliaLang#52657

Make tuple construction from known constant-length iterators inferrable
and prevent allocation.

Fixes JuliaLang#52993

Compute more accurate tuple element types in many cases using
`typeintersect`, with a fallback to the old behavior. This prevents
some cases of `convert` throwing due to ambiguity.

Instead of just calling `typeintersect` on the tuple types, do
`typeintersect` again once `fieldtype` computes the element type.

Fixes JuliaLang#53181

Separate the tuple construction from tuple element conversion, allowing
dropping the `tuple_type_tail` dependency.

Fixes JuliaLang#53182
nsajko added a commit to nsajko/julia that referenced this issue Feb 9, 2024
Make tuple construction from overlong iterators throw instead of
truncating the input iterator.

Trying to construct a tuple from an infinite iterator now throws an
`ArgumentError` instead of succeeding or throwing a `MethodError`.

Fixes JuliaLang#40495

Fixes JuliaLang#52657

Make tuple construction from known constant-length iterators inferrable
and prevent allocation.

Fixes JuliaLang#52993

Compute more accurate tuple element types in many cases using
`typeintersect`, with a fallback to the old behavior. This prevents
some cases of `convert` throwing due to ambiguity.

Instead of just calling `typeintersect` on the tuple types, do
`typeintersect` again once `fieldtype` computes the element type.

Fixes JuliaLang#53181

Separate the tuple construction from tuple element conversion, allowing
dropping the `tuple_type_tail` dependency.

Fixes JuliaLang#53182
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Indicates an unexpected problem or unintended behavior collections Data structures holding multiple items, e.g. sets types and dispatch Types, subtyping and method dispatch
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants