Commit Graph
12807 Commits
Author SHA1 Message Date
Barna Kovacs e25f52019a Optimize disjoint function argument checks (#15637)
Avoid allocating a zipped list before checking whether
function domains are disjoint.
2026-07-19 16:59:13 +02:00
José Valim 85b5838020 Ensure %_{} is precise in guards, closes #15635 2026-07-19 10:05:38 +02:00
LJZN 34abdd4361 Optimize Inspect.List.keyword?/1 by using Atom.to_string/1 (#15631)
Atom.to_charlist/1 allocates a new list per atom key when checking
if a keyword list contains module names. Atom.to_string/1 produces
a binary that can be pattern matched directly, avoiding O(n) temporary
allocations when inspecting large maps and keyword lists.

Benchmark (n=10):
  keyword?/1 (10K):  0.62ms -> 0.48ms (1.3x)
  keyword?/1 (50K):  2.72ms -> 1.69ms (1.6x)
  inspect map (10K): 2.59ms -> 1.52ms (1.7x)
  inspect map (50K): 8.85ms -> 5.94ms (1.5x)

Assisted-by: opencode:deepseek-v4-flash
2026-07-18 12:35:49 +02:00
José Valim d7c0671877 Bring back open_api_spex optimization 2026-07-17 21:10:58 +02:00
José Valim 27438994fd Optimize equal-head BDD intersections
Only preserve a shared union when absorption removes all
residual union terms. Normalize other equal-head intersections
eagerly to prevent exponential growth.

Closes #15629.

Assisted-by: Codex:GPT-5
2026-07-17 19:37:10 +02:00
José Valim 7bb87a7d0a Improve coverage of defguards 2026-07-17 16:21:50 +02:00
José Valim 895b4064c9 Remove :pid from info assertions 2026-07-17 10:35:22 +02:00
José Valim 0a21418534 Underscore unused variable 2026-07-17 10:12:29 +02:00
José Valim ca719e08fb Do not store optional in descr (#15624) 2026-07-17 01:20:39 +02:00
José Valim 2e2fdf84c8 Fix tests on Erlang/OTP main 2026-07-17 01:20:13 +02:00
José Valim 8564fd506a Remove recursive list intersection (#15622)
We couldn't measure any performance
benefit after latest optimizations.
2026-07-16 21:27:36 +02:00
José Valim 59e257d3ca Optimize tuple and map emptiness checks (#15619)
Short-circuit disjoint and subtype tuple elements
before exploring the general difference branches.

Assisted-by: Codex:GPT-5.6
2026-07-16 21:27:06 +02:00
Łukasz Samson 0821930417 Split tuple_insert_static into two paths (#15518)
- bdd_map on pure positive disjunction
- expand to the exact negation-free positive DNF, insert and union on negations and/or implicit :bdd_top

Fixes #15517
2026-07-16 17:49:13 +02:00
Patric f9a7552ab5 Fix incorrect examples and typos in guides (#15620)
The guide pages under lib/elixir/pages are not doctests, so some
example outputs drifted from what current Elixir prints. I re-ran
each example on main (1.21.0-dev, OTP 29) with a clean IEx and
updated the blocks to match the actual output. Also fixes two typos.
Map ordering examples were left untouched since small-map print
order is not guaranteed across OTP versions.

Signed-off-by: Patric Vinicios <psdev7@gmail.com>
2026-07-16 17:29:46 +02:00
José Valim 4fbe8ee9a7 Optimize empty descr keys 2026-07-16 13:53:42 +02:00
Guillaume Duboc d0b5519700 Support recursive type descriptors (#15530) 2026-07-16 13:36:17 +02:00
Panagiotis Nezis 3cf8682687 Fix Duration specs to allow negative microsecond values (#15611)
`Duration.t` and `Duration.unit_pair` referenced `Calendar.microsecond()`,
whose value is a `non_neg_integer`. However, durations may represent
negative amounts of time, negative microsecond values are advertised
by the module documentation, produced by parsing, and returned by the
module's own doctests:

    Duration.from_iso8601!("PT-0.5S")
    #=> %Duration{microsecond: {-500000, 1}}

Introduce a dedicated `Duration.microsecond()` type whose value is an
integer and whose precision is 0..6, matching what `new!/1` validates.
2026-07-14 18:08:30 +02:00
Alexander Gubarev d1a33f8b63 Fix Map.from_struct/1 typecheck (#15610) 2026-07-14 16:51:19 +02:00
Panagiotis Nezis 92c3b9fddd Fix Enum.min/2,3 and Enum.max/2,3 with a custom sorter on ranges (#15603)
The range clause of `aggregate/3` only compared the two endpoints of the
range, which is correct solely for sorters consistent with the natural
integer order. Any other comparator returned a different result than
the identical call on the equivalent list or stream:

    sorter = fn a, b -> rem(a, 5) >= rem(b, 5) end
    Enum.max(1..10, sorter)               #=> 1, expected 4
    Enum.max(Enum.to_list(1..10), sorter) #=> 4

Once the range is known to be non-empty, take the endpoint shortcut
only when the sorter is one of the defaults (`&>=/2` or `&<=/2`, both
order-consistent). Any other sorter traverses the elements through
`reduce_range/5`, seeded with the first element.
2026-07-14 11:19:08 +02:00
Alexander Gubarev 9ed6724440 Update Process.flag/2 specs (#15602) 2026-07-14 11:02:52 +02:00
Panagiotis Nezis 4c42f94aa2 Delete duplicate keys on :pop in Keyword.get_and_update/3 and get_and_update!/3 (#15604)
Both functions document updating "in one pass, deleting duplicate keys",
but the `:pop` branch left any later duplicates in place:

    Keyword.get_and_update([a: 1, a: 2], :a, fn _ -> :pop end)
    #=> {1, [a: 2]}, expected {1, []}
2026-07-14 10:51:11 +02:00
Alexander Gubarev 025d8ef8ce Fix Process.dest() spec and Process.send/3 update docs (#15601) 2026-07-13 19:26:33 +02:00
José Valim 6adff3fcc2 Fix cursor completion after operators
Treat trailing operator keywords as completion fragments
when they follow another operator.

Assisted-by: Codex:GPT-5

Closes #15591.
2026-07-11 16:52:00 +02:00
José Valim 259d52cba7 Provide proper signature for ++
And deal with compatibility checks in to_existing_atom/2.

Closes #15588.
2026-07-11 11:12:15 +02:00
nseaprotector 32597f08f7 Clarify :allow_pre does not affect < and <= in Version docs (#15590)
The `Version` moduledoc and `Version.match?/3` documentation stated
unconditionally that, with `allow_pre: false`, a pre-release version
would not match unless the operand was itself a pre-release. This holds
for the `~>`, `>`, and `>=` operators, which carry the `allow_pre`
guard, but not for `<` and `<=`, which have no such guard and match
pre-releases according to precedence regardless of the option:

    Version.match?("1.9.0-rc", ">= 1.0.0", allow_pre: false)  # => false
    Version.match?("1.9.0-rc", "< 2.0.0",  allow_pre: false)  # => true
2026-07-11 08:58:45 +02:00
Panagiotis Nezis a3522e4a25 Return 1.0 from String.bag_distance/2 with empty strings (#15587)
Both `String.jaro_distance/2` and the general bag distance algorithm return
1.0 for equal strings; the empty pair was the only exception.
2026-07-10 23:11:47 +02:00
Panagiotis Nezis 8fcf677082 Reject integer 0 in Float.round/2 (#15585) 2026-07-10 23:02:32 +02:00
Alexander Gubarev 6b61234adb Registry :compressed type opt and doc (#15586) 2026-07-10 21:40:36 +02:00
Panagiotis Nezis 717952aacf Reject non-integer arguments in Integer.extended_gcd/2 zero clauses (#15584)
The zero base-case clauses guarded only on comparison with 0, so under
Erlang term ordering non-integer arguments (floats, atoms) matched when
the other argument was 0, e.g. `Integer.extended_gcd(2.5, 0)` returned
`{2.5, 1, 0}` instead of raising, violating the spec and diverging from
`Integer.gcd/2`.
2026-07-10 19:46:23 +02:00
nseaprotector 5cad659e6d Fix NaiveDateTime.diff/3 over-counting incomplete units (#15583) 2026-07-10 18:19:18 +02:00
nseaprotector b3e4738a4c Fix Range.disjoint?/2 for single-element ranges with a negative step (#15582) 2026-07-10 13:04:10 +02:00
Alexander Gubarev f54719040c Improve docs for List.to_unsafe_atom/1 and String.to_unsafe_atom/1 (#15576) 2026-07-10 09:59:51 +02:00
Łukasz Samson f3aab1140b Add missing calendar key to Calendar.time() and fix truncate spec (#15572) 2026-07-10 09:51:13 +02:00
Łukasz Samson 5b21c6a168 Fix List specs that are broader than the inputs handled (#15571) 2026-07-10 09:49:32 +02:00
Alexander Gubarev b7a82bfcea Add spec to Registry.lock/3 (#15575) 2026-07-10 09:42:07 +02:00
Alexander Gubarev d0fb26a68a Add missing result marker in Inspect moduledoc (#15577) 2026-07-10 09:41:21 +02:00
Alexander Gubarev a324c883ce Fix Duration.from_iso8601/1 accepting duplicate S (secs) when fractional 2026-07-10 09:40:53 +02:00
Alexander Gubarev f401038c31 Expand Calendar examples and indent paragraph (#15578) 2026-07-10 09:36:10 +02:00
Alexander Gubarev 6d12dcecf7 Clarify pop_lazy docs (#15580) 2026-07-10 09:35:35 +02:00
nseaprotector e746c042bb Refine Time.to_seconds_after_midnight/1 return type (#15570) 2026-07-09 22:36:37 +02:00
nseaprotector 4e840bc094 Fix Agent timeout docs: non-negative, not greater than zero (#15569) 2026-07-09 20:39:38 +02:00
nseaprotector 345deb35cc Align GenServer.call/3 timeout doc to specs (#15568) 2026-07-09 20:38:57 +02:00
nseaprotector b7e22baa45 Fix Calendar.ISO.valid_time?/4 doc (#15567) 2026-07-09 20:38:07 +02:00
nseaprotector 1d9d560fcd Remove inaccurate note from Node.set_cookie/2 doc (#15566) 2026-07-09 20:24:05 +02:00
nseaprotector 6957e15210 Make IO.getn and IO.read docs consistent (#15565) 2026-07-09 20:01:30 +02:00
Alexander Gubarev b82c44a109 Update most common delimeters in Markdown ANSI rendering (#15564) 2026-07-09 16:50:40 +02:00
Łukasz Samson 1cb2089367 Tighten stdlib typespecs to match implementations (#15561)
Candidates found by cross-checking @specs against the type signatures
inferred by the compiler (see #15559): these specs declared strictly
wider return types than the functions can produce, where the gap
carries no intentional API room (deliberately abstract contracts, such
as atom() covering future values, are left untouched):

  * File.Stream.t/0: type the struct fields (mirrors IO.Stream.t/0)
  * Map.new/0: %{} instead of map()
  * Logger.levels/0: Exclude deprecated :warn
  * Macro.Env.location/1 and Macro.Env.stacktrace/1: precise shapes
2026-07-09 16:50:13 +02:00
Łukasz Samson 77426cc770 Handle Erlang/OTP 28 nominal types in Code.Typespec.fetch_types/1 (#15562) 2026-07-09 14:25:59 +02:00
Alexander Gubarev ecf55172c7 Fix DateRange slice step computation (#15560) 2026-07-09 13:46:23 +02:00
nseaprotector 251d3fe5b2 Fix Base.decode16!/2 doc: base 16 has no padding (#15558) 2026-07-09 12:02:39 +02:00