Skip to content

unquote fails to compile in patterns and guards since 1.18 #15461

@lukaszsamson

Description

@lukaszsamson

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.20.1 (compiled with Erlang/OTP 28)

Affected versions: all since 1.18.0

Operating system

any

Current behavior

Since cc68ad9 all unquoted expressions are wrapped in runtime validation call but the validation is not allowing unquotes

Repro:

defmodule SchemaAst do
  def extract_defaulted_field(ast) do
    case ast do
      quote(do: {:field, unquote(name), default: 1}) -> {:ok, name}
      _ -> :error
    end
  end
end

on 1.18.0 - 1.20.1

error: cannot invoke remote function :elixir_quote.unquote/1 inside a match
└─ iex:4: SchemaAst.extract_defaulted_field/1

** (CompileError) iex: cannot compile module SchemaAst (errors have been logged)
    (elixir 1.20.1) src/elixir_expand.erl:659: :elixir_expand.expand_list/5
    (elixir 1.20.1) src/elixir_expand.erl:743: :elixir_expand.mapfold/5
    (elixir 1.20.1) src/elixir_expand.erl:25: :elixir_expand.expand/3
    (elixir 1.20.1) src/elixir_expand.erl:273: :elixir_expand.expand/3
    (elixir 1.20.1) src/elixir_expand.erl:731: :elixir_expand.expand_args/3
    (elixir 1.20.1) src/elixir_clauses.erl:169: :elixir_clauses.match/6
    iex:1: (file)

On 1.17.3

{:module, SchemaAst,
 <<70, 79, 82, 49, 0, 0, 6, 20, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 209,
   0, 0, 0, 21, 16, 69, 108, 105, 120, 105, 114, 46, 83, 99, 104, 101, 109, 97,
   65, 115, 116, 8, 95, 95, 105, 110, 102, ...>>, {:extract_defaulted_field, 1}}
SchemaAst.extract_defaulted_field({:{}, [], [:field, {:asd, [], nil}, [default: 1]]})
{:ok, {:asd, [], nil}}

The same applies for guard context. There were no breaking changes announced in 1.18 changelog and unquote stays supported in patterns and guards.

Expected behavior

Runtime validation should permit unquotes or if for some reason this is no longer supported it should be error with a nice message and be mentioned in as breaking change in changelog

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions