diff options
author | Hans Bolinder <[email protected]> | 2014-11-25 09:04:13 +0100 |
---|---|---|
committer | Hans Bolinder <[email protected]> | 2014-11-25 09:04:13 +0100 |
commit | 872fa86ddebbc84b07dc5426d25f7fb300731f52 (patch) | |
tree | 3c43332e7dd1eb6c83c2f685d8a571d1347a0087 | |
parent | ee11116c547c4559ed899ecadef9cf2038b2b336 (diff) | |
parent | d09c774343b78d663143ecc8930743ccded5f1c1 (diff) | |
download | otp-872fa86ddebbc84b07dc5426d25f7fb300731f52.tar.gz otp-872fa86ddebbc84b07dc5426d25f7fb300731f52.tar.bz2 otp-872fa86ddebbc84b07dc5426d25f7fb300731f52.zip |
Merge branch 'hb/dialyzer/fix_a_record_bug/OTP-12319' into maint
* hb/dialyzer/fix_a_record_bug/OTP-12319:
dialyzer: correct record updates
-rw-r--r-- | lib/dialyzer/test/small_SUITE_data/results/record_update | 2 | ||||
-rw-r--r-- | lib/dialyzer/test/small_SUITE_data/src/record_update.erl | 10 | ||||
-rw-r--r-- | lib/stdlib/src/erl_expand_records.erl | 9 |
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) -> |