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

[Fix #7287] Auto-correction of FrozenStringLiteralComment is unsafe #7307

Merged
merged 1 commit into from Jan 2, 2020

Conversation

buehmann
Copy link
Contributor

@buehmann buehmann commented Aug 23, 2019

Auto-correction of Style/FrozenStringLiteralComment changes the state of
string objects in a program and may thus break it.

This closes #7287.

@koic
Copy link
Member

koic commented Aug 23, 2019

IMHO, SafeAutoCorrect: false may not be a bad choice. For example, it causes a breaking change when a string passed from a dependent gem changes from a mutable string to a frozen string.

However, it may be better to warn users to use String#dup or String#+@ for destructive operations on frozen string literals. AFAIK, matz has not given up the possibility of defaulting to a frozen string in the future. In Ruby 3.0, matz was abandant for changing it because there were not enough tools to prevent destructive changes (I heard that at RubyConf Taiwan 2019).

Therefore, I couldn't conclude and was pending this configuration.

@bbatsov
Copy link
Collaborator

bbatsov commented Aug 28, 2019

However, it may be better to warn users to use String#dup or String#+@ for destructive operations on frozen string literals.

I guess that should be a different cop, though, right?

@@ -2730,6 +2730,7 @@ Style/FrozenStringLiteralComment:
# `never` will enforce that the frozen string literal comment does not
# exist in a file.
- never
SafeAutoCorrect: false
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the cop is actually unsafe (as it doesn't actually check the source to figure out if it's ok to add the magic comment). Unsafe for a cop means that it yields false positives or the suggestions can change the meaning of the code. Unsafe for auto-correct means the cop the cop suggestions are safe, but the auto-correct can't apply those reliably.

Copy link
Member

@koic koic Aug 28, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get it! That makes sense to me. Thanks for the explanation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the cop is actually unsafe

Makes sense. Should we add Safe: false then as well?

Having looked into how --safe and --safe-auto-correct work I am a bit confused, though:

Is it correct that currently rubocop --safe-auto-correct applies "safe" autocorrections of unsafe cops (i.e. it also fixes false positives reliably)? And that you need to use rubocop --safe-auto-correct --safe to really not make any changes to the meaning of the code? 😕

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it correct that currently rubocop --safe-auto-correct applies "safe" autocorrections of unsafe cops (i.e. it also fixes false positives reliably)?

There are no such cases - if a cop is unsafe, its auto-correct is unsafe as well.

And that you need to use rubocop --safe-auto-correct --safe to really not make any changes to the meaning of the code?

Yep - basically you get the safe report, but not all of those offences would have safe fixes, so you need to specify this further. I guess that's somewhat confusing, but we couldn't come up with a better way to express it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. Should we add Safe: false then as well?

Only it - this will affect the auto-correct as well.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PreferredHashMethod is inherently unsafe, as you can never be certain if the receiver is a hash or not. I guess it's simply not marked as unsafe.

Copy link
Contributor Author

@buehmann buehmann Aug 28, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's my point. The cop is marked as unsafe, but its auto-correction is not marked as unsafe. You claimed above that setting Safe: false for a cop implies SafeAutoCorrect: false (if I understood you correctly). My example shows that this is not true.

So we either have a bug here or I still have a misconception about how these two levels of safeness are supposed to work.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or I do. 😆 Since I don't spend as much time on the code as I used to, I'm starting to forget some of my original reasoning. But in general I'm struggling to see how the cop's suggestions can be unsafe, but it corrections can be somehow safe. Safe always meant preserving the semantics on the code intact.

Copy link
Contributor

@marcandre marcandre Aug 1, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the cop is actually unsafe (as it doesn't actually check the source to figure out if it's ok to add the magic comment). Unsafe for a cop means that it yields false positives or the suggestions can change the meaning of the code. Unsafe for auto-correct means the cop the cop suggestions are safe, but the auto-correct can't apply those reliably.

I would propose a different definition. Unsafe for a cop means that it yields false positives and that's it. (e.g. "don't use dig with single argument" is unsafe, as it could be a custom method in a gem dependency and thus perfectly o.k. and without another alternative). The FrozenStringLiteral cop is a good example where the fact that we can't reliably autocorrect a source doesn't mean it can't or shouldn't be done. Since any source can modified to have a frozen string literal comment, that all sources should be modified, and that the cop will always correctly detect if there is a frozen string literal comment, I believe this cop is safe, only its auto-correction is unsafe. How does that sound @bbatsov ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ping @bbatsov

@koic
Copy link
Member

koic commented Aug 28, 2019

I guess that should be a different cop, though, right?

Yes. I think it should be a different cop's responsibility.

@bbatsov
Copy link
Collaborator

bbatsov commented Dec 30, 2019

@buehmann It'd be nice if we wrapped this PR at some point. Going back to https://github.com/rubocop-hq/rubocop/pull/7307/files#r318753133 - it seems to me that marking some cop as unsafe should imply that it's auto-correct is unsafe as well.

@buehmann
Copy link
Contributor Author

buehmann commented Dec 31, 2019

Thanks for the reminder. Then RuboCop does not behave as expected at the moment. I will probably create a separate issue for that and propose a fix. After that we can come back to this one.

I opened #7611

@buehmann buehmann force-pushed the unsafe-frozen-string-literal/7287 branch from adf5c41 to 0efa8db Compare January 2, 2020 09:17
@buehmann
Copy link
Contributor Author

buehmann commented Jan 2, 2020

@bbatsov Now that we have #7611 I changed this PR to declare the cop as Safe: false (only).

@bbatsov bbatsov merged commit 1d0b497 into rubocop:master Jan 2, 2020
@bbatsov
Copy link
Collaborator

bbatsov commented Jan 2, 2020

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Style/FrozenStringLiteralComment should not be considered as safe for autocorrection
4 participants