Age | Commit message (Collapse) | Author |
|
The parser recognizes the 'is_subtype(V, T)' syntax for constraints,
and of course the new 'V :: T' syntax, but other variants result in an
error message. Up to now, the parser and linter have let badly formed
constraints through, and relied upon Dialyzer to emit warnings.
is_subtype/2 cannot easily be taken out from the parser. Not only
would we need find a way to emit a (linter) warning, but there also
needs to be an option for suppressing the linter warning as
compilation with +warnings_as_errors has to work. (Notice that the
abstract format representation for 'V :: T' is the same as for
'is_subtype(V, T)'.)
This correction was triggered by an email from Robert, and Kostis
created pull request 1214 to provide a fix. However, Kostis' fix
disallowed is_subtype() altogether, which breaks backward
compatibility.
As of Erlang/OTP 19.0 (ticket OTP-11879), the 'is_subtype(V, T)' is no
longer documented.
|
|
sys_pre_expand previously did a lot more work, for example,
translating records and funs, but now is merely a grab bag
of small transformations. Move those transformations to
v3_core.
|
|
|
|
It is possible that '...' is added later (OTP 20.0), but for now we
are not sure of all details.
|
|
|
|
|
|
|
|
While we are it, also re-ident the files.
|
|
We want to re-ident the source files after having taken out
all ?line macros. When re-indenting using Emacs, it's important
that comments that should be at the beginning of a line (or
follow the indentation of statements around it) must start with
"%%".
|
|
|
|
There is no practial difference.
|
|
|
|
Either rely on the default 30 minutes timetrap, or set the timeout
using the supported methods in common_test.
|
|
As a first step to removing the test_server application as
as its own separate application, change the inclusion of
test_server.hrl to an inclusion of ct.hrl and remove the
inclusion of test_server_line.hrl.
|
|
|
|
The syntax -spec/callback F/A :: FunctionType; has been removed.
No deprecation was deemed necessary.
|
|
* maint:
doc: Fix some minor issues in Types and Function Specifications
erts: Remove CDATA from The Abstract Format document
erts: Correct the types section in The Abstract Format document
stdlib: Correct pretty-printing of map types
stdlib: Pretty-print constraints as 'V :: T'
Conflicts:
erts/doc/src/absform.xml
|
|
Add parentheses around annotated type union elements in map pair
types. The bug was introduced in Erlang/OTP 18.0.
|
|
Background
-----------
In record fields with a type declaration but without an initializer, the
Erlang parser inserted automatically the singleton type 'undefined' to
the list of declared types, if that value was not present there.
I.e. the record declaration:
-record(rec, {f1 :: float(),
f2 = 42 :: integer(),
f3 :: some_mod:some_typ()}).
was translated by the parser to:
-record(rec, {f1 :: float() | 'undefined',
f2 = 42 :: integer(),
f3 :: some_mod:some_typ() | 'undefined'}).
The rationale for this was that creation of a "dummy" #rec{} record
should not result in a warning from dialyzer that e.g. the implicit
initialization of the #rec.f1 field violates its type declaration.
Problems
---------
This seemingly innocent action has some unforeseen consequences.
For starters, there is no way for programmers to declare that e.g. only
floats make sense for the f1 field of #rec{} records when there is no
`obvious' default initializer for this field. (This also affects tools
like PropEr that use these declarations produced by the Erlang parser to
generate random instances of records for testing purposes.)
It also means that dialyzer does not warn if e.g. an is_atom/1 test or
something more exotic like an atom_to_list/1 call is performed on the
value of the f1 field.
Similarly, there is no way to extend dialyzer to warn if it finds record
constructions where f1 is not initialized to some float.
Last but not least, it is semantically problematic when the type of the
field is an opaque type: creating a union of an opaque and a structured
type is very problematic for analysis because it fundamentally breaks
the opacity of the term at that point.
Change
-------
To solve these problems the parser will not automatically insert the
'undefined' value anymore; instead the user has the option to choose the
places where this value makes sense (for the field) and where it does
not and insert the | 'undefined' there manually.
Consequences of this change
----------------------------
This change means that dialyzer will issue a warning for all places
where records with uninitialized fields are created and those fields have
a declared type that is incompatible with 'undefined' (e.g. float()).
This warning can be suppressed easily by adding | 'undefined' to the
type of this field. This also adds documentation that the user really
intends to create records where this field is uninitialized.
|
|
|
|
Add new functions erl_parse:type_inop_prec() and
erl_parse:type_preop_prec().
Get rid of paren_type used for parentheses in types.
|
|
|
|
Robert has OK'ed the removal of the token ':-'.
|
|
|
|
|
|
|
|
product/_, union/_, range/2 as well as tuple/N (N > 0), map/N (N > 0),
atom/1, integer/1, binary/2, record/_, and 'fun'/_ can now be used as
type names.
|
|
|
|
|
|
|
|
|
|
Conflicts:
bootstrap/lib/stdlib/ebin/erl_pp.beam
|
|
|
|
* maint:
[stdlib] Fix pretty printing of invalid forms
|
|
Thanks to Tomáš Janoušek.
|
|
|
|
Also let the Erlang shell use the new function io:printable_range().
|
|
|
|
|
|
Expect modifications, additions and corrections.
There is a kludge in file_io_server and
erl_scan:continuation_location() that's not so pleasing.
|
|
Currently, the external fun syntax "fun M:F/A" only supports
literals. That is, "fun lists:reverse/1" is allowed but not
"fun M:F/A".
In many real-life situations, some or all of M, F, A are
not known until run-time, and one is forced to either use
the undocumented erlang:make_fun/3 BIF or to use a
"tuple fun" (which is deprecated).
EEP-23 suggests that the parser (erl_parse) should immediately
transform "fun M:F/A" to "erlang:make_fun(M, F, A)". We have
not followed that approach in this implementation, because we
want the abstract code to mirror the source code as closely
as possible, and we also consider erlang:make_fun/3 to
be an implementation detail that we might want to remove in
the future.
Instead, we will change the abstract format for "fun M:F/A" (in a way
that is not backwards compatible), and while we are at it, we will
move the translation from "fun M:F/A" to "erlang:make_fun(M, F, A)"
from sys_pre_expand down to the v3_core pass. We will also update
the debugger and xref to use the new format.
We did consider making the abstract format backward compatible if
no variables were used in the fun, but decided against it. Keeping
it backward compatible would mean that there would be different
abstract formats for the no-variable and variable case, and tools
would have to handle both formats, probably forever.
Reference: http://www.erlang.org/eeps/eep-0023.html
|
|
|
|
The default value 'undefined' was added to records field types in such
a way that the result was not always a well-formed type. This bug has
been fixed.
---
erl_pp has since OTP-8150 formatted types so that 'undefined' was
removed from union types assigned to record fields. Since one cannot
distinguish between 'undefined' added by the parser or supplied by the
user, a side effect was that user supplied 'undefined's were also
removed.
Now the pretty printer shows 'undefined' even if added by the parser.
This is a minor issue.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|