New lint proper_safety_comment
as an alternative to undocumented_unsafe_blocks
and unnecessary_safety_comment
#13887
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.
changelog: new lint: [
proper_safety_comment
]This PR is about proposing an alternative to
undocumented_unsafe_blocks
andunnecessary_safety_comment
that tries to address the following issues:unsafe extern { safe fn }
support #13777unsafe extern
support (undocumented_unsafe_blocks
?) #13560undocumented_unsafe_blocks
) #13316 and Unsafe attributes support (unnecessary_safety_comment
) #13317undocumented_unsafe_blocks
false positives around attributes #13189unnecessary_safety_comment
false positive in_ = unsafe { foo_unsafe() }
expression, conflicts withundocumented_unsafe_blocks
correct analysis #13039undocumented_unsafe_blocks
can be broken byrustfmt
#13024undocumented_unsafe_blocks
doesn't recognise safety comments beforeconst
s inimpl
blocks #12720 and undocumented_unsafe_blocks doesn't detect safety comment above associated constant #11709Proposed new lint: PROPER_SAFETY_COMMENT
What it does
It requires proper safety comments at the barrier of Unsafety.
This includes any part of the code that needs to satisfy extra safety conditions:
unsafe {}
)unsafe impl
)unsafe extern
)#[unsafe(attr)]
)Safety comments are non-doc line comments starting with
SAFETY:
:Furthermore, it detects unnecessary safety comments for non-critical blocks, trait implementations and attributes. However, there can be false negatives.
Code that defines extra safety conditions is covered by
clippy::missing_safety_doc
andclippy::unnecessary_safety_doc
Why restrict this?
Breaking the safety barrier should not be done carelessly.
Proper documentation should be provided as to why each unsafe operation does not introduce undefined behavior.
Thinking about these safety requirements and writing them down can prevent incorrect implementations.
On the other hand, unnecessary safety comments are confusing and should not exist.
Example
Use instead:
Discussion
Moving the safety comment into the
unsafe
-blockundocumented_unsafe_blocks
requires a safety comment above the block:While this is intuitive, there are a number of problems. Firstly, it does not play well with the style guide. As pointed out in #13024,
rustfmt
may break lines with anunsafe
-block not at the beginning of the line into multiple ones.undocumented_unsafe_blocks
andunnecessary_safety_comment
try to solve this problem by identifying valid parents of anunsafe
-block and looking for the safety comment on top of them. But this can get quite complex:This has resulted in a few uncovered cases: #13189, #13039, #12720, #11709.
The main problem is that the distance between the
unsafe
-block and the safety comment in the AST/HIR representation is unknown and can be arbitrarily large.On the other hand, just looking at the previous lines is also quite complicated if you want to avoid false negatives.
That's why
proper_safety_comment
requires a safety comment inside theunsafe
-block at the top:This is well in line with the style guide of blocks and clearly links the safety comment to its
unsafe
-block. But it is also clear that this makes the code less compact:instead of
However, more complex structures are more clearly documented:
instead of
Excluding block comments
RFC 1574 recommends to avoid block comments and use line comments instead, as written down in Comments. This recommendation should be adopted for safety comments, which also simplifies the lint implementation, reducing false positives/negatives. Currently,
proper_safety_comment
requires non-doc line comments:Question: Is there any need for non-doc block comments? Note that
undocumented_unsafe_blocks
allows block comments.Excluding doc comments
Currently,
proper_safety_comment
does not allow doc comments.Question: Is there any need for doc comments? Note that
undocumented_unsafe_blocks
allows doc comments.Items in
unsafe extern
blocksIn addition to #13560 (safety comments for
unsafe extern
blocks), #13777 asks for comments on individual items. Currently,proper_safety_comment
requires safety comments on both:Question: Should there be a more individual solution?
Config parameters from
UndocumentedUnsafeBlocks
accept-comment-above-statement
This config parameter avoids problems with
rustfmt
by allowing line breaks in statements:In general, the following is allowed:
This is not needed any more with
proper_safety_comment
due to moving the safety comment into theunsafe
-block.accept-comment-above-attributes
This config parameter is in conflict with #13316 and #13317.
proper_safety_comment
requires safety comments on unsafe attributes and lints unnecessary safety comments on normal attributes. The idea ofaccept-comment-above-attributes
is as follows:Currently,
proper_safety_comment
does not allow this and there is even no concept for it.Question: Is there any use-case for
accept-comment-above-attribute = false
?Unusual safety comments allowed with
undocumented_unsafe_blocks
Examples have been taken from tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs.
proper_safety_comment
does not allow "prepended text" and only allowsSAFETY:
as a safety comment label.(Corner) cases to avoid false positive/negatives
This section is about collecting a list of all the complex corner cases that need to be addressed for a stable implementation.
tests/ui/safety/proper_safety_comment/attribute.rs
contains examples for attributes.tests/ui/safety/proper_safety_comment/block.rs
contains examples for blocks.tests/ui/safety/proper_safety_comment/proc_macros.rs
contains examples and their expected behaviour with respect to code generated by procedural macros. Question: Is the only way to detect procedural macros to compare the respectivespan
with the actual source code?tests/ui/safety/proper_safety_comment/trait_impl.rs
contains examples for trait implementations.tests/ui/safety/proper_safety_comment/unsafe_extern.rs
contains examples forunsafe extern
.Question: What additional cases should be tested/supported?