aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorHans Bolinder <[email protected]>2014-11-25 09:06:13 +0100
committerHans Bolinder <[email protected]>2014-11-25 09:06:13 +0100
commitb0a48f37a5c04d158369cc69d5a8afafd67663cd (patch)
tree391bb3c30bc396a927f56418f9fd9a5dfe3272c1 /lib
parentb36de499775d6dfcdb61ce1df079911a4ed3f2d5 (diff)
parent872fa86ddebbc84b07dc5426d25f7fb300731f52 (diff)
downloadotp-b0a48f37a5c04d158369cc69d5a8afafd67663cd.tar.gz
otp-b0a48f37a5c04d158369cc69d5a8afafd67663cd.tar.bz2
otp-b0a48f37a5c04d158369cc69d5a8afafd67663cd.zip
Merge branch 'maint'
* maint: dialyzer: correct record updates
Diffstat (limited to 'lib')
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/record_update2
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/record_update.erl10
-rw-r--r--lib/stdlib/src/erl_expand_records.erl9
3 files changed, 19 insertions, 2 deletions
diff --git a/lib/dialyzer/test/small_SUITE_data/results/record_update b/lib/dialyzer/test/small_SUITE_data/results/record_update
new file mode 100644
index 0000000000..ea52057adf
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/results/record_update
@@ -0,0 +1,2 @@
+
+record_update.erl:7: Invalid type specification for function record_update:quux/2. The success typing is (#foo{bar::atom()},atom()) -> #foo{bar::atom()}
diff --git a/lib/dialyzer/test/small_SUITE_data/src/record_update.erl b/lib/dialyzer/test/small_SUITE_data/src/record_update.erl
new file mode 100644
index 0000000000..bad7a0a929
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/record_update.erl
@@ -0,0 +1,10 @@
+-module(record_update).
+
+-export([quux/2]).
+
+-record(foo, {bar :: atom()}).
+
+-spec quux(#foo{}, string()) -> #foo{}.
+
+quux(Foo, NotBar) ->
+ Foo#foo{ bar = NotBar }.
diff --git a/lib/stdlib/src/erl_expand_records.erl b/lib/stdlib/src/erl_expand_records.erl
index c74f68647f..64a00acd88 100644
--- a/lib/stdlib/src/erl_expand_records.erl
+++ b/lib/stdlib/src/erl_expand_records.erl
@@ -702,9 +702,10 @@ record_update(R, Name, Fs, Us0, St0) ->
record_match(R, Name, Lr, Fs, Us, St0) ->
{Ps,News,St1} = record_upd_fs(Fs, Us, St0),
NLr = neg_line(Lr),
+ RLine = record_offset(Lr, St1),
{{'case',Lr,R,
- [{clause,Lr,[{tuple,Lr,[{atom,Lr,Name} | Ps]}],[],
- [{tuple,Lr,[{atom,Lr,Name} | News]}]},
+ [{clause,Lr,[{tuple,RLine,[{atom,Lr,Name} | Ps]}],[],
+ [{tuple,RLine,[{atom,Lr,Name} | News]}]},
{clause,NLr,[{var,NLr,'_'}],[],
[call_error(NLr, {tuple,NLr,[{atom,NLr,badrecord},{atom,NLr,Name}]})]}
]},
@@ -733,6 +734,10 @@ record_setel(R, Name, Fs, Us0) ->
Lr = element(2, hd(Us)),
Wildcards = duplicate(length(Fs), {var,Lr,'_'}),
NLr = neg_line(Lr),
+ %% Note: calling record_offset() here is not necessary since it is
+ %% targeted at Dialyzer which always calls the compiler with
+ %% 'strict_record_updates' meaning that record_setel() will never
+ %% be called.
{'case',Lr,R,
[{clause,Lr,[{tuple,Lr,[{atom,Lr,Name} | Wildcards]}],[],
[foldr(fun ({I,Lf,Val}, Acc) ->