Skip to content

Commit 8460488

Browse files
author
José Valim
committed
Error if guards are given but no implementation, closes #1125
1 parent fed8796 commit 8460488

File tree

2 files changed

+27
-21
lines changed

2 files changed

+27
-21
lines changed

lib/elixir/src/elixir_def.erl

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ store_definition(Kind, Line, CheckClauses, Module, Call, Body, RawS) ->
109109
assert_no_aliases_name(Line, Name, Args, S),
110110
store_definition(Kind, Line, CheckClauses, Module, Name, Args, Guards, Body, S).
111111

112-
store_definition(Kind, Line, _CheckClauses, nil, _Name, _Args, _Guards, _Body, #elixir_scope{} = S) ->
113-
elixir_errors:syntax_error(Line, S#elixir_scope.file, "cannot define function outside module, invalid scope for ~ts", [Kind]);
112+
store_definition(Kind, Line, _CheckClauses, nil, _Name, _Args, _Guards, _Body, #elixir_scope{file=File}) ->
113+
elixir_errors:form_error(Line, File, ?MODULE, { no_module, Kind });
114114

115115
store_definition(Kind, Line, CheckClauses, Module, Name, Args, Guards, Body, #elixir_scope{} = DS) ->
116116
Arity = length(Args),
@@ -196,9 +196,12 @@ translate_definition(Kind, Line, Name, RawArgs, RawGuards, RawBody, S) when is_i
196196
Function = { function, Line, Name, Arity, Clauses },
197197
{ Function, Defaults, TS }.
198198

199-
translate_clause(_Line, _Kind, _Unpacked, _Guards, nil, S) ->
199+
translate_clause(_Line, _Kind, _Unpacked, [], nil, S) ->
200200
{ [], S };
201201

202+
translate_clause(Line, Kind, _Unpacked, _Guards, nil, #elixir_scope{file=File}) ->
203+
elixir_errors:syntax_error(Line, File, "missing keyword do in ~ts", [Kind]);
204+
202205
translate_clause(Line, Kind, Unpacked, Guards, Body, S) ->
203206
Expr = expr_from_body(Line, Body),
204207

@@ -311,8 +314,8 @@ store_each(Check, Kind, File, Location, Table, CTable, Defaults, {function, Line
311314
FinalLocation = StoredLocation,
312315
FinalDefaults = max(Defaults, StoredDefaults),
313316
check_valid_kind(Line, File, Name, Arity, Kind, StoredKind),
314-
check_valid_defaults(Line, File, Name, Arity, Defaults, StoredDefaults),
315-
(Check and StoredCheck) andalso check_valid_clause(Line, File, Name, Arity, Table);
317+
check_valid_defaults(Line, File, Name, Arity, Kind, Defaults, StoredDefaults),
318+
(Check and StoredCheck) andalso check_valid_clause(Line, File, Name, Arity, Kind, Table);
316319
[] ->
317320
FinalLine = Line,
318321
FinalLocation = Location,
@@ -329,38 +332,41 @@ check_valid_kind(Line, File, Name, Arity, Kind, StoredKind) ->
329332
elixir_errors:form_error(Line, File, ?MODULE,
330333
{ changed_kind, { Name, Arity, StoredKind, Kind } }).
331334

332-
check_valid_clause(Line, File, Name, Arity, Table) ->
335+
check_valid_clause(Line, File, Name, Arity, Kind, Table) ->
333336
case ets:lookup_element(Table, last, 2) of
334337
{Name,Arity} -> [];
335338
[] -> [];
336339
_ ->
337340
elixir_errors:handle_file_warning(File, { Line, ?MODULE,
338-
{ override_function, { Name, Arity } } })
341+
{ override_function, { Kind, Name, Arity } } })
339342
end.
340343

341-
check_valid_defaults(_Line, _File, _Name, _Arity, 0, _) -> [];
342-
check_valid_defaults(Line, File, Name, Arity, _, 0) ->
343-
elixir_errors:handle_file_warning(File, { Line, ?MODULE, { out_of_order_defaults, { Name, Arity } } });
344-
check_valid_defaults(Line, File, Name, Arity, _, _) ->
345-
elixir_errors:handle_file_warning(File, { Line, ?MODULE, { clauses_with_defaults, { Name, Arity } } }).
344+
check_valid_defaults(_Line, _File, _Name, _Arity, _Kind, 0, _) -> [];
345+
check_valid_defaults(Line, File, Name, Arity, Kind, _, 0) ->
346+
elixir_errors:handle_file_warning(File, { Line, ?MODULE, { out_of_order_defaults, { Kind, Name, Arity } } });
347+
check_valid_defaults(Line, File, Name, Arity, Kind, _, _) ->
348+
elixir_errors:handle_file_warning(File, { Line, ?MODULE, { clauses_with_defaults, { Kind, Name, Arity } } }).
346349

347350
assert_no_aliases_name(Line, '__aliases__', [Atom], #elixir_scope{file=File}) when is_atom(Atom) ->
348351
Message = "function names should start with lowercase characters or underscore, invalid name ~ts",
349-
elixir_errors:syntax_error(Line, File, Message, [atom_to_binary(Atom, utf8)]);
352+
elixir_errors:syntax_error(Line, File, Message, [Atom]);
350353

351354
assert_no_aliases_name(_Meta, _Aliases, _Args, _S) ->
352355
ok.
353356

354357
%% Format errors
355358

356-
format_error({clauses_with_defaults,{Name,Arity}}) ->
357-
io_lib:format("function ~ts/~B has default values and multiple clauses, use a separate clause for declaring defaults", [Name, Arity]);
359+
format_error({no_module,{Kind,Name,Arity}}) ->
360+
io_lib:format("cannot define function outside module, invalid scope for ~ts ~ts/~B", [Kind, Name, Arity]);
361+
362+
format_error({clauses_with_defaults,{Kind,Name,Arity}}) ->
363+
io_lib:format("~ts ~ts/~B has default values and multiple clauses, use a separate clause for declaring defaults", [Kind, Name, Arity]);
358364

359-
format_error({out_of_order_defaults,{Name,Arity}}) ->
360-
io_lib:format("clause with defaults should be the first clause in function ~ts/~B", [Name, Arity]);
365+
format_error({out_of_order_defaults,{Kind,Name,Arity}}) ->
366+
io_lib:format("clause with defaults should be the first clause in ~ts ~ts/~B", [Kind, Name, Arity]);
361367

362-
format_error({override_function,{Name,Arity}}) ->
363-
io_lib:format("trying to override previously defined function ~ts/~B", [Name, Arity]);
368+
format_error({override_function,{Kind,Name,Arity}}) ->
369+
io_lib:format("trying to override previously defined ~ts ~ts/~B", [Kind, Name, Arity]);
364370

365371
format_error({changed_kind,{Name,Arity,Previous,Current}}) ->
366372
io_lib:format("~ts ~ts/~B already defined as ~ts", [Current, Name, Arity, Previous]).

lib/elixir/test/elixir/kernel/warning_test.exs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ defmodule Kernel.WarningTest do
153153
def hello(arg // 0), do: nil
154154
end
155155
"""
156-
end) =~ %r"clause with defaults should be the first clause in function hello/1"
156+
end) =~ %r"clause with defaults should be the first clause in def hello/1"
157157
after
158158
purge Sample
159159
end
@@ -166,7 +166,7 @@ defmodule Kernel.WarningTest do
166166
def hello(arg // 1), do: nil
167167
end
168168
"""
169-
end) =~ %r"function hello/1 has default values and multiple clauses, use a separate clause for declaring defaults"
169+
end) =~ %r"def hello/1 has default values and multiple clauses, use a separate clause for declaring defaults"
170170
after
171171
purge Sample
172172
end

0 commit comments

Comments
 (0)