Age | Commit message (Collapse) | Author |
|
t_subtract/2 would break its postcondition by always returning the
underapproximation none() when given a variable on the right hand side.
This broke map type parsing, since it relied on t_subtract/2 to tell it
when map keys would shadow each other.
|
|
Opaque keys in maps broke an assumption in
erl_types:mapmerge_otherv/3 (that the infinimum of a singleton type and
some other type would either be none() or that same singleton type),
causing a case_clause crash.
|
|
dialyzer_typesig:traverse/3 would perform an unsafe optimisation when
given a cons pattern that contained a map and could be folded into a
literal with cerl:fold_literal/1. In this case, when traversing the map
a type variable would be generated, but this variable would be dropped
by the erl_types:t_cons/2 constructor by in turn calling t_sup(),
producing the overapproximation any(). However, in this particular case,
dialyzer_typesig:traverse/3 is not allowed to overapproximate, since its
result is used in an EQ-constraint.
Although erl_types:t_tuple/1 does not overapproximate like t_cons/2,
which makes the bug unlikely to affect tuples too, the fix was
nevertheless applied defensively to the case of tuples as well.
Also, fix a bug where dialyzer_utils:refold_pattern/1 would generate
syntax nodes with two {label, _} attributes.
|
|
This is analogous to the case of nil. Since #{} is a base-case of almost
all map types, contract and success typing sharing #{} does not mean
much, and is often sign of a violation.
|
|
Dialyzer relies heavily on the assumption that the type of a literal
that is used as a pattern is the type of any value that can match that
pattern. For maps, that is not true, and it was causing bad analysis
results. A new help function dialyzer_utils:refold_pattern/1 identifies
maps in literal patterns, and unfolds and labels them, allowing them to
be properly analysed.
|
|
|
|
|