Skip to content

Commit ef2c1fc

Browse files
committed
Add regression test for #11709
1 parent 644122a commit ef2c1fc

File tree

3 files changed

+72
-27
lines changed

3 files changed

+72
-27
lines changed

clippy_lints/src/undocumented_unsafe_blocks.rs

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,33 @@ fn is_unsafe_from_proc_macro(cx: &LateContext<'_>, span: Span) -> bool {
339339
.is_none_or(|src| !src.starts_with("unsafe"))
340340
}
341341

342+
fn find_unsafe_block_parent_in_expr<'tcx>(
343+
cx: &LateContext<'tcx>,
344+
expr: &'tcx hir::Expr<'tcx>,
345+
) -> Option<(Span, HirId)> {
346+
match cx.tcx.parent_hir_node(expr.hir_id) {
347+
Node::LetStmt(hir::LetStmt { span, hir_id, .. })
348+
| Node::Expr(hir::Expr {
349+
hir_id,
350+
kind: hir::ExprKind::Assign(_, _, span),
351+
..
352+
}) => Some((*span, *hir_id)),
353+
Node::Expr(expr) => find_unsafe_block_parent_in_expr(cx, expr),
354+
node if let Some((span, hir_id)) = span_and_hid_of_item_alike_node(&node)
355+
&& is_const_or_static(&node) =>
356+
{
357+
Some((span, hir_id))
358+
},
359+
360+
_ => {
361+
if is_branchy(expr) {
362+
return None;
363+
}
364+
Some((expr.span, expr.hir_id))
365+
},
366+
}
367+
}
368+
342369
// Checks if any parent {expression, statement, block, local, const, static}
343370
// has a safety comment
344371
fn block_parents_have_safety_comment(
@@ -348,26 +375,7 @@ fn block_parents_have_safety_comment(
348375
id: HirId,
349376
) -> bool {
350377
let (span, hir_id) = match cx.tcx.parent_hir_node(id) {
351-
Node::Expr(expr) => match cx.tcx.parent_hir_node(expr.hir_id) {
352-
Node::LetStmt(hir::LetStmt { span, hir_id, .. })
353-
| Node::Expr(hir::Expr {
354-
hir_id,
355-
kind: hir::ExprKind::Assign(_, _, span),
356-
..
357-
}) => (*span, *hir_id),
358-
node if let Some((span, hir_id)) = span_and_hid_of_item_alike_node(&node)
359-
&& is_const_or_static(&node) =>
360-
{
361-
(span, hir_id)
362-
},
363-
364-
_ => {
365-
if is_branchy(expr) {
366-
return false;
367-
}
368-
(expr.span, expr.hir_id)
369-
},
370-
},
378+
Node::Expr(expr) if let Some(inner) = find_unsafe_block_parent_in_expr(cx, expr) => inner,
371379
Node::Stmt(hir::Stmt {
372380
kind:
373381
hir::StmtKind::Let(hir::LetStmt { span, hir_id, .. })
@@ -433,12 +441,12 @@ fn block_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool {
433441
}
434442

435443
fn include_attrs_in_span(cx: &LateContext<'_>, hir_id: HirId, span: Span) -> Span {
436-
span.to(cx
437-
.tcx
438-
.hir()
439-
.attrs(hir_id)
440-
.iter()
441-
.fold(span, |acc, attr| acc.to(attr.span)))
444+
span.to(cx.tcx.hir().attrs(hir_id).iter().fold(span, |acc, attr| {
445+
if matches!(attr.kind, hir::AttrKind::DocComment(_, _)) {
446+
return acc;
447+
}
448+
acc.to(attr.span)
449+
}))
442450
}
443451

444452
enum HasSafetyComment {

tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,5 +430,13 @@ LL | unsafe { here_is_another_variable_with_long_name };
430430
|
431431
= help: consider adding a safety comment on the preceding line
432432

433-
error: aborting due to 50 previous errors
433+
error: unsafe block missing a safety comment
434+
--> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:702:9
435+
|
436+
LL | unsafe { Date::__from_ordinal_date_unchecked(1970, 1) }.into_julian_day_just_make_this_line_longer();
437+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
438+
|
439+
= help: consider adding a safety comment on the preceding line
440+
441+
error: aborting due to 51 previous errors
434442

tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,4 +674,33 @@ fn issue_13024() {
674674
//~[disabled]^ undocumented_unsafe_blocks
675675
}
676676

677+
// https://docs.rs/time/0.3.36/src/time/offset_date_time.rs.html#35
678+
mod issue_11709_regression {
679+
use std::num::NonZeroI32;
680+
681+
struct Date {
682+
value: NonZeroI32,
683+
}
684+
685+
impl Date {
686+
const unsafe fn __from_ordinal_date_unchecked(year: i32, ordinal: u16) -> Self {
687+
Self {
688+
// Safety: The caller must guarantee that `ordinal` is not zero.
689+
value: unsafe { NonZeroI32::new_unchecked((year << 9) | ordinal as i32) },
690+
}
691+
}
692+
693+
const fn into_julian_day_just_make_this_line_longer(self) -> i32 {
694+
42
695+
}
696+
}
697+
698+
/// The Julian day of the Unix epoch.
699+
// SAFETY: fail ONLY if `accept-comment-above-attribute = false`
700+
#[allow(unsafe_code)]
701+
const UNIX_EPOCH_JULIAN_DAY: i32 =
702+
unsafe { Date::__from_ordinal_date_unchecked(1970, 1) }.into_julian_day_just_make_this_line_longer();
703+
//~[disabled]^ undocumented_unsafe_blocks
704+
}
705+
677706
fn main() {}

0 commit comments

Comments
 (0)