Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

erl_lint: Warn on updating map/record literals #8069

Conversation

jhogberg
Copy link
Contributor

This PR adds a warning whenever a literal map or record is updated, catching errors like missing commas in lists of records:

-module(foo).
-export([list/0]).

-record(foo, {bar}).

list() ->
    [
        #foo{bar = foo} %% Missing comma!
        #foo{bar = bar}
    ].

https://erlangforums.com/t/maybe-a-bug-compiling-a-list-of-records-without-comma-between-them/3239

@jhogberg jhogberg added team:VM Assigned to OTP team VM enhancement testing currently being tested, tag is used by OTP internal CI labels Jan 30, 2024
@jhogberg jhogberg self-assigned this Jan 30, 2024
Copy link
Contributor

github-actions bot commented Jan 30, 2024

CT Test Results

    2 files     93 suites   35m 18s ⏱️
2 016 tests 1 968 ✅ 48 💤 0 ❌
2 325 runs  2 275 ✅ 50 💤 0 ❌

Results for commit 239f7c1.

♻️ This comment has been updated with latest results.

To speed up review, make sure that you have read Contributing to Erlang/OTP and that all checks pass.

See the TESTING and DEVELOPMENT HowTo guides for details about how to run test locally.

Artifacts

// Erlang/OTP Github Action Bot

@michalmuskala
Copy link
Contributor

This is definitely a very welcome change.

How does this interact with macros? Some code I've seen is shaped like:

-define(FOO_DEFAULT, #foo{...}).

?FOO_DEFAULT#foo{custom = value}

I'm not sure this should be a concern, but just something to consider.

@jhogberg
Copy link
Contributor Author

erl_lint runs after macro expansion, so yes, this PR would warn for that code. :-/

@jhogberg jhogberg merged commit 0122f9b into erlang:master Feb 1, 2024
17 checks passed
@michalmuskala
Copy link
Contributor

As a reference, this can be bypassed in macros by wrapping the literal map that's meant to be updated immediately in a begin/end block, e.g:

-define(range_anno(Tok1, Tok2), begin #{
    location => map_get(location, ?anno(Tok1)),
    end_location => map_get(end_location, ?anno(Tok2))
} end).

And then ?range_anno(X, Y)#{...} does not issue warnings and should introduce no runtime overhead.

We hit this in erlfmt - WhatsApp/erlfmt#354

keynslug added a commit to keynslug/mria that referenced this pull request Oct 18, 2024
Silence "expression updates a literal" compiler lint recently introduced
in erlang/otp#8069.
keynslug added a commit to keynslug/mria that referenced this pull request Oct 21, 2024
Silence "expression updates a literal" compiler lint recently introduced
in erlang/otp#8069.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement team:VM Assigned to OTP team VM testing currently being tested, tag is used by OTP internal CI
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants