Add lint for using a type with a destructor in a zero-length repeat expr #74857
Add this suggestion to a batch that can be applied as a single commit. This suggestion is invalid because no changes were made to the code. Suggestions cannot be applied while the pull request is closed. Suggestions cannot be applied while viewing a subset of changes. Only one suggestion per line can be applied in a batch. Add this suggestion to a batch that can be applied as a single commit. Applying suggestions on deleted lines is not supported. You must change the existing code in this line in order to create a valid suggestion. Outdated suggestions cannot be applied. This suggestion has been applied or marked resolved. Suggestions cannot be applied from pending reviews. Suggestions cannot be applied on multi-line comments. Suggestions cannot be applied while the pull request is queued to merge. Suggestion cannot be applied right now. Please check back later.
Currently, writing a zero-length array repeat expression (e.g.
[String::new(); 0]) will cause the initializer value to be leaked.See #74836 for more details
There are three ways that we could potentially handle this case:
array.
dropped (i.e. at the end of the lexical scope)
Note that the 'obvious' choice (running the destructor when the array is
dropped) does not work, since a zero-length array does not actually
store the value we want to drop.
All of these options seem likely to be surprising and inconsistent
to users. Since any fully monomorphic constant can be used as the repeat
length, this has the potential to cause confusing 'action at a distance'
(e.g. changing a
constfrom 0 to 1 results in drop order changing).Regardless of which option we decide on, we should tell users
to use an empty array (
[]) instead.This commit adds a new lint ZERO_REPEAT_WITH_DROP, which fires when a
type that (potentially) has a destructor is used in a zero-length array
repeat expression.
If a type has no drop glue, we skip linting, since dropping it has no
user-visible side effects. If we do not know if a type has drop glue
(e.g.
Option<T>), we lint anyway, since some choice of genericarguments could trigger the strange drop behavior.
If the length const expression is not fully monomorphic (e.g. contains a
generic parameter), the compiler requires the type used in the repeat
expression to be
Copy. Therefore, we don't need to lint in this case,since a
Copytype can never have drop glue.