commit
609cd310be
51 changed files with 164 additions and 247 deletions
|
|
@ -2,9 +2,10 @@ use clippy_config::Conf;
|
|||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use rustc_ast::ast::{FloatTy, LitFloatType, LitKind};
|
||||
use rustc_attr_parsing::RustcVersion;
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::{RustcVersion, impl_lint_pass};
|
||||
use rustc_session::impl_lint_pass;
|
||||
use rustc_span::symbol;
|
||||
use std::f64::consts as f64;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use super::INLINE_ALWAYS;
|
||||
use super::utils::is_word;
|
||||
use clippy_utils::diagnostics::span_lint;
|
||||
use rustc_ast::Attribute;
|
||||
use rustc_hir::Attribute;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_span::{Span, sym};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use rustc_ast::Attribute;
|
||||
use rustc_hir::Attribute;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::{Span, sym};
|
||||
|
||||
|
|
|
|||
|
|
@ -2,24 +2,20 @@ 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, AttrArgsEq, AttrKind};
|
||||
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 {
|
||||
value: AttrArgsEq::Ast(_),
|
||||
..
|
||||
} = &normal_attr.item.args
|
||||
{
|
||||
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.trees()
|
||||
&& let mut tt_iter = args.tokens.iter()
|
||||
&& let Some(TokenTree::Token(
|
||||
Token {
|
||||
kind: TokenKind::Ident(sym::expected, _),
|
||||
|
|
|
|||
|
|
@ -5,11 +5,12 @@ use clippy_utils::msrvs::{self, Msrv};
|
|||
use clippy_utils::source::SpanRangeExt;
|
||||
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
|
||||
use rustc_ast::ast::LitKind;
|
||||
use rustc_attr_parsing::RustcVersion;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::intravisit::{FnKind, Visitor, walk_expr};
|
||||
use rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, UnOp};
|
||||
use rustc_lint::{LateContext, LateLintPass, Level};
|
||||
use rustc_session::{RustcVersion, impl_lint_pass};
|
||||
use rustc_session::impl_lint_pass;
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
use rustc_span::{Span, sym};
|
||||
|
||||
|
|
|
|||
|
|
@ -5,9 +5,8 @@ use clippy_utils::ty::is_type_diagnostic_item;
|
|||
use clippy_utils::visitors::for_each_expr_without_closures;
|
||||
use clippy_utils::{LimitStack, get_async_fn_body, is_async_fn};
|
||||
use core::ops::ControlFlow;
|
||||
use rustc_ast::ast::Attribute;
|
||||
use rustc_hir::intravisit::FnKind;
|
||||
use rustc_hir::{Body, Expr, ExprKind, FnDecl};
|
||||
use rustc_hir::{Attribute, Body, Expr, ExprKind, FnDecl};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_session::impl_lint_pass;
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
|
|
|
|||
|
|
@ -82,11 +82,11 @@ fn is_macro_export(attr: &Attribute) -> bool {
|
|||
|
||||
fn contains_unhygienic_crate_reference(tts: &TokenStream) -> Option<Span> {
|
||||
let mut prev_is_dollar = false;
|
||||
let mut cursor = tts.trees();
|
||||
while let Some(curr) = cursor.next() {
|
||||
let mut iter = tts.iter();
|
||||
while let Some(curr) = iter.next() {
|
||||
if !prev_is_dollar
|
||||
&& let Some(span) = is_crate_keyword(curr)
|
||||
&& let Some(next) = cursor.look_ahead(0)
|
||||
&& let Some(next) = iter.peek()
|
||||
&& is_token(next, &TokenKind::PathSep)
|
||||
{
|
||||
return Some(span);
|
||||
|
|
|
|||
|
|
@ -877,7 +877,8 @@ impl TyCoercionStability {
|
|||
| ty::CoroutineClosure(..)
|
||||
| ty::Never
|
||||
| ty::Tuple(_)
|
||||
| ty::Alias(ty::Projection, _) => Self::Deref,
|
||||
| ty::Alias(ty::Projection, _)
|
||||
| ty::UnsafeBinder(_) => Self::Deref,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,7 @@ use clippy_utils::{has_non_exhaustive_attr, is_lint_allowed, match_def_path, pat
|
|||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::intravisit::{FnKind, Visitor, walk_expr, walk_fn, walk_item};
|
||||
use rustc_hir::{
|
||||
self as hir, BlockCheckMode, BodyId, Expr, ExprKind, FnDecl, Impl, Item, ItemKind, Safety, UnsafeSource,
|
||||
};
|
||||
use rustc_hir::{self as hir, BlockCheckMode, BodyId, Expr, ExprKind, FnDecl, Impl, Item, ItemKind, UnsafeSource};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::ty::{
|
||||
|
|
@ -421,7 +419,7 @@ impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> {
|
|||
id: LocalDefId,
|
||||
) -> Self::Result {
|
||||
if let Some(header) = kind.header()
|
||||
&& header.safety == Safety::Unsafe
|
||||
&& header.safety.is_unsafe()
|
||||
{
|
||||
ControlFlow::Break(())
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@ use clippy_utils::diagnostics::span_lint_and_then;
|
|||
use clippy_utils::source::{SpanRangeExt, snippet_indent};
|
||||
use clippy_utils::tokenize_with_text;
|
||||
use itertools::Itertools;
|
||||
use rustc_ast::AttrStyle;
|
||||
use rustc_ast::token::CommentKind;
|
||||
use rustc_ast::{AttrKind, AttrStyle, Attribute};
|
||||
use rustc_errors::{Applicability, Diag, SuggestionStyle};
|
||||
use rustc_hir::{ItemKind, Node};
|
||||
use rustc_hir::{AttrKind, Attribute, ItemKind, Node};
|
||||
use rustc_lexer::TokenKind;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::{BytePos, ExpnKind, InnerSpan, Span, SpanData};
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::source::snippet_opt;
|
||||
use rustc_ast::{AttrArgs, AttrArgsEq, AttrKind, AttrStyle, Attribute};
|
||||
use rustc_ast::AttrStyle;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{AttrArgs, AttrKind, Attribute};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::sym;
|
||||
|
||||
use super::DOC_INCLUDE_WITHOUT_CFG;
|
||||
|
||||
pub fn check(cx: &LateContext<'_>, attrs: &[Attribute]) {
|
||||
for attr in attrs {
|
||||
if !attr.span.from_expansion()
|
||||
&& let AttrKind::Normal(ref normal) = attr.kind
|
||||
&& normal.item.path == sym::doc
|
||||
&& let AttrArgs::Eq { value: AttrArgsEq::Hir(ref meta), .. } = normal.item.args
|
||||
&& let AttrKind::Normal(ref item) = attr.kind
|
||||
&& attr.doc_str().is_some()
|
||||
&& let AttrArgs::Eq { expr: meta, .. } = &item.args
|
||||
&& !attr.span.contains(meta.span)
|
||||
// Since the `include_str` is already expanded at this point, we can only take the
|
||||
// whole attribute snippet and then modify for our suggestion.
|
||||
|
|
|
|||
|
|
@ -16,11 +16,10 @@ use pulldown_cmark::Event::{
|
|||
};
|
||||
use pulldown_cmark::Tag::{BlockQuote, CodeBlock, FootnoteDefinition, Heading, Item, Link, Paragraph};
|
||||
use pulldown_cmark::{BrokenLink, CodeBlockKind, CowStr, Options, TagEnd};
|
||||
use rustc_ast::ast::Attribute;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_hir::{AnonConst, Expr, ImplItemKind, ItemKind, Node, Safety, TraitItemKind};
|
||||
use rustc_hir::{AnonConst, Attribute, Expr, ImplItemKind, ItemKind, Node, Safety, TraitItemKind};
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use rustc_ast::AttrStyle;
|
||||
use rustc_ast::token::CommentKind;
|
||||
use rustc_ast::{AttrKind, AttrStyle, Attribute};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::Attribute;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::Span;
|
||||
|
||||
|
|
@ -35,7 +36,7 @@ fn collect_doc_replacements(attrs: &[Attribute]) -> Vec<(Span, String)> {
|
|||
attrs
|
||||
.iter()
|
||||
.filter_map(|attr| {
|
||||
if let AttrKind::DocComment(com_kind, sym) = attr.kind
|
||||
if let Some((sym, com_kind)) = attr.doc_str_and_comment_kind()
|
||||
&& let AttrStyle::Outer = attr.style
|
||||
&& let Some(com) = sym.as_str().strip_prefix('!')
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
use rustc_ast::ast::Attribute;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Item, ItemKind};
|
||||
use rustc_hir::{Attribute, Item, ItemKind};
|
||||
use rustc_lint::LateContext;
|
||||
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
|
|
|
|||
|
|
@ -281,7 +281,7 @@ fn check_inputs(
|
|||
}
|
||||
|
||||
fn check_sig<'tcx>(closure_sig: FnSig<'tcx>, call_sig: FnSig<'tcx>) -> bool {
|
||||
call_sig.safety == Safety::Safe && !has_late_bound_to_non_late_bound_regions(closure_sig, call_sig)
|
||||
call_sig.safety.is_safe() && !has_late_bound_to_non_late_bound_regions(closure_sig, call_sig)
|
||||
}
|
||||
|
||||
/// This walks through both signatures and checks for any time a late-bound region is expected by an
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
|
|||
use clippy_utils::source::snippet;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::intravisit::FnKind;
|
||||
use rustc_hir::{Body, ExprKind, FnDecl, ImplicitSelfKind, Safety};
|
||||
use rustc_hir::{Body, ExprKind, FnDecl, ImplicitSelfKind};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty;
|
||||
use rustc_span::Span;
|
||||
|
|
@ -34,7 +34,7 @@ pub fn check_fn(cx: &LateContext<'_>, kind: FnKind<'_>, decl: &FnDecl<'_>, body:
|
|||
ImplicitSelfKind::None => return,
|
||||
};
|
||||
|
||||
let name = if sig.header.safety == Safety::Unsafe {
|
||||
let name = if sig.header.safety.is_unsafe() {
|
||||
name.strip_suffix("_unchecked").unwrap_or(name)
|
||||
} else {
|
||||
name
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
use hir::FnSig;
|
||||
use rustc_ast::ast::Attribute;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::def_id::DefIdSet;
|
||||
use rustc_hir::{self as hir, QPath};
|
||||
use rustc_hir::{self as hir, Attribute, QPath};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_lint::{LateContext, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ fn check_raw_ptr<'tcx>(
|
|||
body: &'tcx hir::Body<'tcx>,
|
||||
def_id: LocalDefId,
|
||||
) {
|
||||
if safety == hir::Safety::Safe && cx.effective_visibilities.is_exported(def_id) {
|
||||
if safety.is_safe() && cx.effective_visibilities.is_exported(def_id) {
|
||||
let raw_ptrs = iter_input_pats(decl, body)
|
||||
.filter_map(|arg| raw_ptr_arg(cx, arg))
|
||||
.collect::<HirIdSet>();
|
||||
|
|
@ -58,7 +58,7 @@ fn check_raw_ptr<'tcx>(
|
|||
},
|
||||
hir::ExprKind::MethodCall(_, recv, args, _) => {
|
||||
let def_id = typeck.type_dependent_def_id(e.hir_id).unwrap();
|
||||
if cx.tcx.fn_sig(def_id).skip_binder().skip_binder().safety == hir::Safety::Unsafe {
|
||||
if cx.tcx.fn_sig(def_id).skip_binder().skip_binder().safety.is_unsafe() {
|
||||
check_arg(cx, &raw_ptrs, recv);
|
||||
for arg in args {
|
||||
check_arg(cx, &raw_ptrs, arg);
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@ use clippy_config::Conf;
|
|||
use clippy_utils::diagnostics::span_lint;
|
||||
use clippy_utils::is_in_test;
|
||||
use clippy_utils::msrvs::Msrv;
|
||||
use rustc_attr::{StabilityLevel, StableSince};
|
||||
use rustc_attr_parsing::{RustcVersion, StabilityLevel, StableSince};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_hir::{Expr, ExprKind, HirId};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::{RustcVersion, impl_lint_pass};
|
||||
use rustc_session::impl_lint_pass;
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::{ExpnKind, Span};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use clippy_utils::ty::{implements_trait, is_type_lang_item};
|
||||
use clippy_utils::{return_ty, trait_ref_of_method};
|
||||
use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind, LangItem, Safety};
|
||||
use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind, LangItem};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::declare_lint_pass;
|
||||
use rustc_span::sym;
|
||||
|
|
@ -95,7 +95,7 @@ impl<'tcx> LateLintPass<'tcx> for InherentToString {
|
|||
if let ImplItemKind::Fn(ref signature, _) = impl_item.kind
|
||||
// #11201
|
||||
&& let header = signature.header
|
||||
&& header.safety == Safety::Safe
|
||||
&& header.safety.is_safe()
|
||||
&& header.abi == Abi::Rust
|
||||
&& impl_item.ident.name == sym::to_string
|
||||
&& let decl = signature.decl
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ use clippy_config::Conf;
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::macros::root_macro_call_first_node;
|
||||
use clippy_utils::source::snippet_opt;
|
||||
use rustc_ast::{AttrArgs, AttrArgsEq, AttrKind, Attribute, LitKind};
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_ast::LitKind;
|
||||
use rustc_hir::{AttrArgs, AttrKind, Attribute, Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::impl_lint_pass;
|
||||
use rustc_span::{Span, sym};
|
||||
|
|
@ -93,10 +93,10 @@ impl LateLintPass<'_> for LargeIncludeFile {
|
|||
if !attr.span.from_expansion()
|
||||
// Currently, rustc limits the usage of macro at the top-level of attributes,
|
||||
// so we don't need to recurse into each level.
|
||||
&& let AttrKind::Normal(ref normal) = attr.kind
|
||||
&& let AttrKind::Normal(ref item) = attr.kind
|
||||
&& let Some(doc) = attr.doc_str()
|
||||
&& doc.as_str().len() as u64 > self.max_file_size
|
||||
&& let AttrArgs::Eq { value: AttrArgsEq::Hir(ref meta), .. } = normal.item.args
|
||||
&& let AttrArgs::Eq { expr: meta, .. } = &item.args
|
||||
&& !attr.span.contains(meta.span)
|
||||
// Since the `include_str` is already expanded at this point, we can only take the
|
||||
// whole attribute snippet and then modify for our suggestion.
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ extern crate rustc_abi;
|
|||
extern crate rustc_arena;
|
||||
extern crate rustc_ast;
|
||||
extern crate rustc_ast_pretty;
|
||||
extern crate rustc_attr;
|
||||
extern crate rustc_attr_parsing;
|
||||
extern crate rustc_data_structures;
|
||||
extern crate rustc_driver;
|
||||
extern crate rustc_errors;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
use clippy_utils::diagnostics::span_lint_hir_and_then;
|
||||
use clippy_utils::source::snippet;
|
||||
use hir::def::{DefKind, Res};
|
||||
use rustc_ast::ast;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
|
|
@ -104,7 +103,7 @@ impl LateLintPass<'_> for MacroUseImports {
|
|||
self.push_unique_macro_pat_ty(cx, item.span);
|
||||
}
|
||||
}
|
||||
fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &ast::Attribute) {
|
||||
fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &hir::Attribute) {
|
||||
if attr.span.from_expansion() {
|
||||
self.push_unique_macro(cx, attr.span);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ use super::REDUNDANT_PATTERN_MATCHING;
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::{is_lint_allowed, is_wild, span_contains_comment};
|
||||
use rustc_ast::{Attribute, LitKind};
|
||||
use rustc_ast::LitKind;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Arm, BorrowKind, Expr, ExprKind, Pat, PatKind, QPath};
|
||||
use rustc_hir::{Arm, Attribute, BorrowKind, Expr, ExprKind, Pat, PatKind, QPath};
|
||||
use rustc_lint::{LateContext, LintContext};
|
||||
use rustc_middle::ty;
|
||||
use rustc_span::source_map::Spanned;
|
||||
|
|
|
|||
|
|
@ -10,8 +10,9 @@ use clippy_utils::attrs::is_doc_hidden;
|
|||
use clippy_utils::diagnostics::span_lint;
|
||||
use clippy_utils::is_from_proc_macro;
|
||||
use clippy_utils::source::SpanRangeExt;
|
||||
use rustc_ast::ast::{self, MetaItem, MetaItemKind};
|
||||
use rustc_ast::ast::MetaItemInner;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::Attribute;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
|
|
@ -67,9 +68,8 @@ impl MissingDoc {
|
|||
*self.doc_hidden_stack.last().expect("empty doc_hidden_stack")
|
||||
}
|
||||
|
||||
fn has_include(meta: Option<MetaItem>) -> bool {
|
||||
if let Some(meta) = meta
|
||||
&& let MetaItemKind::List(list) = meta.kind
|
||||
fn has_include(meta: Option<&[MetaItemInner]>) -> bool {
|
||||
if let Some(list) = meta
|
||||
&& let Some(meta) = list.first()
|
||||
&& let Some(name) = meta.ident()
|
||||
{
|
||||
|
|
@ -83,7 +83,7 @@ impl MissingDoc {
|
|||
&self,
|
||||
cx: &LateContext<'_>,
|
||||
def_id: LocalDefId,
|
||||
attrs: &[ast::Attribute],
|
||||
attrs: &[Attribute],
|
||||
sp: Span,
|
||||
article: &'static str,
|
||||
desc: &'static str,
|
||||
|
|
@ -129,7 +129,7 @@ impl MissingDoc {
|
|||
|
||||
let has_doc = attrs
|
||||
.iter()
|
||||
.any(|a| a.doc_str().is_some() || Self::has_include(a.meta()))
|
||||
.any(|a| a.doc_str().is_some() || Self::has_include(a.meta_item_list().as_deref()))
|
||||
|| matches!(self.search_span(sp), Some(span) if span_to_snippet_contains_docs(cx, span));
|
||||
|
||||
if !has_doc {
|
||||
|
|
@ -172,12 +172,12 @@ impl MissingDoc {
|
|||
impl_lint_pass!(MissingDoc => [MISSING_DOCS_IN_PRIVATE_ITEMS]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for MissingDoc {
|
||||
fn check_attributes(&mut self, _: &LateContext<'tcx>, attrs: &'tcx [ast::Attribute]) {
|
||||
fn check_attributes(&mut self, _: &LateContext<'tcx>, attrs: &'tcx [Attribute]) {
|
||||
let doc_hidden = self.doc_hidden() || is_doc_hidden(attrs);
|
||||
self.doc_hidden_stack.push(doc_hidden);
|
||||
}
|
||||
|
||||
fn check_attributes_post(&mut self, _: &LateContext<'tcx>, _: &'tcx [ast::Attribute]) {
|
||||
fn check_attributes_post(&mut self, _: &LateContext<'tcx>, _: &'tcx [Attribute]) {
|
||||
self.doc_hidden_stack.pop().expect("empty doc_hidden_stack");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use clippy_utils::diagnostics::span_lint;
|
||||
use rustc_ast::ast;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::Attribute;
|
||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||
use rustc_middle::ty::AssocItemContainer;
|
||||
use rustc_session::declare_lint_pass;
|
||||
|
|
@ -63,7 +63,7 @@ declare_clippy_lint! {
|
|||
"detects missing `#[inline]` attribute for public callables (functions, trait methods, methods...)"
|
||||
}
|
||||
|
||||
fn check_missing_inline_attrs(cx: &LateContext<'_>, attrs: &[ast::Attribute], sp: Span, desc: &'static str) {
|
||||
fn check_missing_inline_attrs(cx: &LateContext<'_>, attrs: &[Attribute], sp: Span, desc: &'static str) {
|
||||
let has_inline = attrs.iter().any(|a| a.has_name(sym::inline));
|
||||
if !has_inline {
|
||||
span_lint(
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
|
|||
use clippy_utils::visitors::{Descend, Visitable, for_each_expr};
|
||||
use core::ops::ControlFlow::Continue;
|
||||
use hir::def::{DefKind, Res};
|
||||
use hir::{BlockCheckMode, ExprKind, QPath, Safety, UnOp};
|
||||
use hir::{BlockCheckMode, ExprKind, QPath, UnOp};
|
||||
use rustc_ast::Mutability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
|
|
@ -133,7 +133,7 @@ fn collect_unsafe_exprs<'tcx>(
|
|||
ty::FnPtr(sig_tys, hdr) => sig_tys.with(hdr),
|
||||
_ => return Continue(Descend::Yes),
|
||||
};
|
||||
if sig.safety() == Safety::Unsafe {
|
||||
if sig.safety().is_unsafe() {
|
||||
unsafe_ops.push(("unsafe function call occurs here", expr.span));
|
||||
}
|
||||
},
|
||||
|
|
@ -144,7 +144,7 @@ fn collect_unsafe_exprs<'tcx>(
|
|||
.type_dependent_def_id(expr.hir_id)
|
||||
.map(|def_id| cx.tcx.fn_sig(def_id))
|
||||
{
|
||||
if sig.skip_binder().safety() == Safety::Unsafe {
|
||||
if sig.skip_binder().safety().is_unsafe() {
|
||||
unsafe_ops.push(("unsafe method call occurs here", expr.span));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,12 +5,11 @@ use clippy_utils::source::{SpanRangeExt, snippet};
|
|||
use clippy_utils::ty::{
|
||||
implements_trait, implements_trait_with_env_from_iter, is_copy, is_type_diagnostic_item, is_type_lang_item,
|
||||
};
|
||||
use rustc_ast::ast::Attribute;
|
||||
use rustc_errors::{Applicability, Diag};
|
||||
use rustc_hir::intravisit::FnKind;
|
||||
use rustc_hir::{
|
||||
BindingMode, Body, FnDecl, GenericArg, HirId, HirIdSet, Impl, ItemKind, LangItem, Mutability, Node, PatKind, QPath,
|
||||
TyKind,
|
||||
Attribute, BindingMode, Body, FnDecl, GenericArg, HirId, HirIdSet, Impl, ItemKind, LangItem, Mutability, Node,
|
||||
PatKind, QPath, TyKind,
|
||||
};
|
||||
use rustc_hir_typeck::expr_use_visitor as euv;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
|
|||
if let hir::ImplItemKind::Fn(ref sig, _) = impl_item.kind {
|
||||
let name = impl_item.ident.name;
|
||||
let id = impl_item.owner_id;
|
||||
if sig.header.safety == hir::Safety::Unsafe {
|
||||
if sig.header.safety.is_unsafe() {
|
||||
// can't be implemented for unsafe new
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use rustc_hir::hir_id::{HirId, HirIdMap};
|
|||
use rustc_hir::intravisit::{Visitor, walk_expr};
|
||||
use rustc_hir::{
|
||||
self as hir, AnonConst, BinOpKind, BindingMode, Body, Expr, ExprKind, FnRetTy, FnSig, GenericArg, ImplItemKind,
|
||||
ItemKind, Lifetime, Mutability, Node, Param, PatKind, QPath, Safety, TraitFn, TraitItem, TraitItemKind, TyKind,
|
||||
ItemKind, Lifetime, Mutability, Node, Param, PatKind, QPath, TraitFn, TraitItem, TraitItemKind, TyKind,
|
||||
};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_infer::traits::{Obligation, ObligationCause};
|
||||
|
|
@ -475,7 +475,7 @@ fn check_fn_args<'cx, 'tcx: 'cx>(
|
|||
.def_id,
|
||||
),
|
||||
ty::ReBound(_, r) => r.kind.get_id(),
|
||||
ty::ReLateParam(r) => r.bound_region.get_id(),
|
||||
ty::ReLateParam(r) => r.kind.get_id(),
|
||||
ty::ReStatic
|
||||
| ty::ReVar(_)
|
||||
| ty::RePlaceholder(_)
|
||||
|
|
@ -541,7 +541,7 @@ fn check_mut_from_ref<'tcx>(cx: &LateContext<'tcx>, sig: &FnSig<'_>, body: Optio
|
|||
.collect();
|
||||
if let Some(args) = args
|
||||
&& !args.is_empty()
|
||||
&& body.is_none_or(|body| sig.header.safety == Safety::Unsafe || contains_unsafe_block(cx, body.value))
|
||||
&& body.is_none_or(|body| sig.header.safety.is_unsafe() || contains_unsafe_block(cx, body.value))
|
||||
{
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use clippy_config::Conf;
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::is_from_proc_macro;
|
||||
use clippy_utils::msrvs::Msrv;
|
||||
use rustc_attr::{StabilityLevel, StableSince};
|
||||
use rustc_attr_parsing::{StabilityLevel, StableSince};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::def_id::DefId;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use clippy_utils::ty::implements_trait;
|
||||
use rustc_hir::{Impl, Item, ItemKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::declare_lint_pass;
|
||||
|
|
@ -54,8 +53,6 @@ impl<'tcx> LateLintPass<'tcx> for ToStringTraitImpl {
|
|||
}) = it.kind
|
||||
&& let Some(trait_did) = trait_ref.trait_def_id()
|
||||
&& cx.tcx.is_diagnostic_item(sym::ToString, trait_did)
|
||||
&& let Some(display_did) = cx.tcx.get_diagnostic_item(sym::Display)
|
||||
&& !implements_trait(cx, cx.tcx.type_of(it.owner_id).instantiate_identity(), display_did, &[])
|
||||
{
|
||||
span_lint_and_help(
|
||||
cx,
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
|
|||
let item_has_safety_comment = item_has_safety_comment(cx, item);
|
||||
match (&item.kind, item_has_safety_comment) {
|
||||
// lint unsafe impl without safety comment
|
||||
(ItemKind::Impl(impl_), HasSafetyComment::No) if impl_.safety == hir::Safety::Unsafe => {
|
||||
(ItemKind::Impl(impl_), HasSafetyComment::No) if impl_.safety.is_unsafe() => {
|
||||
if !is_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, item.hir_id())
|
||||
&& !is_unsafe_from_proc_macro(cx, item.span)
|
||||
{
|
||||
|
|
@ -227,7 +227,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
|
|||
}
|
||||
},
|
||||
// lint safe impl with unnecessary safety comment
|
||||
(ItemKind::Impl(impl_), HasSafetyComment::Yes(pos)) if impl_.safety == hir::Safety::Safe => {
|
||||
(ItemKind::Impl(impl_), HasSafetyComment::Yes(pos)) if impl_.safety.is_safe() => {
|
||||
if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, item.hir_id()) {
|
||||
let (span, help_span) = mk_spans(pos);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
use crate::utils::internal_lints::lint_without_lint_pass::is_lint_ref_type;
|
||||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use regex::Regex;
|
||||
use rustc_ast as ast;
|
||||
use rustc_hir::{Item, ItemKind, Mutability};
|
||||
use rustc_hir::{Attribute, Item, ItemKind, Mutability};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::impl_lint_pass;
|
||||
|
||||
|
|
@ -51,7 +50,7 @@ impl<'tcx> LateLintPass<'tcx> for AlmostStandardFormulation {
|
|||
.hir()
|
||||
.attrs(item.hir_id())
|
||||
.iter()
|
||||
.filter_map(|attr| ast::Attribute::doc_str(attr).map(|sym| (sym, attr)));
|
||||
.filter_map(|attr| Attribute::doc_str(attr).map(|sym| (sym, attr)));
|
||||
if is_lint_ref_type(cx, ty) {
|
||||
for (line, attr) in lines {
|
||||
let cur_line = line.as_str().trim();
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use clippy_utils::macros::root_macro_call_first_node;
|
|||
use clippy_utils::{is_lint_allowed, match_def_path, paths};
|
||||
use rustc_ast::ast::LitKind;
|
||||
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::hir_id::CRATE_HIR_ID;
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
|
|
@ -13,7 +14,6 @@ use rustc_session::impl_lint_pass;
|
|||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_span::{Span, sym};
|
||||
use {rustc_ast as ast, rustc_hir as hir};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
|
|
@ -222,7 +222,7 @@ fn check_invalid_clippy_version_attribute(cx: &LateContext<'_>, item: &'_ Item<'
|
|||
return;
|
||||
}
|
||||
|
||||
if rustc_attr::parse_version(value).is_none() {
|
||||
if rustc_attr_parsing::parse_version(value).is_none() {
|
||||
span_lint_and_help(
|
||||
cx,
|
||||
INVALID_CLIPPY_VERSION_ATTRIBUTE,
|
||||
|
|
@ -249,11 +249,11 @@ fn check_invalid_clippy_version_attribute(cx: &LateContext<'_>, item: &'_ Item<'
|
|||
pub(super) fn extract_clippy_version_value(cx: &LateContext<'_>, item: &'_ Item<'_>) -> Option<Symbol> {
|
||||
let attrs = cx.tcx.hir().attrs(item.hir_id());
|
||||
attrs.iter().find_map(|attr| {
|
||||
if let ast::AttrKind::Normal(attr_kind) = &attr.kind
|
||||
if let hir::AttrKind::Normal(attr_kind) = &attr.kind
|
||||
// Identify attribute
|
||||
&& let [tool_name, attr_name] = &attr_kind.item.path.segments[..]
|
||||
&& tool_name.ident.name == sym::clippy
|
||||
&& attr_name.ident.name == sym::version
|
||||
&& let [tool_name, attr_name] = &attr_kind.path.segments[..]
|
||||
&& tool_name.name == sym::clippy
|
||||
&& attr_name.name == sym::version
|
||||
&& let Some(version) = attr.value_str()
|
||||
{
|
||||
Some(version)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ This crate is only guaranteed to build with this `nightly` toolchain:
|
|||
|
||||
<!-- begin autogenerated nightly -->
|
||||
```
|
||||
nightly-2024-12-15
|
||||
nightly-2024-12-26
|
||||
```
|
||||
<!-- end autogenerated nightly -->
|
||||
|
||||
|
|
|
|||
|
|
@ -872,26 +872,7 @@ pub fn eq_attr_args(l: &AttrArgs, r: &AttrArgs) -> bool {
|
|||
match (l, r) {
|
||||
(Empty, Empty) => true,
|
||||
(Delimited(la), Delimited(ra)) => eq_delim_args(la, ra),
|
||||
(
|
||||
Eq {
|
||||
value: AttrArgsEq::Ast(le),
|
||||
..
|
||||
},
|
||||
Eq {
|
||||
value: AttrArgsEq::Ast(re),
|
||||
..
|
||||
},
|
||||
) => eq_expr(le, re),
|
||||
(
|
||||
Eq {
|
||||
value: AttrArgsEq::Hir(ll),
|
||||
..
|
||||
},
|
||||
Eq {
|
||||
value: AttrArgsEq::Hir(rl),
|
||||
..
|
||||
},
|
||||
) => ll.kind == rl.kind,
|
||||
(Eq { eq_span: _, expr: le }, Eq { eq_span: _, expr: re }) => eq_expr(le, re),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use rustc_ast::{ast, attr};
|
||||
use rustc_ast::attr;
|
||||
use rustc_ast::attr::AttributeExt;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_lexer::TokenKind;
|
||||
use rustc_lint::LateContext;
|
||||
|
|
@ -51,33 +52,31 @@ impl LimitStack {
|
|||
pub fn limit(&self) -> u64 {
|
||||
*self.stack.last().expect("there should always be a value in the stack")
|
||||
}
|
||||
pub fn push_attrs(&mut self, sess: &Session, attrs: &[ast::Attribute], name: &'static str) {
|
||||
pub fn push_attrs(&mut self, sess: &Session, attrs: &[impl AttributeExt], name: &'static str) {
|
||||
let stack = &mut self.stack;
|
||||
parse_attrs(sess, attrs, name, |val| stack.push(val));
|
||||
}
|
||||
pub fn pop_attrs(&mut self, sess: &Session, attrs: &[ast::Attribute], name: &'static str) {
|
||||
pub fn pop_attrs(&mut self, sess: &Session, attrs: &[impl AttributeExt], name: &'static str) {
|
||||
let stack = &mut self.stack;
|
||||
parse_attrs(sess, attrs, name, |val| assert_eq!(stack.pop(), Some(val)));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_attr<'a>(
|
||||
pub fn get_attr<'a, A: AttributeExt + 'a>(
|
||||
sess: &'a Session,
|
||||
attrs: &'a [ast::Attribute],
|
||||
attrs: &'a [A],
|
||||
name: &'static str,
|
||||
) -> impl Iterator<Item = &'a ast::Attribute> {
|
||||
) -> impl Iterator<Item = &'a A> {
|
||||
attrs.iter().filter(move |attr| {
|
||||
let attr = if let ast::AttrKind::Normal(ref normal) = attr.kind {
|
||||
&normal.item
|
||||
} else {
|
||||
let Some(attr_segments) = attr.ident_path() else {
|
||||
return false;
|
||||
};
|
||||
let attr_segments = &attr.path.segments;
|
||||
if attr_segments.len() == 2 && attr_segments[0].ident.name == sym::clippy {
|
||||
|
||||
if attr_segments.len() == 2 && attr_segments[0].name == sym::clippy {
|
||||
BUILTIN_ATTRIBUTES
|
||||
.iter()
|
||||
.find_map(|&(builtin_name, ref deprecation_status)| {
|
||||
if attr_segments[1].ident.name.as_str() == builtin_name {
|
||||
if attr_segments[1].name.as_str() == builtin_name {
|
||||
Some(deprecation_status)
|
||||
} else {
|
||||
None
|
||||
|
|
@ -85,14 +84,13 @@ pub fn get_attr<'a>(
|
|||
})
|
||||
.map_or_else(
|
||||
|| {
|
||||
sess.dcx()
|
||||
.span_err(attr_segments[1].ident.span, "usage of unknown attribute");
|
||||
sess.dcx().span_err(attr_segments[1].span, "usage of unknown attribute");
|
||||
false
|
||||
},
|
||||
|deprecation_status| {
|
||||
let mut diag = sess
|
||||
.dcx()
|
||||
.struct_span_err(attr_segments[1].ident.span, "usage of deprecated attribute");
|
||||
.struct_span_err(attr_segments[1].span, "usage of deprecated attribute");
|
||||
match *deprecation_status {
|
||||
DeprecationStatus::Deprecated => {
|
||||
diag.emit();
|
||||
|
|
@ -100,7 +98,7 @@ pub fn get_attr<'a>(
|
|||
},
|
||||
DeprecationStatus::Replaced(new_name) => {
|
||||
diag.span_suggestion(
|
||||
attr_segments[1].ident.span,
|
||||
attr_segments[1].span,
|
||||
"consider using",
|
||||
new_name,
|
||||
Applicability::MachineApplicable,
|
||||
|
|
@ -110,7 +108,7 @@ pub fn get_attr<'a>(
|
|||
},
|
||||
DeprecationStatus::None => {
|
||||
diag.cancel();
|
||||
attr_segments[1].ident.name.as_str() == name
|
||||
attr_segments[1].as_str() == name
|
||||
},
|
||||
}
|
||||
},
|
||||
|
|
@ -121,31 +119,27 @@ pub fn get_attr<'a>(
|
|||
})
|
||||
}
|
||||
|
||||
fn parse_attrs<F: FnMut(u64)>(sess: &Session, attrs: &[ast::Attribute], name: &'static str, mut f: F) {
|
||||
fn parse_attrs<F: FnMut(u64)>(sess: &Session, attrs: &[impl AttributeExt], name: &'static str, mut f: F) {
|
||||
for attr in get_attr(sess, attrs, name) {
|
||||
if let Some(ref value) = attr.value_str() {
|
||||
if let Ok(value) = FromStr::from_str(value.as_str()) {
|
||||
f(value);
|
||||
} else {
|
||||
sess.dcx().span_err(attr.span, "not a number");
|
||||
sess.dcx().span_err(attr.span(), "not a number");
|
||||
}
|
||||
} else {
|
||||
sess.dcx().span_err(attr.span, "bad clippy attribute");
|
||||
sess.dcx().span_err(attr.span(), "bad clippy attribute");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_unique_attr<'a>(
|
||||
sess: &'a Session,
|
||||
attrs: &'a [ast::Attribute],
|
||||
name: &'static str,
|
||||
) -> Option<&'a ast::Attribute> {
|
||||
let mut unique_attr: Option<&ast::Attribute> = None;
|
||||
pub fn get_unique_attr<'a, A: AttributeExt>(sess: &'a Session, attrs: &'a [A], name: &'static str) -> Option<&'a A> {
|
||||
let mut unique_attr: Option<&A> = None;
|
||||
for attr in get_attr(sess, attrs, name) {
|
||||
if let Some(duplicate) = unique_attr {
|
||||
sess.dcx()
|
||||
.struct_span_err(attr.span, format!("`{name}` is defined multiple times"))
|
||||
.with_span_note(duplicate.span, "first definition found here")
|
||||
.struct_span_err(attr.span(), format!("`{name}` is defined multiple times"))
|
||||
.with_span_note(duplicate.span(), "first definition found here")
|
||||
.emit();
|
||||
} else {
|
||||
unique_attr = Some(attr);
|
||||
|
|
@ -156,16 +150,16 @@ pub fn get_unique_attr<'a>(
|
|||
|
||||
/// Returns true if the attributes contain any of `proc_macro`,
|
||||
/// `proc_macro_derive` or `proc_macro_attribute`, false otherwise
|
||||
pub fn is_proc_macro(attrs: &[ast::Attribute]) -> bool {
|
||||
attrs.iter().any(rustc_ast::Attribute::is_proc_macro_attr)
|
||||
pub fn is_proc_macro(attrs: &[impl AttributeExt]) -> bool {
|
||||
attrs.iter().any(AttributeExt::is_proc_macro_attr)
|
||||
}
|
||||
|
||||
/// Returns true if the attributes contain `#[doc(hidden)]`
|
||||
pub fn is_doc_hidden(attrs: &[ast::Attribute]) -> bool {
|
||||
pub fn is_doc_hidden(attrs: &[impl AttributeExt]) -> bool {
|
||||
attrs
|
||||
.iter()
|
||||
.filter(|attr| attr.has_name(sym::doc))
|
||||
.filter_map(ast::Attribute::meta_item_list)
|
||||
.filter_map(AttributeExt::meta_item_list)
|
||||
.any(|l| attr::list_contains_name(&l, sym::hidden))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -373,7 +373,7 @@ fn ty_search_pat(ty: &Ty<'_>) -> (Pat, Pat) {
|
|||
TyKind::Ptr(MutTy { ty, .. }) => (Pat::Str("*"), ty_search_pat(ty).1),
|
||||
TyKind::Ref(_, MutTy { ty, .. }) => (Pat::Str("&"), ty_search_pat(ty).1),
|
||||
TyKind::BareFn(bare_fn) => (
|
||||
if bare_fn.safety == Safety::Unsafe {
|
||||
if bare_fn.safety.is_unsafe() {
|
||||
Pat::Str("unsafe")
|
||||
} else if bare_fn.abi != Abi::Rust {
|
||||
Pat::Str("extern")
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
// (Currently there is no way to opt into sysroot crates without `extern crate`.)
|
||||
extern crate rustc_ast;
|
||||
extern crate rustc_ast_pretty;
|
||||
extern crate rustc_attr;
|
||||
extern crate rustc_attr_parsing;
|
||||
extern crate rustc_const_eval;
|
||||
extern crate rustc_data_structures;
|
||||
// The `rustc_driver` crate seems to be required in order to use the `rust_ast` crate.
|
||||
|
|
@ -135,13 +135,24 @@ use rustc_middle::hir::nested_filter;
|
|||
|
||||
#[macro_export]
|
||||
macro_rules! extract_msrv_attr {
|
||||
($context:ident) => {
|
||||
fn check_attributes(&mut self, cx: &rustc_lint::$context<'_>, attrs: &[rustc_ast::ast::Attribute]) {
|
||||
(LateContext) => {
|
||||
fn check_attributes(&mut self, cx: &rustc_lint::LateContext<'_>, attrs: &[rustc_hir::Attribute]) {
|
||||
let sess = rustc_lint::LintContext::sess(cx);
|
||||
self.msrv.check_attributes(sess, attrs);
|
||||
}
|
||||
|
||||
fn check_attributes_post(&mut self, cx: &rustc_lint::$context<'_>, attrs: &[rustc_ast::ast::Attribute]) {
|
||||
fn check_attributes_post(&mut self, cx: &rustc_lint::LateContext<'_>, attrs: &[rustc_hir::Attribute]) {
|
||||
let sess = rustc_lint::LintContext::sess(cx);
|
||||
self.msrv.check_attributes_post(sess, attrs);
|
||||
}
|
||||
};
|
||||
(EarlyContext) => {
|
||||
fn check_attributes(&mut self, cx: &rustc_lint::EarlyContext<'_>, attrs: &[rustc_ast::Attribute]) {
|
||||
let sess = rustc_lint::LintContext::sess(cx);
|
||||
self.msrv.check_attributes(sess, attrs);
|
||||
}
|
||||
|
||||
fn check_attributes_post(&mut self, cx: &rustc_lint::EarlyContext<'_>, attrs: &[rustc_ast::Attribute]) {
|
||||
let sess = rustc_lint::LintContext::sess(cx);
|
||||
self.msrv.check_attributes_post(sess, attrs);
|
||||
}
|
||||
|
|
@ -1912,7 +1923,7 @@ pub fn clip(tcx: TyCtxt<'_>, u: u128, ity: UintTy) -> u128 {
|
|||
(u << amt) >> amt
|
||||
}
|
||||
|
||||
pub fn has_attr(attrs: &[ast::Attribute], symbol: Symbol) -> bool {
|
||||
pub fn has_attr(attrs: &[hir::Attribute], symbol: Symbol) -> bool {
|
||||
attrs.iter().any(|attr| attr.has_name(symbol))
|
||||
}
|
||||
|
||||
|
|
@ -2225,23 +2236,19 @@ pub fn std_or_core(cx: &LateContext<'_>) -> Option<&'static str> {
|
|||
}
|
||||
|
||||
pub fn is_no_std_crate(cx: &LateContext<'_>) -> bool {
|
||||
cx.tcx.hir().attrs(hir::CRATE_HIR_ID).iter().any(|attr| {
|
||||
if let ast::AttrKind::Normal(ref normal) = attr.kind {
|
||||
normal.item.path == sym::no_std
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
cx.tcx
|
||||
.hir()
|
||||
.attrs(hir::CRATE_HIR_ID)
|
||||
.iter()
|
||||
.any(|attr| attr.name_or_empty() == sym::no_std)
|
||||
}
|
||||
|
||||
pub fn is_no_core_crate(cx: &LateContext<'_>) -> bool {
|
||||
cx.tcx.hir().attrs(hir::CRATE_HIR_ID).iter().any(|attr| {
|
||||
if let ast::AttrKind::Normal(ref normal) = attr.kind {
|
||||
normal.item.path == sym::no_core
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
cx.tcx
|
||||
.hir()
|
||||
.attrs(hir::CRATE_HIR_ID)
|
||||
.iter()
|
||||
.any(|attr| attr.name_or_empty() == sym::no_core)
|
||||
}
|
||||
|
||||
/// Check if parent of a hir node is a trait implementation block.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use rustc_ast::Attribute;
|
||||
use rustc_attr::parse_version;
|
||||
use rustc_session::{RustcVersion, Session};
|
||||
use rustc_ast::attr::AttributeExt;
|
||||
use rustc_attr_parsing::{RustcVersion, parse_version};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::{Symbol, sym};
|
||||
use serde::Deserialize;
|
||||
use smallvec::{SmallVec, smallvec};
|
||||
|
|
@ -125,15 +125,15 @@ impl Msrv {
|
|||
self.current().is_none_or(|msrv| msrv >= required)
|
||||
}
|
||||
|
||||
fn parse_attr(sess: &Session, attrs: &[Attribute]) -> Option<RustcVersion> {
|
||||
fn parse_attr(sess: &Session, attrs: &[impl AttributeExt]) -> Option<RustcVersion> {
|
||||
let sym_msrv = Symbol::intern("msrv");
|
||||
let mut msrv_attrs = attrs.iter().filter(|attr| attr.path_matches(&[sym::clippy, sym_msrv]));
|
||||
|
||||
if let Some(msrv_attr) = msrv_attrs.next() {
|
||||
if let Some(duplicate) = msrv_attrs.last() {
|
||||
sess.dcx()
|
||||
.struct_span_err(duplicate.span, "`clippy::msrv` is defined multiple times")
|
||||
.with_span_note(msrv_attr.span, "first definition found here")
|
||||
.struct_span_err(duplicate.span(), "`clippy::msrv` is defined multiple times")
|
||||
.with_span_note(msrv_attr.span(), "first definition found here")
|
||||
.emit();
|
||||
}
|
||||
|
||||
|
|
@ -143,22 +143,22 @@ impl Msrv {
|
|||
}
|
||||
|
||||
sess.dcx()
|
||||
.span_err(msrv_attr.span, format!("`{msrv}` is not a valid Rust version"));
|
||||
.span_err(msrv_attr.span(), format!("`{msrv}` is not a valid Rust version"));
|
||||
} else {
|
||||
sess.dcx().span_err(msrv_attr.span, "bad clippy attribute");
|
||||
sess.dcx().span_err(msrv_attr.span(), "bad clippy attribute");
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn check_attributes(&mut self, sess: &Session, attrs: &[Attribute]) {
|
||||
pub fn check_attributes(&mut self, sess: &Session, attrs: &[impl AttributeExt]) {
|
||||
if let Some(version) = Self::parse_attr(sess, attrs) {
|
||||
self.stack.push(version);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_attributes_post(&mut self, sess: &Session, attrs: &[Attribute]) {
|
||||
pub fn check_attributes_post(&mut self, sess: &Session, attrs: &[impl AttributeExt]) {
|
||||
if Self::parse_attr(sess, attrs).is_some() {
|
||||
self.stack.pop();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
use crate::msrvs::{self, Msrv};
|
||||
use hir::LangItem;
|
||||
use rustc_attr::StableSince;
|
||||
use rustc_attr_parsing::{RustcVersion, StableSince};
|
||||
use rustc_const_eval::check_consts::ConstCx;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
|
|
@ -109,7 +109,7 @@ fn check_rvalue<'tcx>(
|
|||
) -> McfResult {
|
||||
match rvalue {
|
||||
Rvalue::ThreadLocalRef(_) => Err((span, "cannot access thread local storage in const fn".into())),
|
||||
Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => {
|
||||
Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => {
|
||||
check_place(tcx, *place, span, body, msrv)
|
||||
},
|
||||
Rvalue::CopyForDeref(place) => check_place(tcx, *place, span, body, msrv),
|
||||
|
|
@ -381,14 +381,14 @@ fn check_terminator<'tcx>(
|
|||
fn is_stable_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: &Msrv) -> bool {
|
||||
tcx.is_const_fn(def_id)
|
||||
&& tcx.lookup_const_stability(def_id).is_none_or(|const_stab| {
|
||||
if let rustc_attr::StabilityLevel::Stable { since, .. } = const_stab.level {
|
||||
if let rustc_attr_parsing::StabilityLevel::Stable { since, .. } = const_stab.level {
|
||||
// Checking MSRV is manually necessary because `rustc` has no such concept. This entire
|
||||
// function could be removed if `rustc` provided a MSRV-aware version of `is_stable_const_fn`.
|
||||
// as a part of an unimplemented MSRV check https://github.com/rust-lang/rust/issues/65262.
|
||||
|
||||
let const_stab_rust_version = match since {
|
||||
StableSince::Version(version) => version,
|
||||
StableSince::Current => rustc_session::RustcVersion::CURRENT,
|
||||
StableSince::Current => RustcVersion::CURRENT,
|
||||
StableSince::Err => return false,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
|||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::{Expr, FnDecl, LangItem, Safety, TyKind};
|
||||
use rustc_hir::{Expr, FnDecl, LangItem, TyKind};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::mir::ConstValue;
|
||||
|
|
@ -531,7 +531,7 @@ pub fn peel_mid_ty_refs_is_mutable(ty: Ty<'_>) -> (Ty<'_>, usize, Mutability) {
|
|||
/// Returns `true` if the given type is an `unsafe` function.
|
||||
pub fn type_is_unsafe_function<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
match ty.kind() {
|
||||
ty::FnDef(..) | ty::FnPtr(..) => ty.fn_sig(cx.tcx).safety() == Safety::Unsafe,
|
||||
ty::FnDef(..) | ty::FnPtr(..) => ty.fn_sig(cx.tcx).safety().is_unsafe(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res};
|
|||
use rustc_hir::intravisit::{self, Visitor, walk_block, walk_expr};
|
||||
use rustc_hir::{
|
||||
AnonConst, Arm, Block, BlockCheckMode, Body, BodyId, Expr, ExprKind, HirId, ItemId, ItemKind, LetExpr, Pat, QPath,
|
||||
Safety, Stmt, StructTailExpr, UnOp, UnsafeSource,
|
||||
Stmt, StructTailExpr, UnOp, UnsafeSource,
|
||||
};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::hir::nested_filter;
|
||||
|
|
@ -426,15 +426,15 @@ pub fn is_expr_unsafe<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool {
|
|||
.cx
|
||||
.typeck_results()
|
||||
.type_dependent_def_id(e.hir_id)
|
||||
.is_some_and(|id| self.cx.tcx.fn_sig(id).skip_binder().safety() == Safety::Unsafe) =>
|
||||
.is_some_and(|id| self.cx.tcx.fn_sig(id).skip_binder().safety().is_unsafe()) =>
|
||||
{
|
||||
ControlFlow::Break(())
|
||||
},
|
||||
ExprKind::Call(func, _) => match *self.cx.typeck_results().expr_ty(func).peel_refs().kind() {
|
||||
ty::FnDef(id, _) if self.cx.tcx.fn_sig(id).skip_binder().safety() == Safety::Unsafe => {
|
||||
ty::FnDef(id, _) if self.cx.tcx.fn_sig(id).skip_binder().safety().is_unsafe() => {
|
||||
ControlFlow::Break(())
|
||||
},
|
||||
ty::FnPtr(_, hdr) if hdr.safety == Safety::Unsafe => ControlFlow::Break(()),
|
||||
ty::FnPtr(_, hdr) if hdr.safety.is_unsafe() => ControlFlow::Break(()),
|
||||
_ => walk_expr(self, e),
|
||||
},
|
||||
ExprKind::Path(ref p)
|
||||
|
|
@ -458,7 +458,7 @@ pub fn is_expr_unsafe<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool {
|
|||
}
|
||||
fn visit_nested_item(&mut self, id: ItemId) -> Self::Result {
|
||||
if let ItemKind::Impl(i) = &self.cx.tcx.hir().item(id).kind
|
||||
&& i.safety == Safety::Unsafe
|
||||
&& i.safety.is_unsafe()
|
||||
{
|
||||
ControlFlow::Break(())
|
||||
} else {
|
||||
|
|
@ -677,6 +677,9 @@ pub fn for_each_unconsumed_temporary<'tcx, B>(
|
|||
ExprKind::Type(e, _) => {
|
||||
helper(typeck, consume, e, f)?;
|
||||
},
|
||||
ExprKind::UnsafeBinderCast(_, e, _) => {
|
||||
helper(typeck, consume, e, f)?;
|
||||
},
|
||||
|
||||
// Either drops temporaries, jumps out of the current expression, or has no sub expression.
|
||||
ExprKind::DropTemps(_)
|
||||
|
|
@ -694,7 +697,6 @@ pub fn for_each_unconsumed_temporary<'tcx, B>(
|
|||
| ExprKind::Continue(_)
|
||||
| ExprKind::InlineAsm(_)
|
||||
| ExprKind::OffsetOf(..)
|
||||
| ExprKind::UnsafeBinderCast(..)
|
||||
| ExprKind::Err(_) => (),
|
||||
}
|
||||
ControlFlow::Continue(())
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[toolchain]
|
||||
# begin autogenerated nightly
|
||||
channel = "nightly-2024-12-15"
|
||||
channel = "nightly-2024-12-26"
|
||||
# end autogenerated nightly
|
||||
components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
|
||||
profile = "minimal"
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ fn main() {
|
|||
let _ = rustc_span::sym::proc_dash_macro;
|
||||
|
||||
// interning a keyword
|
||||
let _ = rustc_span::symbol::kw::SelfLower;
|
||||
let _ = rustc_span::kw::SelfLower;
|
||||
|
||||
// Interning a symbol that is not defined
|
||||
let _ = Symbol::intern("xyz123");
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ error: interning a defined symbol
|
|||
--> tests/ui-internal/interning_defined_symbol.rs:26:13
|
||||
|
|
||||
LL | let _ = Symbol::intern("self");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `rustc_span::symbol::kw::SelfLower`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `rustc_span::kw::SelfLower`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ use rustc_span::symbol::{Ident, Symbol};
|
|||
|
||||
fn main() {
|
||||
Symbol::intern("foo") == rustc_span::sym::clippy;
|
||||
Symbol::intern("foo") == rustc_span::symbol::kw::SelfLower;
|
||||
Symbol::intern("foo") != rustc_span::symbol::kw::SelfUpper;
|
||||
Symbol::intern("foo") == rustc_span::kw::SelfLower;
|
||||
Symbol::intern("foo") != rustc_span::kw::SelfUpper;
|
||||
Ident::empty().name == rustc_span::sym::clippy;
|
||||
rustc_span::sym::clippy == Ident::empty().name;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,13 +15,13 @@ error: unnecessary `Symbol` to string conversion
|
|||
--> tests/ui-internal/unnecessary_symbol_str.rs:17:5
|
||||
|
|
||||
LL | Symbol::intern("foo").to_string() == "self";
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Symbol::intern("foo") == rustc_span::symbol::kw::SelfLower`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Symbol::intern("foo") == rustc_span::kw::SelfLower`
|
||||
|
||||
error: unnecessary `Symbol` to string conversion
|
||||
--> tests/ui-internal/unnecessary_symbol_str.rs:18:5
|
||||
|
|
||||
LL | Symbol::intern("foo").to_ident_string() != "Self";
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Symbol::intern("foo") != rustc_span::symbol::kw::SelfUpper`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Symbol::intern("foo") != rustc_span::kw::SelfUpper`
|
||||
|
||||
error: unnecessary `Symbol` to string conversion
|
||||
--> tests/ui-internal/unnecessary_symbol_str.rs:19:5
|
||||
|
|
|
|||
|
|
@ -30,46 +30,3 @@ impl Bar {
|
|||
String::from("Bar")
|
||||
}
|
||||
}
|
||||
|
||||
mod issue12263 {
|
||||
pub struct MyStringWrapper<'a>(&'a str);
|
||||
|
||||
impl std::fmt::Display for MyStringWrapper<'_> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for MyStringWrapper<'_> {
|
||||
fn to_string(&self) -> String {
|
||||
self.0.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct S<T>(T);
|
||||
impl std::fmt::Display for S<String> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
// no specialization if the generics differ, so lint
|
||||
impl ToString for S<i32> {
|
||||
fn to_string(&self) -> String {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct S2<T>(T);
|
||||
impl std::fmt::Display for S2<String> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
// also specialization if the generics don't differ
|
||||
impl ToString for S2<String> {
|
||||
fn to_string(&self) -> String {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,17 +12,5 @@ LL | | }
|
|||
= note: `-D clippy::to-string-trait-impl` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::to_string_trait_impl)]`
|
||||
|
||||
error: direct implementation of `ToString`
|
||||
--> tests/ui/to_string_trait_impl.rs:56:5
|
||||
|
|
||||
LL | / impl ToString for S<i32> {
|
||||
LL | | fn to_string(&self) -> String {
|
||||
LL | | todo!()
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
|
||||
= help: prefer implementing `Display` instead
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue