aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stdlib/src/erl_expand_records.erl
AgeCommit message (Collapse)Author
2017-05-04Update copyright yearRaimo Niskanen
2017-02-12Use maps instead of dict in erl_expand_recordsJosé Valim
2016-09-02Fix overridden BIFsBjörn Gustavsson
The filters in a list comprehension can be guard expressions or an ordinary expressions. If a guard expression is used as a filter, an exception will basically mean the same as 'false': t() -> L = [{some_tag,42},an_atom], [X || X <- L, element(1, X) =:= some_tag] %% Returns [{some_tag,42}] On the other hand, if an ordinary expression is used as a filter, there will be an exception: my_element(N, T) -> element(N, T). t() -> L = [{some_tag,42},an_atom], [X || X <- L, my_element(1, X) =:= some_tag] %% Causes a 'badarg' exception when element(1, an_atom) is evaluated It has been allowed for several releases to override a BIF with a local function. Thus, if we define a function called element/2, it will be called instead of the BIF element/2 within the module. We must use the "erlang:" prefix to call the BIF. Therefore, the following code is expected to work the same way as in our second example above: -compile({no_auto_import,[element/2]}). element(N, T) -> erlang:element(N, T). t() -> L = [{some_tag,42},an_atom], [X || X <- L, element(1, X) =:= some_tag]. %% Causes a 'badarg' exception when element(1, an_atom) is evaluated But the compiler refuses to compile the code with the following diagnostic: call to local/imported function element/2 is illegal in guard
2016-09-01Teach erl_expand_records to translate module-less callsBjörn Gustavsson
As the next step in eliminating sys_pre_expand, teach erl_expand_records to handle calls without explicit module name. If such call refer to a BIF or imported function, add an explicit module name. That means that any subsequent pass will know that a call without a module name is always to a local function defined in the module.
2016-06-09stdlib: Correct types and specsHans Bolinder
2016-02-17stdlib: Update erl_expand_records to handle typed record fieldsBjörn Gustavsson
2015-06-18Change license text to APLv2Bruce Yinhe
2015-04-30stdlib: Use module erl_annoHans Bolinder
2015-04-22erl_expand_records: Simplify handling of call_ext instructionsBjörn Gustavsson
The erl_expand_records module have inherited code from sys_pre_expand. We can simplify the code for handling the call_ext instruction to make the code clearer and a smidge faster.
2014-11-24dialyzer: correct record updatesHans Bolinder
Correct a bug introduced in commit 8498a3.
2014-06-17[dialyzer] Use the option 'dialyzer' to control the compilerHans Bolinder
2014-06-17[dialyzer] Fix handling of literal recordsHans Bolinder
This ticket is about records in Erlang code, and when to check the fields against the (optional) types given when defining records. Dialyzer operates on the Erlang Core format, where there are no trace of records. The fix implemented is a Real Hack: Given the new option 'dialyzer' erl_expand_records marks the line number of records in a way that is undone by v3_core, which in turn inserts annotations that can be recognized by Dialyzer.
2014-04-03compiler,stdlib: Fix Map literals as keys for Maps in patternsBjörn-Egil Dahlberg
2014-02-04Fix expansion of records in mapsAnthony Ramine
Records were not properly expanded in keys in patterns and in arguments in map updates.
2014-01-28Update erl_lint, erl_expand_records, sys_pre_expand for MapsBjörn-Egil Dahlberg
Update erlang lint and syntax expand for #{ K := V }
2014-01-28Update erl_lint, erl_expand_records, sys_pre_expand for mapsBjörn Gustavsson
2013-12-12EEP 37: Funs with namesAnthony Ramine
This adds optional names to fun expressions. A named fun expression is parsed as a tuple `{named_fun,Loc,Name,Clauses}` in erl_parse. If a fun expression has a name, it must be present and be the same in every of its clauses. The function name shadows the environment of the expression shadowing the environment and it is shadowed by the environment of the clauses' arguments. An unused function name triggers a warning unless it is prefixed by _, just as every variable. Variable _ is allowed as a function name. It is not an error to put a named function in a record field default value. When transforming to Core Erlang, the named fun Fun is changed into the following expression: letrec 'Fun'/Arity = fun (Args) -> let <Fun> = 'Fun'/Arity in Case in 'Fun'/Arity where Args is the list of arguments of 'Fun'/Arity and Case the Core Erlang expression corresponding to the clauses of Fun. This transformation allows us to entirely skip any k_var to k_local transformation in the fun's clauses bodies.
2013-01-09erl_expand_records: Remove support for packagesBjörn Gustavsson
2012-12-03erl_expand_records: Remove stale support for literal tuple funsBjörn Gustavsson
2012-03-30Update copyright yearsBjörn-Egil Dahlberg
2012-01-25Ensure that generated record operations don't call local functionsBjörn Gustavsson
Consistently use external (remote) calls to the BIFs element/2, setelement/3, and is_record/3.
2011-09-15Fix misspelling of successfulTuncer Ayaz
2011-05-12Types and specifications have been modified and addedHans Bolinder
2010-06-07Fix confusing dialyzer warnings for is_record/2 with illegal recordsBjörn Gustavsson
In commit 1858cb81391d2bce29b4b7620574ca60128cebf7, erl_expand_records started to optimize is_record/2 in guards by replacing it with pattern matching (if possible). Unfortunately, dialyzer will no longer see the code before the optimization, so any warnings produced in code such as: case ExprNotProducingRecord#rec{} of X when is_record(X, rec, N) -> ... will refer to the optimized code and not the source code, which is confusing for the user. Introduce the no_is_record_optimization option for turning off the optimization and use it in dialyzer. Reported-by: Kostis Sagonas
2010-06-02erl_expand_records: Replace is_record() with matchingBjörn Gustavsson
The compiler currently generates better code for: f(#r1{}) -> r1; f(#r2{}) -> r2; f(#r3{}) -> r3. than for: g(X) when is_record(X, r1) -> r1; g(X) when is_record(X, r2) -> r2; g(X) when is_record(X, r3) -> r3. The compiler generates good code for pattern matching (as in f/1), but in g/1 there are no patterns to match, and the clause to be executed must be chosen by evaluating the guards sequentially until one succeeds. Make the compiler generate better code by replacing calls to is_record() with matching in the function head (basically, g/1 will automatically be rewritten to do pattern matching as in f/1). Note that this rewrite will also benefit code such as: h(X) when X#r1.a =:= 1 -> ok. because it would have been rewritten to: h(X) when (is_record(X, r1, 3) orelse fail) and (element(2, X) =:= 1) -> ok. which in turn will be rewritten to: h({r1,_,_}=X) when (true orelse fail) and (element(2, X) =:= 1) -> ok. (That will be further simplified in later compiler passes.)
2010-03-16Remove stray code supporting 'cond'Björn Gustavsson
'cond' is an experimental feature that was never completed.
2010-03-16Remove stray code supporting constant/1Björn Gustavsson
The guard test constant/1 was removed in R13B.
2009-11-20The R13B03 release.OTP_R13B03Erlang/OTP