Skip to content

Commit 07c276a

Browse files
michalmuskalaJosé Valim
authored and
José Valim
committed
Fix issues with dialyzer infinite loop (#7993)
Signed-off-by: José Valim <[email protected]>
1 parent 89e3a81 commit 07c276a

File tree

4 files changed

+38
-24
lines changed

4 files changed

+38
-24
lines changed

lib/elixir/lib/calendar/date.ex

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -263,24 +263,29 @@ defmodule Date do
263263
@spec from_iso8601(String.t(), Calendar.calendar()) :: {:ok, t} | {:error, atom}
264264
def from_iso8601(string, calendar \\ Calendar.ISO)
265265

266-
[match_date, guard_date, read_date] = Calendar.ISO.__match_date__()
267-
268-
def from_iso8601(unquote(match_date), calendar) when unquote(guard_date) do
269-
{year, month, day} = unquote(read_date)
270-
271-
with {:ok, date} <- new(year, month, day, Calendar.ISO) do
272-
convert(date, calendar)
266+
def from_iso8601(<<?-, rest::binary>>, calendar) do
267+
with {:ok, %{year: year} = date} <- raw_from_iso8601(rest, calendar) do
268+
{:ok, %{date | year: -year}}
273269
end
274270
end
275271

276-
def from_iso8601(<<?-, next, rest::binary>>, calendar) when next != ?- do
277-
with {:ok, %{year: year} = date} <- from_iso8601(<<next>> <> rest, calendar) do
278-
{:ok, %{date | year: -year}}
279-
end
272+
def from_iso8601(<<rest::binary>>, calendar) do
273+
raw_from_iso8601(rest, calendar)
280274
end
281275

282-
def from_iso8601(<<_::binary>>, _calendar) do
283-
{:error, :invalid_format}
276+
[match_date, guard_date, read_date] = Calendar.ISO.__match_date__()
277+
278+
defp raw_from_iso8601(string, calendar) do
279+
with unquote(match_date) <- string,
280+
true <- unquote(guard_date) do
281+
{year, month, day} = unquote(read_date)
282+
283+
with {:ok, date} <- new(year, month, day, Calendar.ISO) do
284+
convert(date, calendar)
285+
end
286+
else
287+
_ -> {:error, :invalid_format}
288+
end
284289
end
285290

286291
@doc """

lib/elixir/lib/calendar/datetime.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -511,8 +511,8 @@ defmodule DateTime do
511511
[match_time, guard_time, read_time] = Calendar.ISO.__match_time__()
512512

513513
def from_iso8601(string, calendar \\ Calendar.ISO) when is_binary(string) do
514-
with <<unquote(match_date), sep, unquote(match_time), rest::binary>>
515-
when unquote(guard_date) and sep in @sep and unquote(guard_time) <- string,
514+
with <<unquote(match_date), sep, unquote(match_time), rest::binary>> <- string,
515+
true <- unquote(guard_date) and sep in @sep and unquote(guard_time),
516516
{microsecond, rest} <- Calendar.ISO.parse_microsecond(rest),
517517
{offset, ""} <- Calendar.ISO.parse_offset(rest) do
518518
{year, month, day} = unquote(read_date)

lib/elixir/lib/calendar/naive_datetime.ex

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -495,19 +495,23 @@ defmodule NaiveDateTime do
495495
@spec from_iso8601(String.t(), Calendar.calendar()) :: {:ok, t} | {:error, atom}
496496
def from_iso8601(string, calendar \\ Calendar.ISO)
497497

498-
def from_iso8601(<<?-, next, rest::binary>>, calendar) when next != ?- do
499-
with {:ok, %{year: year} = naive_datetime} <- from_iso8601(<<next>> <> rest, calendar) do
498+
def from_iso8601(<<?-, rest::binary>>, calendar) do
499+
with {:ok, %{year: year} = naive_datetime} <- raw_from_iso8601(rest, calendar) do
500500
{:ok, %{naive_datetime | year: -year}}
501501
end
502502
end
503503

504+
def from_iso8601(<<rest::binary>>, calendar) do
505+
raw_from_iso8601(rest, calendar)
506+
end
507+
504508
@sep [?\s, ?T]
505509
[match_date, guard_date, read_date] = Calendar.ISO.__match_date__()
506510
[match_time, guard_time, read_time] = Calendar.ISO.__match_time__()
507511

508-
def from_iso8601(string, calendar) when is_binary(string) do
509-
with <<unquote(match_date), sep, unquote(match_time), rest::binary>>
510-
when unquote(guard_date) and sep in @sep and unquote(guard_time) <- string,
512+
defp raw_from_iso8601(string, calendar) do
513+
with <<unquote(match_date), sep, unquote(match_time), rest::binary>> <- string,
514+
true <- unquote(guard_date) and sep in @sep and unquote(guard_time),
511515
{microsec, rest} <- Calendar.ISO.parse_microsecond(rest),
512516
{_offset, ""} <- Calendar.ISO.parse_offset(rest) do
513517
{year, month, day} = unquote(read_date)

lib/elixir/lib/calendar/time.ex

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,14 +217,19 @@ defmodule Time do
217217
@spec from_iso8601(String.t(), Calendar.calendar()) :: {:ok, t} | {:error, atom}
218218
def from_iso8601(string, calendar \\ Calendar.ISO)
219219

220-
def from_iso8601(<<?T, h, rest::binary>>, calendar) when h in ?0..?9 do
221-
from_iso8601(<<h, rest::binary>>, calendar)
220+
def from_iso8601(<<?T, rest::binary>>, calendar) do
221+
raw_from_iso8601(rest, calendar)
222+
end
223+
224+
def from_iso8601(<<rest::binary>>, calendar) do
225+
raw_from_iso8601(rest, calendar)
222226
end
223227

224228
[match_time, guard_time, read_time] = Calendar.ISO.__match_time__()
225229

226-
def from_iso8601(string, calendar) do
227-
with <<unquote(match_time), rest::binary>> when unquote(guard_time) <- string,
230+
defp raw_from_iso8601(string, calendar) do
231+
with <<unquote(match_time), rest::binary>> <- string,
232+
true <- unquote(guard_time),
228233
{microsec, rest} <- Calendar.ISO.parse_microsecond(rest),
229234
{_offset, ""} <- Calendar.ISO.parse_offset(rest) do
230235
{hour, min, sec} = unquote(read_time)

0 commit comments

Comments
 (0)