| use super::{Attribute, SHOULD_PANIC_WITHOUT_EXPECT}; |
| use clippy_utils::diagnostics::span_lint_and_sugg; |
| use rustc_ast::token::{Token, TokenKind}; |
| use rustc_ast::tokenstream::TokenTree; |
| use rustc_ast::{AttrArgs, AttrKind}; |
| use rustc_errors::Applicability; |
| use rustc_lint::EarlyContext; |
| use rustc_span::sym; |
| |
| pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute) { |
| if let AttrKind::Normal(normal_attr) = &attr.kind { |
| if let AttrArgs::Eq { .. } = &normal_attr.item.args { |
| // `#[should_panic = ".."]` found, good |
| return; |
| } |
| |
| if let AttrArgs::Delimited(args) = &normal_attr.item.args |
| && let mut tt_iter = args.tokens.iter() |
| && let Some(TokenTree::Token( |
| Token { |
| kind: TokenKind::Ident(sym::expected, _), |
| .. |
| }, |
| _, |
| )) = tt_iter.next() |
| && let Some(TokenTree::Token( |
| Token { |
| kind: TokenKind::Eq, .. |
| }, |
| _, |
| )) = tt_iter.next() |
| && let Some(TokenTree::Token( |
| Token { |
| kind: TokenKind::Literal(_), |
| .. |
| }, |
| _, |
| )) = tt_iter.next() |
| { |
| // `#[should_panic(expected = "..")]` found, good |
| return; |
| } |
| |
| span_lint_and_sugg( |
| cx, |
| SHOULD_PANIC_WITHOUT_EXPECT, |
| attr.span, |
| "#[should_panic] attribute without a reason", |
| "consider specifying the expected panic", |
| "#[should_panic(expected = /* panic message */)]".into(), |
| Applicability::HasPlaceholders, |
| ); |
| } |
| } |