mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-02 11:44:28 +00:00
Auto merge of #9881 - flip1995:rustup, r=flip1995
Rustup
r? `@ghost`
It took >4 weeks, but I finally got to do the sync 🎉
changelog: none
This commit is contained in:
commit
f4850f7292
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "clippy"
|
||||
version = "0.1.66"
|
||||
version = "0.1.67"
|
||||
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
|
||||
repository = "https://github.com/rust-lang/rust-clippy"
|
||||
readme = "README.md"
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "clippy_lints"
|
||||
version = "0.1.66"
|
||||
version = "0.1.67"
|
||||
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
|
||||
repository = "https://github.com/rust-lang/rust-clippy"
|
||||
readme = "README.md"
|
||||
|
@ -73,12 +73,21 @@ impl EarlyLintPass for AlmostCompleteLetterRange {
|
||||
}
|
||||
|
||||
fn check_range(cx: &EarlyContext<'_>, span: Span, start: &Expr, end: &Expr, sugg: Option<(Span, &str)>) {
|
||||
if let ExprKind::Lit(start_lit) = &start.peel_parens().kind
|
||||
&& let ExprKind::Lit(end_lit) = &end.peel_parens().kind
|
||||
if let ExprKind::Lit(start_token_lit) = start.peel_parens().kind
|
||||
&& let ExprKind::Lit(end_token_lit) = end.peel_parens().kind
|
||||
&& matches!(
|
||||
(&start_lit.kind, &end_lit.kind),
|
||||
(LitKind::Byte(b'a') | LitKind::Char('a'), LitKind::Byte(b'z') | LitKind::Char('z'))
|
||||
| (LitKind::Byte(b'A') | LitKind::Char('A'), LitKind::Byte(b'Z') | LitKind::Char('Z'))
|
||||
(
|
||||
LitKind::from_token_lit(start_token_lit),
|
||||
LitKind::from_token_lit(end_token_lit),
|
||||
),
|
||||
(
|
||||
Ok(LitKind::Byte(b'a') | LitKind::Char('a')),
|
||||
Ok(LitKind::Byte(b'z') | LitKind::Char('z'))
|
||||
)
|
||||
| (
|
||||
Ok(LitKind::Byte(b'A') | LitKind::Char('A')),
|
||||
Ok(LitKind::Byte(b'Z') | LitKind::Char('Z')),
|
||||
)
|
||||
)
|
||||
&& !in_external_macro(cx.sess(), span)
|
||||
{
|
||||
|
@ -26,7 +26,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: Option<RustcVer
|
||||
(Mutability::Not, Mutability::Not) | (Mutability::Mut, Mutability::Mut));
|
||||
// The `U` in `pointer::cast` have to be `Sized`
|
||||
// as explained here: https://github.com/rust-lang/rust/issues/60602.
|
||||
if to_pointee_ty.is_sized(cx.tcx.at(expr.span), cx.param_env);
|
||||
if to_pointee_ty.is_sized(cx.tcx, cx.param_env);
|
||||
then {
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
let cast_expr_sugg = Sugg::hir_with_applicability(cx, cast_expr, "_", &mut applicability);
|
||||
|
@ -43,7 +43,7 @@ impl<'tcx> LateLintPass<'tcx> for CopyIterator {
|
||||
of_trait: Some(ref trait_ref),
|
||||
..
|
||||
}) = item.kind;
|
||||
let ty = cx.tcx.type_of(item.def_id);
|
||||
let ty = cx.tcx.type_of(item.owner_id);
|
||||
if is_copy(cx, ty);
|
||||
if let Some(trait_id) = trait_ref.trait_def_id();
|
||||
if cx.tcx.is_diagnostic_item(sym::Iterator, trait_id);
|
||||
|
@ -61,7 +61,7 @@ impl<'tcx> LateLintPass<'tcx> for DefaultUnionRepresentation {
|
||||
None,
|
||||
&format!(
|
||||
"consider annotating `{}` with `#[repr(C)]` to explicitly specify memory layout",
|
||||
cx.tcx.def_path_str(item.def_id.to_def_id())
|
||||
cx.tcx.def_path_str(item.owner_id.to_def_id())
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ use rustc_middle::ty::{
|
||||
};
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::{symbol::sym, Span, Symbol, DUMMY_SP};
|
||||
use rustc_span::{symbol::sym, Span, Symbol};
|
||||
use rustc_trait_selection::infer::InferCtxtExt as _;
|
||||
use rustc_trait_selection::traits::{query::evaluate_obligation::InferCtxtExt as _, Obligation, ObligationCause};
|
||||
use std::collections::VecDeque;
|
||||
@ -714,47 +714,47 @@ fn walk_parents<'tcx>(
|
||||
},
|
||||
Node::Item(&Item {
|
||||
kind: ItemKind::Static(..) | ItemKind::Const(..),
|
||||
def_id,
|
||||
owner_id,
|
||||
span,
|
||||
..
|
||||
})
|
||||
| Node::TraitItem(&TraitItem {
|
||||
kind: TraitItemKind::Const(..),
|
||||
def_id,
|
||||
owner_id,
|
||||
span,
|
||||
..
|
||||
})
|
||||
| Node::ImplItem(&ImplItem {
|
||||
kind: ImplItemKind::Const(..),
|
||||
def_id,
|
||||
owner_id,
|
||||
span,
|
||||
..
|
||||
}) if span.ctxt() == ctxt => {
|
||||
let ty = cx.tcx.type_of(def_id.def_id);
|
||||
let ty = cx.tcx.type_of(owner_id.def_id);
|
||||
Some(ty_auto_deref_stability(cx, ty, precedence).position_for_result(cx))
|
||||
},
|
||||
|
||||
Node::Item(&Item {
|
||||
kind: ItemKind::Fn(..),
|
||||
def_id,
|
||||
owner_id,
|
||||
span,
|
||||
..
|
||||
})
|
||||
| Node::TraitItem(&TraitItem {
|
||||
kind: TraitItemKind::Fn(..),
|
||||
def_id,
|
||||
owner_id,
|
||||
span,
|
||||
..
|
||||
})
|
||||
| Node::ImplItem(&ImplItem {
|
||||
kind: ImplItemKind::Fn(..),
|
||||
def_id,
|
||||
owner_id,
|
||||
span,
|
||||
..
|
||||
}) if span.ctxt() == ctxt => {
|
||||
let output = cx
|
||||
.tcx
|
||||
.erase_late_bound_regions(cx.tcx.fn_sig(def_id.to_def_id()).output());
|
||||
.erase_late_bound_regions(cx.tcx.fn_sig(owner_id.to_def_id()).output());
|
||||
Some(ty_auto_deref_stability(cx, output, precedence).position_for_result(cx))
|
||||
},
|
||||
|
||||
@ -1000,7 +1000,7 @@ fn binding_ty_auto_deref_stability<'tcx>(
|
||||
cx.typeck_results().node_type(ty.ty.hir_id),
|
||||
binder_args,
|
||||
))
|
||||
.is_sized(cx.tcx.at(DUMMY_SP), cx.param_env.without_caller_bounds()),
|
||||
.is_sized(cx.tcx, cx.param_env.without_caller_bounds()),
|
||||
)
|
||||
}
|
||||
},
|
||||
@ -1015,7 +1015,7 @@ fn binding_ty_auto_deref_stability<'tcx>(
|
||||
cx.typeck_results().node_type(ty.ty.hir_id),
|
||||
binder_args,
|
||||
))
|
||||
.is_sized(cx.tcx.at(DUMMY_SP), cx.param_env.without_caller_bounds()),
|
||||
.is_sized(cx.tcx, cx.param_env.without_caller_bounds()),
|
||||
),
|
||||
TyKind::OpaqueDef(..) | TyKind::Infer | TyKind::Typeof(..) | TyKind::TraitObject(..) | TyKind::Err => {
|
||||
Position::ReborrowStable(precedence)
|
||||
@ -1116,7 +1116,7 @@ fn needless_borrow_impl_arg_position<'tcx>(
|
||||
.iter()
|
||||
.filter_map(|predicate| {
|
||||
if let PredicateKind::Trait(trait_predicate) = predicate.kind().skip_binder()
|
||||
&& trait_predicate.self_ty() == param_ty.to_ty(cx.tcx)
|
||||
&& trait_predicate.trait_ref.self_ty() == param_ty.to_ty(cx.tcx)
|
||||
{
|
||||
Some(trait_predicate.trait_ref.def_id)
|
||||
} else {
|
||||
@ -1188,7 +1188,7 @@ fn needless_borrow_impl_arg_position<'tcx>(
|
||||
}
|
||||
|
||||
let predicate = EarlyBinder(predicate).subst(cx.tcx, &substs_with_referent_ty);
|
||||
let obligation = Obligation::new(ObligationCause::dummy(), cx.param_env, predicate);
|
||||
let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);
|
||||
let infcx = cx.tcx.infer_ctxt().build();
|
||||
infcx.predicate_must_hold_modulo_regions(&obligation)
|
||||
})
|
||||
@ -1362,7 +1362,7 @@ impl<'tcx> TyPosition<'tcx> {
|
||||
fn position_for_result(self, cx: &LateContext<'tcx>) -> Position {
|
||||
match (self.position, self.ty) {
|
||||
(Position::ReborrowStable(precedence), Some(ty)) => {
|
||||
Position::DerefStable(precedence, ty.is_sized(cx.tcx.at(DUMMY_SP), cx.param_env))
|
||||
Position::DerefStable(precedence, ty.is_sized(cx.tcx, cx.param_env))
|
||||
},
|
||||
(position, _) => position,
|
||||
}
|
||||
@ -1412,11 +1412,9 @@ fn ty_auto_deref_stability<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, precedenc
|
||||
| ty::Closure(..)
|
||||
| ty::Never
|
||||
| ty::Tuple(_)
|
||||
| ty::Projection(_) => Position::DerefStable(
|
||||
precedence,
|
||||
ty.is_sized(cx.tcx.at(DUMMY_SP), cx.param_env.without_caller_bounds()),
|
||||
)
|
||||
.into(),
|
||||
| ty::Projection(_) => {
|
||||
Position::DerefStable(precedence, ty.is_sized(cx.tcx, cx.param_env.without_caller_bounds())).into()
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls {
|
||||
self_ty,
|
||||
..
|
||||
}) = item.kind;
|
||||
if !cx.tcx.has_attr(item.def_id.to_def_id(), sym::automatically_derived);
|
||||
if !cx.tcx.has_attr(item.owner_id.to_def_id(), sym::automatically_derived);
|
||||
if !item.span.from_expansion();
|
||||
if let Some(def_id) = trait_ref.trait_def_id();
|
||||
if cx.tcx.is_diagnostic_item(sym::Default, def_id);
|
||||
@ -78,7 +78,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls {
|
||||
if let Some(Node::ImplItem(impl_item)) = cx.tcx.hir().find(impl_item_hir);
|
||||
if let ImplItemKind::Fn(_, b) = &impl_item.kind;
|
||||
if let Body { value: func_expr, .. } = cx.tcx.hir().body(*b);
|
||||
if let Some(adt_def) = cx.tcx.type_of(item.def_id).ty_adt_def();
|
||||
if let Some(adt_def) = cx.tcx.type_of(item.owner_id).ty_adt_def();
|
||||
if let attrs = cx.tcx.hir().attrs(item.hir_id());
|
||||
if !attrs.iter().any(|attr| attr.doc_str().is_some());
|
||||
if let child_attrs = cx.tcx.hir().attrs(impl_item_hir);
|
||||
|
@ -210,8 +210,8 @@ impl<'tcx> LateLintPass<'tcx> for Derive {
|
||||
..
|
||||
}) = item.kind
|
||||
{
|
||||
let ty = cx.tcx.type_of(item.def_id);
|
||||
let is_automatically_derived = cx.tcx.has_attr(item.def_id.to_def_id(), sym::automatically_derived);
|
||||
let ty = cx.tcx.type_of(item.owner_id);
|
||||
let is_automatically_derived = cx.tcx.has_attr(item.owner_id.to_def_id(), sym::automatically_derived);
|
||||
|
||||
check_hash_peq(cx, item.span, trait_ref, ty, is_automatically_derived);
|
||||
check_ord_partial_ord(cx, item.span, trait_ref, ty, is_automatically_derived);
|
||||
|
@ -294,15 +294,15 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
|
||||
let Some(headers) = check_attrs(cx, &self.valid_idents, attrs) else { return };
|
||||
match item.kind {
|
||||
hir::ItemKind::Fn(ref sig, _, body_id) => {
|
||||
if !(is_entrypoint_fn(cx, item.def_id.to_def_id()) || in_external_macro(cx.tcx.sess, item.span)) {
|
||||
if !(is_entrypoint_fn(cx, item.owner_id.to_def_id()) || in_external_macro(cx.tcx.sess, item.span)) {
|
||||
let body = cx.tcx.hir().body(body_id);
|
||||
let mut fpu = FindPanicUnwrap {
|
||||
cx,
|
||||
typeck_results: cx.tcx.typeck(item.def_id.def_id),
|
||||
typeck_results: cx.tcx.typeck(item.owner_id.def_id),
|
||||
panic_span: None,
|
||||
};
|
||||
fpu.visit_expr(body.value);
|
||||
lint_for_missing_headers(cx, item.def_id.def_id, sig, headers, Some(body_id), fpu.panic_span);
|
||||
lint_for_missing_headers(cx, item.owner_id.def_id, sig, headers, Some(body_id), fpu.panic_span);
|
||||
}
|
||||
},
|
||||
hir::ItemKind::Impl(impl_) => {
|
||||
@ -312,13 +312,13 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
|
||||
(false, hir::Unsafety::Unsafe) => span_lint(
|
||||
cx,
|
||||
MISSING_SAFETY_DOC,
|
||||
cx.tcx.def_span(item.def_id),
|
||||
cx.tcx.def_span(item.owner_id),
|
||||
"docs for unsafe trait missing `# Safety` section",
|
||||
),
|
||||
(true, hir::Unsafety::Normal) => span_lint(
|
||||
cx,
|
||||
UNNECESSARY_SAFETY_DOC,
|
||||
cx.tcx.def_span(item.def_id),
|
||||
cx.tcx.def_span(item.owner_id),
|
||||
"docs for safe trait have unnecessary `# Safety` section",
|
||||
),
|
||||
_ => (),
|
||||
@ -338,7 +338,7 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
|
||||
let Some(headers) = check_attrs(cx, &self.valid_idents, attrs) else { return };
|
||||
if let hir::TraitItemKind::Fn(ref sig, ..) = item.kind {
|
||||
if !in_external_macro(cx.tcx.sess, item.span) {
|
||||
lint_for_missing_headers(cx, item.def_id.def_id, sig, headers, None, None);
|
||||
lint_for_missing_headers(cx, item.owner_id.def_id, sig, headers, None, None);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -353,11 +353,11 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
|
||||
let body = cx.tcx.hir().body(body_id);
|
||||
let mut fpu = FindPanicUnwrap {
|
||||
cx,
|
||||
typeck_results: cx.tcx.typeck(item.def_id.def_id),
|
||||
typeck_results: cx.tcx.typeck(item.owner_id.def_id),
|
||||
panic_span: None,
|
||||
};
|
||||
fpu.visit_expr(body.value);
|
||||
lint_for_missing_headers(cx, item.def_id.def_id, sig, headers, Some(body_id), fpu.panic_span);
|
||||
lint_for_missing_headers(cx, item.owner_id.def_id, sig, headers, Some(body_id), fpu.panic_span);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -370,7 +370,7 @@ fn lint_for_missing_headers(
|
||||
body_id: Option<hir::BodyId>,
|
||||
panic_span: Option<Span>,
|
||||
) {
|
||||
if !cx.access_levels.is_exported(def_id) {
|
||||
if !cx.effective_visibilities.is_exported(def_id) {
|
||||
return; // Private functions do not require doc comments
|
||||
}
|
||||
|
||||
@ -720,6 +720,7 @@ fn check_code(cx: &LateContext<'_>, text: &str, edition: Edition, span: Span) {
|
||||
false,
|
||||
None,
|
||||
false,
|
||||
false,
|
||||
);
|
||||
let handler = Handler::with_emitter(false, None, Box::new(emitter));
|
||||
let sess = ParseSess::with_span_handler(handler, sm);
|
||||
|
@ -61,10 +61,10 @@ impl EarlyLintPass for DoubleParens {
|
||||
}
|
||||
}
|
||||
},
|
||||
ExprKind::MethodCall(_, _, ref params, _) => {
|
||||
if let [ref param] = params[..] {
|
||||
if let ExprKind::Paren(_) = param.kind {
|
||||
span_lint(cx, DOUBLE_PARENS, param.span, msg);
|
||||
ExprKind::MethodCall(ref call) => {
|
||||
if let [ref arg] = call.args[..] {
|
||||
if let ExprKind::Paren(_) = arg.kind {
|
||||
span_lint(cx, DOUBLE_PARENS, arg.span, msg);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -49,7 +49,7 @@ impl<'tcx> LateLintPass<'tcx> for EmptyEnum {
|
||||
}
|
||||
|
||||
if let ItemKind::Enum(..) = item.kind {
|
||||
let ty = cx.tcx.type_of(item.def_id);
|
||||
let ty = cx.tcx.type_of(item.owner_id);
|
||||
let adt = ty.ty_adt_def().expect("already checked whether this is an enum");
|
||||
if adt.variants().is_empty() {
|
||||
span_lint_and_help(
|
||||
|
@ -265,7 +265,7 @@ impl LateLintPass<'_> for EnumVariantNames {
|
||||
}
|
||||
// The `module_name_repetitions` lint should only trigger if the item has the module in its
|
||||
// name. Having the same name is accepted.
|
||||
if cx.tcx.visibility(item.def_id).is_public() && item_camel.len() > mod_camel.len() {
|
||||
if cx.tcx.visibility(item.owner_id).is_public() && item_camel.len() > mod_camel.len() {
|
||||
let matching = count_match_start(mod_camel, &item_camel);
|
||||
let rmatching = count_match_end(mod_camel, &item_camel);
|
||||
let nchars = mod_camel.chars().count();
|
||||
@ -296,7 +296,7 @@ impl LateLintPass<'_> for EnumVariantNames {
|
||||
}
|
||||
}
|
||||
if let ItemKind::Enum(ref def, _) = item.kind {
|
||||
if !(self.avoid_breaking_exported_api && cx.access_levels.is_exported(item.def_id.def_id)) {
|
||||
if !(self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(item.owner_id.def_id)) {
|
||||
check_variant(cx, self.threshold, def, item_name, item.span);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use clippy_utils::diagnostics::span_lint_hir;
|
||||
use rustc_hir::intravisit;
|
||||
use rustc_hir::{self, AssocItemKind, Body, FnDecl, HirId, HirIdSet, Impl, ItemKind, Node, Pat, PatKind};
|
||||
use rustc_hir_analysis::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
|
||||
use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::mir::FakeReadCause;
|
||||
@ -88,7 +88,7 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
|
||||
// be sure we have `self` parameter in this function
|
||||
if trait_item.kind == (AssocItemKind::Fn { has_self: true }) {
|
||||
trait_self_ty = Some(
|
||||
TraitRef::identity(cx.tcx, trait_item.id.def_id.to_def_id())
|
||||
TraitRef::identity(cx.tcx, trait_item.id.owner_id.to_def_id())
|
||||
.self_ty()
|
||||
.skip_binder(),
|
||||
);
|
||||
@ -176,13 +176,7 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn fake_read(
|
||||
&mut self,
|
||||
_: &rustc_hir_analysis::expr_use_visitor::PlaceWithHirId<'tcx>,
|
||||
_: FakeReadCause,
|
||||
_: HirId,
|
||||
) {
|
||||
}
|
||||
fn fake_read(&mut self, _: &rustc_hir_typeck::expr_use_visitor::PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> EscapeDelegate<'a, 'tcx> {
|
||||
|
@ -73,7 +73,7 @@ impl LateLintPass<'_> for ExhaustiveItems {
|
||||
fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
|
||||
if_chain! {
|
||||
if let ItemKind::Enum(..) | ItemKind::Struct(..) = item.kind;
|
||||
if cx.access_levels.is_exported(item.def_id.def_id);
|
||||
if cx.effective_visibilities.is_exported(item.owner_id.def_id);
|
||||
let attrs = cx.tcx.hir().attrs(item.hir_id());
|
||||
if !attrs.iter().any(|a| a.has_name(sym::non_exhaustive));
|
||||
then {
|
||||
|
@ -55,7 +55,7 @@ impl<'tcx> LateLintPass<'tcx> for FallibleImplFrom {
|
||||
// check for `impl From<???> for ..`
|
||||
if_chain! {
|
||||
if let hir::ItemKind::Impl(impl_) = &item.kind;
|
||||
if let Some(impl_trait_ref) = cx.tcx.impl_trait_ref(item.def_id);
|
||||
if let Some(impl_trait_ref) = cx.tcx.impl_trait_ref(item.owner_id);
|
||||
if cx.tcx.is_diagnostic_item(sym::From, impl_trait_ref.def_id);
|
||||
then {
|
||||
lint_impl_body(cx, item.span, impl_.items);
|
||||
@ -107,7 +107,7 @@ fn lint_impl_body(cx: &LateContext<'_>, impl_span: Span, impl_items: &[hir::Impl
|
||||
let body = cx.tcx.hir().body(body_id);
|
||||
let mut fpu = FindPanicUnwrap {
|
||||
lcx: cx,
|
||||
typeck_results: cx.tcx.typeck(impl_item.id.def_id.def_id),
|
||||
typeck_results: cx.tcx.typeck(impl_item.id.owner_id.def_id),
|
||||
result: Vec::new(),
|
||||
};
|
||||
fpu.visit_expr(body.value);
|
||||
|
@ -73,7 +73,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessFormat {
|
||||
if format_args.format_string.parts == [kw::Empty];
|
||||
if arg.format.is_default();
|
||||
if match cx.typeck_results().expr_ty(value).peel_refs().kind() {
|
||||
ty::Adt(adt, _) => cx.tcx.is_diagnostic_item(sym::String, adt.did()),
|
||||
ty::Adt(adt, _) => Some(adt.did()) == cx.tcx.lang_items().string(),
|
||||
ty::Str => true,
|
||||
_ => false,
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::ty::is_type_lang_item;
|
||||
use clippy_utils::{match_def_path, paths, peel_hir_expr_refs};
|
||||
use rustc_hir::{BinOpKind, Expr, ExprKind};
|
||||
use rustc_hir::{BinOpKind, Expr, ExprKind, LangItem};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::sym;
|
||||
@ -41,7 +41,7 @@ declare_clippy_lint! {
|
||||
declare_lint_pass!(FormatPushString => [FORMAT_PUSH_STRING]);
|
||||
|
||||
fn is_string(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
|
||||
is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(e).peel_refs(), sym::String)
|
||||
is_type_lang_item(cx, cx.typeck_results().expr_ty(e).peel_refs(), LangItem::String)
|
||||
}
|
||||
fn is_format(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
|
||||
if let Some(macro_def_id) = e.span.ctxt().outer_expn_data().macro_def_id {
|
||||
|
@ -76,7 +76,7 @@ impl<'tcx> LateLintPass<'tcx> for FromOverInto {
|
||||
&& let Some(into_trait_seg) = hir_trait_ref.path.segments.last()
|
||||
// `impl Into<target_ty> for self_ty`
|
||||
&& let Some(GenericArgs { args: [GenericArg::Type(target_ty)], .. }) = into_trait_seg.args
|
||||
&& let Some(middle_trait_ref) = cx.tcx.impl_trait_ref(item.def_id)
|
||||
&& let Some(middle_trait_ref) = cx.tcx.impl_trait_ref(item.owner_id)
|
||||
&& cx.tcx.is_diagnostic_item(sym::Into, middle_trait_ref.def_id)
|
||||
{
|
||||
span_lint_and_then(
|
||||
|
@ -1,10 +1,10 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::is_integer_literal;
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{def, Expr, ExprKind, PrimTy, QPath, TyKind};
|
||||
use rustc_hir::{def, Expr, ExprKind, LangItem, PrimTy, QPath, TyKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
@ -98,5 +98,5 @@ impl<'tcx> LateLintPass<'tcx> for FromStrRadix10 {
|
||||
|
||||
/// Checks if a Ty is `String` or `&str`
|
||||
fn is_ty_stringish(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
|
||||
is_type_diagnostic_item(cx, ty, sym::String) || is_type_diagnostic_item(cx, ty, sym::str)
|
||||
is_type_lang_item(cx, ty, LangItem::String) || is_type_diagnostic_item(cx, ty, sym::str)
|
||||
}
|
||||
|
@ -22,9 +22,9 @@ use super::{DOUBLE_MUST_USE, MUST_USE_CANDIDATE, MUST_USE_UNIT};
|
||||
|
||||
pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
|
||||
let attrs = cx.tcx.hir().attrs(item.hir_id());
|
||||
let attr = cx.tcx.get_attr(item.def_id.to_def_id(), sym::must_use);
|
||||
let attr = cx.tcx.get_attr(item.owner_id.to_def_id(), sym::must_use);
|
||||
if let hir::ItemKind::Fn(ref sig, _generics, ref body_id) = item.kind {
|
||||
let is_public = cx.access_levels.is_exported(item.def_id.def_id);
|
||||
let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id);
|
||||
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
|
||||
if let Some(attr) = attr {
|
||||
check_needless_must_use(cx, sig.decl, item.hir_id(), item.span, fn_header_span, attr);
|
||||
@ -34,7 +34,7 @@ pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>
|
||||
sig.decl,
|
||||
cx.tcx.hir().body(*body_id),
|
||||
item.span,
|
||||
item.def_id.def_id,
|
||||
item.owner_id.def_id,
|
||||
item.span.with_hi(sig.decl.output.span().hi()),
|
||||
"this function could have a `#[must_use]` attribute",
|
||||
);
|
||||
@ -44,20 +44,22 @@ pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>
|
||||
|
||||
pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) {
|
||||
if let hir::ImplItemKind::Fn(ref sig, ref body_id) = item.kind {
|
||||
let is_public = cx.access_levels.is_exported(item.def_id.def_id);
|
||||
let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id);
|
||||
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
|
||||
let attrs = cx.tcx.hir().attrs(item.hir_id());
|
||||
let attr = cx.tcx.get_attr(item.def_id.to_def_id(), sym::must_use);
|
||||
let attr = cx.tcx.get_attr(item.owner_id.to_def_id(), sym::must_use);
|
||||
if let Some(attr) = attr {
|
||||
check_needless_must_use(cx, sig.decl, item.hir_id(), item.span, fn_header_span, attr);
|
||||
} else if is_public && !is_proc_macro(cx.sess(), attrs) && trait_ref_of_method(cx, item.def_id.def_id).is_none()
|
||||
} else if is_public
|
||||
&& !is_proc_macro(cx.sess(), attrs)
|
||||
&& trait_ref_of_method(cx, item.owner_id.def_id).is_none()
|
||||
{
|
||||
check_must_use_candidate(
|
||||
cx,
|
||||
sig.decl,
|
||||
cx.tcx.hir().body(*body_id),
|
||||
item.span,
|
||||
item.def_id.def_id,
|
||||
item.owner_id.def_id,
|
||||
item.span.with_hi(sig.decl.output.span().hi()),
|
||||
"this method could have a `#[must_use]` attribute",
|
||||
);
|
||||
@ -67,11 +69,11 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Imp
|
||||
|
||||
pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) {
|
||||
if let hir::TraitItemKind::Fn(ref sig, ref eid) = item.kind {
|
||||
let is_public = cx.access_levels.is_exported(item.def_id.def_id);
|
||||
let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id);
|
||||
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
|
||||
|
||||
let attrs = cx.tcx.hir().attrs(item.hir_id());
|
||||
let attr = cx.tcx.get_attr(item.def_id.to_def_id(), sym::must_use);
|
||||
let attr = cx.tcx.get_attr(item.owner_id.to_def_id(), sym::must_use);
|
||||
if let Some(attr) = attr {
|
||||
check_needless_must_use(cx, sig.decl, item.hir_id(), item.span, fn_header_span, attr);
|
||||
} else if let hir::TraitFn::Provided(eid) = *eid {
|
||||
@ -82,7 +84,7 @@ pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Tr
|
||||
sig.decl,
|
||||
body,
|
||||
item.span,
|
||||
item.def_id.def_id,
|
||||
item.owner_id.def_id,
|
||||
item.span.with_hi(sig.decl.output.span().hi()),
|
||||
"this method could have a `#[must_use]` attribute",
|
||||
);
|
||||
@ -137,7 +139,7 @@ fn check_must_use_candidate<'tcx>(
|
||||
|| mutates_static(cx, body)
|
||||
|| in_external_macro(cx.sess(), item_span)
|
||||
|| returns_unit(decl)
|
||||
|| !cx.access_levels.is_exported(item_id)
|
||||
|| !cx.effective_visibilities.is_exported(item_id)
|
||||
|| is_must_use_ty(cx, return_ty(cx, cx.tcx.hir().local_def_id_to_hir_id(item_id)))
|
||||
{
|
||||
return;
|
||||
@ -175,7 +177,7 @@ fn is_mutable_pat(cx: &LateContext<'_>, pat: &hir::Pat<'_>, tys: &mut DefIdSet)
|
||||
return false; // ignore `_` patterns
|
||||
}
|
||||
if cx.tcx.has_typeck_results(pat.hir_id.owner.to_def_id()) {
|
||||
is_mutable_ty(cx, cx.tcx.typeck(pat.hir_id.owner.def_id).pat_ty(pat), pat.span, tys)
|
||||
is_mutable_ty(cx, cx.tcx.typeck(pat.hir_id.owner.def_id).pat_ty(pat), tys)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
@ -183,21 +185,21 @@ fn is_mutable_pat(cx: &LateContext<'_>, pat: &hir::Pat<'_>, tys: &mut DefIdSet)
|
||||
|
||||
static KNOWN_WRAPPER_TYS: &[Symbol] = &[sym::Rc, sym::Arc];
|
||||
|
||||
fn is_mutable_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, span: Span, tys: &mut DefIdSet) -> bool {
|
||||
fn is_mutable_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, tys: &mut DefIdSet) -> bool {
|
||||
match *ty.kind() {
|
||||
// primitive types are never mutable
|
||||
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str => false,
|
||||
ty::Adt(adt, substs) => {
|
||||
tys.insert(adt.did()) && !ty.is_freeze(cx.tcx.at(span), cx.param_env)
|
||||
tys.insert(adt.did()) && !ty.is_freeze(cx.tcx, cx.param_env)
|
||||
|| KNOWN_WRAPPER_TYS
|
||||
.iter()
|
||||
.any(|&sym| cx.tcx.is_diagnostic_item(sym, adt.did()))
|
||||
&& substs.types().any(|ty| is_mutable_ty(cx, ty, span, tys))
|
||||
&& substs.types().any(|ty| is_mutable_ty(cx, ty, tys))
|
||||
},
|
||||
ty::Tuple(substs) => substs.iter().any(|ty| is_mutable_ty(cx, ty, span, tys)),
|
||||
ty::Array(ty, _) | ty::Slice(ty) => is_mutable_ty(cx, ty, span, tys),
|
||||
ty::Tuple(substs) => substs.iter().any(|ty| is_mutable_ty(cx, ty, tys)),
|
||||
ty::Array(ty, _) | ty::Slice(ty) => is_mutable_ty(cx, ty, tys),
|
||||
ty::RawPtr(ty::TypeAndMut { ty, mutbl }) | ty::Ref(_, ty, mutbl) => {
|
||||
mutbl == hir::Mutability::Mut || is_mutable_ty(cx, ty, span, tys)
|
||||
mutbl == hir::Mutability::Mut || is_mutable_ty(cx, ty, tys)
|
||||
},
|
||||
// calling something constitutes a side effect, so return true on all callables
|
||||
// also never calls need not be used, so return true for them, too
|
||||
@ -225,12 +227,7 @@ fn mutates_static<'tcx>(cx: &LateContext<'tcx>, body: &'tcx hir::Body<'_>) -> bo
|
||||
let mut tys = DefIdSet::default();
|
||||
for arg in args {
|
||||
if cx.tcx.has_typeck_results(arg.hir_id.owner.to_def_id())
|
||||
&& is_mutable_ty(
|
||||
cx,
|
||||
cx.tcx.typeck(arg.hir_id.owner.def_id).expr_ty(arg),
|
||||
arg.span,
|
||||
&mut tys,
|
||||
)
|
||||
&& is_mutable_ty(cx, cx.tcx.typeck(arg.hir_id.owner.def_id).expr_ty(arg), &mut tys)
|
||||
&& is_mutated_static(arg)
|
||||
{
|
||||
return ControlFlow::Break(());
|
||||
@ -243,12 +240,7 @@ fn mutates_static<'tcx>(cx: &LateContext<'tcx>, body: &'tcx hir::Body<'_>) -> bo
|
||||
let mut tys = DefIdSet::default();
|
||||
for arg in std::iter::once(receiver).chain(args.iter()) {
|
||||
if cx.tcx.has_typeck_results(arg.hir_id.owner.to_def_id())
|
||||
&& is_mutable_ty(
|
||||
cx,
|
||||
cx.tcx.typeck(arg.hir_id.owner.def_id).expr_ty(arg),
|
||||
arg.span,
|
||||
&mut tys,
|
||||
)
|
||||
&& is_mutable_ty(cx, cx.tcx.typeck(arg.hir_id.owner.def_id).expr_ty(arg), &mut tys)
|
||||
&& is_mutated_static(arg)
|
||||
{
|
||||
return ControlFlow::Break(());
|
||||
|
@ -31,7 +31,7 @@ pub(super) fn check_fn<'tcx>(
|
||||
pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) {
|
||||
if let hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(eid)) = item.kind {
|
||||
let body = cx.tcx.hir().body(eid);
|
||||
check_raw_ptr(cx, sig.header.unsafety, sig.decl, body, item.def_id.def_id);
|
||||
check_raw_ptr(cx, sig.header.unsafety, sig.decl, body, item.owner_id.def_id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ fn check_raw_ptr<'tcx>(
|
||||
body: &'tcx hir::Body<'tcx>,
|
||||
def_id: LocalDefId,
|
||||
) {
|
||||
if unsafety == hir::Unsafety::Normal && cx.access_levels.is_exported(def_id) {
|
||||
if unsafety == hir::Unsafety::Normal && 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>();
|
||||
|
@ -34,9 +34,9 @@ fn result_err_ty<'tcx>(
|
||||
|
||||
pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &hir::Item<'tcx>, large_err_threshold: u64) {
|
||||
if let hir::ItemKind::Fn(ref sig, _generics, _) = item.kind
|
||||
&& let Some((hir_ty, err_ty)) = result_err_ty(cx, sig.decl, item.def_id.def_id, item.span)
|
||||
&& let Some((hir_ty, err_ty)) = result_err_ty(cx, sig.decl, item.owner_id.def_id, item.span)
|
||||
{
|
||||
if cx.access_levels.is_exported(item.def_id.def_id) {
|
||||
if cx.effective_visibilities.is_exported(item.owner_id.def_id) {
|
||||
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
|
||||
check_result_unit_err(cx, err_ty, fn_header_span);
|
||||
}
|
||||
@ -47,10 +47,10 @@ pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &hir::Item<'tcx>, l
|
||||
pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &hir::ImplItem<'tcx>, large_err_threshold: u64) {
|
||||
// Don't lint if method is a trait's implementation, we can't do anything about those
|
||||
if let hir::ImplItemKind::Fn(ref sig, _) = item.kind
|
||||
&& let Some((hir_ty, err_ty)) = result_err_ty(cx, sig.decl, item.def_id.def_id, item.span)
|
||||
&& trait_ref_of_method(cx, item.def_id.def_id).is_none()
|
||||
&& let Some((hir_ty, err_ty)) = result_err_ty(cx, sig.decl, item.owner_id.def_id, item.span)
|
||||
&& trait_ref_of_method(cx, item.owner_id.def_id).is_none()
|
||||
{
|
||||
if cx.access_levels.is_exported(item.def_id.def_id) {
|
||||
if cx.effective_visibilities.is_exported(item.owner_id.def_id) {
|
||||
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
|
||||
check_result_unit_err(cx, err_ty, fn_header_span);
|
||||
}
|
||||
@ -61,8 +61,8 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &hir::ImplItem
|
||||
pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &hir::TraitItem<'tcx>, large_err_threshold: u64) {
|
||||
if let hir::TraitItemKind::Fn(ref sig, _) = item.kind {
|
||||
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
|
||||
if let Some((hir_ty, err_ty)) = result_err_ty(cx, sig.decl, item.def_id.def_id, item.span) {
|
||||
if cx.access_levels.is_exported(item.def_id.def_id) {
|
||||
if let Some((hir_ty, err_ty)) = result_err_ty(cx, sig.decl, item.owner_id.def_id, item.span) {
|
||||
if cx.effective_visibilities.is_exported(item.owner_id.def_id) {
|
||||
check_result_unit_err(cx, err_ty, fn_header_span);
|
||||
}
|
||||
check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold);
|
||||
|
@ -111,7 +111,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher {
|
||||
}
|
||||
}
|
||||
|
||||
if !cx.access_levels.is_exported(item.def_id.def_id) {
|
||||
if !cx.effective_visibilities.is_exported(item.owner_id.def_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
|
||||
use clippy_utils::ty::{implements_trait, is_type_lang_item};
|
||||
use clippy_utils::{return_ty, trait_ref_of_method};
|
||||
use if_chain::if_chain;
|
||||
use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind};
|
||||
use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind, LangItem};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::sym;
|
||||
@ -105,10 +105,10 @@ impl<'tcx> LateLintPass<'tcx> for InherentToString {
|
||||
if impl_item.generics.params.iter().all(|p| matches!(p.kind, GenericParamKind::Lifetime { .. }));
|
||||
|
||||
// Check if return type is String
|
||||
if is_type_diagnostic_item(cx, return_ty(cx, impl_item.hir_id()), sym::String);
|
||||
if is_type_lang_item(cx, return_ty(cx, impl_item.hir_id()), LangItem::String);
|
||||
|
||||
// Filters instances of to_string which are required by a trait
|
||||
if trait_ref_of_method(cx, impl_item.def_id.def_id).is_none();
|
||||
if trait_ref_of_method(cx, impl_item.owner_id.def_id).is_none();
|
||||
|
||||
then {
|
||||
show_lint(cx, impl_item);
|
||||
@ -124,7 +124,7 @@ fn show_lint(cx: &LateContext<'_>, item: &ImplItem<'_>) {
|
||||
.expect("Failed to get trait ID of `Display`!");
|
||||
|
||||
// Get the real type of 'self'
|
||||
let self_type = cx.tcx.fn_sig(item.def_id).input(0);
|
||||
let self_type = cx.tcx.fn_sig(item.owner_id).input(0);
|
||||
let self_type = self_type.skip_binder().peel_refs();
|
||||
|
||||
// Emit either a warning or an error
|
||||
|
@ -2,7 +2,8 @@
|
||||
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::source::snippet_opt;
|
||||
use rustc_ast::ast::{BinOpKind, Expr, ExprKind, Lit, LitKind};
|
||||
use rustc_ast::ast::{BinOpKind, Expr, ExprKind, LitKind};
|
||||
use rustc_ast::token;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
@ -52,8 +53,8 @@ enum Side {
|
||||
|
||||
impl IntPlusOne {
|
||||
#[expect(clippy::cast_sign_loss)]
|
||||
fn check_lit(lit: &Lit, target_value: i128) -> bool {
|
||||
if let LitKind::Int(value, ..) = lit.kind {
|
||||
fn check_lit(token_lit: token::Lit, target_value: i128) -> bool {
|
||||
if let Ok(LitKind::Int(value, ..)) = LitKind::from_token_lit(token_lit) {
|
||||
return value == (target_value as u128);
|
||||
}
|
||||
false
|
||||
@ -65,11 +66,11 @@ impl IntPlusOne {
|
||||
(BinOpKind::Ge, ExprKind::Binary(lhskind, lhslhs, lhsrhs), _) => {
|
||||
match (lhskind.node, &lhslhs.kind, &lhsrhs.kind) {
|
||||
// `-1 + x`
|
||||
(BinOpKind::Add, ExprKind::Lit(lit), _) if Self::check_lit(lit, -1) => {
|
||||
(BinOpKind::Add, ExprKind::Lit(lit), _) if Self::check_lit(*lit, -1) => {
|
||||
Self::generate_recommendation(cx, binop, lhsrhs, rhs, Side::Lhs)
|
||||
},
|
||||
// `x - 1`
|
||||
(BinOpKind::Sub, _, ExprKind::Lit(lit)) if Self::check_lit(lit, 1) => {
|
||||
(BinOpKind::Sub, _, ExprKind::Lit(lit)) if Self::check_lit(*lit, 1) => {
|
||||
Self::generate_recommendation(cx, binop, lhslhs, rhs, Side::Lhs)
|
||||
},
|
||||
_ => None,
|
||||
@ -79,10 +80,10 @@ impl IntPlusOne {
|
||||
(BinOpKind::Ge, _, ExprKind::Binary(rhskind, rhslhs, rhsrhs)) if rhskind.node == BinOpKind::Add => {
|
||||
match (&rhslhs.kind, &rhsrhs.kind) {
|
||||
// `y + 1` and `1 + y`
|
||||
(ExprKind::Lit(lit), _) if Self::check_lit(lit, 1) => {
|
||||
(ExprKind::Lit(lit), _) if Self::check_lit(*lit, 1) => {
|
||||
Self::generate_recommendation(cx, binop, rhsrhs, lhs, Side::Rhs)
|
||||
},
|
||||
(_, ExprKind::Lit(lit)) if Self::check_lit(lit, 1) => {
|
||||
(_, ExprKind::Lit(lit)) if Self::check_lit(*lit, 1) => {
|
||||
Self::generate_recommendation(cx, binop, rhslhs, lhs, Side::Rhs)
|
||||
},
|
||||
_ => None,
|
||||
@ -92,10 +93,10 @@ impl IntPlusOne {
|
||||
(BinOpKind::Le, ExprKind::Binary(lhskind, lhslhs, lhsrhs), _) if lhskind.node == BinOpKind::Add => {
|
||||
match (&lhslhs.kind, &lhsrhs.kind) {
|
||||
// `1 + x` and `x + 1`
|
||||
(ExprKind::Lit(lit), _) if Self::check_lit(lit, 1) => {
|
||||
(ExprKind::Lit(lit), _) if Self::check_lit(*lit, 1) => {
|
||||
Self::generate_recommendation(cx, binop, lhsrhs, rhs, Side::Lhs)
|
||||
},
|
||||
(_, ExprKind::Lit(lit)) if Self::check_lit(lit, 1) => {
|
||||
(_, ExprKind::Lit(lit)) if Self::check_lit(*lit, 1) => {
|
||||
Self::generate_recommendation(cx, binop, lhslhs, rhs, Side::Lhs)
|
||||
},
|
||||
_ => None,
|
||||
@ -105,11 +106,11 @@ impl IntPlusOne {
|
||||
(BinOpKind::Le, _, ExprKind::Binary(rhskind, rhslhs, rhsrhs)) => {
|
||||
match (rhskind.node, &rhslhs.kind, &rhsrhs.kind) {
|
||||
// `-1 + y`
|
||||
(BinOpKind::Add, ExprKind::Lit(lit), _) if Self::check_lit(lit, -1) => {
|
||||
(BinOpKind::Add, ExprKind::Lit(lit), _) if Self::check_lit(*lit, -1) => {
|
||||
Self::generate_recommendation(cx, binop, rhsrhs, lhs, Side::Rhs)
|
||||
},
|
||||
// `y - 1`
|
||||
(BinOpKind::Sub, _, ExprKind::Lit(lit)) if Self::check_lit(lit, 1) => {
|
||||
(BinOpKind::Sub, _, ExprKind::Lit(lit)) if Self::check_lit(*lit, 1) => {
|
||||
Self::generate_recommendation(cx, binop, rhslhs, lhs, Side::Rhs)
|
||||
},
|
||||
_ => None,
|
||||
|
@ -44,7 +44,7 @@ impl<'tcx> LateLintPass<'tcx> for IterNotReturningIterator {
|
||||
let name = item.ident.name.as_str();
|
||||
if matches!(name, "iter" | "iter_mut") {
|
||||
if let TraitItemKind::Fn(fn_sig, _) = &item.kind {
|
||||
check_sig(cx, name, fn_sig, item.def_id.def_id);
|
||||
check_sig(cx, name, fn_sig, item.owner_id.def_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -58,7 +58,7 @@ impl<'tcx> LateLintPass<'tcx> for IterNotReturningIterator {
|
||||
)
|
||||
{
|
||||
if let ImplItemKind::Fn(fn_sig, _) = &item.kind {
|
||||
check_sig(cx, name, fn_sig, item.def_id.def_id);
|
||||
check_sig(cx, name, fn_sig, item.owner_id.def_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
|
||||
return;
|
||||
}
|
||||
if let ItemKind::Enum(ref def, _) = item.kind {
|
||||
let ty = cx.tcx.type_of(item.def_id);
|
||||
let ty = cx.tcx.type_of(item.owner_id);
|
||||
let Adt(adt, subst) = ty.kind() else {
|
||||
panic!("already checked whether this is an enum")
|
||||
};
|
||||
|
@ -134,7 +134,7 @@ impl<'tcx> LateLintPass<'tcx> for LenZero {
|
||||
if item.ident.name == sym::len;
|
||||
if let ImplItemKind::Fn(sig, _) = &item.kind;
|
||||
if sig.decl.implicit_self.has_implicit_self();
|
||||
if cx.access_levels.is_exported(item.def_id.def_id);
|
||||
if cx.effective_visibilities.is_exported(item.owner_id.def_id);
|
||||
if matches!(sig.decl.output, FnRetTy::Return(_));
|
||||
if let Some(imp) = get_parent_as_impl(cx.tcx, item.hir_id());
|
||||
if imp.of_trait.is_none();
|
||||
@ -143,7 +143,7 @@ impl<'tcx> LateLintPass<'tcx> for LenZero {
|
||||
if let Some(local_id) = ty_id.as_local();
|
||||
let ty_hir_id = cx.tcx.hir().local_def_id_to_hir_id(local_id);
|
||||
if !is_lint_allowed(cx, LEN_WITHOUT_IS_EMPTY, ty_hir_id);
|
||||
if let Some(output) = parse_len_output(cx, cx.tcx.fn_sig(item.def_id).skip_binder());
|
||||
if let Some(output) = parse_len_output(cx, cx.tcx.fn_sig(item.owner_id).skip_binder());
|
||||
then {
|
||||
let (name, kind) = match cx.tcx.hir().find(ty_hir_id) {
|
||||
Some(Node::ForeignItem(x)) => (x.ident.name, "extern type"),
|
||||
@ -195,7 +195,7 @@ fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, trait_items
|
||||
fn is_named_self(cx: &LateContext<'_>, item: &TraitItemRef, name: Symbol) -> bool {
|
||||
item.ident.name == name
|
||||
&& if let AssocItemKind::Fn { has_self } = item.kind {
|
||||
has_self && { cx.tcx.fn_sig(item.id.def_id).inputs().skip_binder().len() == 1 }
|
||||
has_self && { cx.tcx.fn_sig(item.id.owner_id).inputs().skip_binder().len() == 1 }
|
||||
} else {
|
||||
false
|
||||
}
|
||||
@ -210,11 +210,11 @@ fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, trait_items
|
||||
}
|
||||
}
|
||||
|
||||
if cx.access_levels.is_exported(visited_trait.def_id.def_id)
|
||||
if cx.effective_visibilities.is_exported(visited_trait.owner_id.def_id)
|
||||
&& trait_items.iter().any(|i| is_named_self(cx, i, sym::len))
|
||||
{
|
||||
let mut current_and_super_traits = DefIdSet::default();
|
||||
fill_trait_set(visited_trait.def_id.to_def_id(), &mut current_and_super_traits, cx);
|
||||
fill_trait_set(visited_trait.owner_id.to_def_id(), &mut current_and_super_traits, cx);
|
||||
let is_empty = sym!(is_empty);
|
||||
|
||||
let is_empty_method_found = current_and_super_traits
|
||||
@ -331,7 +331,7 @@ fn check_for_is_empty<'tcx>(
|
||||
None,
|
||||
None,
|
||||
),
|
||||
Some(is_empty) if !cx.access_levels.is_exported(is_empty.def_id.expect_local()) => (
|
||||
Some(is_empty) if !cx.effective_visibilities.is_exported(is_empty.def_id.expect_local()) => (
|
||||
format!(
|
||||
"{item_kind} `{}` has a public `len` method, but a private `is_empty` method",
|
||||
item_name.as_str(),
|
||||
|
@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for LetIfSeq {
|
||||
let span = stmt.span.to(if_.span);
|
||||
|
||||
let has_interior_mutability = !cx.typeck_results().node_type(canonical_id).is_freeze(
|
||||
cx.tcx.at(span),
|
||||
cx.tcx,
|
||||
cx.param_env,
|
||||
);
|
||||
if has_interior_mutability { return; }
|
||||
|
@ -33,6 +33,7 @@ extern crate rustc_errors;
|
||||
extern crate rustc_hir;
|
||||
extern crate rustc_hir_analysis;
|
||||
extern crate rustc_hir_pretty;
|
||||
extern crate rustc_hir_typeck;
|
||||
extern crate rustc_index;
|
||||
extern crate rustc_infer;
|
||||
extern crate rustc_lexer;
|
||||
|
@ -6,11 +6,12 @@ use rustc_hir::intravisit::{
|
||||
walk_fn_decl, walk_generic_param, walk_generics, walk_impl_item_ref, walk_item, walk_param_bound,
|
||||
walk_poly_trait_ref, walk_trait_ref, walk_ty, Visitor,
|
||||
};
|
||||
use rustc_hir::lang_items;
|
||||
use rustc_hir::FnRetTy::Return;
|
||||
use rustc_hir::{
|
||||
BareFnTy, BodyId, FnDecl, GenericArg, GenericBound, GenericParam, GenericParamKind, Generics, Impl, ImplItem,
|
||||
ImplItemKind, Item, ItemKind, LangItem, Lifetime, LifetimeName, ParamName, PolyTraitRef, PredicateOrigin, TraitFn,
|
||||
TraitItem, TraitItemKind, Ty, TyKind, WherePredicate,
|
||||
ImplItemKind, Item, ItemKind, Lifetime, LifetimeName, ParamName, PolyTraitRef, PredicateOrigin, TraitFn, TraitItem,
|
||||
TraitItemKind, Ty, TyKind, WherePredicate,
|
||||
};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::hir::nested_filter as middle_nested_filter;
|
||||
@ -102,7 +103,7 @@ impl<'tcx> LateLintPass<'tcx> for Lifetimes {
|
||||
|
||||
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) {
|
||||
if let ImplItemKind::Fn(ref sig, id) = item.kind {
|
||||
let report_extra_lifetimes = trait_ref_of_method(cx, item.def_id.def_id).is_none();
|
||||
let report_extra_lifetimes = trait_ref_of_method(cx, item.owner_id.def_id).is_none();
|
||||
check_fn_inner(
|
||||
cx,
|
||||
sig.decl,
|
||||
@ -391,8 +392,6 @@ fn named_lifetime_occurrences(lts: &[RefLt]) -> Vec<(LocalDefId, usize)> {
|
||||
occurrences
|
||||
}
|
||||
|
||||
const CLOSURE_TRAIT_BOUNDS: [LangItem; 3] = [LangItem::Fn, LangItem::FnMut, LangItem::FnOnce];
|
||||
|
||||
/// A visitor usable for `rustc_front::visit::walk_ty()`.
|
||||
struct RefVisitor<'a, 'tcx> {
|
||||
cx: &'a LateContext<'tcx>,
|
||||
@ -453,12 +452,8 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
|
||||
|
||||
fn visit_poly_trait_ref(&mut self, poly_tref: &'tcx PolyTraitRef<'tcx>) {
|
||||
let trait_ref = &poly_tref.trait_ref;
|
||||
if CLOSURE_TRAIT_BOUNDS.iter().any(|&item| {
|
||||
self.cx
|
||||
.tcx
|
||||
.lang_items()
|
||||
.require(item)
|
||||
.map_or(false, |id| Some(id) == trait_ref.trait_def_id())
|
||||
if let Some(id) = trait_ref.trait_def_id() && lang_items::FN_TRAITS.iter().any(|&item| {
|
||||
self.cx.tcx.lang_items().get(item) == Some(id)
|
||||
}) {
|
||||
let mut sub_visitor = RefVisitor::new(self.cx);
|
||||
sub_visitor.visit_trait_ref(trait_ref);
|
||||
|
@ -5,11 +5,13 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::numeric_literal::{NumericLiteral, Radix};
|
||||
use clippy_utils::source::snippet_opt;
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast::{Expr, ExprKind, Lit, LitKind};
|
||||
use rustc_ast::ast::{Expr, ExprKind, LitKind};
|
||||
use rustc_ast::token;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::Span;
|
||||
use std::iter;
|
||||
|
||||
declare_clippy_lint! {
|
||||
@ -236,8 +238,8 @@ impl EarlyLintPass for LiteralDigitGrouping {
|
||||
return;
|
||||
}
|
||||
|
||||
if let ExprKind::Lit(ref lit) = expr.kind {
|
||||
self.check_lit(cx, lit);
|
||||
if let ExprKind::Lit(lit) = expr.kind {
|
||||
self.check_lit(cx, lit, expr.span);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -252,12 +254,13 @@ impl LiteralDigitGrouping {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_lit(self, cx: &EarlyContext<'_>, lit: &Lit) {
|
||||
fn check_lit(self, cx: &EarlyContext<'_>, lit: token::Lit, span: Span) {
|
||||
if_chain! {
|
||||
if let Some(src) = snippet_opt(cx, lit.span);
|
||||
if let Some(mut num_lit) = NumericLiteral::from_lit(&src, lit);
|
||||
if let Some(src) = snippet_opt(cx, span);
|
||||
if let Ok(lit_kind) = LitKind::from_token_lit(lit);
|
||||
if let Some(mut num_lit) = NumericLiteral::from_lit_kind(&src, &lit_kind);
|
||||
then {
|
||||
if !Self::check_for_mistyped_suffix(cx, lit.span, &mut num_lit) {
|
||||
if !Self::check_for_mistyped_suffix(cx, span, &mut num_lit) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -293,14 +296,14 @@ impl LiteralDigitGrouping {
|
||||
| WarningType::InconsistentDigitGrouping
|
||||
| WarningType::UnusualByteGroupings
|
||||
| WarningType::LargeDigitGroups => {
|
||||
!lit.span.from_expansion()
|
||||
!span.from_expansion()
|
||||
}
|
||||
WarningType::DecimalRepresentation | WarningType::MistypedLiteralSuffix => {
|
||||
true
|
||||
}
|
||||
};
|
||||
if should_warn {
|
||||
warning_type.display(num_lit.format(), cx, lit.span);
|
||||
warning_type.display(num_lit.format(), cx, span);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -458,8 +461,8 @@ impl EarlyLintPass for DecimalLiteralRepresentation {
|
||||
return;
|
||||
}
|
||||
|
||||
if let ExprKind::Lit(ref lit) = expr.kind {
|
||||
self.check_lit(cx, lit);
|
||||
if let ExprKind::Lit(lit) = expr.kind {
|
||||
self.check_lit(cx, lit, expr.span);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -469,19 +472,20 @@ impl DecimalLiteralRepresentation {
|
||||
pub fn new(threshold: u64) -> Self {
|
||||
Self { threshold }
|
||||
}
|
||||
fn check_lit(self, cx: &EarlyContext<'_>, lit: &Lit) {
|
||||
fn check_lit(self, cx: &EarlyContext<'_>, lit: token::Lit, span: Span) {
|
||||
// Lint integral literals.
|
||||
if_chain! {
|
||||
if let LitKind::Int(val, _) = lit.kind;
|
||||
if let Some(src) = snippet_opt(cx, lit.span);
|
||||
if let Some(num_lit) = NumericLiteral::from_lit(&src, lit);
|
||||
if let Ok(lit_kind) = LitKind::from_token_lit(lit);
|
||||
if let LitKind::Int(val, _) = lit_kind;
|
||||
if let Some(src) = snippet_opt(cx, span);
|
||||
if let Some(num_lit) = NumericLiteral::from_lit_kind(&src, &lit_kind);
|
||||
if num_lit.radix == Radix::Decimal;
|
||||
if val >= u128::from(self.threshold);
|
||||
then {
|
||||
let hex = format!("{val:#X}");
|
||||
let num_lit = NumericLiteral::new(&hex, num_lit.suffix, false);
|
||||
let _ = Self::do_lint(num_lit.integer).map_err(|warning_type| {
|
||||
warning_type.display(num_lit.format(), cx, lit.span);
|
||||
warning_type.display(num_lit.format(), cx, span);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ use clippy_utils::{get_enclosing_block, higher, path_to_local};
|
||||
use if_chain::if_chain;
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_hir::{BindingAnnotation, Expr, ExprKind, HirId, Node, PatKind};
|
||||
use rustc_hir_analysis::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
|
||||
use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::{mir::FakeReadCause, ty};
|
||||
@ -113,13 +113,7 @@ impl<'tcx> Delegate<'tcx> for MutatePairDelegate<'_, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn fake_read(
|
||||
&mut self,
|
||||
_: &rustc_hir_analysis::expr_use_visitor::PlaceWithHirId<'tcx>,
|
||||
_: FakeReadCause,
|
||||
_: HirId,
|
||||
) {
|
||||
}
|
||||
fn fake_read(&mut self, _: &rustc_hir_typeck::expr_use_visitor::PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
|
||||
}
|
||||
|
||||
impl MutatePairDelegate<'_, '_> {
|
||||
|
@ -69,11 +69,13 @@ impl<'tcx> LateLintPass<'tcx> for ManualAssert {
|
||||
"only a `panic!` in `if`-then statement",
|
||||
|diag| {
|
||||
// comments can be noisy, do not show them to the user
|
||||
diag.tool_only_span_suggestion(
|
||||
expr.span.shrink_to_lo(),
|
||||
"add comments back",
|
||||
comments,
|
||||
applicability);
|
||||
if !comments.is_empty() {
|
||||
diag.tool_only_span_suggestion(
|
||||
expr.span.shrink_to_lo(),
|
||||
"add comments back",
|
||||
comments,
|
||||
applicability);
|
||||
}
|
||||
diag.span_suggestion(
|
||||
expr.span,
|
||||
"try instead",
|
||||
|
@ -6,7 +6,7 @@ use rustc_errors::Applicability;
|
||||
use rustc_hir::intravisit::FnKind;
|
||||
use rustc_hir::{
|
||||
AsyncGeneratorKind, Block, Body, Closure, Expr, ExprKind, FnDecl, FnRetTy, GeneratorKind, GenericArg, GenericBound,
|
||||
HirId, IsAsync, ItemKind, LifetimeName, Term, TraitRef, Ty, TyKind, TypeBindingKind,
|
||||
HirId, ItemKind, LifetimeName, Term, TraitRef, Ty, TyKind, TypeBindingKind,
|
||||
};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
@ -49,7 +49,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn {
|
||||
) {
|
||||
if_chain! {
|
||||
if let Some(header) = kind.header();
|
||||
if header.asyncness == IsAsync::NotAsync;
|
||||
if !header.asyncness.is_async();
|
||||
// Check that this function returns `impl Future`
|
||||
if let FnRetTy::Return(ret_ty) = decl.output;
|
||||
if let Some((trait_ref, output_lifetimes)) = future_trait_ref(cx, ret_ty);
|
||||
|
@ -157,16 +157,16 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustiveEnum {
|
||||
&& def.variants.len() > 1
|
||||
{
|
||||
let mut iter = def.variants.iter().filter_map(|v| {
|
||||
let id = cx.tcx.hir().local_def_id(v.id);
|
||||
(matches!(v.data, hir::VariantData::Unit(_))
|
||||
let id = cx.tcx.hir().local_def_id(v.hir_id);
|
||||
(matches!(v.data, hir::VariantData::Unit(..))
|
||||
&& v.ident.as_str().starts_with('_')
|
||||
&& is_doc_hidden(cx.tcx.hir().attrs(v.id)))
|
||||
&& is_doc_hidden(cx.tcx.hir().attrs(v.hir_id)))
|
||||
.then_some((id, v.span))
|
||||
});
|
||||
if let Some((id, span)) = iter.next()
|
||||
&& iter.next().is_none()
|
||||
{
|
||||
self.potential_enums.push((item.def_id.def_id, id, item.span, span));
|
||||
self.potential_enums.push((item.owner_id.def_id, id, item.span, span));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::source::snippet;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
|
||||
use clippy_utils::{get_parent_expr, match_def_path, paths, SpanlessEq};
|
||||
use clippy_utils::{meets_msrv, msrvs};
|
||||
use rustc_errors::Applicability;
|
||||
@ -92,7 +92,7 @@ fn check_into_iter(
|
||||
&& match_def_path(cx, filter_def_id, &paths::CORE_ITER_FILTER)
|
||||
&& let hir::ExprKind::MethodCall(_, struct_expr, [], _) = &into_iter_expr.kind
|
||||
&& let Some(into_iter_def_id) = cx.typeck_results().type_dependent_def_id(into_iter_expr.hir_id)
|
||||
&& cx.tcx.lang_items().require(hir::LangItem::IntoIterIntoIter).ok() == Some(into_iter_def_id)
|
||||
&& Some(into_iter_def_id) == cx.tcx.lang_items().into_iter_fn()
|
||||
&& match_acceptable_type(cx, left_expr, msrv)
|
||||
&& SpanlessEq::new(cx).eq_expr(left_expr, struct_expr) {
|
||||
suggest(cx, parent_expr, left_expr, target_expr);
|
||||
@ -140,7 +140,7 @@ fn check_to_owned(
|
||||
&& let Some(chars_expr_def_id) = cx.typeck_results().type_dependent_def_id(chars_expr.hir_id)
|
||||
&& match_def_path(cx, chars_expr_def_id, &paths::STR_CHARS)
|
||||
&& let ty = cx.typeck_results().expr_ty(str_expr).peel_refs()
|
||||
&& is_type_diagnostic_item(cx, ty, sym::String)
|
||||
&& is_type_lang_item(cx, ty, hir::LangItem::String)
|
||||
&& SpanlessEq::new(cx).eq_expr(left_expr, str_expr) {
|
||||
suggest(cx, parent_expr, left_expr, filter_expr);
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ impl LateLintPass<'_> for ManualStringNew {
|
||||
let ty = cx.typeck_results().expr_ty(expr);
|
||||
match ty.kind() {
|
||||
ty::Adt(adt_def, _) if adt_def.is_struct() => {
|
||||
if !cx.tcx.is_diagnostic_item(sym::String, adt_def.did()) {
|
||||
if cx.tcx.lang_items().string() != Some(adt_def.did()) {
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
@ -1,13 +1,13 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::ty::is_type_lang_item;
|
||||
use rustc_ast::ast::LitKind;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::intravisit::{walk_expr, Visitor};
|
||||
use rustc_hir::{Arm, Expr, ExprKind, PatKind};
|
||||
use rustc_hir::{Arm, Expr, ExprKind, LangItem, PatKind};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty;
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_span::{sym, Span};
|
||||
use rustc_span::Span;
|
||||
|
||||
use super::MATCH_STR_CASE_MISMATCH;
|
||||
|
||||
@ -59,7 +59,7 @@ impl<'a, 'tcx> MatchExprVisitor<'a, 'tcx> {
|
||||
if let Some(case_method) = get_case_method(segment_ident) {
|
||||
let ty = self.cx.typeck_results().expr_ty(receiver).peel_refs();
|
||||
|
||||
if is_type_diagnostic_item(self.cx, ty, sym::String) || ty.kind() == &ty::Str {
|
||||
if is_type_lang_item(self.cx, ty, LangItem::String) || ty.kind() == &ty::Str {
|
||||
self.case_method = Some(case_method);
|
||||
return true;
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ pub(crate) trait BindInsteadOfMap {
|
||||
const GOOD_METHOD_NAME: &'static str;
|
||||
|
||||
fn no_op_msg(cx: &LateContext<'_>) -> Option<String> {
|
||||
let variant_id = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM).ok()?;
|
||||
let variant_id = cx.tcx.lang_items().get(Self::VARIANT_LANG_ITEM)?;
|
||||
let item_id = cx.tcx.parent(variant_id);
|
||||
Some(format!(
|
||||
"using `{}.{}({})`, which is a no-op",
|
||||
@ -52,7 +52,7 @@ pub(crate) trait BindInsteadOfMap {
|
||||
}
|
||||
|
||||
fn lint_msg(cx: &LateContext<'_>) -> Option<String> {
|
||||
let variant_id = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM).ok()?;
|
||||
let variant_id = cx.tcx.lang_items().get(Self::VARIANT_LANG_ITEM)?;
|
||||
let item_id = cx.tcx.parent(variant_id);
|
||||
Some(format!(
|
||||
"using `{}.{}(|x| {}(y))`, which is more succinctly expressed as `{}(|x| y)`",
|
||||
@ -144,7 +144,7 @@ pub(crate) trait BindInsteadOfMap {
|
||||
fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>) -> bool {
|
||||
if_chain! {
|
||||
if let Some(adt) = cx.typeck_results().expr_ty(recv).ty_adt_def();
|
||||
if let Ok(vid) = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM);
|
||||
if let Some(vid) = cx.tcx.lang_items().get(Self::VARIANT_LANG_ITEM);
|
||||
if adt.did() == cx.tcx.parent(vid);
|
||||
then {} else { return false; }
|
||||
}
|
||||
@ -181,7 +181,7 @@ pub(crate) trait BindInsteadOfMap {
|
||||
|
||||
fn is_variant(cx: &LateContext<'_>, res: Res) -> bool {
|
||||
if let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fn), id) = res {
|
||||
if let Ok(variant_id) = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM) {
|
||||
if let Some(variant_id) = cx.tcx.lang_items().get(Self::VARIANT_LANG_ITEM) {
|
||||
return cx.tcx.parent(id) == variant_id;
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,10 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::ty::is_type_lang_item;
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::sym;
|
||||
|
||||
use super::BYTES_COUNT_TO_LEN;
|
||||
|
||||
@ -20,7 +19,7 @@ pub(super) fn check<'tcx>(
|
||||
if let Some(impl_id) = cx.tcx.impl_of_method(bytes_id);
|
||||
if cx.tcx.type_of(impl_id).is_str();
|
||||
let ty = cx.typeck_results().expr_ty(bytes_recv).peel_refs();
|
||||
if ty.is_str() || is_type_diagnostic_item(cx, ty, sym::String);
|
||||
if ty.is_str() || is_type_lang_item(cx, ty, hir::LangItem::String);
|
||||
then {
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
span_lint_and_sugg(
|
||||
|
@ -1,10 +1,9 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::ty::is_type_lang_item;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::Expr;
|
||||
use rustc_hir::{Expr, LangItem};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::sym;
|
||||
|
||||
use super::BYTES_NTH;
|
||||
|
||||
@ -12,7 +11,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, recv: &'tcx E
|
||||
let ty = cx.typeck_results().expr_ty(recv).peel_refs();
|
||||
let caller_type = if ty.is_str() {
|
||||
"str"
|
||||
} else if is_type_diagnostic_item(cx, ty, sym::String) {
|
||||
} else if is_type_lang_item(cx, ty, LangItem::String) {
|
||||
"String"
|
||||
} else {
|
||||
return;
|
||||
|
@ -1,10 +1,10 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::ty::is_type_lang_item;
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast::LitKind;
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_hir::{Expr, ExprKind, LangItem};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::{source_map::Spanned, symbol::sym, Span};
|
||||
use rustc_span::{source_map::Spanned, Span};
|
||||
|
||||
use super::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS;
|
||||
|
||||
@ -26,7 +26,7 @@ pub(super) fn check<'tcx>(
|
||||
if ext_str.chars().skip(1).all(|c| c.is_uppercase() || c.is_ascii_digit())
|
||||
|| ext_str.chars().skip(1).all(|c| c.is_lowercase() || c.is_ascii_digit());
|
||||
let recv_ty = cx.typeck_results().expr_ty(recv).peel_refs();
|
||||
if recv_ty.is_str() || is_type_diagnostic_item(cx, recv_ty, sym::String);
|
||||
if recv_ty.is_str() || is_type_lang_item(cx, recv_ty, LangItem::String);
|
||||
then {
|
||||
span_lint_and_help(
|
||||
cx,
|
||||
|
@ -1,7 +1,7 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::macros::{root_macro_call_first_node, FormatArgsExpn};
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::LateContext;
|
||||
@ -33,7 +33,7 @@ pub(super) fn check<'tcx>(
|
||||
if (method_name.ident.name == sym::as_str || method_name.ident.name == sym::as_ref) && {
|
||||
let arg_type = cx.typeck_results().expr_ty(receiver);
|
||||
let base_type = arg_type.peel_refs();
|
||||
*base_type.kind() == ty::Str || is_type_diagnostic_item(cx, base_type, sym::String)
|
||||
*base_type.kind() == ty::Str || is_type_lang_item(cx, base_type, hir::LangItem::String)
|
||||
} {
|
||||
receiver
|
||||
} else {
|
||||
@ -50,7 +50,7 @@ pub(super) fn check<'tcx>(
|
||||
// converted to string.
|
||||
fn requires_to_string(cx: &LateContext<'_>, arg: &hir::Expr<'_>) -> bool {
|
||||
let arg_ty = cx.typeck_results().expr_ty(arg);
|
||||
if is_type_diagnostic_item(cx, arg_ty, sym::String) {
|
||||
if is_type_lang_item(cx, arg_ty, hir::LangItem::String) {
|
||||
return false;
|
||||
}
|
||||
if let ty::Ref(_, ty, ..) = arg_ty.kind() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::ty::{is_type_diagnostic_item, walk_ptrs_ty_depth};
|
||||
use clippy_utils::ty::{is_type_lang_item, walk_ptrs_ty_depth};
|
||||
use clippy_utils::{match_def_path, paths};
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
@ -60,7 +60,7 @@ fn specializes_tostring(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
if is_type_diagnostic_item(cx, ty, sym::String) {
|
||||
if is_type_lang_item(cx, ty, hir::LangItem::String) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -36,14 +36,14 @@ fn parse_repeat_arg(cx: &LateContext<'_>, e: &Expr<'_>) -> Option<RepeatKind> {
|
||||
}
|
||||
} else {
|
||||
let ty = cx.typeck_results().expr_ty(e);
|
||||
if is_type_diagnostic_item(cx, ty, sym::String)
|
||||
if is_type_lang_item(cx, ty, LangItem::String)
|
||||
|| (is_type_lang_item(cx, ty, LangItem::OwnedBox) && get_ty_param(ty).map_or(false, Ty::is_str))
|
||||
|| (is_type_diagnostic_item(cx, ty, sym::Cow) && get_ty_param(ty).map_or(false, Ty::is_str))
|
||||
{
|
||||
Some(RepeatKind::String)
|
||||
} else {
|
||||
let ty = ty.peel_refs();
|
||||
(ty.is_str() || is_type_diagnostic_item(cx, ty, sym::String)).then_some(RepeatKind::String)
|
||||
(ty.is_str() || is_type_lang_item(cx, ty, LangItem::String)).then_some(RepeatKind::String)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -58,7 +58,7 @@ pub(super) fn check(
|
||||
if_chain! {
|
||||
if let ExprKind::Call(repeat_fn, [repeat_arg]) = take_self_arg.kind;
|
||||
if is_path_diagnostic_item(cx, repeat_fn, sym::iter_repeat);
|
||||
if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(collect_expr), sym::String);
|
||||
if is_type_lang_item(cx, cx.typeck_results().expr_ty(collect_expr), LangItem::String);
|
||||
if let Some(take_id) = cx.typeck_results().type_dependent_def_id(take_expr.hir_id);
|
||||
if let Some(iter_trait_id) = cx.tcx.get_diagnostic_item(sym::Iterator);
|
||||
if cx.tcx.trait_of_item(take_id) == Some(iter_trait_id);
|
||||
|
@ -3348,15 +3348,15 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
|
||||
let name = impl_item.ident.name.as_str();
|
||||
let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id()).def_id;
|
||||
let item = cx.tcx.hir().expect_item(parent);
|
||||
let self_ty = cx.tcx.type_of(item.def_id);
|
||||
let self_ty = cx.tcx.type_of(item.owner_id);
|
||||
|
||||
let implements_trait = matches!(item.kind, hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }));
|
||||
if let hir::ImplItemKind::Fn(ref sig, id) = impl_item.kind {
|
||||
let method_sig = cx.tcx.fn_sig(impl_item.def_id);
|
||||
let method_sig = cx.tcx.fn_sig(impl_item.owner_id);
|
||||
let method_sig = cx.tcx.erase_late_bound_regions(method_sig);
|
||||
let first_arg_ty_opt = method_sig.inputs().iter().next().copied();
|
||||
// if this impl block implements a trait, lint in trait definition instead
|
||||
if !implements_trait && cx.access_levels.is_exported(impl_item.def_id.def_id) {
|
||||
if !implements_trait && cx.effective_visibilities.is_exported(impl_item.owner_id.def_id) {
|
||||
// check missing trait implementations
|
||||
for method_config in &TRAIT_METHODS {
|
||||
if name == method_config.method_name
|
||||
@ -3390,7 +3390,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
|
||||
|
||||
if sig.decl.implicit_self.has_implicit_self()
|
||||
&& !(self.avoid_breaking_exported_api
|
||||
&& cx.access_levels.is_exported(impl_item.def_id.def_id))
|
||||
&& cx.effective_visibilities.is_exported(impl_item.owner_id.def_id))
|
||||
&& let Some(first_arg) = iter_input_pats(sig.decl, cx.tcx.hir().body(id)).next()
|
||||
&& let Some(first_arg_ty) = first_arg_ty_opt
|
||||
{
|
||||
@ -3442,7 +3442,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
|
||||
then {
|
||||
let first_arg_span = first_arg_ty.span;
|
||||
let first_arg_ty = hir_ty_to_ty(cx.tcx, first_arg_ty);
|
||||
let self_ty = TraitRef::identity(cx.tcx, item.def_id.to_def_id())
|
||||
let self_ty = TraitRef::identity(cx.tcx, item.owner_id.to_def_id())
|
||||
.self_ty()
|
||||
.skip_binder();
|
||||
wrong_self_convention::check(
|
||||
@ -3461,7 +3461,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
|
||||
if item.ident.name == sym::new;
|
||||
if let TraitItemKind::Fn(_, _) = item.kind;
|
||||
let ret_ty = return_ty(cx, item.hir_id());
|
||||
let self_ty = TraitRef::identity(cx.tcx, item.def_id.to_def_id())
|
||||
let self_ty = TraitRef::identity(cx.tcx, item.owner_id.to_def_id())
|
||||
.self_ty()
|
||||
.skip_binder();
|
||||
if !ret_ty.contains(self_ty);
|
||||
|
@ -1,11 +1,10 @@
|
||||
use clippy_utils::diagnostics::span_lint;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::ty::is_type_lang_item;
|
||||
use clippy_utils::SpanlessEq;
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::LitKind;
|
||||
use rustc_hir::ExprKind;
|
||||
use rustc_hir::{ExprKind, LangItem};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::sym;
|
||||
|
||||
use super::NO_EFFECT_REPLACE;
|
||||
|
||||
@ -16,7 +15,7 @@ pub(super) fn check<'tcx>(
|
||||
arg2: &'tcx rustc_hir::Expr<'_>,
|
||||
) {
|
||||
let ty = cx.typeck_results().expr_ty(expr).peel_refs();
|
||||
if !(ty.is_str() || is_type_diagnostic_item(cx, ty, sym::String)) {
|
||||
if !(ty.is_str() || is_type_lang_item(cx, ty, LangItem::String)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,10 @@
|
||||
use clippy_utils::consts::{constant_context, Constant};
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::source::snippet;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::ty::is_type_lang_item;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::Expr;
|
||||
use rustc_hir::{Expr, LangItem};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::sym;
|
||||
|
||||
use super::REPEAT_ONCE;
|
||||
|
||||
@ -37,7 +36,7 @@ pub(super) fn check<'tcx>(
|
||||
format!("{}.to_vec()", snippet(cx, recv.span, r#""...""#)),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else if is_type_diagnostic_item(cx, ty, sym::String) {
|
||||
} else if is_type_lang_item(cx, ty, LangItem::String) {
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
REPEAT_ONCE,
|
||||
|
@ -1,7 +1,7 @@
|
||||
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
|
||||
use clippy_utils::source::{snippet, snippet_with_applicability};
|
||||
use clippy_utils::sugg::deref_closure_args;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::ty::is_type_lang_item;
|
||||
use clippy_utils::{is_trait_method, strip_pat_refs};
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
@ -105,7 +105,7 @@ pub(super) fn check<'tcx>(
|
||||
else if search_method == "find" {
|
||||
let is_string_or_str_slice = |e| {
|
||||
let self_ty = cx.typeck_results().expr_ty(e).peel_refs();
|
||||
if is_type_diagnostic_item(cx, self_ty, sym::String) {
|
||||
if is_type_lang_item(cx, self_ty, hir::LangItem::String) {
|
||||
true
|
||||
} else {
|
||||
*self_ty.kind() == ty::Str
|
||||
|
@ -1,18 +1,17 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::method_chain_args;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::ty::is_type_lang_item;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty;
|
||||
use rustc_span::symbol::sym;
|
||||
|
||||
use super::STRING_EXTEND_CHARS;
|
||||
|
||||
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>) {
|
||||
let obj_ty = cx.typeck_results().expr_ty(recv).peel_refs();
|
||||
if !is_type_diagnostic_item(cx, obj_ty, sym::String) {
|
||||
if !is_type_lang_item(cx, obj_ty, hir::LangItem::String) {
|
||||
return;
|
||||
}
|
||||
if let Some(arglists) = method_chain_args(arg, &["chars"]) {
|
||||
@ -24,7 +23,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr
|
||||
} else {
|
||||
""
|
||||
}
|
||||
} else if is_type_diagnostic_item(cx, self_ty, sym::String) {
|
||||
} else if is_type_lang_item(cx, self_ty, hir::LangItem::String) {
|
||||
"&"
|
||||
} else {
|
||||
return;
|
||||
|
@ -5,7 +5,7 @@ use clippy_utils::source::snippet_opt;
|
||||
use clippy_utils::ty::{get_associated_type, get_iterator_item_ty, implements_trait};
|
||||
use clippy_utils::{fn_def_id, get_parent_expr};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{def_id::DefId, Expr, ExprKind, LangItem};
|
||||
use rustc_hir::{def_id::DefId, Expr, ExprKind};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::{sym, Symbol};
|
||||
|
||||
@ -100,5 +100,5 @@ pub fn check_for_loop_iter(
|
||||
|
||||
/// Returns true if the named method is `IntoIterator::into_iter`.
|
||||
pub fn is_into_iter(cx: &LateContext<'_>, callee_def_id: DefId) -> bool {
|
||||
cx.tcx.lang_items().require(LangItem::IntoIterIntoIter) == Ok(callee_def_id)
|
||||
Some(callee_def_id) == cx.tcx.lang_items().into_iter_fn()
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
use clippy_utils::{diagnostics::span_lint_and_sugg, ty::is_type_diagnostic_item};
|
||||
use clippy_utils::{diagnostics::span_lint_and_sugg, ty::is_type_lang_item};
|
||||
use rustc_ast::ast::LitKind;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_hir::{Expr, ExprKind, LangItem};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty::{Ref, Slice};
|
||||
use rustc_span::{sym, Span};
|
||||
use rustc_span::Span;
|
||||
|
||||
use super::UNNECESSARY_JOIN;
|
||||
|
||||
@ -21,7 +21,7 @@ pub(super) fn check<'tcx>(
|
||||
// the turbofish for collect is ::<Vec<String>>
|
||||
if let Ref(_, ref_type, _) = collect_output_adjusted_type.kind();
|
||||
if let Slice(slice) = ref_type.kind();
|
||||
if is_type_diagnostic_item(cx, *slice, sym::String);
|
||||
if is_type_lang_item(cx, *slice, LangItem::String);
|
||||
// the argument for join is ""
|
||||
if let ExprKind::Lit(spanned) = &join_arg.kind;
|
||||
if let LitKind::Str(symbol, _) = spanned.node;
|
||||
|
@ -7,8 +7,8 @@ use clippy_utils::visitors::find_all_ret_expressions;
|
||||
use clippy_utils::{fn_def_id, get_parent_expr, is_diag_item_method, is_diag_trait_item, return_ty};
|
||||
use clippy_utils::{meets_msrv, msrvs};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{def_id::DefId, BorrowKind, Expr, ExprKind, ItemKind, LangItem, Node};
|
||||
use rustc_hir_analysis::check::{FnCtxt, Inherited};
|
||||
use rustc_hir::{def_id::DefId, BorrowKind, Expr, ExprKind, ItemKind, Node};
|
||||
use rustc_hir_typeck::{FnCtxt, Inherited};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::mir::Mutability;
|
||||
@ -378,7 +378,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
|
||||
Node::Expr(parent_expr) => {
|
||||
if let Some((callee_def_id, call_substs, recv, call_args)) = get_callee_substs_and_args(cx, parent_expr)
|
||||
{
|
||||
if cx.tcx.lang_items().require(LangItem::IntoFutureIntoFuture) == Ok(callee_def_id) {
|
||||
if Some(callee_def_id) == cx.tcx.lang_items().into_future_fn() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -419,7 +419,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
|
||||
|
||||
if trait_predicates.any(|predicate| {
|
||||
let predicate = EarlyBinder(predicate).subst(cx.tcx, new_subst);
|
||||
let obligation = Obligation::new(ObligationCause::dummy(), cx.param_env, predicate);
|
||||
let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);
|
||||
!cx.tcx.infer_ctxt().build().predicate_must_hold_modulo_regions(&obligation)
|
||||
}) {
|
||||
return false;
|
||||
|
@ -1,11 +1,11 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use rustc_ast::ast::Lit;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_lint::EarlyContext;
|
||||
use rustc_span::Span;
|
||||
|
||||
use super::{SEPARATED_LITERAL_SUFFIX, UNSEPARATED_LITERAL_SUFFIX};
|
||||
|
||||
pub(super) fn check(cx: &EarlyContext<'_>, lit: &Lit, lit_snip: &str, suffix: &str, sugg_type: &str) {
|
||||
pub(super) fn check(cx: &EarlyContext<'_>, lit_span: Span, lit_snip: &str, suffix: &str, sugg_type: &str) {
|
||||
let Some(maybe_last_sep_idx) = lit_snip.len().checked_sub(suffix.len() + 1) else {
|
||||
return; // It's useless so shouldn't lint.
|
||||
};
|
||||
@ -15,7 +15,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, lit: &Lit, lit_snip: &str, suffix: &s
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
SEPARATED_LITERAL_SUFFIX,
|
||||
lit.span,
|
||||
lit_span,
|
||||
&format!("{sugg_type} type suffix should not be separated by an underscore"),
|
||||
"remove the underscore",
|
||||
format!("{}{suffix}", &lit_snip[..maybe_last_sep_idx]),
|
||||
@ -25,7 +25,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, lit: &Lit, lit_snip: &str, suffix: &s
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
UNSEPARATED_LITERAL_SUFFIX,
|
||||
lit.span,
|
||||
lit_span,
|
||||
&format!("{sugg_type} type suffix should be separated by an underscore"),
|
||||
"add an underscore",
|
||||
format!("{}_{suffix}", &lit_snip[..=maybe_last_sep_idx]),
|
||||
|
@ -1,10 +1,10 @@
|
||||
use clippy_utils::diagnostics::span_lint;
|
||||
use rustc_ast::ast::Lit;
|
||||
use rustc_lint::EarlyContext;
|
||||
use rustc_span::Span;
|
||||
|
||||
use super::MIXED_CASE_HEX_LITERALS;
|
||||
|
||||
pub(super) fn check(cx: &EarlyContext<'_>, lit: &Lit, suffix: &str, lit_snip: &str) {
|
||||
pub(super) fn check(cx: &EarlyContext<'_>, lit_span: Span, suffix: &str, lit_snip: &str) {
|
||||
let Some(maybe_last_sep_idx) = lit_snip.len().checked_sub(suffix.len() + 1) else {
|
||||
return; // It's useless so shouldn't lint.
|
||||
};
|
||||
@ -23,7 +23,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, lit: &Lit, suffix: &str, lit_snip: &s
|
||||
span_lint(
|
||||
cx,
|
||||
MIXED_CASE_HEX_LITERALS,
|
||||
lit.span,
|
||||
lit_span,
|
||||
"inconsistent casing in hexadecimal literal",
|
||||
);
|
||||
break;
|
||||
|
@ -9,7 +9,8 @@ mod zero_prefixed_literal;
|
||||
|
||||
use clippy_utils::diagnostics::span_lint;
|
||||
use clippy_utils::source::snippet_opt;
|
||||
use rustc_ast::ast::{Expr, ExprKind, Generics, Lit, LitFloatType, LitIntType, LitKind, NodeId, Pat, PatKind};
|
||||
use rustc_ast::ast::{Expr, ExprKind, Generics, LitFloatType, LitIntType, LitKind, NodeId, Pat, PatKind};
|
||||
use rustc_ast::token;
|
||||
use rustc_ast::visit::FnKind;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||
@ -374,42 +375,43 @@ impl EarlyLintPass for MiscEarlyLints {
|
||||
return;
|
||||
}
|
||||
|
||||
if let ExprKind::Lit(ref lit) = expr.kind {
|
||||
MiscEarlyLints::check_lit(cx, lit);
|
||||
if let ExprKind::Lit(lit) = expr.kind {
|
||||
MiscEarlyLints::check_lit(cx, lit, expr.span);
|
||||
}
|
||||
double_neg::check(cx, expr);
|
||||
}
|
||||
}
|
||||
|
||||
impl MiscEarlyLints {
|
||||
fn check_lit(cx: &EarlyContext<'_>, lit: &Lit) {
|
||||
fn check_lit(cx: &EarlyContext<'_>, lit: token::Lit, span: Span) {
|
||||
// We test if first character in snippet is a number, because the snippet could be an expansion
|
||||
// from a built-in macro like `line!()` or a proc-macro like `#[wasm_bindgen]`.
|
||||
// Note that this check also covers special case that `line!()` is eagerly expanded by compiler.
|
||||
// See <https://github.com/rust-lang/rust-clippy/issues/4507> for a regression.
|
||||
// FIXME: Find a better way to detect those cases.
|
||||
let lit_snip = match snippet_opt(cx, lit.span) {
|
||||
let lit_snip = match snippet_opt(cx, span) {
|
||||
Some(snip) if snip.chars().next().map_or(false, |c| c.is_ascii_digit()) => snip,
|
||||
_ => return,
|
||||
};
|
||||
|
||||
if let LitKind::Int(value, lit_int_type) = lit.kind {
|
||||
let lit_kind = LitKind::from_token_lit(lit);
|
||||
if let Ok(LitKind::Int(value, lit_int_type)) = lit_kind {
|
||||
let suffix = match lit_int_type {
|
||||
LitIntType::Signed(ty) => ty.name_str(),
|
||||
LitIntType::Unsigned(ty) => ty.name_str(),
|
||||
LitIntType::Unsuffixed => "",
|
||||
};
|
||||
literal_suffix::check(cx, lit, &lit_snip, suffix, "integer");
|
||||
literal_suffix::check(cx, span, &lit_snip, suffix, "integer");
|
||||
if lit_snip.starts_with("0x") {
|
||||
mixed_case_hex_literals::check(cx, lit, suffix, &lit_snip);
|
||||
mixed_case_hex_literals::check(cx, span, suffix, &lit_snip);
|
||||
} else if lit_snip.starts_with("0b") || lit_snip.starts_with("0o") {
|
||||
// nothing to do
|
||||
} else if value != 0 && lit_snip.starts_with('0') {
|
||||
zero_prefixed_literal::check(cx, lit, &lit_snip);
|
||||
zero_prefixed_literal::check(cx, span, &lit_snip);
|
||||
}
|
||||
} else if let LitKind::Float(_, LitFloatType::Suffixed(float_ty)) = lit.kind {
|
||||
} else if let Ok(LitKind::Float(_, LitFloatType::Suffixed(float_ty))) = lit_kind {
|
||||
let suffix = float_ty.name_str();
|
||||
literal_suffix::check(cx, lit, &lit_snip, suffix, "float");
|
||||
literal_suffix::check(cx, span, &lit_snip, suffix, "float");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,20 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use rustc_ast::ast::Lit;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_lint::EarlyContext;
|
||||
use rustc_span::Span;
|
||||
|
||||
use super::ZERO_PREFIXED_LITERAL;
|
||||
|
||||
pub(super) fn check(cx: &EarlyContext<'_>, lit: &Lit, lit_snip: &str) {
|
||||
pub(super) fn check(cx: &EarlyContext<'_>, lit_span: Span, lit_snip: &str) {
|
||||
let trimmed_lit_snip = lit_snip.trim_start_matches(|c| c == '_' || c == '0');
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
ZERO_PREFIXED_LITERAL,
|
||||
lit.span,
|
||||
lit_span,
|
||||
"this is a decimal constant",
|
||||
|diag| {
|
||||
diag.span_suggestion(
|
||||
lit.span,
|
||||
lit_span,
|
||||
"if you mean to use a decimal constant, remove the `0` to avoid confusion",
|
||||
trimmed_lit_snip.to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
@ -22,7 +22,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, lit: &Lit, lit_snip: &str) {
|
||||
// do not advise to use octal form if the literal cannot be expressed in base 8.
|
||||
if !lit_snip.contains(|c| c == '8' || c == '9') {
|
||||
diag.span_suggestion(
|
||||
lit.span,
|
||||
lit_span,
|
||||
"if you mean to use an octal constant, use `0o`",
|
||||
format!("0o{trimmed_lit_snip}"),
|
||||
Applicability::MaybeIncorrect,
|
||||
|
@ -132,7 +132,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
|
||||
hir::ItemKind::Fn(..) => {
|
||||
// ignore main()
|
||||
if it.ident.name == sym::main {
|
||||
let at_root = cx.tcx.local_parent(it.def_id.def_id) == CRATE_DEF_ID;
|
||||
let at_root = cx.tcx.local_parent(it.owner_id.def_id) == CRATE_DEF_ID;
|
||||
if at_root {
|
||||
return;
|
||||
}
|
||||
@ -156,7 +156,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
|
||||
| hir::ItemKind::Use(..) => return,
|
||||
};
|
||||
|
||||
let (article, desc) = cx.tcx.article_and_description(it.def_id.to_def_id());
|
||||
let (article, desc) = cx.tcx.article_and_description(it.owner_id.to_def_id());
|
||||
|
||||
let attrs = cx.tcx.hir().attrs(it.hir_id());
|
||||
if !is_from_proc_macro(cx, it) {
|
||||
@ -165,7 +165,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
|
||||
}
|
||||
|
||||
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx hir::TraitItem<'_>) {
|
||||
let (article, desc) = cx.tcx.article_and_description(trait_item.def_id.to_def_id());
|
||||
let (article, desc) = cx.tcx.article_and_description(trait_item.owner_id.to_def_id());
|
||||
|
||||
let attrs = cx.tcx.hir().attrs(trait_item.hir_id());
|
||||
if !is_from_proc_macro(cx, trait_item) {
|
||||
@ -175,7 +175,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
|
||||
|
||||
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) {
|
||||
// If the method is an impl for a trait, don't doc.
|
||||
if let Some(cid) = cx.tcx.associated_item(impl_item.def_id).impl_container(cx.tcx) {
|
||||
if let Some(cid) = cx.tcx.associated_item(impl_item.owner_id).impl_container(cx.tcx) {
|
||||
if cx.tcx.impl_trait_ref(cid).is_some() {
|
||||
return;
|
||||
}
|
||||
@ -183,7 +183,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
|
||||
return;
|
||||
}
|
||||
|
||||
let (article, desc) = cx.tcx.article_and_description(impl_item.def_id.to_def_id());
|
||||
let (article, desc) = cx.tcx.article_and_description(impl_item.owner_id.to_def_id());
|
||||
let attrs = cx.tcx.hir().attrs(impl_item.hir_id());
|
||||
if !is_from_proc_macro(cx, impl_item) {
|
||||
self.check_missing_docs_attrs(cx, attrs, impl_item.span, article, desc);
|
||||
@ -200,7 +200,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
|
||||
}
|
||||
|
||||
fn check_variant(&mut self, cx: &LateContext<'tcx>, v: &'tcx hir::Variant<'_>) {
|
||||
let attrs = cx.tcx.hir().attrs(v.id);
|
||||
let attrs = cx.tcx.hir().attrs(v.hir_id);
|
||||
if !is_from_proc_macro(cx, v) {
|
||||
self.check_missing_docs_attrs(cx, attrs, v.span, "a", "variant");
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
|
||||
return;
|
||||
}
|
||||
|
||||
if !cx.access_levels.is_exported(it.def_id.def_id) {
|
||||
if !cx.effective_visibilities.is_exported(it.owner_id.def_id) {
|
||||
return;
|
||||
}
|
||||
match it.kind {
|
||||
@ -105,7 +105,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
|
||||
match tit_.kind {
|
||||
hir::TraitItemKind::Const(..) | hir::TraitItemKind::Type(..) => {},
|
||||
hir::TraitItemKind::Fn(..) => {
|
||||
if cx.tcx.impl_defaultness(tit.id.def_id).has_value() {
|
||||
if cx.tcx.impl_defaultness(tit.id.owner_id).has_value() {
|
||||
// trait method with default body needs inline in case
|
||||
// an impl is not provided
|
||||
let desc = "a default trait method";
|
||||
@ -142,7 +142,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
|
||||
}
|
||||
|
||||
// If the item being implemented is not exported, then we don't need #[inline]
|
||||
if !cx.access_levels.is_exported(impl_item.def_id.def_id) {
|
||||
if !cx.effective_visibilities.is_exported(impl_item.owner_id.def_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -151,7 +151,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
|
||||
hir::ImplItemKind::Const(..) | hir::ImplItemKind::Type(_) => return,
|
||||
};
|
||||
|
||||
let assoc_item = cx.tcx.associated_item(impl_item.def_id);
|
||||
let assoc_item = cx.tcx.associated_item(impl_item.owner_id);
|
||||
let container_id = assoc_item.container_id(cx.tcx);
|
||||
let trait_def_id = match assoc_item.container {
|
||||
TraitContainer => Some(container_id),
|
||||
@ -159,7 +159,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
|
||||
};
|
||||
|
||||
if let Some(trait_def_id) = trait_def_id {
|
||||
if trait_def_id.is_local() && !cx.access_levels.is_exported(impl_item.def_id.def_id) {
|
||||
if trait_def_id.is_local() && !cx.effective_visibilities.is_exported(impl_item.owner_id.def_id) {
|
||||
// If a trait is being implemented for an item, and the
|
||||
// trait is not exported, we don't need #[inline]
|
||||
return;
|
||||
|
@ -108,7 +108,7 @@ impl<'tcx> LateLintPass<'tcx> for MutableKeyType {
|
||||
|
||||
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'tcx>) {
|
||||
if let hir::ImplItemKind::Fn(ref sig, ..) = item.kind {
|
||||
if trait_ref_of_method(cx, item.def_id.def_id).is_none() {
|
||||
if trait_ref_of_method(cx, item.owner_id.def_id).is_none() {
|
||||
self.check_sig(cx, item.hir_id(), sig.decl);
|
||||
}
|
||||
}
|
||||
@ -153,7 +153,7 @@ impl MutableKeyType {
|
||||
let is_keyed_type = [sym::HashMap, sym::BTreeMap, sym::HashSet, sym::BTreeSet]
|
||||
.iter()
|
||||
.any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def.did()));
|
||||
if is_keyed_type && self.is_interior_mutable_type(cx, substs.type_at(0), span) {
|
||||
if is_keyed_type && self.is_interior_mutable_type(cx, substs.type_at(0)) {
|
||||
span_lint(cx, MUTABLE_KEY_TYPE, span, "mutable key type");
|
||||
}
|
||||
}
|
||||
@ -161,17 +161,15 @@ impl MutableKeyType {
|
||||
|
||||
/// Determines if a type contains interior mutability which would affect its implementation of
|
||||
/// [`Hash`] or [`Ord`].
|
||||
fn is_interior_mutable_type<'tcx>(&self, cx: &LateContext<'tcx>, ty: Ty<'tcx>, span: Span) -> bool {
|
||||
fn is_interior_mutable_type<'tcx>(&self, cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
match *ty.kind() {
|
||||
Ref(_, inner_ty, mutbl) => {
|
||||
mutbl == hir::Mutability::Mut || self.is_interior_mutable_type(cx, inner_ty, span)
|
||||
},
|
||||
Slice(inner_ty) => self.is_interior_mutable_type(cx, inner_ty, span),
|
||||
Ref(_, inner_ty, mutbl) => mutbl == hir::Mutability::Mut || self.is_interior_mutable_type(cx, inner_ty),
|
||||
Slice(inner_ty) => self.is_interior_mutable_type(cx, inner_ty),
|
||||
Array(inner_ty, size) => {
|
||||
size.try_eval_usize(cx.tcx, cx.param_env).map_or(true, |u| u != 0)
|
||||
&& self.is_interior_mutable_type(cx, inner_ty, span)
|
||||
&& self.is_interior_mutable_type(cx, inner_ty)
|
||||
},
|
||||
Tuple(fields) => fields.iter().any(|ty| self.is_interior_mutable_type(cx, ty, span)),
|
||||
Tuple(fields) => fields.iter().any(|ty| self.is_interior_mutable_type(cx, ty)),
|
||||
Adt(def, substs) => {
|
||||
// Special case for collections in `std` who's impl of `Hash` or `Ord` delegates to
|
||||
// that of their type parameters. Note: we don't include `HashSet` and `HashMap`
|
||||
@ -193,11 +191,11 @@ impl MutableKeyType {
|
||||
let is_box = Some(def_id) == cx.tcx.lang_items().owned_box();
|
||||
if is_std_collection || is_box || self.ignore_mut_def_ids.contains(&def_id) {
|
||||
// The type is mutable if any of its type parameters are
|
||||
substs.types().any(|ty| self.is_interior_mutable_type(cx, ty, span))
|
||||
substs.types().any(|ty| self.is_interior_mutable_type(cx, ty))
|
||||
} else {
|
||||
!ty.has_escaping_bound_vars()
|
||||
&& cx.tcx.layout_of(cx.param_env.and(ty)).is_ok()
|
||||
&& !ty.is_freeze(cx.tcx.at(span), cx.param_env)
|
||||
&& !ty.is_freeze(cx.tcx, cx.param_env)
|
||||
}
|
||||
},
|
||||
_ => false,
|
||||
|
@ -69,7 +69,7 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for MutVisitor<'a, 'tcx> {
|
||||
"generally you want to avoid `&mut &mut _` if possible",
|
||||
);
|
||||
} else if let ty::Ref(_, ty, hir::Mutability::Mut) = self.cx.typeck_results().expr_ty(e).kind() {
|
||||
if ty.peel_refs().is_sized(self.cx.tcx.at(expr.span), self.cx.param_env) {
|
||||
if ty.peel_refs().is_sized(self.cx.tcx, self.cx.param_env) {
|
||||
span_lint(
|
||||
self.cx,
|
||||
MUT_MUT,
|
||||
|
@ -180,10 +180,13 @@ fn assignment_suggestions<'tcx>(
|
||||
let suggestions = assignments
|
||||
.iter()
|
||||
.flat_map(|assignment| {
|
||||
[
|
||||
assignment.span.until(assignment.rhs_span),
|
||||
assignment.rhs_span.shrink_to_hi().with_hi(assignment.span.hi()),
|
||||
]
|
||||
let mut spans = vec![assignment.span.until(assignment.rhs_span)];
|
||||
|
||||
if assignment.rhs_span.hi() != assignment.span.hi() {
|
||||
spans.push(assignment.rhs_span.shrink_to_hi().with_hi(assignment.span.hi()));
|
||||
}
|
||||
|
||||
spans
|
||||
})
|
||||
.map(|span| (span, String::new()))
|
||||
.collect::<Vec<(Span, String)>>();
|
||||
|
@ -1,7 +1,7 @@
|
||||
use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then};
|
||||
use clippy_utils::ptr::get_spans;
|
||||
use clippy_utils::source::{snippet, snippet_opt};
|
||||
use clippy_utils::ty::{implements_trait, is_copy, is_type_diagnostic_item};
|
||||
use clippy_utils::ty::{implements_trait, is_copy, is_type_diagnostic_item, is_type_lang_item};
|
||||
use clippy_utils::{get_trait_def_id, is_self, paths};
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast::Attribute;
|
||||
@ -11,15 +11,15 @@ use rustc_hir::intravisit::FnKind;
|
||||
use rustc_hir::{
|
||||
BindingAnnotation, Body, FnDecl, GenericArg, HirId, Impl, ItemKind, Mutability, Node, PatKind, QPath, TyKind,
|
||||
};
|
||||
use rustc_hir::{HirIdMap, HirIdSet};
|
||||
use rustc_hir_analysis::expr_use_visitor as euv;
|
||||
use rustc_hir::{HirIdMap, HirIdSet, LangItem};
|
||||
use rustc_hir_typeck::expr_use_visitor as euv;
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::mir::FakeReadCause;
|
||||
use rustc_middle::ty::{self, TypeVisitable};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::symbol::kw;
|
||||
use rustc_span::{sym, Span, DUMMY_SP};
|
||||
use rustc_span::{sym, Span};
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use rustc_trait_selection::traits;
|
||||
use rustc_trait_selection::traits::misc::can_type_implement_copy;
|
||||
@ -184,7 +184,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
|
||||
if !is_self(arg);
|
||||
if !ty.is_mutable_ptr();
|
||||
if !is_copy(cx, ty);
|
||||
if ty.is_sized(cx.tcx.at(DUMMY_SP), cx.param_env);
|
||||
if ty.is_sized(cx.tcx, cx.param_env);
|
||||
if !allowed_traits.iter().any(|&t| implements_trait(cx, ty, t, &[]));
|
||||
if !implements_borrow_trait;
|
||||
if !all_borrowable_trait;
|
||||
@ -249,7 +249,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
|
||||
}
|
||||
}
|
||||
|
||||
if is_type_diagnostic_item(cx, ty, sym::String) {
|
||||
if is_type_lang_item(cx, ty, LangItem::String) {
|
||||
if let Some(clone_spans) =
|
||||
get_spans(cx, Some(body.id()), idx, &[("clone", ".to_string()"), ("as_str", "")]) {
|
||||
diag.span_suggestion(
|
||||
@ -340,11 +340,5 @@ impl<'tcx> euv::Delegate<'tcx> for MovedVariablesCtxt {
|
||||
|
||||
fn mutate(&mut self, _: &euv::PlaceWithHirId<'tcx>, _: HirId) {}
|
||||
|
||||
fn fake_read(
|
||||
&mut self,
|
||||
_: &rustc_hir_analysis::expr_use_visitor::PlaceWithHirId<'tcx>,
|
||||
_: FakeReadCause,
|
||||
_: HirId,
|
||||
) {
|
||||
}
|
||||
fn fake_read(&mut self, _: &rustc_hir_typeck::expr_use_visitor::PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
|
||||
// can't be implemented for unsafe new
|
||||
return;
|
||||
}
|
||||
if cx.tcx.is_doc_hidden(impl_item.def_id.def_id) {
|
||||
if cx.tcx.is_doc_hidden(impl_item.owner_id.def_id) {
|
||||
// shouldn't be implemented when it is hidden in docs
|
||||
return;
|
||||
}
|
||||
@ -96,7 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
|
||||
if_chain! {
|
||||
if sig.decl.inputs.is_empty();
|
||||
if name == sym::new;
|
||||
if cx.access_levels.is_reachable(impl_item.def_id.def_id);
|
||||
if cx.effective_visibilities.is_reachable(impl_item.owner_id.def_id);
|
||||
let self_def_id = cx.tcx.hir().get_parent_item(id);
|
||||
let self_ty = cx.tcx.type_of(self_def_id);
|
||||
if self_ty == return_ty(cx, id);
|
||||
|
@ -20,7 +20,7 @@ use rustc_middle::mir::interpret::{ConstValue, ErrorHandled};
|
||||
use rustc_middle::ty::adjustment::Adjust;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::{sym, InnerSpan, Span, DUMMY_SP};
|
||||
use rustc_span::{sym, InnerSpan, Span};
|
||||
|
||||
// FIXME: this is a correctness problem but there's no suitable
|
||||
// warn-by-default category.
|
||||
@ -136,7 +136,7 @@ fn is_unfrozen<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
// since it works when a pointer indirection involves (`Cell<*const T>`).
|
||||
// Making up a `ParamEnv` where every generic params and assoc types are `Freeze`is another option;
|
||||
// but I'm not sure whether it's a decent way, if possible.
|
||||
cx.tcx.layout_of(cx.param_env.and(ty)).is_ok() && !ty.is_freeze(cx.tcx.at(DUMMY_SP), cx.param_env)
|
||||
cx.tcx.layout_of(cx.param_env.and(ty)).is_ok() && !ty.is_freeze(cx.tcx, cx.param_env)
|
||||
}
|
||||
|
||||
fn is_value_unfrozen_raw<'tcx>(
|
||||
@ -303,7 +303,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
|
||||
if let Some(of_trait_def_id) = of_trait_ref.trait_def_id();
|
||||
if let Some(of_assoc_item) = cx
|
||||
.tcx
|
||||
.associated_item(impl_item.def_id)
|
||||
.associated_item(impl_item.owner_id)
|
||||
.trait_item_def_id;
|
||||
if cx
|
||||
.tcx
|
||||
|
@ -89,7 +89,7 @@ impl<'tcx> LateLintPass<'tcx> for NonSendFieldInSendTy {
|
||||
if let Some(trait_id) = trait_ref.trait_def_id();
|
||||
if send_trait == trait_id;
|
||||
if hir_impl.polarity == ImplPolarity::Positive;
|
||||
if let Some(ty_trait_ref) = cx.tcx.impl_trait_ref(item.def_id);
|
||||
if let Some(ty_trait_ref) = cx.tcx.impl_trait_ref(item.owner_id);
|
||||
if let self_ty = ty_trait_ref.self_ty();
|
||||
if let ty::Adt(adt_def, impl_trait_substs) = self_ty.kind();
|
||||
then {
|
||||
|
@ -56,11 +56,11 @@ impl EarlyLintPass for OctalEscapes {
|
||||
return;
|
||||
}
|
||||
|
||||
if let ExprKind::Lit(lit) = &expr.kind {
|
||||
if matches!(lit.token_lit.kind, LitKind::Str) {
|
||||
check_lit(cx, &lit.token_lit, lit.span, true);
|
||||
} else if matches!(lit.token_lit.kind, LitKind::ByteStr) {
|
||||
check_lit(cx, &lit.token_lit, lit.span, false);
|
||||
if let ExprKind::Lit(token_lit) = &expr.kind {
|
||||
if matches!(token_lit.kind, LitKind::Str) {
|
||||
check_lit(cx, token_lit, expr.span, true);
|
||||
} else if matches!(token_lit.kind, LitKind::ByteStr) {
|
||||
check_lit(cx, token_lit, expr.span, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -227,25 +227,25 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion {
|
||||
// `skip_params` is either `0` or `1` to skip the `self` parameter in trait functions.
|
||||
// It can't be renamed, and it can't be removed without removing it from multiple functions.
|
||||
let (fn_id, fn_kind, skip_params) = match get_parent_node(cx.tcx, body.value.hir_id) {
|
||||
Some(Node::Item(i)) => (i.def_id.to_def_id(), FnKind::Fn, 0),
|
||||
Some(Node::Item(i)) => (i.owner_id.to_def_id(), FnKind::Fn, 0),
|
||||
Some(Node::TraitItem(&TraitItem {
|
||||
kind: TraitItemKind::Fn(ref sig, _),
|
||||
def_id,
|
||||
owner_id,
|
||||
..
|
||||
})) => (
|
||||
def_id.to_def_id(),
|
||||
owner_id.to_def_id(),
|
||||
FnKind::TraitFn,
|
||||
usize::from(sig.decl.implicit_self.has_implicit_self()),
|
||||
),
|
||||
Some(Node::ImplItem(&ImplItem {
|
||||
kind: ImplItemKind::Fn(ref sig, _),
|
||||
def_id,
|
||||
owner_id,
|
||||
..
|
||||
})) => {
|
||||
#[allow(trivial_casts)]
|
||||
if let Some(Node::Item(item)) = get_parent_node(cx.tcx, def_id.into())
|
||||
&& let Some(trait_ref) = cx.tcx.impl_trait_ref(item.def_id)
|
||||
&& let Some(trait_item_id) = cx.tcx.associated_item(def_id).trait_item_def_id
|
||||
if let Some(Node::Item(item)) = get_parent_node(cx.tcx, owner_id.into())
|
||||
&& let Some(trait_ref) = cx.tcx.impl_trait_ref(item.owner_id)
|
||||
&& let Some(trait_item_id) = cx.tcx.associated_item(owner_id).trait_item_def_id
|
||||
{
|
||||
(
|
||||
trait_item_id,
|
||||
@ -253,7 +253,7 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion {
|
||||
usize::from(sig.decl.implicit_self.has_implicit_self()),
|
||||
)
|
||||
} else {
|
||||
(def_id.to_def_id(), FnKind::Fn, 0)
|
||||
(owner_id.to_def_id(), FnKind::Fn, 0)
|
||||
}
|
||||
},
|
||||
_ => return,
|
||||
|
@ -8,7 +8,7 @@ use core::ops::ControlFlow;
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir_analysis::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
|
||||
use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::mir::FakeReadCause;
|
||||
use rustc_middle::ty::BorrowKind;
|
||||
@ -28,7 +28,7 @@ pub(super) fn check<'tcx>(
|
||||
let rty = cx.typeck_results().expr_ty(rhs);
|
||||
if_chain! {
|
||||
if let Some((_, lang_item)) = binop_traits(op.node);
|
||||
if let Ok(trait_id) = cx.tcx.lang_items().require(lang_item);
|
||||
if let Some(trait_id) = cx.tcx.lang_items().get(lang_item);
|
||||
let parent_fn = cx.tcx.hir().get_parent_item(e.hir_id).def_id;
|
||||
if trait_ref_of_method(cx, parent_fn)
|
||||
.map_or(true, |t| t.path.res.def_id() != trait_id);
|
||||
|
@ -204,7 +204,7 @@ fn are_equal(cx: &LateContext<'_>, middle_ty: Ty<'_>, hir_ty: &rustc_hir::Ty<'_>
|
||||
if let ty::Adt(adt_def, _) = middle_ty.kind();
|
||||
if let Some(local_did) = adt_def.did().as_local();
|
||||
let item = cx.tcx.hir().expect_item(local_did);
|
||||
let middle_ty_id = item.def_id.to_def_id();
|
||||
let middle_ty_id = item.owner_id.to_def_id();
|
||||
if let TyKind::Path(QPath::Resolved(_, path)) = hir_ty.kind;
|
||||
if let Res::Def(_, hir_ty_id) = path.res;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use clippy_utils::is_direct_expn_of;
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast::{Expr, ExprKind};
|
||||
use rustc_ast::ast::{Expr, ExprKind, MethodCall};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::sym;
|
||||
@ -37,8 +37,8 @@ declare_lint_pass!(OptionEnvUnwrap => [OPTION_ENV_UNWRAP]);
|
||||
impl EarlyLintPass for OptionEnvUnwrap {
|
||||
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
|
||||
if_chain! {
|
||||
if let ExprKind::MethodCall(path_segment, receiver, _, _) = &expr.kind;
|
||||
if matches!(path_segment.ident.name, sym::expect | sym::unwrap);
|
||||
if let ExprKind::MethodCall(box MethodCall { seg, receiver, .. }) = &expr.kind;
|
||||
if matches!(seg.ident.name, sym::expect | sym::unwrap);
|
||||
if let ExprKind::Call(caller, _) = &receiver.kind;
|
||||
if is_direct_expn_of(caller.span, "option_env").is_some();
|
||||
then {
|
||||
|
@ -36,7 +36,7 @@ impl<'tcx> LateLintPass<'tcx> for PartialEqNeImpl {
|
||||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
|
||||
if_chain! {
|
||||
if let ItemKind::Impl(Impl { of_trait: Some(ref trait_ref), items: impl_items, .. }) = item.kind;
|
||||
if !cx.tcx.has_attr(item.def_id.to_def_id(), sym::automatically_derived);
|
||||
if !cx.tcx.has_attr(item.owner_id.to_def_id(), sym::automatically_derived);
|
||||
if let Some(eq_trait) = cx.tcx.lang_items().eq_trait();
|
||||
if trait_ref.path.res.def_id() == eq_trait;
|
||||
then {
|
||||
|
@ -139,7 +139,7 @@ impl<'tcx> PassByRefOrValue {
|
||||
}
|
||||
|
||||
fn check_poly_fn(&mut self, cx: &LateContext<'tcx>, def_id: LocalDefId, decl: &FnDecl<'_>, span: Option<Span>) {
|
||||
if self.avoid_breaking_exported_api && cx.access_levels.is_exported(def_id) {
|
||||
if self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(def_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -261,7 +261,7 @@ impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue {
|
||||
}
|
||||
|
||||
if let hir::TraitItemKind::Fn(method_sig, _) = &item.kind {
|
||||
self.check_poly_fn(cx, item.def_id.def_id, method_sig.decl, None);
|
||||
self.check_poly_fn(cx, item.owner_id.def_id, method_sig.decl, None);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast::{BinOpKind, Expr, ExprKind, LitKind, UnOp};
|
||||
use rustc_ast::ast::{BinOpKind, Expr, ExprKind, MethodCall, UnOp};
|
||||
use rustc_ast::token;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
@ -109,18 +110,18 @@ impl EarlyLintPass for Precedence {
|
||||
let mut arg = operand;
|
||||
|
||||
let mut all_odd = true;
|
||||
while let ExprKind::MethodCall(path_segment, receiver, _, _) = &arg.kind {
|
||||
let path_segment_str = path_segment.ident.name.as_str();
|
||||
while let ExprKind::MethodCall(box MethodCall { seg, receiver, .. }) = &arg.kind {
|
||||
let seg_str = seg.ident.name.as_str();
|
||||
all_odd &= ALLOWED_ODD_FUNCTIONS
|
||||
.iter()
|
||||
.any(|odd_function| **odd_function == *path_segment_str);
|
||||
.any(|odd_function| **odd_function == *seg_str);
|
||||
arg = receiver;
|
||||
}
|
||||
|
||||
if_chain! {
|
||||
if !all_odd;
|
||||
if let ExprKind::Lit(lit) = &arg.kind;
|
||||
if let LitKind::Int(..) | LitKind::Float(..) = &lit.kind;
|
||||
if let token::LitKind::Integer | token::LitKind::Float = &lit.kind;
|
||||
then {
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
span_lint_and_sugg(
|
||||
|
@ -164,7 +164,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
|
||||
check_mut_from_ref(cx, sig, None);
|
||||
for arg in check_fn_args(
|
||||
cx,
|
||||
cx.tcx.fn_sig(item.def_id).skip_binder().inputs(),
|
||||
cx.tcx.fn_sig(item.owner_id).skip_binder().inputs(),
|
||||
sig.decl.inputs,
|
||||
&[],
|
||||
)
|
||||
@ -188,7 +188,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
|
||||
let (item_id, sig, is_trait_item) = match parents.next() {
|
||||
Some((_, Node::Item(i))) => {
|
||||
if let ItemKind::Fn(sig, ..) = &i.kind {
|
||||
(i.def_id, sig, false)
|
||||
(i.owner_id, sig, false)
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
@ -200,14 +200,14 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
|
||||
return;
|
||||
}
|
||||
if let ImplItemKind::Fn(sig, _) = &i.kind {
|
||||
(i.def_id, sig, false)
|
||||
(i.owner_id, sig, false)
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
},
|
||||
Some((_, Node::TraitItem(i))) => {
|
||||
if let TraitItemKind::Fn(sig, _) = &i.kind {
|
||||
(i.def_id, sig, true)
|
||||
(i.owner_id, sig, true)
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
@ -450,7 +450,7 @@ fn check_fn_args<'cx, 'tcx: 'cx>(
|
||||
substs.type_at(0),
|
||||
),
|
||||
),
|
||||
Some(sym::String) => (
|
||||
_ if Some(adt.did()) == cx.tcx.lang_items().string() => (
|
||||
[("clone", ".to_owned()"), ("as_str", "")].as_slice(),
|
||||
DerefTy::Str,
|
||||
),
|
||||
@ -695,6 +695,7 @@ fn matches_preds<'tcx>(
|
||||
.type_implements_trait(p.def_id, ty, p.substs, cx.param_env)
|
||||
.must_apply_modulo_regions(),
|
||||
ExistentialPredicate::Projection(p) => infcx.predicate_must_hold_modulo_regions(&Obligation::new(
|
||||
cx.tcx,
|
||||
ObligationCause::dummy(),
|
||||
cx.param_env,
|
||||
cx.tcx.mk_predicate(Binder::bind_with_vars(
|
||||
|
@ -94,7 +94,7 @@ fn check_is_none_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr: &Ex
|
||||
then {
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
let receiver_str = snippet_with_applicability(cx, caller.span, "..", &mut applicability);
|
||||
let by_ref = !caller_ty.is_copy_modulo_regions(cx.tcx.at(caller.span), cx.param_env) &&
|
||||
let by_ref = !caller_ty.is_copy_modulo_regions(cx.tcx, cx.param_env) &&
|
||||
!matches!(caller.kind, ExprKind::Call(..) | ExprKind::MethodCall(..));
|
||||
let sugg = if let Some(else_inner) = r#else {
|
||||
if eq_expr_value(cx, caller, peel_blocks(else_inner)) {
|
||||
|
@ -1,12 +1,12 @@
|
||||
use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then};
|
||||
use clippy_utils::mir::{visit_local_usage, LocalUsage, PossibleBorrowerMap};
|
||||
use clippy_utils::source::snippet_opt;
|
||||
use clippy_utils::ty::{has_drop, is_copy, is_type_diagnostic_item, walk_ptrs_ty_depth};
|
||||
use clippy_utils::ty::{has_drop, is_copy, is_type_diagnostic_item, is_type_lang_item, walk_ptrs_ty_depth};
|
||||
use clippy_utils::{fn_has_unsatisfiable_preds, match_def_path, paths};
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::intravisit::FnKind;
|
||||
use rustc_hir::{def_id, Body, FnDecl, HirId};
|
||||
use rustc_hir::{def_id, Body, FnDecl, HirId, LangItem};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
@ -102,7 +102,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone {
|
||||
let from_borrow = match_def_path(cx, fn_def_id, &paths::CLONE_TRAIT_METHOD)
|
||||
|| match_def_path(cx, fn_def_id, &paths::TO_OWNED_METHOD)
|
||||
|| (match_def_path(cx, fn_def_id, &paths::TO_STRING_METHOD)
|
||||
&& is_type_diagnostic_item(cx, arg_ty, sym::String));
|
||||
&& is_type_lang_item(cx, arg_ty, LangItem::String));
|
||||
|
||||
let from_deref = !from_borrow
|
||||
&& (match_def_path(cx, fn_def_id, &paths::PATH_TO_PATH_BUF)
|
||||
|
@ -69,10 +69,10 @@ impl EarlyLintPass for RedundantClosureCall {
|
||||
if_chain! {
|
||||
if let ast::ExprKind::Call(ref paren, _) = expr.kind;
|
||||
if let ast::ExprKind::Paren(ref closure) = paren.kind;
|
||||
if let ast::ExprKind::Closure(_, _, ref r#async, _, ref decl, ref block, _) = closure.kind;
|
||||
if let ast::ExprKind::Closure(box ast::Closure { ref asyncness, ref fn_decl, ref body, .. }) = closure.kind;
|
||||
then {
|
||||
let mut visitor = ReturnVisitor::new();
|
||||
visitor.visit_expr(block);
|
||||
visitor.visit_expr(body);
|
||||
if !visitor.found_return {
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
@ -80,13 +80,13 @@ impl EarlyLintPass for RedundantClosureCall {
|
||||
expr.span,
|
||||
"try not to call a closure in the expression where it is declared",
|
||||
|diag| {
|
||||
if decl.inputs.is_empty() {
|
||||
if fn_decl.inputs.is_empty() {
|
||||
let app = Applicability::MachineApplicable;
|
||||
let mut hint = Sugg::ast(cx, block, "..");
|
||||
let mut hint = Sugg::ast(cx, body, "..");
|
||||
|
||||
if r#async.is_async() {
|
||||
if asyncness.is_async() {
|
||||
// `async x` is a syntax error, so it becomes `async { x }`
|
||||
if !matches!(block.kind, ast::ExprKind::Block(_, _)) {
|
||||
if !matches!(body.kind, ast::ExprKind::Block(_, _)) {
|
||||
hint = hint.blockify();
|
||||
}
|
||||
|
||||
|
@ -46,12 +46,12 @@ impl_lint_pass!(RedundantPubCrate => [REDUNDANT_PUB_CRATE]);
|
||||
impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate {
|
||||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
|
||||
if_chain! {
|
||||
if cx.tcx.visibility(item.def_id.def_id) == ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id());
|
||||
if !cx.access_levels.is_exported(item.def_id.def_id) && self.is_exported.last() == Some(&false);
|
||||
if cx.tcx.visibility(item.owner_id.def_id) == ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id());
|
||||
if !cx.effective_visibilities.is_exported(item.owner_id.def_id) && self.is_exported.last() == Some(&false);
|
||||
if is_not_macro_export(item);
|
||||
then {
|
||||
let span = item.span.with_hi(item.ident.span.hi());
|
||||
let descr = cx.tcx.def_kind(item.def_id).descr(item.def_id.to_def_id());
|
||||
let descr = cx.tcx.def_kind(item.owner_id).descr(item.owner_id.to_def_id());
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
REDUNDANT_PUB_CRATE,
|
||||
@ -70,7 +70,8 @@ impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate {
|
||||
}
|
||||
|
||||
if let ItemKind::Mod { .. } = item.kind {
|
||||
self.is_exported.push(cx.access_levels.is_exported(item.def_id.def_id));
|
||||
self.is_exported
|
||||
.push(cx.effective_visibilities.is_exported(item.owner_id.def_id));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ fn check_method(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_def: LocalDefId, spa
|
||||
if !in_external_macro(cx.sess(), span);
|
||||
if decl.implicit_self.has_implicit_self();
|
||||
// We only show this warning for public exported methods.
|
||||
if cx.access_levels.is_exported(fn_def);
|
||||
if cx.effective_visibilities.is_exported(fn_def);
|
||||
// We don't want to emit this lint if the `#[must_use]` attribute is already there.
|
||||
if !cx.tcx.hir().attrs(hir_id).iter().any(|attr| attr.has_name(sym::must_use));
|
||||
if cx.tcx.visibility(fn_def.to_def_id()).is_public();
|
||||
@ -128,7 +128,7 @@ impl<'tcx> LateLintPass<'tcx> for ReturnSelfNotMustUse {
|
||||
|
||||
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'tcx>) {
|
||||
if let TraitItemKind::Fn(ref sig, _) = item.kind {
|
||||
check_method(cx, sig.decl, item.def_id.def_id, item.span, item.hir_id());
|
||||
check_method(cx, sig.decl, item.owner_id.def_id, item.span, item.hir_id());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod {
|
||||
let mut map = FxHashMap::<Res, ExistingName>::default();
|
||||
|
||||
for id in cx.tcx.hir().items() {
|
||||
if matches!(cx.tcx.def_kind(id.def_id), DefKind::Impl)
|
||||
if matches!(cx.tcx.def_kind(id.owner_id), DefKind::Impl)
|
||||
&& let item = cx.tcx.hir().item(id)
|
||||
&& let ItemKind::Impl(Impl {
|
||||
items,
|
||||
|
@ -53,7 +53,7 @@ impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructors {
|
||||
|
||||
let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id()).def_id;
|
||||
let item = cx.tcx.hir().expect_item(parent);
|
||||
let self_ty = cx.tcx.type_of(item.def_id);
|
||||
let self_ty = cx.tcx.type_of(item.owner_id);
|
||||
let ret_ty = return_ty(cx, impl_item.hir_id());
|
||||
|
||||
// Do not check trait impls
|
||||
|
@ -1,6 +1,6 @@
|
||||
use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_sugg};
|
||||
use clippy_utils::source::{snippet, snippet_with_applicability};
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::ty::is_type_lang_item;
|
||||
use clippy_utils::{get_parent_expr, is_lint_allowed, match_function_call, method_calls, paths};
|
||||
use clippy_utils::{peel_blocks, SpanlessEq};
|
||||
use if_chain::if_chain;
|
||||
@ -190,7 +190,7 @@ impl<'tcx> LateLintPass<'tcx> for StringAdd {
|
||||
},
|
||||
ExprKind::Index(target, _idx) => {
|
||||
let e_ty = cx.typeck_results().expr_ty(target).peel_refs();
|
||||
if matches!(e_ty.kind(), ty::Str) || is_type_diagnostic_item(cx, e_ty, sym::String) {
|
||||
if matches!(e_ty.kind(), ty::Str) || is_type_lang_item(cx, e_ty, LangItem::String) {
|
||||
span_lint(
|
||||
cx,
|
||||
STRING_SLICE,
|
||||
@ -205,7 +205,7 @@ impl<'tcx> LateLintPass<'tcx> for StringAdd {
|
||||
}
|
||||
|
||||
fn is_string(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
|
||||
is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(e).peel_refs(), sym::String)
|
||||
is_type_lang_item(cx, cx.typeck_results().expr_ty(e).peel_refs(), LangItem::String)
|
||||
}
|
||||
|
||||
fn is_add(cx: &LateContext<'_>, src: &Expr<'_>, target: &Expr<'_>) -> bool {
|
||||
@ -446,7 +446,7 @@ impl<'tcx> LateLintPass<'tcx> for StringToString {
|
||||
if let ExprKind::MethodCall(path, self_arg, ..) = &expr.kind;
|
||||
if path.ident.name == sym::to_string;
|
||||
let ty = cx.typeck_results().expr_ty(self_arg);
|
||||
if is_type_diagnostic_item(cx, ty, sym::String);
|
||||
if is_type_lang_item(cx, ty, LangItem::String);
|
||||
then {
|
||||
span_lint_and_help(
|
||||
cx,
|
||||
|
@ -580,7 +580,7 @@ fn ident_difference_expr_with_base_location(
|
||||
| (Await(_), Await(_))
|
||||
| (Async(_, _, _), Async(_, _, _))
|
||||
| (Block(_, _), Block(_, _))
|
||||
| (Closure(_, _, _, _, _, _, _), Closure(_, _, _, _, _, _, _))
|
||||
| (Closure(_), Closure(_))
|
||||
| (Match(_, _), Match(_, _))
|
||||
| (Loop(_, _), Loop(_, _))
|
||||
| (ForLoop(_, _, _, _), ForLoop(_, _, _, _))
|
||||
@ -593,7 +593,7 @@ fn ident_difference_expr_with_base_location(
|
||||
| (Unary(_, _), Unary(_, _))
|
||||
| (Binary(_, _, _), Binary(_, _, _))
|
||||
| (Tup(_), Tup(_))
|
||||
| (MethodCall(_, _, _, _), MethodCall(_, _, _, _))
|
||||
| (MethodCall(_), MethodCall(_))
|
||||
| (Call(_, _), Call(_, _))
|
||||
| (ConstBlock(_), ConstBlock(_))
|
||||
| (Array(_), Array(_))
|
||||
|
@ -60,8 +60,8 @@ impl<'tcx> LateLintPass<'tcx> for SuspiciousImpl {
|
||||
if_chain! {
|
||||
if let hir::ExprKind::Binary(binop, _, _) | hir::ExprKind::AssignOp(binop, ..) = expr.kind;
|
||||
if let Some((binop_trait_lang, op_assign_trait_lang)) = binop_traits(binop.node);
|
||||
if let Ok(binop_trait_id) = cx.tcx.lang_items().require(binop_trait_lang);
|
||||
if let Ok(op_assign_trait_id) = cx.tcx.lang_items().require(op_assign_trait_lang);
|
||||
if let Some(binop_trait_id) = cx.tcx.lang_items().get(binop_trait_lang);
|
||||
if let Some(op_assign_trait_id) = cx.tcx.lang_items().get(op_assign_trait_lang);
|
||||
|
||||
// Check for more than one binary operation in the implemented function
|
||||
// Linting when multiple operations are involved can result in false positives
|
||||
@ -78,7 +78,7 @@ impl<'tcx> LateLintPass<'tcx> for SuspiciousImpl {
|
||||
(&OP_ASSIGN_TRAITS, SUSPICIOUS_OP_ASSIGN_IMPL),
|
||||
]
|
||||
.iter()
|
||||
.find(|&(ts, _)| ts.iter().any(|&t| Ok(trait_id) == cx.tcx.lang_items().require(t)));
|
||||
.find(|&(ts, _)| ts.iter().any(|&t| Some(trait_id) == cx.tcx.lang_items().get(t)));
|
||||
if count_binops(body.value) == 1;
|
||||
then {
|
||||
span_lint(
|
||||
|
@ -46,7 +46,7 @@ impl<'tcx> LateLintPass<'tcx> for TrailingEmptyArray {
|
||||
None,
|
||||
&format!(
|
||||
"consider annotating `{}` with `#[repr(C)]` or another `repr` attribute",
|
||||
cx.tcx.def_path_str(item.def_id.to_def_id())
|
||||
cx.tcx.def_path_str(item.owner_id.to_def_id())
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ use rustc_hir::Expr;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty::SubstsRef;
|
||||
use rustc_middle::ty::{self, IntTy, Ty, TypeAndMut, UintTy};
|
||||
use rustc_span::DUMMY_SP;
|
||||
|
||||
#[expect(clippy::too_many_lines)]
|
||||
pub(super) fn check<'tcx>(
|
||||
@ -210,12 +209,12 @@ fn reduce_refs<'tcx>(cx: &LateContext<'tcx>, mut from_ty: Ty<'tcx>, mut to_ty: T
|
||||
continue;
|
||||
},
|
||||
(&(ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. })), _)
|
||||
if !unsized_ty.is_sized(cx.tcx.at(DUMMY_SP), cx.param_env) =>
|
||||
if !unsized_ty.is_sized(cx.tcx, cx.param_env) =>
|
||||
{
|
||||
(true, false)
|
||||
},
|
||||
(_, &(ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. })))
|
||||
if !unsized_ty.is_sized(cx.tcx.at(DUMMY_SP), cx.param_env) =>
|
||||
if !unsized_ty.is_sized(cx.tcx, cx.param_env) =>
|
||||
{
|
||||
(false, true)
|
||||
},
|
||||
|
@ -1,5 +1,6 @@
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::Expr;
|
||||
use rustc_hir_analysis::check::{cast, FnCtxt, Inherited};
|
||||
use rustc_hir_typeck::{cast, FnCtxt, Inherited};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty::{cast::CastKind, Ty};
|
||||
use rustc_span::DUMMY_SP;
|
||||
@ -54,9 +55,14 @@ fn check_cast<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>
|
||||
);
|
||||
|
||||
if let Ok(check) = cast::CastCheck::new(
|
||||
&fn_ctxt, e, from_ty, to_ty,
|
||||
&fn_ctxt,
|
||||
e,
|
||||
from_ty,
|
||||
to_ty,
|
||||
// We won't show any error to the user, so we don't care what the span is here.
|
||||
DUMMY_SP, DUMMY_SP,
|
||||
DUMMY_SP,
|
||||
DUMMY_SP,
|
||||
hir::Constness::NotConst,
|
||||
) {
|
||||
let res = check.do_check(&fn_ctxt);
|
||||
|
||||
|
@ -37,18 +37,26 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
|
||||
fn get_std_collection(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<Symbol> {
|
||||
let param = qpath_generic_tys(qpath).next()?;
|
||||
let id = path_def_id(cx, param)?;
|
||||
cx.tcx.get_diagnostic_name(id).filter(|&name| {
|
||||
matches!(
|
||||
name,
|
||||
sym::HashMap
|
||||
| sym::String
|
||||
| sym::Vec
|
||||
| sym::HashSet
|
||||
| sym::VecDeque
|
||||
| sym::LinkedList
|
||||
| sym::BTreeMap
|
||||
| sym::BTreeSet
|
||||
| sym::BinaryHeap
|
||||
)
|
||||
})
|
||||
cx.tcx
|
||||
.get_diagnostic_name(id)
|
||||
.filter(|&name| {
|
||||
matches!(
|
||||
name,
|
||||
sym::HashMap
|
||||
| sym::Vec
|
||||
| sym::HashSet
|
||||
| sym::VecDeque
|
||||
| sym::LinkedList
|
||||
| sym::BTreeMap
|
||||
| sym::BTreeSet
|
||||
| sym::BinaryHeap
|
||||
)
|
||||
})
|
||||
.or_else(|| {
|
||||
cx.tcx
|
||||
.lang_items()
|
||||
.string()
|
||||
.filter(|did| id == *did)
|
||||
.map(|_| sym::String)
|
||||
})
|
||||
}
|
||||
|
@ -319,7 +319,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
|
||||
false
|
||||
};
|
||||
|
||||
let is_exported = cx.access_levels.is_exported(cx.tcx.hir().local_def_id(id));
|
||||
let is_exported = cx.effective_visibilities.is_exported(cx.tcx.hir().local_def_id(id));
|
||||
|
||||
self.check_fn_decl(
|
||||
cx,
|
||||
@ -333,7 +333,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
|
||||
}
|
||||
|
||||
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
|
||||
let is_exported = cx.access_levels.is_exported(item.def_id.def_id);
|
||||
let is_exported = cx.effective_visibilities.is_exported(item.owner_id.def_id);
|
||||
|
||||
match item.kind {
|
||||
ItemKind::Static(ty, _, _) | ItemKind::Const(ty, _) => self.check_ty(
|
||||
@ -379,7 +379,9 @@ impl<'tcx> LateLintPass<'tcx> for Types {
|
||||
}
|
||||
|
||||
fn check_field_def(&mut self, cx: &LateContext<'_>, field: &hir::FieldDef<'_>) {
|
||||
let is_exported = cx.access_levels.is_exported(cx.tcx.hir().local_def_id(field.hir_id));
|
||||
let is_exported = cx
|
||||
.effective_visibilities
|
||||
.is_exported(cx.tcx.hir().local_def_id(field.hir_id));
|
||||
|
||||
self.check_ty(
|
||||
cx,
|
||||
@ -392,7 +394,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
|
||||
}
|
||||
|
||||
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &TraitItem<'_>) {
|
||||
let is_exported = cx.access_levels.is_exported(item.def_id.def_id);
|
||||
let is_exported = cx.effective_visibilities.is_exported(item.owner_id.def_id);
|
||||
|
||||
let context = CheckTyContext {
|
||||
is_exported,
|
||||
|
@ -91,10 +91,10 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
|
||||
fn match_buffer_type(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<&'static str> {
|
||||
let ty = qpath_generic_tys(qpath).next()?;
|
||||
let id = path_def_id(cx, ty)?;
|
||||
let path = match cx.tcx.get_diagnostic_name(id)? {
|
||||
sym::String => "str",
|
||||
sym::OsString => "std::ffi::OsStr",
|
||||
sym::PathBuf => "std::path::Path",
|
||||
let path = match cx.tcx.get_diagnostic_name(id) {
|
||||
Some(sym::OsString) => "std::ffi::OsStr",
|
||||
Some(sym::PathBuf) => "std::path::Path",
|
||||
_ if Some(id) == cx.tcx.lang_items().string() => "str",
|
||||
_ => return None,
|
||||
};
|
||||
Some(path)
|
||||
|
@ -57,7 +57,7 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
|
||||
// here because `mod.rs` guarantees this lint is only run on types outside of bodies and
|
||||
// is not run on locals.
|
||||
let ty = hir_ty_to_ty(cx.tcx, hir_ty);
|
||||
if ty.has_escaping_bound_vars() || !ty.is_sized(cx.tcx.at(hir_ty.span), cx.param_env) {
|
||||
if ty.has_escaping_bound_vars() || !ty.is_sized(cx.tcx, cx.param_env) {
|
||||
return false;
|
||||
}
|
||||
hir_ty.span
|
||||
|
@ -40,7 +40,7 @@ pub(super) fn check(
|
||||
});
|
||||
let ty_ty = hir_ty_to_ty(cx.tcx, boxed_ty);
|
||||
if !ty_ty.has_escaping_bound_vars();
|
||||
if ty_ty.is_sized(cx.tcx.at(ty.span), cx.param_env);
|
||||
if ty_ty.is_sized(cx.tcx, cx.param_env);
|
||||
if let Ok(ty_ty_size) = cx.layout_of(ty_ty).map(|l| l.size.bytes());
|
||||
if ty_ty_size < box_size_threshold;
|
||||
then {
|
||||
|
@ -1,4 +1,4 @@
|
||||
use clippy_utils::{diagnostics::span_lint_and_sugg, ty::is_type_diagnostic_item};
|
||||
use clippy_utils::{diagnostics::span_lint_and_sugg, ty::is_type_lang_item};
|
||||
use clippy_utils::{match_def_path, paths};
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast::LitKind;
|
||||
@ -7,7 +7,6 @@ use rustc_hir::{BorrowKind, Expr, ExprKind, LangItem, Mutability};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::sym;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
@ -55,13 +54,13 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryOwnedEmptyStrings {
|
||||
);
|
||||
} else {
|
||||
if_chain! {
|
||||
if cx.tcx.lang_items().require(LangItem::FromFrom).ok() == Some(fun_def_id);
|
||||
if Some(fun_def_id) == cx.tcx.lang_items().from_fn();
|
||||
if let [.., last_arg] = args;
|
||||
if let ExprKind::Lit(spanned) = &last_arg.kind;
|
||||
if let LitKind::Str(symbol, _) = spanned.node;
|
||||
if symbol.is_empty();
|
||||
let inner_expr_type = cx.typeck_results().expr_ty(inner_expr);
|
||||
if is_type_diagnostic_item(cx, inner_expr_type, sym::String);
|
||||
if is_type_lang_item(cx, inner_expr_type, LangItem::String);
|
||||
then {
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
|
@ -83,7 +83,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryWraps {
|
||||
match fn_kind {
|
||||
FnKind::ItemFn(..) | FnKind::Method(..) => {
|
||||
let def_id = cx.tcx.hir().local_def_id(hir_id);
|
||||
if self.avoid_breaking_exported_api && cx.access_levels.is_exported(def_id) {
|
||||
if self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(def_id) {
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
@ -292,7 +292,7 @@ fn transform_with_focus_on_idx(alternatives: &mut Vec<P<Pat>>, focus_idx: usize)
|
||||
/// So when we fixate on some `ident_k: pat_k`, we try to find `ident_k` in the other pattern
|
||||
/// and check that all `fp_i` where `i ∈ ((0...n) \ k)` between two patterns are equal.
|
||||
fn extend_with_struct_pat(
|
||||
qself1: &Option<ast::QSelf>,
|
||||
qself1: &Option<P<ast::QSelf>>,
|
||||
path1: &ast::Path,
|
||||
fps1: &mut [ast::PatField],
|
||||
rest1: bool,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use rustc_hir::intravisit::{walk_expr, walk_fn, FnKind, Visitor};
|
||||
use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId, IsAsync, YieldSource};
|
||||
use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId, YieldSource};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
@ -68,7 +68,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAsync {
|
||||
span: Span,
|
||||
hir_id: HirId,
|
||||
) {
|
||||
if !span.from_expansion() && fn_kind.asyncness() == IsAsync::Async {
|
||||
if !span.from_expansion() && fn_kind.asyncness().is_async() {
|
||||
let mut visitor = AsyncFnVisitor { cx, found_await: false };
|
||||
walk_fn(&mut visitor, fn_kind, fn_decl, body.id(), hir_id);
|
||||
if !visitor.found_await {
|
||||
|
@ -3,7 +3,6 @@ use clippy_utils::ty::{match_type, peel_mid_ty_refs_is_mutable};
|
||||
use clippy_utils::{fn_def_id, is_trait_method, path_to_local_id, paths, peel_ref_operators};
|
||||
use rustc_ast::Mutability;
|
||||
use rustc_hir::intravisit::{walk_expr, Visitor};
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_hir::{Block, Expr, ExprKind, HirId, Local, Node, PatKind, PathSegment, StmtKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::hir::nested_filter::OnlyBodies;
|
||||
@ -132,11 +131,11 @@ impl<'tcx> Visitor<'tcx> for PeekableVisitor<'_, 'tcx> {
|
||||
// If the Peekable is passed to a function, stop
|
||||
ExprKind::Call(_, args) => {
|
||||
if let Some(func_did) = fn_def_id(self.cx, expr)
|
||||
&& let Ok(into_iter_did) = self
|
||||
&& let Some(into_iter_did) = self
|
||||
.cx
|
||||
.tcx
|
||||
.lang_items()
|
||||
.require(LangItem::IntoIterIntoIter)
|
||||
.into_iter_fn()
|
||||
&& func_did == into_iter_did
|
||||
{
|
||||
// Probably a for loop desugar, stop searching
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user