Add regression test for #11709

This commit is contained in:
yanglsh 2025-02-18 03:23:42 +08:00
parent 3899488e53
commit d027ca95de
3 changed files with 72 additions and 27 deletions

View file

@ -339,6 +339,33 @@ fn is_unsafe_from_proc_macro(cx: &LateContext<'_>, span: Span) -> bool {
.is_none_or(|src| !src.starts_with("unsafe"))
}
fn find_unsafe_block_parent_in_expr<'tcx>(
cx: &LateContext<'tcx>,
expr: &'tcx hir::Expr<'tcx>,
) -> Option<(Span, HirId)> {
match cx.tcx.parent_hir_node(expr.hir_id) {
Node::LetStmt(hir::LetStmt { span, hir_id, .. })
| Node::Expr(hir::Expr {
hir_id,
kind: hir::ExprKind::Assign(_, _, span),
..
}) => Some((*span, *hir_id)),
Node::Expr(expr) => find_unsafe_block_parent_in_expr(cx, expr),
node if let Some((span, hir_id)) = span_and_hid_of_item_alike_node(&node)
&& is_const_or_static(&node) =>
{
Some((span, hir_id))
},
_ => {
if is_branchy(expr) {
return None;
}
Some((expr.span, expr.hir_id))
},
}
}
// Checks if any parent {expression, statement, block, local, const, static}
// has a safety comment
fn block_parents_have_safety_comment(
@ -348,26 +375,7 @@ fn block_parents_have_safety_comment(
id: HirId,
) -> bool {
let (span, hir_id) = match cx.tcx.parent_hir_node(id) {
Node::Expr(expr) => match cx.tcx.parent_hir_node(expr.hir_id) {
Node::LetStmt(hir::LetStmt { span, hir_id, .. })
| Node::Expr(hir::Expr {
hir_id,
kind: hir::ExprKind::Assign(_, _, span),
..
}) => (*span, *hir_id),
node if let Some((span, hir_id)) = span_and_hid_of_item_alike_node(&node)
&& is_const_or_static(&node) =>
{
(span, hir_id)
},
_ => {
if is_branchy(expr) {
return false;
}
(expr.span, expr.hir_id)
},
},
Node::Expr(expr) if let Some(inner) = find_unsafe_block_parent_in_expr(cx, expr) => inner,
Node::Stmt(hir::Stmt {
kind:
hir::StmtKind::Let(hir::LetStmt { span, hir_id, .. })
@ -433,12 +441,12 @@ fn block_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool {
}
fn include_attrs_in_span(cx: &LateContext<'_>, hir_id: HirId, span: Span) -> Span {
span.to(cx
.tcx
.hir()
.attrs(hir_id)
.iter()
.fold(span, |acc, attr| acc.to(attr.span())))
span.to(cx.tcx.hir().attrs(hir_id).iter().fold(span, |acc, attr| {
if attr.is_doc_comment() {
return acc;
}
acc.to(attr.span())
}))
}
enum HasSafetyComment {

View file

@ -430,5 +430,13 @@ LL | unsafe { here_is_another_variable_with_long_name };
|
= help: consider adding a safety comment on the preceding line
error: aborting due to 50 previous errors
error: unsafe block missing a safety comment
--> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:702:9
|
LL | unsafe { Date::__from_ordinal_date_unchecked(1970, 1) }.into_julian_day_just_make_this_line_longer();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding a safety comment on the preceding line
error: aborting due to 51 previous errors

View file

@ -674,4 +674,33 @@ fn issue_13024() {
//~[disabled]^ undocumented_unsafe_blocks
}
// https://docs.rs/time/0.3.36/src/time/offset_date_time.rs.html#35
mod issue_11709_regression {
use std::num::NonZeroI32;
struct Date {
value: NonZeroI32,
}
impl Date {
const unsafe fn __from_ordinal_date_unchecked(year: i32, ordinal: u16) -> Self {
Self {
// Safety: The caller must guarantee that `ordinal` is not zero.
value: unsafe { NonZeroI32::new_unchecked((year << 9) | ordinal as i32) },
}
}
const fn into_julian_day_just_make_this_line_longer(self) -> i32 {
42
}
}
/// The Julian day of the Unix epoch.
// SAFETY: fail ONLY if `accept-comment-above-attribute = false`
#[allow(unsafe_code)]
const UNIX_EPOCH_JULIAN_DAY: i32 =
unsafe { Date::__from_ordinal_date_unchecked(1970, 1) }.into_julian_day_just_make_this_line_longer();
//~[disabled]^ undocumented_unsafe_blocks
}
fn main() {}