anchor.diff:  -export([match/3, clause/5, def/2, head/2,
            'case'/3, 'receive'/3, 'try'/3, 'cond'/3, with/3,
            format_error/1]).
  --import(elixir_errors, [form_error/4]).
  +-import(elixir_errors, [form_error/4, form_warn/4]).
   -include("elixir.hrl").
   
   match(Fun, Expr, #{context := match} = E) ->
  
positive.code:   warn_zero_length_guard(EGuard, EG),
    {EGuard, EG}.
  
  warn_zero_length_guard({{'.', _, [erlang, '==']}, Meta,
                          [{{'.', _, [erlang, length]}, _, [Arg]}, 0]}, E) ->
    ArgString = 'Elixir.Macro':to_string(Arg),
    Message = io_lib:format("do not use \"length(~ts) == 0\" to check if a list is empty "
                            "since length always traverses the whole list. "
                            "Prefer to pattern match on an empty list or use "
                            "\"~ts == []\" as a guard", [ArgString, ArgString]),
    elixir_errors:warn(?line(Meta), ?key(E, file), Message);
  warn_zero_length_guard({{'.', _, [erlang, '>']}, Meta,
                          [{{'.', _, [erlang, length]}, _, [Arg]}, 0]}, E) ->
    ArgString = 'Elixir.Macro':to_string(Arg),
    Message = io_lib:format("do not use \"length(~ts) > 0\" to check if a list is not empty "
                            "since length always traverses the whole list. "
                            "Prefer to pattern match on a non-empty list, such as [_ | _], "
                            "or use \"~ts != []\" as a guard", [ArgString, ArgString]),
    elixir_errors:warn(?line(Meta), ?key(E, file), Message);
  warn_zero_length_guard({Op, _, [L, R]}, E) when Op == 'or'; Op == 'and' ->
    warn_zero_length_guard(L, E),
    warn_zero_length_guard(R, E);
  
negative.code: 
  format_error(invalid_rescue_clause) ->
    "invalid \"rescue\" clause. The clause should match on an alias, a variable "
      "or be in the \"var in [alias]\" format";
  
  format_error(catch_before_rescue) ->
    "\"catch\" should always come after \"rescue\" in try";
  
  format_error(unmatchable_else_in_with) ->
    "\"else\" clauses will never match because all patterns in \"with\" will always match";
  
  format_error({zero_list_length_in_guard, ListArg}) ->
    Arg = 'Elixir.Macro':to_string(ListArg),
    io_lib:format("do not use \"length(~ts) == 0\" to check if a list is empty since length "
                  "always traverses the whole list. Prefer to pattern match on an empty list or "
                  "use \"~ts == []\" as a guard", [Arg, Arg]);
  
  format_error({positive_list_length_in_guard, ListArg}) ->
    Arg = 'Elixir.Macro':to_string(ListArg),
    io_lib:format("do not use \"length(~ts) > 0\" to check if a list is not empty since length "
                  "always traverses the whole list. Prefer to pattern match on a non-empty list, "
                  "such as [_ | _], or use \"~ts != []\" as a guard", [Arg, Arg]).
  