Incorrect type narrowing of `for` comprehension initial accumulator
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 38/100
Línea de trabajo
Start by running both scripts from the issue as reduce_repro.exs and reduce_repro_1.exs to reproduce the false-positive type warnings. Trace the type handling for reduce: comprehensions in the compiler/type checker, using the gradual typing reference only to assess the documented alternative. Done means the initializer retains its input type and both examples execute without warnings while preserving their outputs.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Existing issue
- I have searched existing issues and could not find a duplicate.
Elixir and Erlang/OTP versions
Erlang/OTP 28 [erts-16.4.0.1] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit]
Elixir 1.21.0-dev (7a40579)
Operating system
any
Current behavior
The current implementation types the initializer with the expected type of the comprehension result. An initializer is always evaluated but its value may never reach the final reduction result.
Repro:
save this as reduce_repro.exs and execute
defmodule ReduceRepro do
def calculate(initial) do
(for _ <- [1], reduce: initial do
_ -> 1
end) + 1
end
def run, do: calculate(:old)
end
IO.inspect(ReduceRepro.run())
Result:
the code works fine and prints 2 but emits a false positive warning:
warning: incompatible types given to calculate/1:
calculate(:old)
given types:
:old
but expected one of:
float() or integer()
type warning found at:
│
8 │ def run, do: calculate(:old)
│ ~
│
└─ reduce_repro.exs:8:20: ReduceRepro.run/0
another example:
defmodule ReduceRepro1 do
def original(initial) do
:ok =
for _ <- [1], reduce: initial do
_ -> :ok
end
case initial do
:old -> :kept
_ -> :other
end
end
end
IO.inspect(ReduceRepro1.original(:old))
result: code prints kept and warns
warning: the following clause will never match:
:old ->
because it attempts to match on the result of:
initial
which has type:
dynamic(:ok)
type warning found at:
│
17 │ :old -> :kept
│ ~~~~~~~~~~~~~
│
└─ reduce_repro_1.exs:17: ReduceRepro1.original/1
initial is incorrectly narrowed to dynamic(:ok)
I believe this is a separate problem from https://github.com/elixir-lang/elixir/issues/15451 - covers refinements inside conditional code branches
Expected behavior
Initializer type should not be narrowed. Precise typing is probably not possible as the reducer callback is not guaranteed to execute (as in #15451).
Alternatively, if the behaviour is intended it should be documented in https://github.com/elixir-lang/elixir/blob/main/lib/elixir/pages/references/gradual-set-theoretic-types.md#false-positives
- Lenguaje dominante
- Elixir
- Estrellas
- 26.7k
- Forks
- 3.7k
- Merge medio
- 8 h 8 min
- PR fusionados (30 d)
- 61
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de elixir-lang/elixir
-
map_(get|put|update) ignore atom fields with static term() keyPosiblemente ocupada @lukaszsamson la tomó hace 25 días. Abierto
Dificultad 4/5 3-5 días Aptitud para principiantes 45/100
elixir-lang/elixir#15932 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 4/5 3-5 días Aptitud para principiantes 55/100
elixir-lang/elixir#15909 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 3/5 1-2 días Aptitud para principiantes 64/100
elixir-lang/elixir#15900 ·
Los mantenedores suelen responder en 1 día
-
Gradual map domain with `none` looses static part when computing lower boundPosiblemente ocupada @lukaszsamson la tomó hace 43 días. Abierto
Dificultad 4/5 3-5 días Aptitud para principiantes 48/100
elixir-lang/elixir#15854 · 2 comentarios ·
Los mantenedores suelen responder en 1 día
-
Dificultad 3/5 1-2 días Aptitud para principiantes 56/100
elixir-lang/elixir#15837 ·
Los mantenedores suelen responder en 1 día
Todos los issues de elixir-lang/elixir
Issues similares
-
bug(bgp): every BGP routing upsert fails because ON CONFLICT names an index, not a constraintAbiertobug
Dificultad 2/5 1-3 horas Aptitud para principiantes 80/100
carverauto/serviceradar#5732 ·
Los mantenedores suelen responder en 1 día
-
Markdown preview can show an outdated version of the cell sourcePosiblemente ocupada @RaphaelFakhri la tomó hace 1 día. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
livebook-dev/livebook#3228 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 93/100
TomerAberbach/profiler-md#732 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 83/100
inertiajs/inertia-phoenix#84 ·
-
good first issue
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
beyond-all-reason/teiserver#1676 ·
Los mantenedores suelen responder en 1 día