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

Add the undocumented_unsafe_blocks lint #7557

Conversation

LeSeulArtichaut
Copy link
Contributor

changelog: add the [undocumented_unsafe_blocks] lint.

Fixes #7464.

The lint was proposed as a style lint, I implemented it as a restriction lint, which is preferred?

@rust-highfive
Copy link

r? @flip1995

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Aug 11, 2021
@LeSeulArtichaut LeSeulArtichaut force-pushed the lint-undocumented-unsafe branch 3 times, most recently from 9ce9984 to d049720 Compare August 11, 2021 23:37
Copy link
Member

@flip1995 flip1995 left a comment

Choose a reason for hiding this comment

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

I have some concerns when it comes to performance with this lint. With the current implementation, this lint will potentially re-lex every file in the crate, if there are unsafe blocks.

I agree that this lint fits best in restriction, but I would also add a

if is_lint_allowed(...) {
    return;
}

to the top of the check_expr/check_block method. That and my suggestions below should deal with the performance impact.

impl_lint_pass!(UndocumentedUnsafeBlocks => [UNDOCUMENTED_UNSAFE_BLOCKS]);

impl EarlyLintPass for UndocumentedUnsafeBlocks {
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &rustc_ast::Expr) {
Copy link
Member

Choose a reason for hiding this comment

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

There's also a check_block method.

Comment on lines +68 to +69
let mut pos = rustc_lexer::strip_shebang(src).unwrap_or(0);
for token in rustc_lexer::tokenize(&src[pos..]) {
Copy link
Member

@flip1995 flip1995 Aug 12, 2021

Choose a reason for hiding this comment

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

Since we don't really care about correct and complete syntax in the file, but only finding comments immediately above the unsafe block, you should be able to optimize this. I think you can use the get_enclosing_scope in combination with the opt_span methods and then slice the to-tokenize src with the start of the enclosing scope up until the start of the block/the start of the line the unsafe block is in (for let stmts).

To do this, you would have to turn this lint into a LatePassLint, but that is a tradeoff I'm willing to take in order to not re-lex whole files just to find a comment, of which we already know where it should be.

To make sure that just slicing the src works as expected, please add a test case with unicode chars in the comment and the code above the unsafe block.


With this change, you also might be able to just directly return if the checked block has a SAFETY comment right above it, without having to do BytePos and span.hi()/.lo() gymnastics. Basically you have to track if after lexing the suggested part of the file, the last thing you saw was a comment and if it was a SAFETY comment.


impl EarlyLintPass for UndocumentedUnsafeBlocks {
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &rustc_ast::Expr) {
let (block, comments) = if_chain! {
Copy link
Member

Choose a reason for hiding this comment

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

I think you can add a in_external_macro check here, since this lint shouldn't be triggered for those.

@@ -0,0 +1,74 @@
#![warn(clippy::undocumented_unsafe_blocks)]
Copy link
Member

Choose a reason for hiding this comment

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

I'd like to see some tests of how this lint behaves in macros.

comments.remove(i);
}
else {
span_lint(cx, UNDOCUMENTED_UNSAFE_BLOCKS, expr.span, "this `unsafe` block is missing a SAFETY comment");
Copy link
Member

Choose a reason for hiding this comment

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

I think we should produce a help message here, suggesting to add a // SAFETY: ... above the unsafe block.

Comment on lines +37 to +39
let _ =
// SAFETY
unsafe {};
Copy link
Member

Choose a reason for hiding this comment

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

There's a test missing for the example in the documentation:

// SAFETY: bla
let _ = unsafe {};

@flip1995 flip1995 added S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties labels Aug 12, 2021
@bors
Copy link
Collaborator

bors commented Aug 23, 2021

☔ The latest upstream changes (presumably #7539) made this pull request unmergeable. Please resolve the merge conflicts.

@giraffate
Copy link
Contributor

ping from triage @LeSeulArtichaut. Can you have any update on this?

@giraffate
Copy link
Contributor

ping from triage @LeSeulArtichaut. According to the triage procedure, I'm closing this because 2 weeks have passed with no activity. If you have more time to work on this, feel free to reopen this.

@giraffate giraffate closed this Sep 27, 2021
@giraffate giraffate added S-inactive-closed Status: Closed due to inactivity and removed S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) labels Sep 27, 2021
@blyxyas blyxyas removed the S-inactive-closed Status: Closed due to inactivity label Oct 9, 2023
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.

missing_unsafe_doc, explain why an unsafe block is safe/sound
6 participants