1
Fork 0

Auto merge of #12200 - flip1995:rustup, r=flip1995

Rustup

r? `@ghost`

changelog: none
This commit is contained in:
bors 2024-01-25 18:06:39 +00:00
commit 66c29b973b
61 changed files with 265 additions and 180 deletions

View file

@ -2,6 +2,6 @@ avoid-breaking-exported-api = false
# use the various `span_lint_*` methods instead, which also add a link to the docs # use the various `span_lint_*` methods instead, which also add a link to the docs
disallowed-methods = [ disallowed-methods = [
"rustc_lint::context::LintContext::struct_span_lint", "rustc_lint::context::LintContext::span_lint",
"rustc_middle::ty::context::TyCtxt::struct_span_lint_hir" "rustc_middle::ty::context::TyCtxt::node_span_lint"
] ]

View file

@ -45,25 +45,49 @@ declare_lint_pass!(AsyncYieldsAsync => [ASYNC_YIELDS_ASYNC]);
impl<'tcx> LateLintPass<'tcx> for AsyncYieldsAsync { impl<'tcx> LateLintPass<'tcx> for AsyncYieldsAsync {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
// For functions, with explicitly defined types, don't warn. let ExprKind::Closure(Closure {
// XXXkhuey maybe we should? kind: ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, kind)),
if let ExprKind::Closure(Closure {
kind:
ClosureKind::Coroutine(CoroutineKind::Desugared(
CoroutineDesugaring::Async,
CoroutineSource::Block | CoroutineSource::Closure,
)),
body: body_id, body: body_id,
.. ..
}) = expr.kind }) = expr.kind
{ else {
if let Some(future_trait_def_id) = cx.tcx.lang_items().future_trait() { return;
};
let body_expr = match kind {
CoroutineSource::Fn => {
// For functions, with explicitly defined types, don't warn.
// XXXkhuey maybe we should?
return;
},
CoroutineSource::Block => cx.tcx.hir().body(*body_id).value,
CoroutineSource::Closure => {
// Like `async fn`, async closures are wrapped in an additional block
// to move all of the closure's arguments into the future.
let async_closure_body = cx.tcx.hir().body(*body_id).value;
let ExprKind::Block(block, _) = async_closure_body.kind else {
return;
};
let Some(block_expr) = block.expr else {
return;
};
let ExprKind::DropTemps(body_expr) = block_expr.kind else {
return;
};
body_expr
},
};
let Some(future_trait_def_id) = cx.tcx.lang_items().future_trait() else {
return;
};
let typeck_results = cx.tcx.typeck_body(*body_id); let typeck_results = cx.tcx.typeck_body(*body_id);
let body = cx.tcx.hir().body(*body_id); let expr_ty = typeck_results.expr_ty(body_expr);
let expr_ty = typeck_results.expr_ty(body.value);
if implements_trait(cx, expr_ty, future_trait_def_id, &[]) { if implements_trait(cx, expr_ty, future_trait_def_id, &[]) {
let return_expr_span = match &body.value.kind { let return_expr_span = match &body_expr.kind {
// XXXkhuey there has to be a better way. // XXXkhuey there has to be a better way.
ExprKind::Block(block, _) => block.expr.map(|e| e.span), ExprKind::Block(block, _) => block.expr.map(|e| e.span),
ExprKind::Path(QPath::Resolved(_, path)) => Some(path.span), ExprKind::Path(QPath::Resolved(_, path)) => Some(path.span),
@ -73,11 +97,11 @@ impl<'tcx> LateLintPass<'tcx> for AsyncYieldsAsync {
span_lint_hir_and_then( span_lint_hir_and_then(
cx, cx,
ASYNC_YIELDS_ASYNC, ASYNC_YIELDS_ASYNC,
body.value.hir_id, body_expr.hir_id,
return_expr_span, return_expr_span,
"an async construct yields a type which is itself awaitable", "an async construct yields a type which is itself awaitable",
|db| { |db| {
db.span_label(body.value.span, "outer async construct"); db.span_label(body_expr.span, "outer async construct");
db.span_label(return_expr_span, "awaitable value not awaited"); db.span_label(return_expr_span, "awaitable value not awaited");
db.span_suggestion( db.span_suggestion(
return_expr_span, return_expr_span,
@ -90,6 +114,4 @@ impl<'tcx> LateLintPass<'tcx> for AsyncYieldsAsync {
} }
} }
} }
}
}
} }

View file

@ -107,7 +107,7 @@ pub(super) fn check<'tcx>(
&& let Some(src) = snippet_opt(cx, cast_expr.span) && let Some(src) = snippet_opt(cx, cast_expr.span)
&& cast_to.is_floating_point() && cast_to.is_floating_point()
&& let Some(num_lit) = NumericLiteral::from_lit_kind(&src, &lit.node) && let Some(num_lit) = NumericLiteral::from_lit_kind(&src, &lit.node)
&& let from_nbits = 128 - n.leading_zeros() && let from_nbits = 128 - n.get().leading_zeros()
&& let to_nbits = fp_ty_mantissa_nbits(cast_to) && let to_nbits = fp_ty_mantissa_nbits(cast_to)
&& from_nbits != 0 && from_nbits != 0
&& to_nbits != 0 && to_nbits != 0

View file

@ -75,7 +75,7 @@ impl<'tcx> LateLintPass<'tcx> for DefaultUnionRepresentation {
/// (ZST fields having an arbitrary offset is completely inconsequential, and /// (ZST fields having an arbitrary offset is completely inconsequential, and
/// if there is only one field left after ignoring ZST fields then the offset /// if there is only one field left after ignoring ZST fields then the offset
/// of that field does not matter either.) /// of that field does not matter either.)
fn is_union_with_two_non_zst_fields(cx: &LateContext<'_>, item: &Item<'_>) -> bool { fn is_union_with_two_non_zst_fields<'tcx>(cx: &LateContext<'tcx>, item: &Item<'tcx>) -> bool {
if let ItemKind::Union(..) = &item.kind if let ItemKind::Union(..) = &item.kind
&& let ty::Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind() && let ty::Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind()
{ {

View file

@ -830,6 +830,7 @@ impl TyCoercionStability {
| TyKind::Infer | TyKind::Infer
| TyKind::Typeof(..) | TyKind::Typeof(..)
| TyKind::TraitObject(..) | TyKind::TraitObject(..)
| TyKind::InferDelegation(..)
| TyKind::Err(_) => Self::Reborrow, | TyKind::Err(_) => Self::Reborrow,
}; };
} }

View file

@ -386,7 +386,8 @@ fn check_unsafe_derive_deserialize<'tcx>(
&& cx && cx
.tcx .tcx
.inherent_impls(def.did()) .inherent_impls(def.did())
.iter() .into_iter()
.flatten()
.map(|imp_did| cx.tcx.hir().expect_item(imp_did.expect_local())) .map(|imp_did| cx.tcx.hir().expect_item(imp_did.expect_local()))
.any(|imp| has_unsafe(cx, imp)) .any(|imp| has_unsafe(cx, imp))
{ {
@ -451,12 +452,12 @@ fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_r
&& cx.tcx.is_diagnostic_item(sym::PartialEq, def_id) && cx.tcx.is_diagnostic_item(sym::PartialEq, def_id)
&& !has_non_exhaustive_attr(cx.tcx, *adt) && !has_non_exhaustive_attr(cx.tcx, *adt)
&& let param_env = param_env_for_derived_eq(cx.tcx, adt.did(), eq_trait_def_id) && let param_env = param_env_for_derived_eq(cx.tcx, adt.did(), eq_trait_def_id)
&& !implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, adt.did(),&[]) && !implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, None, &[])
// If all of our fields implement `Eq`, we can implement `Eq` too // If all of our fields implement `Eq`, we can implement `Eq` too
&& adt && adt
.all_fields() .all_fields()
.map(|f| f.ty(cx.tcx, args)) .map(|f| f.ty(cx.tcx, args))
.all(|ty| implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, adt.did(), &[])) .all(|ty| implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, None, &[]))
{ {
span_lint_and_sugg( span_lint_and_sugg(
cx, cx,

View file

@ -6,7 +6,7 @@ use clippy_utils::diagnostics::span_lint;
use rustc_ast::{CoroutineKind, Fn, FnRetTy, Item, ItemKind}; use rustc_ast::{CoroutineKind, Fn, FnRetTy, Item, ItemKind};
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::Lrc;
use rustc_errors::emitter::HumanEmitter; use rustc_errors::emitter::HumanEmitter;
use rustc_errors::DiagCtxt; use rustc_errors::{DiagCtxt, DiagnosticBuilder};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_parse::maybe_new_parser_from_source_str; use rustc_parse::maybe_new_parser_from_source_str;
use rustc_parse::parser::ForceCollect; use rustc_parse::parser::ForceCollect;
@ -53,7 +53,7 @@ pub fn check(
let mut parser = match maybe_new_parser_from_source_str(&sess, filename, code) { let mut parser = match maybe_new_parser_from_source_str(&sess, filename, code) {
Ok(p) => p, Ok(p) => p,
Err(errs) => { Err(errs) => {
drop(errs); errs.into_iter().for_each(DiagnosticBuilder::cancel);
return (false, test_attr_spans); return (false, test_attr_spans);
}, },
}; };

View file

@ -51,7 +51,8 @@ fn unary_pattern(pat: &Pat<'_>) -> bool {
| PatKind::Binding(..) | PatKind::Binding(..)
| PatKind::Wild | PatKind::Wild
| PatKind::Never | PatKind::Never
| PatKind::Or(_) => false, | PatKind::Or(_)
| PatKind::Err(_) => false,
PatKind::Struct(_, a, etc) => !etc && a.iter().all(|x| unary_pattern(x.pat)), PatKind::Struct(_, a, etc) => !etc && a.iter().all(|x| unary_pattern(x.pat)),
PatKind::Tuple(a, etc) | PatKind::TupleStruct(_, a, etc) => etc.as_opt_usize().is_none() && array_rec(a), PatKind::Tuple(a, etc) | PatKind::TupleStruct(_, a, etc) => etc.as_opt_usize().is_none() && array_rec(a),
PatKind::Ref(x, _) | PatKind::Box(x) => unary_pattern(x), PatKind::Ref(x, _) | PatKind::Box(x) => unary_pattern(x),

View file

@ -210,7 +210,7 @@ enum ImplicitHasherType<'tcx> {
impl<'tcx> ImplicitHasherType<'tcx> { impl<'tcx> ImplicitHasherType<'tcx> {
/// Checks that `ty` is a target type without a `BuildHasher`. /// Checks that `ty` is a target type without a `BuildHasher`.
fn new(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'_>) -> Option<Self> { fn new(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Option<Self> {
if let TyKind::Path(QPath::Resolved(None, path)) = hir_ty.kind { if let TyKind::Path(QPath::Resolved(None, path)) = hir_ty.kind {
let params: Vec<_> = path let params: Vec<_> = path
.segments .segments

View file

@ -3,6 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::get_parent_expr; use clippy_utils::get_parent_expr;
use clippy_utils::source::snippet_with_context; use clippy_utils::source::snippet_with_context;
use rustc_ast::ast::{LitIntType, LitKind}; use rustc_ast::ast::{LitIntType, LitKind};
use rustc_data_structures::packed::Pu128;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{BinOpKind, Block, Expr, ExprKind, Stmt, StmtKind}; use rustc_hir::{BinOpKind, Block, Expr, ExprKind, Stmt, StmtKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
@ -69,7 +70,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingAdd {
&& clippy_utils::SpanlessEq::new(cx).eq_expr(l, target) && clippy_utils::SpanlessEq::new(cx).eq_expr(l, target)
&& BinOpKind::Add == op1.node && BinOpKind::Add == op1.node
&& let ExprKind::Lit(lit) = value.kind && let ExprKind::Lit(lit) = value.kind
&& let LitKind::Int(1, LitIntType::Unsuffixed) = lit.node && let LitKind::Int(Pu128(1), LitIntType::Unsuffixed) = lit.node
&& block.expr.is_none() && block.expr.is_none()
{ {
let mut app = Applicability::MachineApplicable; let mut app = Applicability::MachineApplicable;

View file

@ -1,6 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::{higher, is_integer_literal, peel_blocks_with_stmt, SpanlessEq}; use clippy_utils::{higher, is_integer_literal, peel_blocks_with_stmt, SpanlessEq};
use rustc_ast::ast::LitKind; use rustc_ast::ast::LitKind;
use rustc_data_structures::packed::Pu128;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{BinOpKind, Expr, ExprKind, QPath}; use rustc_hir::{BinOpKind, Expr, ExprKind, QPath};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
@ -86,7 +87,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub {
match cond_num_val.kind { match cond_num_val.kind {
ExprKind::Lit(cond_lit) => { ExprKind::Lit(cond_lit) => {
// Check if the constant is zero // Check if the constant is zero
if let LitKind::Int(0, _) = cond_lit.node { if let LitKind::Int(Pu128(0), _) = cond_lit.node {
if cx.typeck_results().expr_ty(cond_left).is_signed() { if cx.typeck_results().expr_ty(cond_left).is_signed() {
} else { } else {
print_lint_and_sugg(cx, var_name, expr); print_lint_and_sugg(cx, var_name, expr);

View file

@ -53,9 +53,12 @@ impl<'tcx> LateLintPass<'tcx> for MultipleInherentImpl {
// List of spans to lint. (lint_span, first_span) // List of spans to lint. (lint_span, first_span)
let mut lint_spans = Vec::new(); let mut lint_spans = Vec::new();
let Ok(impls) = cx.tcx.crate_inherent_impls(()) else {
return;
};
let inherent_impls = cx let inherent_impls = cx
.tcx .tcx
.with_stable_hashing_context(|hcx| cx.tcx.crate_inherent_impls(()).inherent_impls.to_sorted(&hcx, true)); .with_stable_hashing_context(|hcx| impls.inherent_impls.to_sorted(&hcx, true));
for (_, impl_ids) in inherent_impls.into_iter().filter(|(&id, impls)| { for (_, impl_ids) in inherent_impls.into_iter().filter(|(&id, impls)| {
impls.len() > 1 impls.len() > 1

View file

@ -139,7 +139,7 @@ fn deref_chain<'cx, 'tcx>(cx: &'cx LateContext<'tcx>, ty: Ty<'tcx>) -> impl Iter
fn adt_has_inherent_method(cx: &LateContext<'_>, ty: Ty<'_>, method_name: Symbol) -> bool { fn adt_has_inherent_method(cx: &LateContext<'_>, ty: Ty<'_>, method_name: Symbol) -> bool {
if let Some(ty_did) = ty.ty_adt_def().map(ty::AdtDef::did) { if let Some(ty_did) = ty.ty_adt_def().map(ty::AdtDef::did) {
cx.tcx.inherent_impls(ty_did).iter().any(|&did| { cx.tcx.inherent_impls(ty_did).into_iter().flatten().any(|&did| {
cx.tcx cx.tcx
.associated_items(did) .associated_items(did)
.filter_by_name_unhygienic(method_name) .filter_by_name_unhygienic(method_name)

View file

@ -441,7 +441,8 @@ fn check_for_is_empty(
let is_empty = cx let is_empty = cx
.tcx .tcx
.inherent_impls(impl_ty) .inherent_impls(impl_ty)
.iter() .into_iter()
.flatten()
.flat_map(|&id| cx.tcx.associated_items(id).filter_by_name_unhygienic(is_empty)) .flat_map(|&id| cx.tcx.associated_items(id).filter_by_name_unhygienic(is_empty))
.find(|item| item.kind == AssocKind::Fn); .find(|item| item.kind == AssocKind::Fn);
@ -605,7 +606,7 @@ fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
/// Checks the inherent impl's items for an `is_empty(self)` method. /// Checks the inherent impl's items for an `is_empty(self)` method.
fn has_is_empty_impl(cx: &LateContext<'_>, id: DefId) -> bool { fn has_is_empty_impl(cx: &LateContext<'_>, id: DefId) -> bool {
let is_empty = sym!(is_empty); let is_empty = sym!(is_empty);
cx.tcx.inherent_impls(id).iter().any(|imp| { cx.tcx.inherent_impls(id).into_iter().flatten().any(|imp| {
cx.tcx cx.tcx
.associated_items(*imp) .associated_items(*imp)
.filter_by_name_unhygienic(is_empty) .filter_by_name_unhygienic(is_empty)

View file

@ -118,7 +118,7 @@ fn is_ref_iterable<'tcx>(
.liberate_late_bound_regions(fn_id, cx.tcx.fn_sig(fn_id).skip_binder()) .liberate_late_bound_regions(fn_id, cx.tcx.fn_sig(fn_id).skip_binder())
&& let &[req_self_ty, req_res_ty] = &**sig.inputs_and_output && let &[req_self_ty, req_res_ty] = &**sig.inputs_and_output
&& let param_env = cx.tcx.param_env(fn_id) && let param_env = cx.tcx.param_env(fn_id)
&& implements_trait_with_env(cx.tcx, param_env, req_self_ty, trait_id, fn_id, &[]) && implements_trait_with_env(cx.tcx, param_env, req_self_ty, trait_id, Some(fn_id), &[])
&& let Some(into_iter_ty) = && let Some(into_iter_ty) =
make_normalized_projection_with_regions(cx.tcx, param_env, trait_id, sym!(IntoIter), [req_self_ty]) make_normalized_projection_with_regions(cx.tcx, param_env, trait_id, sym!(IntoIter), [req_self_ty])
&& let req_res_ty = normalize_with_regions(cx.tcx, param_env, req_res_ty) && let req_res_ty = normalize_with_regions(cx.tcx, param_env, req_res_ty)

View file

@ -461,7 +461,7 @@ fn is_array_length_equal_to_range(cx: &LateContext<'_>, start: &Expr<'_>, end: &
if let ExprKind::Lit(lit) = expr.kind if let ExprKind::Lit(lit) = expr.kind
&& let ast::LitKind::Int(value, _) = lit.node && let ast::LitKind::Int(value, _) = lit.node
{ {
Some(value) Some(value.get())
} else { } else {
None None
} }

View file

@ -209,8 +209,8 @@ fn is_end_eq_array_len<'tcx>(
&& let Some(arr_len) = arr_len_const.try_eval_target_usize(cx.tcx, cx.param_env) && let Some(arr_len) = arr_len_const.try_eval_target_usize(cx.tcx, cx.param_env)
{ {
return match limits { return match limits {
ast::RangeLimits::Closed => end_int + 1 >= arr_len.into(), ast::RangeLimits::Closed => end_int.get() + 1 >= arr_len.into(),
ast::RangeLimits::HalfOpen => end_int >= arr_len.into(), ast::RangeLimits::HalfOpen => end_int.get() >= arr_len.into(),
}; };
} }

View file

@ -3,6 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::get_parent_expr; use clippy_utils::get_parent_expr;
use clippy_utils::source::snippet_with_context; use clippy_utils::source::snippet_with_context;
use rustc_ast::ast::LitKind; use rustc_ast::ast::LitKind;
use rustc_data_structures::packed::Pu128;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{BinOpKind, Expr, ExprKind, GenericArg, QPath}; use rustc_hir::{BinOpKind, Expr, ExprKind, GenericArg, QPath};
use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_lint::{LateContext, LateLintPass, LintContext};
@ -62,7 +63,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualBits {
&& let Some((real_ty, resolved_ty, other_expr)) = get_one_size_of_ty(cx, left_expr, right_expr) && let Some((real_ty, resolved_ty, other_expr)) = get_one_size_of_ty(cx, left_expr, right_expr)
&& matches!(resolved_ty.kind(), ty::Int(_) | ty::Uint(_)) && matches!(resolved_ty.kind(), ty::Int(_) | ty::Uint(_))
&& let ExprKind::Lit(lit) = &other_expr.kind && let ExprKind::Lit(lit) = &other_expr.kind
&& let LitKind::Int(8, _) = lit.node && let LitKind::Int(Pu128(8), _) = lit.node
{ {
let mut app = Applicability::MachineApplicable; let mut app = Applicability::MachineApplicable;
let ty_snip = snippet_with_context(cx, real_ty.span, ctxt, "..", &mut app).0; let ty_snip = snippet_with_context(cx, real_ty.span, ctxt, "..", &mut app).0;

View file

@ -45,7 +45,7 @@ fn expr_as_i128(expr: &Expr<'_>) -> Option<i128> {
&& let LitKind::Int(num, _) = lit.node && let LitKind::Int(num, _) = lit.node
{ {
// Intentionally not handling numbers greater than i128::MAX (for u128 literals) for now. // Intentionally not handling numbers greater than i128::MAX (for u128 literals) for now.
num.try_into().ok() num.get().try_into().ok()
} else { } else {
None None
} }

View file

@ -161,7 +161,7 @@ fn eq_pattern_length<'tcx>(cx: &LateContext<'tcx>, pattern: &Expr<'_>, expr: &'t
.. ..
}) = expr.kind }) = expr.kind
{ {
constant_length(cx, pattern).map_or(false, |length| length == *n) constant_length(cx, pattern).map_or(false, |length| *n == length)
} else { } else {
len_arg(cx, expr).map_or(false, |arg| eq_expr_value(cx, pattern, arg)) len_arg(cx, expr).map_or(false, |arg| eq_expr_value(cx, pattern, arg))
} }

View file

@ -11,7 +11,7 @@ use rustc_hir::{Arm, Expr, ExprKind, HirId, HirIdMap, HirIdMapEntry, HirIdSet, P
use rustc_lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; use rustc_lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_middle::ty; use rustc_middle::ty;
use rustc_span::Symbol; use rustc_span::{ErrorGuaranteed, Symbol};
use super::MATCH_SAME_ARMS; use super::MATCH_SAME_ARMS;
@ -167,6 +167,8 @@ enum NormalizedPat<'a> {
/// contains everything afterwards. Note that either side, or both sides, may contain zero /// contains everything afterwards. Note that either side, or both sides, may contain zero
/// patterns. /// patterns.
Slice(&'a [Self], Option<&'a [Self]>), Slice(&'a [Self], Option<&'a [Self]>),
/// A placeholder for a pattern that wasn't well formed in some way.
Err(ErrorGuaranteed),
} }
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
@ -291,7 +293,7 @@ impl<'a> NormalizedPat<'a> {
LitKind::ByteStr(ref bytes, _) | LitKind::CStr(ref bytes, _) => Self::LitBytes(bytes), LitKind::ByteStr(ref bytes, _) | LitKind::CStr(ref bytes, _) => Self::LitBytes(bytes),
LitKind::Byte(val) => Self::LitInt(val.into()), LitKind::Byte(val) => Self::LitInt(val.into()),
LitKind::Char(val) => Self::LitInt(val.into()), LitKind::Char(val) => Self::LitInt(val.into()),
LitKind::Int(val, _) => Self::LitInt(val), LitKind::Int(val, _) => Self::LitInt(val.get()),
LitKind::Bool(val) => Self::LitBool(val), LitKind::Bool(val) => Self::LitBool(val),
LitKind::Float(..) | LitKind::Err => Self::Wild, LitKind::Float(..) | LitKind::Err => Self::Wild,
}, },
@ -303,7 +305,7 @@ impl<'a> NormalizedPat<'a> {
None => 0, None => 0,
Some(e) => match &e.kind { Some(e) => match &e.kind {
ExprKind::Lit(lit) => match lit.node { ExprKind::Lit(lit) => match lit.node {
LitKind::Int(val, _) => val, LitKind::Int(val, _) => val.get(),
LitKind::Char(val) => val.into(), LitKind::Char(val) => val.into(),
LitKind::Byte(val) => val.into(), LitKind::Byte(val) => val.into(),
_ => return Self::Wild, _ => return Self::Wild,
@ -315,7 +317,7 @@ impl<'a> NormalizedPat<'a> {
None => (u128::MAX, RangeEnd::Included), None => (u128::MAX, RangeEnd::Included),
Some(e) => match &e.kind { Some(e) => match &e.kind {
ExprKind::Lit(lit) => match lit.node { ExprKind::Lit(lit) => match lit.node {
LitKind::Int(val, _) => (val, bounds), LitKind::Int(val, _) => (val.get(), bounds),
LitKind::Char(val) => (val.into(), bounds), LitKind::Char(val) => (val.into(), bounds),
LitKind::Byte(val) => (val.into(), bounds), LitKind::Byte(val) => (val.into(), bounds),
_ => return Self::Wild, _ => return Self::Wild,
@ -329,6 +331,7 @@ impl<'a> NormalizedPat<'a> {
arena.alloc_from_iter(front.iter().map(|pat| Self::from_pat(cx, arena, pat))), arena.alloc_from_iter(front.iter().map(|pat| Self::from_pat(cx, arena, pat))),
wild_pat.map(|_| &*arena.alloc_from_iter(back.iter().map(|pat| Self::from_pat(cx, arena, pat)))), wild_pat.map(|_| &*arena.alloc_from_iter(back.iter().map(|pat| Self::from_pat(cx, arena, pat)))),
), ),
PatKind::Err(guar) => Self::Err(guar),
} }
} }

View file

@ -2,6 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_applicability; use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::ty::is_type_diagnostic_item;
use rustc_ast::LitKind; use rustc_ast::LitKind;
use rustc_data_structures::packed::Pu128;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_lint::LateContext; use rustc_lint::LateContext;
@ -20,7 +21,7 @@ pub(super) fn check<'tcx>(
&& let Some(impl_id) = cx.tcx.impl_of_method(method_id) && let Some(impl_id) = cx.tcx.impl_of_method(method_id)
&& let identity = cx.tcx.type_of(impl_id).instantiate_identity() && let identity = cx.tcx.type_of(impl_id).instantiate_identity()
&& let hir::ExprKind::Lit(Spanned { && let hir::ExprKind::Lit(Spanned {
node: LitKind::Int(0, _), node: LitKind::Int(Pu128(0), _),
.. ..
}) = arg.kind }) = arg.kind
{ {

View file

@ -13,7 +13,7 @@ fn expr_as_u128(cx: &LateContext<'_>, e: &Expr<'_>) -> Option<u128> {
if let ExprKind::Lit(lit) = expr_or_init(cx, e).kind if let ExprKind::Lit(lit) = expr_or_init(cx, e).kind
&& let LitKind::Int(n, _) = lit.node && let LitKind::Int(n, _) = lit.node
{ {
Some(n) Some(n.get())
} else { } else {
None None
} }

View file

@ -73,7 +73,8 @@ pub(super) fn check<'tcx>(
let has_suggested_method = receiver_ty.ty_adt_def().is_some_and(|adt_def| { let has_suggested_method = receiver_ty.ty_adt_def().is_some_and(|adt_def| {
cx.tcx cx.tcx
.inherent_impls(adt_def.did()) .inherent_impls(adt_def.did())
.iter() .into_iter()
.flatten()
.flat_map(|impl_id| cx.tcx.associated_items(impl_id).filter_by_name_unhygienic(sugg)) .flat_map(|impl_id| cx.tcx.associated_items(impl_id).filter_by_name_unhygienic(sugg))
.any(|assoc| { .any(|assoc| {
assoc.fn_has_self_parameter assoc.fn_has_self_parameter

View file

@ -1,4 +1,5 @@
use rustc_ast::ast::{LitIntType, LitKind}; use rustc_ast::ast::{LitIntType, LitKind};
use rustc_data_structures::packed::Pu128;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind}; use rustc_hir::{Expr, ExprKind};
use rustc_lint::LateContext; use rustc_lint::LateContext;
@ -41,7 +42,7 @@ fn arg_is_seek_from_current<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>)
// check if argument of `SeekFrom::Current` is `0` // check if argument of `SeekFrom::Current` is `0`
if args.len() == 1 if args.len() == 1
&& let ExprKind::Lit(lit) = args[0].kind && let ExprKind::Lit(lit) = args[0].kind
&& let LitKind::Int(0, LitIntType::Unsuffixed) = lit.node && let LitKind::Int(Pu128(0), LitIntType::Unsuffixed) = lit.node
{ {
return true; return true;
} }

View file

@ -2,6 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::ty::implements_trait; use clippy_utils::ty::implements_trait;
use clippy_utils::{is_expr_used_or_unified, match_def_path, paths}; use clippy_utils::{is_expr_used_or_unified, match_def_path, paths};
use rustc_ast::ast::{LitIntType, LitKind}; use rustc_ast::ast::{LitIntType, LitKind};
use rustc_data_structures::packed::Pu128;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind}; use rustc_hir::{Expr, ExprKind};
use rustc_lint::LateContext; use rustc_lint::LateContext;
@ -31,7 +32,7 @@ pub(super) fn check<'tcx>(
&& match_def_path(cx, def_id, &paths::STD_IO_SEEKFROM_START) && match_def_path(cx, def_id, &paths::STD_IO_SEEKFROM_START)
&& args1.len() == 1 && args1.len() == 1
&& let ExprKind::Lit(lit) = args1[0].kind && let ExprKind::Lit(lit) = args1[0].kind
&& let LitKind::Int(0, LitIntType::Unsuffixed) = lit.node && let LitKind::Int(Pu128(0), LitIntType::Unsuffixed) = lit.node
{ {
let method_call_span = expr.span.with_lo(name_span.lo()); let method_call_span = expr.span.with_lo(name_span.lo());
span_lint_and_then( span_lint_and_then(

View file

@ -2,6 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_applicability; use clippy_utils::source::snippet_with_applicability;
use clippy_utils::{is_trait_method, path_to_local_id, peel_blocks, strip_pat_refs}; use clippy_utils::{is_trait_method, path_to_local_id, peel_blocks, strip_pat_refs};
use rustc_ast::ast; use rustc_ast::ast;
use rustc_data_structures::packed::Pu128;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::PatKind; use rustc_hir::PatKind;
@ -150,7 +151,7 @@ pub(super) fn check(
}, },
); );
}, },
ast::LitKind::Int(0, _) => check_fold_with_op( ast::LitKind::Int(Pu128(0), _) => check_fold_with_op(
cx, cx,
expr, expr,
acc, acc,
@ -162,7 +163,7 @@ pub(super) fn check(
method_name: "sum", method_name: "sum",
}, },
), ),
ast::LitKind::Int(1, _) => { ast::LitKind::Int(Pu128(1), _) => {
check_fold_with_op( check_fold_with_op(
cx, cx,
expr, expr,

View file

@ -1,6 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::ty::is_type_diagnostic_item;
use rustc_ast::LitKind; use rustc_ast::LitKind;
use rustc_data_structures::packed::Pu128;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind}; use rustc_hir::{Expr, ExprKind};
use rustc_lint::LateContext; use rustc_lint::LateContext;
@ -20,7 +21,7 @@ pub(super) fn check<'tcx>(
&& let Some(impl_id) = cx.tcx.impl_of_method(method_id) && let Some(impl_id) = cx.tcx.impl_of_method(method_id)
&& is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).instantiate_identity(), sym::Vec) && is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).instantiate_identity(), sym::Vec)
&& let ExprKind::Lit(Spanned { && let ExprKind::Lit(Spanned {
node: LitKind::Int(0, _), node: LitKind::Int(Pu128(0), _),
.. ..
}) = count_arg.kind }) = count_arg.kind
&& let ExprKind::Lit(Spanned { && let ExprKind::Lit(Spanned {

View file

@ -7,6 +7,7 @@ use clippy_utils::source::snippet;
use clippy_utils::visitors::for_each_expr; use clippy_utils::visitors::for_each_expr;
use clippy_utils::{eq_expr_value, hash_expr, higher}; use clippy_utils::{eq_expr_value, hash_expr, higher};
use rustc_ast::{LitKind, RangeLimits}; use rustc_ast::{LitKind, RangeLimits};
use rustc_data_structures::packed::Pu128;
use rustc_data_structures::unhash::UnhashMap; use rustc_data_structures::unhash::UnhashMap;
use rustc_errors::{Applicability, Diagnostic}; use rustc_errors::{Applicability, Diagnostic};
use rustc_hir::{BinOp, Block, Body, Expr, ExprKind, UnOp}; use rustc_hir::{BinOp, Block, Body, Expr, ExprKind, UnOp};
@ -102,8 +103,8 @@ fn len_comparison<'hir>(
) -> Option<(LengthComparison, usize, &'hir Expr<'hir>)> { ) -> Option<(LengthComparison, usize, &'hir Expr<'hir>)> {
macro_rules! int_lit_pat { macro_rules! int_lit_pat {
($id:ident) => { ($id:ident) => {
ExprKind::Lit(Spanned { ExprKind::Lit(&Spanned {
node: LitKind::Int($id, _), node: LitKind::Int(Pu128($id), _),
.. ..
}) })
}; };
@ -112,13 +113,13 @@ fn len_comparison<'hir>(
// normalize comparison, `v.len() > 4` becomes `4 < v.len()` // normalize comparison, `v.len() > 4` becomes `4 < v.len()`
// this simplifies the logic a bit // this simplifies the logic a bit
let (op, left, right) = normalize_comparison(bin_op.node, left, right)?; let (op, left, right) = normalize_comparison(bin_op.node, left, right)?;
match (op, &left.kind, &right.kind) { match (op, left.kind, right.kind) {
(Rel::Lt, int_lit_pat!(left), _) => Some((LengthComparison::IntLessThanLength, *left as usize, right)), (Rel::Lt, int_lit_pat!(left), _) => Some((LengthComparison::IntLessThanLength, left as usize, right)),
(Rel::Lt, _, int_lit_pat!(right)) => Some((LengthComparison::LengthLessThanInt, *right as usize, left)), (Rel::Lt, _, int_lit_pat!(right)) => Some((LengthComparison::LengthLessThanInt, right as usize, left)),
(Rel::Le, int_lit_pat!(left), _) => Some((LengthComparison::IntLessThanOrEqualLength, *left as usize, right)), (Rel::Le, int_lit_pat!(left), _) => Some((LengthComparison::IntLessThanOrEqualLength, left as usize, right)),
(Rel::Le, _, int_lit_pat!(right)) => Some((LengthComparison::LengthLessThanOrEqualInt, *right as usize, left)), (Rel::Le, _, int_lit_pat!(right)) => Some((LengthComparison::LengthLessThanOrEqualInt, right as usize, left)),
(Rel::Eq, int_lit_pat!(left), _) => Some((LengthComparison::LengthEqualInt, *left as usize, right)), (Rel::Eq, int_lit_pat!(left), _) => Some((LengthComparison::LengthEqualInt, left as usize, right)),
(Rel::Eq, _, int_lit_pat!(right)) => Some((LengthComparison::LengthEqualInt, *right as usize, left)), (Rel::Eq, _, int_lit_pat!(right)) => Some((LengthComparison::LengthEqualInt, right as usize, left)),
_ => None, _ => None,
} }
} }
@ -206,14 +207,14 @@ impl<'hir> IndexEntry<'hir> {
/// for `..=5` this returns `Some(5)` /// for `..=5` this returns `Some(5)`
fn upper_index_expr(expr: &Expr<'_>) -> Option<usize> { fn upper_index_expr(expr: &Expr<'_>) -> Option<usize> {
if let ExprKind::Lit(lit) = &expr.kind if let ExprKind::Lit(lit) = &expr.kind
&& let LitKind::Int(index, _) = lit.node && let LitKind::Int(Pu128(index), _) = lit.node
{ {
Some(index as usize) Some(index as usize)
} else if let Some(higher::Range { } else if let Some(higher::Range {
end: Some(end), limits, .. end: Some(end), limits, ..
}) = higher::Range::hir(expr) }) = higher::Range::hir(expr)
&& let ExprKind::Lit(lit) = &end.kind && let ExprKind::Lit(lit) = &end.kind
&& let LitKind::Int(index @ 1.., _) = lit.node && let LitKind::Int(Pu128(index @ 1..), _) = lit.node
{ {
match limits { match limits {
RangeLimits::HalfOpen => Some(index as usize - 1), RangeLimits::HalfOpen => Some(index as usize - 1),

View file

@ -151,7 +151,7 @@ impl ArithmeticSideEffects {
if let hir::ExprKind::Lit(lit) = actual.kind if let hir::ExprKind::Lit(lit) = actual.kind
&& let ast::LitKind::Int(n, _) = lit.node && let ast::LitKind::Int(n, _) = lit.node
{ {
return Some(n); return Some(n.get());
} }
if let Some(Constant::Int(n)) = constant(cx, cx.typeck_results(), expr) { if let Some(Constant::Int(n)) = constant(cx, cx.typeck_results(), expr) {
return Some(n); return Some(n);

View file

@ -1,6 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::sugg::Sugg; use clippy_utils::sugg::Sugg;
use rustc_ast::ast::LitKind; use rustc_ast::ast::LitKind;
use rustc_data_structures::packed::Pu128;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_hir::{BinOpKind, Expr, ExprKind};
use rustc_lint::LateContext; use rustc_lint::LateContext;
@ -19,9 +20,9 @@ pub(super) fn check<'tcx>(
&& let ExprKind::Binary(op1, left1, right1) = &left.kind && let ExprKind::Binary(op1, left1, right1) = &left.kind
&& BinOpKind::BitAnd == op1.node && BinOpKind::BitAnd == op1.node
&& let ExprKind::Lit(lit) = &right1.kind && let ExprKind::Lit(lit) = &right1.kind
&& let LitKind::Int(n, _) = lit.node && let LitKind::Int(Pu128(n), _) = lit.node
&& let ExprKind::Lit(lit1) = &right.kind && let ExprKind::Lit(lit1) = &right.kind
&& let LitKind::Int(0, _) = lit1.node && let LitKind::Int(Pu128(0), _) = lit1.node
&& n.leading_zeros() == n.count_zeros() && n.leading_zeros() == n.count_zeros()
&& n > u128::from(threshold) && n > u128::from(threshold)
{ {

View file

@ -257,9 +257,9 @@ fn is_call_with_ref_arg<'tcx>(
.. ..
} = kind } = kind
&& args.len() == 1 && args.len() == 1
&& let mir::Operand::Move(mir::Place { local, .. }) = &args[0] && let mir::Operand::Move(mir::Place { local, .. }) = &args[0].node
&& let ty::FnDef(def_id, _) = *func.ty(mir, cx.tcx).kind() && let ty::FnDef(def_id, _) = *func.ty(mir, cx.tcx).kind()
&& let (inner_ty, 1) = walk_ptrs_ty_depth(args[0].ty(mir, cx.tcx)) && let (inner_ty, 1) = walk_ptrs_ty_depth(args[0].node.ty(mir, cx.tcx))
&& !is_copy(cx, inner_ty) && !is_copy(cx, inner_ty)
{ {
Some((def_id, *local, inner_ty, destination.as_local()?)) Some((def_id, *local, inner_ty, destination.as_local()?))

View file

@ -5,7 +5,9 @@ use clippy_utils::sugg::Sugg;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::intravisit::{Visitor as HirVisitor, Visitor}; use rustc_hir::intravisit::{Visitor as HirVisitor, Visitor};
use rustc_hir::{intravisit as hir_visit, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Node}; use rustc_hir::{
intravisit as hir_visit, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, ExprKind, Node,
};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::nested_filter; use rustc_middle::hir::nested_filter;
use rustc_middle::lint::in_external_macro; use rustc_middle::lint::in_external_macro;
@ -166,10 +168,22 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
if coroutine_kind.is_async() if coroutine_kind.is_async()
&& let hir::ExprKind::Closure(closure) = body.kind && let hir::ExprKind::Closure(closure) = body.kind
{ {
let async_closure_body = cx.tcx.hir().body(closure.body); // Like `async fn`, async closures are wrapped in an additional block
// to move all of the closure's arguments into the future.
let async_closure_body = cx.tcx.hir().body(closure.body).value;
let ExprKind::Block(block, _) = async_closure_body.kind else {
return;
};
let Some(block_expr) = block.expr else {
return;
};
let ExprKind::DropTemps(body_expr) = block_expr.kind else {
return;
};
// `async x` is a syntax error, so it becomes `async { x }` // `async x` is a syntax error, so it becomes `async { x }`
if !matches!(async_closure_body.value.kind, hir::ExprKind::Block(_, _)) { if !matches!(body_expr.kind, hir::ExprKind::Block(_, _)) {
hint = hint.blockify(); hint = hint.blockify();
} }

View file

@ -314,9 +314,9 @@ impl_lint_pass!(Types => [BOX_COLLECTION, VEC_BOX, OPTION_OPTION, LINKEDLIST, BO
impl<'tcx> LateLintPass<'tcx> for Types { impl<'tcx> LateLintPass<'tcx> for Types {
fn check_fn( fn check_fn(
&mut self, &mut self,
cx: &LateContext<'_>, cx: &LateContext<'tcx>,
fn_kind: FnKind<'_>, fn_kind: FnKind<'_>,
decl: &FnDecl<'_>, decl: &FnDecl<'tcx>,
_: &Body<'_>, _: &Body<'_>,
_: Span, _: Span,
def_id: LocalDefId, def_id: LocalDefId,
@ -346,7 +346,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
); );
} }
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
let is_exported = cx.effective_visibilities.is_exported(item.owner_id.def_id); let is_exported = cx.effective_visibilities.is_exported(item.owner_id.def_id);
match item.kind { match item.kind {
@ -363,7 +363,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
} }
} }
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) { fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'tcx>) {
match item.kind { match item.kind {
ImplItemKind::Const(ty, _) => { ImplItemKind::Const(ty, _) => {
let is_in_trait_impl = if let Some(hir::Node::Item(item)) = cx let is_in_trait_impl = if let Some(hir::Node::Item(item)) = cx
@ -391,7 +391,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
} }
} }
fn check_field_def(&mut self, cx: &LateContext<'_>, field: &hir::FieldDef<'_>) { fn check_field_def(&mut self, cx: &LateContext<'tcx>, field: &hir::FieldDef<'tcx>) {
let is_exported = cx.effective_visibilities.is_exported(field.def_id); let is_exported = cx.effective_visibilities.is_exported(field.def_id);
self.check_ty( self.check_ty(
@ -404,7 +404,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
); );
} }
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &TraitItem<'_>) { fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &TraitItem<'tcx>) {
let is_exported = cx.effective_visibilities.is_exported(item.owner_id.def_id); let is_exported = cx.effective_visibilities.is_exported(item.owner_id.def_id);
let context = CheckTyContext { let context = CheckTyContext {
@ -421,7 +421,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
} }
} }
fn check_local(&mut self, cx: &LateContext<'_>, local: &Local<'_>) { fn check_local(&mut self, cx: &LateContext<'tcx>, local: &Local<'tcx>) {
if let Some(ty) = local.ty { if let Some(ty) = local.ty {
self.check_ty( self.check_ty(
cx, cx,
@ -444,7 +444,7 @@ impl Types {
} }
} }
fn check_fn_decl(&mut self, cx: &LateContext<'_>, decl: &FnDecl<'_>, context: CheckTyContext) { fn check_fn_decl<'tcx>(&mut self, cx: &LateContext<'tcx>, decl: &FnDecl<'tcx>, context: CheckTyContext) {
// Ignore functions in trait implementations as they are usually forced by the trait definition. // Ignore functions in trait implementations as they are usually forced by the trait definition.
// //
// FIXME: ideally we would like to warn *if the complicated type can be simplified*, but it's hard // FIXME: ideally we would like to warn *if the complicated type can be simplified*, but it's hard
@ -466,7 +466,7 @@ impl Types {
/// lint found. /// lint found.
/// ///
/// The parameter `is_local` distinguishes the context of the type. /// The parameter `is_local` distinguishes the context of the type.
fn check_ty(&mut self, cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, mut context: CheckTyContext) { fn check_ty<'tcx>(&mut self, cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>, mut context: CheckTyContext) {
if hir_ty.span.from_expansion() { if hir_ty.span.from_expansion() {
return; return;
} }

View file

@ -11,7 +11,7 @@ use rustc_span::symbol::sym;
use super::{utils, REDUNDANT_ALLOCATION}; use super::{utils, REDUNDANT_ALLOCATION};
pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool { pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>, qpath: &QPath<'tcx>, def_id: DefId) -> bool {
let mut applicability = Applicability::MaybeIncorrect; let mut applicability = Applicability::MaybeIncorrect;
let outer_sym = if Some(def_id) == cx.tcx.lang_items().owned_box() { let outer_sym = if Some(def_id) == cx.tcx.lang_items().owned_box() {
"Box" "Box"

View file

@ -13,10 +13,10 @@ use rustc_span::symbol::sym;
use super::VEC_BOX; use super::VEC_BOX;
pub(super) fn check( pub(super) fn check<'tcx>(
cx: &LateContext<'_>, cx: &LateContext<'tcx>,
hir_ty: &hir::Ty<'_>, hir_ty: &hir::Ty<'_>,
qpath: &QPath<'_>, qpath: &QPath<'tcx>,
def_id: DefId, def_id: DefId,
box_size_threshold: u64, box_size_threshold: u64,
) -> bool { ) -> bool {

View file

@ -77,7 +77,7 @@ fn get_ty_def_id(ty: Ty<'_>) -> Option<DefId> {
} }
} }
fn get_hir_ty_def_id(tcx: TyCtxt<'_>, hir_ty: rustc_hir::Ty<'_>) -> Option<DefId> { fn get_hir_ty_def_id<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: rustc_hir::Ty<'tcx>) -> Option<DefId> {
let TyKind::Path(qpath) = hir_ty.kind else { return None }; let TyKind::Path(qpath) = hir_ty.kind else { return None };
match qpath { match qpath {
QPath::Resolved(_, path) => path.res.opt_def_id(), QPath::Resolved(_, path) => path.res.opt_def_id(),
@ -237,7 +237,7 @@ fn check_to_string(cx: &LateContext<'_>, method_span: Span, method_def_id: Local
} }
} }
fn is_default_method_on_current_ty(tcx: TyCtxt<'_>, qpath: QPath<'_>, implemented_ty_id: DefId) -> bool { fn is_default_method_on_current_ty<'tcx>(tcx: TyCtxt<'tcx>, qpath: QPath<'tcx>, implemented_ty_id: DefId) -> bool {
match qpath { match qpath {
QPath::Resolved(_, path) => match path.segments { QPath::Resolved(_, path) => match path.segments {
[first, .., last] => last.ident.name == kw::Default && first.res.opt_def_id() == Some(implemented_ty_id), [first, .., last] => last.ident.name == kw::Default && first.res.opt_def_id() == Some(implemented_ty_id),

View file

@ -57,11 +57,11 @@ impl LateLintPass<'_> for UninhabitedReferences {
} }
} }
fn check_fn( fn check_fn<'tcx>(
&mut self, &mut self,
cx: &LateContext<'_>, cx: &LateContext<'tcx>,
kind: FnKind<'_>, kind: FnKind<'_>,
fndecl: &'_ FnDecl<'_>, fndecl: &'_ FnDecl<'tcx>,
_: &'_ Body<'_>, _: &'_ Body<'_>,
span: Span, span: Span,
_: LocalDefId, _: LocalDefId,

View file

@ -226,7 +226,7 @@ fn transform_with_focus_on_idx(alternatives: &mut ThinVec<P<Pat>>, focus_idx: us
// Therefore they are not some form of constructor `C`, // Therefore they are not some form of constructor `C`,
// with which a pattern `C(p_0)` may be formed, // with which a pattern `C(p_0)` may be formed,
// which we would want to join with other `C(p_j)`s. // which we would want to join with other `C(p_j)`s.
Ident(.., None) | Lit(_) | Wild | Never | Path(..) | Range(..) | Rest | MacCall(_) Ident(.., None) | Lit(_) | Wild | Err(_) | Never | Path(..) | Range(..) | Rest | MacCall(_)
// Skip immutable refs, as grouping them saves few characters, // Skip immutable refs, as grouping them saves few characters,
// and almost always requires adding parens (increasing noisiness). // and almost always requires adding parens (increasing noisiness).
// In the case of only two patterns, replacement adds net characters. // In the case of only two patterns, replacement adds net characters.

View file

@ -207,7 +207,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
} }
} }
fn check_ty(&mut self, cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>) { fn check_ty(&mut self, cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>) {
if !hir_ty.span.from_expansion() if !hir_ty.span.from_expansion()
&& self.msrv.meets(msrvs::TYPE_ALIAS_ENUM_VARIANTS) && self.msrv.meets(msrvs::TYPE_ALIAS_ENUM_VARIANTS)
&& let Some(&StackItem::Check { && let Some(&StackItem::Check {

View file

@ -710,6 +710,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
self.slice(start, |pat| self.pat(pat)); self.slice(start, |pat| self.pat(pat));
self.slice(end, |pat| self.pat(pat)); self.slice(end, |pat| self.pat(pat));
}, },
PatKind::Err(_) => kind!("Err"),
} }
} }

View file

@ -41,7 +41,6 @@ impl CompilerLintFunctions {
pub fn new() -> Self { pub fn new() -> Self {
let mut map = FxHashMap::default(); let mut map = FxHashMap::default();
map.insert("span_lint", "utils::span_lint"); map.insert("span_lint", "utils::span_lint");
map.insert("struct_span_lint", "utils::span_lint");
map.insert("lint", "utils::span_lint"); map.insert("lint", "utils::span_lint");
map.insert("span_lint_note", "utils::span_lint_and_note"); map.insert("span_lint_note", "utils::span_lint_and_note");
map.insert("span_lint_help", "utils::span_lint_and_help"); map.insert("span_lint_help", "utils::span_lint_and_help");

View file

@ -71,7 +71,9 @@ pub fn check_path(cx: &LateContext<'_>, path: &[&str]) -> bool {
SimplifiedType::Str, SimplifiedType::Str,
] ]
.iter() .iter()
.flat_map(|&ty| cx.tcx.incoherent_impls(ty).iter().copied()); .flat_map(|&ty| cx.tcx.incoherent_impls(ty).into_iter())
.flatten()
.copied();
for item_def_id in lang_items.iter().map(|(_, def_id)| def_id).chain(incoherent_impls) { for item_def_id in lang_items.iter().map(|(_, def_id)| def_id).chain(incoherent_impls) {
let lang_item_path = cx.get_def_path(item_def_id); let lang_item_path = cx.get_def_path(item_def_id);
if path_syms.starts_with(&lang_item_path) { if path_syms.starts_with(&lang_item_path) {

View file

@ -44,7 +44,7 @@ declare_clippy_lint! {
declare_lint_pass!(ZeroSizedMapValues => [ZERO_SIZED_MAP_VALUES]); declare_lint_pass!(ZeroSizedMapValues => [ZERO_SIZED_MAP_VALUES]);
impl LateLintPass<'_> for ZeroSizedMapValues { impl LateLintPass<'_> for ZeroSizedMapValues {
fn check_ty(&mut self, cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>) { fn check_ty<'tcx>(&mut self, cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>) {
if !hir_ty.span.from_expansion() if !hir_ty.span.from_expansion()
&& !in_trait_impl(cx, hir_ty.hir_id) && !in_trait_impl(cx, hir_ty.hir_id)
&& let ty = ty_from_hir_ty(cx, hir_ty) && let ty = ty_from_hir_ty(cx, hir_ty)
@ -82,7 +82,7 @@ fn in_trait_impl(cx: &LateContext<'_>, hir_id: HirId) -> bool {
false false
} }
fn ty_from_hir_ty<'tcx>(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'_>) -> Ty<'tcx> { fn ty_from_hir_ty<'tcx>(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
cx.maybe_typeck_results() cx.maybe_typeck_results()
.and_then(|results| { .and_then(|results| {
if results.hir_owner == hir_ty.hir_id.owner { if results.hir_owner == hir_ty.hir_id.owner {

View file

@ -275,7 +275,7 @@ pub fn lit_to_mir_constant<'tcx>(lit: &LitKind, ty: Option<Ty<'tcx>>) -> Constan
LitKind::Byte(b) => Constant::Int(u128::from(b)), LitKind::Byte(b) => Constant::Int(u128::from(b)),
LitKind::ByteStr(ref s, _) | LitKind::CStr(ref s, _) => Constant::Binary(Lrc::clone(s)), LitKind::ByteStr(ref s, _) | LitKind::CStr(ref s, _) => Constant::Binary(Lrc::clone(s)),
LitKind::Char(c) => Constant::Char(c), LitKind::Char(c) => Constant::Char(c),
LitKind::Int(n, _) => Constant::Int(n), LitKind::Int(n, _) => Constant::Int(n.get()),
LitKind::Float(ref is, LitFloatType::Suffixed(fty)) => match fty { LitKind::Float(ref is, LitFloatType::Suffixed(fty)) => match fty {
ast::FloatTy::F32 => Constant::F32(is.as_str().parse().unwrap()), ast::FloatTy::F32 => Constant::F32(is.as_str().parse().unwrap()),
ast::FloatTy::F64 => Constant::F64(is.as_str().parse().unwrap()), ast::FloatTy::F64 => Constant::F64(is.as_str().parse().unwrap()),

View file

@ -47,7 +47,7 @@ fn docs_link(diag: &mut Diagnostic, lint: &'static Lint) {
/// ``` /// ```
pub fn span_lint<T: LintContext>(cx: &T, lint: &'static Lint, sp: impl Into<MultiSpan>, msg: &str) { pub fn span_lint<T: LintContext>(cx: &T, lint: &'static Lint, sp: impl Into<MultiSpan>, msg: &str) {
#[expect(clippy::disallowed_methods)] #[expect(clippy::disallowed_methods)]
cx.struct_span_lint(lint, sp, msg.to_string(), |diag| { cx.span_lint(lint, sp, msg.to_string(), |diag| {
docs_link(diag, lint); docs_link(diag, lint);
}); });
} }
@ -81,7 +81,7 @@ pub fn span_lint_and_help<T: LintContext>(
help: &str, help: &str,
) { ) {
#[expect(clippy::disallowed_methods)] #[expect(clippy::disallowed_methods)]
cx.struct_span_lint(lint, span, msg.to_string(), |diag| { cx.span_lint(lint, span, msg.to_string(), |diag| {
let help = help.to_string(); let help = help.to_string();
if let Some(help_span) = help_span { if let Some(help_span) = help_span {
diag.span_help(help_span, help); diag.span_help(help_span, help);
@ -124,7 +124,7 @@ pub fn span_lint_and_note<T: LintContext>(
note: &str, note: &str,
) { ) {
#[expect(clippy::disallowed_methods)] #[expect(clippy::disallowed_methods)]
cx.struct_span_lint(lint, span, msg.to_string(), |diag| { cx.span_lint(lint, span, msg.to_string(), |diag| {
let note = note.to_string(); let note = note.to_string();
if let Some(note_span) = note_span { if let Some(note_span) = note_span {
diag.span_note(note_span, note); diag.span_note(note_span, note);
@ -146,7 +146,7 @@ where
F: FnOnce(&mut Diagnostic), F: FnOnce(&mut Diagnostic),
{ {
#[expect(clippy::disallowed_methods)] #[expect(clippy::disallowed_methods)]
cx.struct_span_lint(lint, sp, msg.to_string(), |diag| { cx.span_lint(lint, sp, msg.to_string(), |diag| {
f(diag); f(diag);
docs_link(diag, lint); docs_link(diag, lint);
}); });
@ -154,7 +154,7 @@ where
pub fn span_lint_hir(cx: &LateContext<'_>, lint: &'static Lint, hir_id: HirId, sp: Span, msg: &str) { pub fn span_lint_hir(cx: &LateContext<'_>, lint: &'static Lint, hir_id: HirId, sp: Span, msg: &str) {
#[expect(clippy::disallowed_methods)] #[expect(clippy::disallowed_methods)]
cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg.to_string(), |diag| { cx.tcx.node_span_lint(lint, hir_id, sp, msg.to_string(), |diag| {
docs_link(diag, lint); docs_link(diag, lint);
}); });
} }
@ -168,7 +168,7 @@ pub fn span_lint_hir_and_then(
f: impl FnOnce(&mut Diagnostic), f: impl FnOnce(&mut Diagnostic),
) { ) {
#[expect(clippy::disallowed_methods)] #[expect(clippy::disallowed_methods)]
cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg.to_string(), |diag| { cx.tcx.node_span_lint(lint, hir_id, sp, msg.to_string(), |diag| {
f(diag); f(diag);
docs_link(diag, lint); docs_link(diag, lint);
}); });

View file

@ -1007,7 +1007,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
} }
e.hash(&mut self.s); e.hash(&mut self.s);
}, },
PatKind::Never | PatKind::Wild => {}, PatKind::Never | PatKind::Wild | PatKind::Err(_) => {},
} }
} }
@ -1108,7 +1108,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
TyKind::Typeof(anon_const) => { TyKind::Typeof(anon_const) => {
self.hash_body(anon_const.body); self.hash_body(anon_const.body);
}, },
TyKind::Err(_) | TyKind::Infer | TyKind::Never => {}, TyKind::Err(_) | TyKind::Infer | TyKind::Never | TyKind::InferDelegation(..) => {},
} }
} }

View file

@ -80,6 +80,7 @@ use std::sync::{Mutex, MutexGuard, OnceLock};
use itertools::Itertools; use itertools::Itertools;
use rustc_ast::ast::{self, LitKind, RangeLimits}; use rustc_ast::ast::{self, LitKind, RangeLimits};
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::packed::Pu128;
use rustc_data_structures::unhash::UnhashMap; use rustc_data_structures::unhash::UnhashMap;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalModDefId, LOCAL_CRATE}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalModDefId, LOCAL_CRATE};
@ -534,10 +535,16 @@ fn find_primitive_impls<'tcx>(tcx: TyCtxt<'tcx>, name: &str) -> impl Iterator<It
"u128" => SimplifiedType::Uint(UintTy::U128), "u128" => SimplifiedType::Uint(UintTy::U128),
"f32" => SimplifiedType::Float(FloatTy::F32), "f32" => SimplifiedType::Float(FloatTy::F32),
"f64" => SimplifiedType::Float(FloatTy::F64), "f64" => SimplifiedType::Float(FloatTy::F64),
_ => return [].iter().copied(), #[allow(trivial_casts)]
_ => {
return Result::<_, rustc_errors::ErrorGuaranteed>::Ok(&[] as &[_])
.into_iter()
.flatten()
.copied();
},
}; };
tcx.incoherent_impls(ty).iter().copied() tcx.incoherent_impls(ty).into_iter().flatten().copied()
} }
fn non_local_item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Vec<Res> { fn non_local_item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Vec<Res> {
@ -663,7 +670,8 @@ pub fn def_path_res(cx: &LateContext<'_>, path: &[&str]) -> Vec<Res> {
// `impl S { ... }` // `impl S { ... }`
let inherent_impl_children = tcx let inherent_impl_children = tcx
.inherent_impls(def_id) .inherent_impls(def_id)
.iter() .into_iter()
.flatten()
.flat_map(|&impl_def_id| item_children_by_name(tcx, impl_def_id, segment)); .flat_map(|&impl_def_id| item_children_by_name(tcx, impl_def_id, segment));
let direct_children = item_children_by_name(tcx, def_id, segment); let direct_children = item_children_by_name(tcx, def_id, segment);
@ -836,7 +844,7 @@ pub fn is_default_equivalent_call(cx: &LateContext<'_>, repl_func: &Expr<'_>) ->
pub fn is_default_equivalent(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { pub fn is_default_equivalent(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
match &e.kind { match &e.kind {
ExprKind::Lit(lit) => match lit.node { ExprKind::Lit(lit) => match lit.node {
LitKind::Bool(false) | LitKind::Int(0, _) => true, LitKind::Bool(false) | LitKind::Int(Pu128(0), _) => true,
LitKind::Str(s, _) => s.is_empty(), LitKind::Str(s, _) => s.is_empty(),
_ => false, _ => false,
}, },
@ -1709,7 +1717,6 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {
PatKind::Wild | PatKind::Never => false, // If `!` typechecked then the type is empty, so not refutable. PatKind::Wild | PatKind::Never => false, // If `!` typechecked then the type is empty, so not refutable.
PatKind::Binding(_, _, _, pat) => pat.map_or(false, |pat| is_refutable(cx, pat)), PatKind::Binding(_, _, _, pat) => pat.map_or(false, |pat| is_refutable(cx, pat)),
PatKind::Box(pat) | PatKind::Ref(pat, _) => is_refutable(cx, pat), PatKind::Box(pat) | PatKind::Ref(pat, _) => is_refutable(cx, pat),
PatKind::Lit(..) | PatKind::Range(..) => true,
PatKind::Path(ref qpath) => is_enum_variant(cx, qpath, pat.hir_id), PatKind::Path(ref qpath) => is_enum_variant(cx, qpath, pat.hir_id),
PatKind::Or(pats) => { PatKind::Or(pats) => {
// TODO: should be the honest check, that pats is exhaustive set // TODO: should be the honest check, that pats is exhaustive set
@ -1733,6 +1740,7 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {
}, },
} }
}, },
PatKind::Lit(..) | PatKind::Range(..) | PatKind::Err(_) => true,
} }
} }

View file

@ -104,7 +104,7 @@ impl<'a, 'b, 'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'a, 'b,
let mut mutable_borrowers = vec![]; let mut mutable_borrowers = vec![];
for op in args { for op in args {
match op { match &op.node {
mir::Operand::Copy(p) | mir::Operand::Move(p) => { mir::Operand::Copy(p) | mir::Operand::Move(p) => {
if let ty::Ref(_, _, Mutability::Mut) = self.body.local_decls[p.local].ty.kind() { if let ty::Ref(_, _, Mutability::Mut) = self.body.local_decls[p.local].ty.kind() {
mutable_borrowers.push(p.local); mutable_borrowers.push(p.local);

View file

@ -345,7 +345,7 @@ fn check_terminator<'tcx>(
check_operand(tcx, func, span, body)?; check_operand(tcx, func, span, body)?;
for arg in args { for arg in args {
check_operand(tcx, arg, span, body)?; check_operand(tcx, &arg.node, span, body)?;
} }
Ok(()) Ok(())
} else { } else {

View file

@ -214,36 +214,22 @@ pub fn implements_trait<'tcx>(
trait_id: DefId, trait_id: DefId,
args: &[GenericArg<'tcx>], args: &[GenericArg<'tcx>],
) -> bool { ) -> bool {
let callee_id = cx implements_trait_with_env_from_iter(cx.tcx, cx.param_env, ty, trait_id, None, args.iter().map(|&x| Some(x)))
.enclosing_body
.map(|body| cx.tcx.hir().body_owner(body).owner.to_def_id());
implements_trait_with_env_from_iter(
cx.tcx,
cx.param_env,
ty,
trait_id,
callee_id,
args.iter().map(|&x| Some(x)),
)
} }
/// Same as `implements_trait` but allows using a `ParamEnv` different from the lint context. /// Same as `implements_trait` but allows using a `ParamEnv` different from the lint context.
///
/// The `callee_id` argument is used to determine whether this is a function call in a `const fn`
/// environment, used for checking const traits.
pub fn implements_trait_with_env<'tcx>( pub fn implements_trait_with_env<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>, param_env: ParamEnv<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
trait_id: DefId, trait_id: DefId,
callee_id: DefId, callee_id: Option<DefId>,
args: &[GenericArg<'tcx>], args: &[GenericArg<'tcx>],
) -> bool { ) -> bool {
implements_trait_with_env_from_iter( implements_trait_with_env_from_iter(tcx, param_env, ty, trait_id, callee_id, args.iter().map(|&x| Some(x)))
tcx,
param_env,
ty,
trait_id,
Some(callee_id),
args.iter().map(|&x| Some(x)),
)
} }
/// Same as `implements_trait_from_env` but takes the arguments as an iterator. /// Same as `implements_trait_from_env` but takes the arguments as an iterator.
@ -258,6 +244,13 @@ pub fn implements_trait_with_env_from_iter<'tcx>(
// Clippy shouldn't have infer types // Clippy shouldn't have infer types
assert!(!ty.has_infer()); assert!(!ty.has_infer());
// If a `callee_id` is passed, then we assert that it is a body owner
// through calling `body_owner_kind`, which would panic if the callee
// does not have a body.
if let Some(callee_id) = callee_id {
let _ = tcx.hir().body_owner_kind(callee_id);
}
let ty = tcx.erase_regions(ty); let ty = tcx.erase_regions(ty);
if ty.has_escaping_bound_vars() { if ty.has_escaping_bound_vars() {
return false; return false;

View file

@ -1,3 +1,3 @@
[toolchain] [toolchain]
channel = "nightly-2024-01-11" channel = "nightly-2024-01-25"
components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]

View file

@ -11,7 +11,7 @@ use rustc_lint::{Lint, LintContext};
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
pub fn a(cx: impl LintContext, lint: &'static Lint, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) { pub fn a(cx: impl LintContext, lint: &'static Lint, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) {
cx.struct_span_lint(lint, span, msg, |_| {}); cx.span_lint(lint, span, msg, |_| {});
} }
pub fn b( pub fn b(
@ -21,7 +21,7 @@ pub fn b(
span: impl Into<MultiSpan>, span: impl Into<MultiSpan>,
msg: impl Into<DiagnosticMessage>, msg: impl Into<DiagnosticMessage>,
) { ) {
tcx.struct_span_lint_hir(lint, hir_id, span, msg, |_| {}); tcx.node_span_lint(lint, hir_id, span, msg, |_| {});
} }
fn main() {} fn main() {}

View file

@ -0,0 +1,17 @@
error: use of a disallowed method `rustc_lint::context::LintContext::span_lint`
--> $DIR/disallow_span_lint.rs:14:5
|
LL | cx.span_lint(lint, span, msg, |_| {});
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::disallowed-methods` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::disallowed_methods)]`
error: use of a disallowed method `rustc_middle::ty::context::TyCtxt::node_span_lint`
--> $DIR/disallow_span_lint.rs:24:5
|
LL | tcx.node_span_lint(lint, hir_id, span, msg, |_| {});
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors

View file

@ -1,17 +0,0 @@
error: use of a disallowed method `rustc_lint::context::LintContext::struct_span_lint`
--> $DIR/disallow_struct_span_lint.rs:14:5
|
LL | cx.struct_span_lint(lint, span, msg, |_| {});
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::disallowed-methods` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::disallowed_methods)]`
error: use of a disallowed method `rustc_middle::ty::context::TyCtxt::struct_span_lint_hir`
--> $DIR/disallow_struct_span_lint.rs:24:5
|
LL | tcx.struct_span_lint_hir(lint, hir_id, span, msg, |_| {});
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors

View file

@ -48,7 +48,11 @@ if let ExprKind::Closure { capture_clause: CaptureBy::Value { .. }, fn_decl: fn_
&& expr2 = &cx.tcx.hir().body(body_id1).value && expr2 = &cx.tcx.hir().body(body_id1).value
&& let ExprKind::Block(block, None) = expr2.kind && let ExprKind::Block(block, None) = expr2.kind
&& block.stmts.is_empty() && block.stmts.is_empty()
&& block.expr.is_none() && let Some(trailing_expr) = block.expr
&& let ExprKind::DropTemps(expr3) = trailing_expr.kind
&& let ExprKind::Block(block1, None) = expr3.kind
&& block1.stmts.is_empty()
&& block1.expr.is_none()
{ {
// report your lint here // report your lint here
} }

View file

@ -26,6 +26,7 @@ fn main() {
let _ = p_rw; let _ = p_rw;
} }
#[allow(let_underscore_lock)]
fn uplifted() { fn uplifted() {
// shouldn't lint std locks as they were uplifted as rustc's `let_underscore_lock` // shouldn't lint std locks as they were uplifted as rustc's `let_underscore_lock`

View file

@ -7,10 +7,12 @@
#[warn(clippy::if_not_else)] #[warn(clippy::if_not_else)]
#[warn(clippy::unnecessary_cast)] #[warn(clippy::unnecessary_cast)]
#[warn(clippy::useless_transmute)] #[warn(clippy::useless_transmute)]
// Shouldn't suggest rustc lint name(`dead_code`) // Should suggest rustc lint name(`dead_code`)
#[warn(clippy::eq_op)] #[warn(dead_code)]
// Shouldn't suggest removed/deprecated clippy lint name(`unused_collect`) // Shouldn't suggest removed/deprecated clippy lint name(`unused_collect`)
#[warn(clippy::unused_self)] #[warn(clippy::unused_self)]
// Shouldn't suggest renamed clippy lint name(`const_static_lifetime`) // Shouldn't suggest renamed clippy lint name(`const_static_lifetime`)
#[warn(clippy::redundant_static_lifetimes)] #[warn(clippy::redundant_static_lifetimes)]
// issue #118183, should report `missing_docs` from rustc lint
#[warn(missing_docs)]
fn main() {} fn main() {}

View file

@ -7,10 +7,12 @@
#[warn(clippy::if_not_els)] #[warn(clippy::if_not_els)]
#[warn(clippy::UNNecsaRy_cAst)] #[warn(clippy::UNNecsaRy_cAst)]
#[warn(clippy::useles_transute)] #[warn(clippy::useles_transute)]
// Shouldn't suggest rustc lint name(`dead_code`) // Should suggest rustc lint name(`dead_code`)
#[warn(clippy::dead_cod)] #[warn(clippy::dead_cod)]
// Shouldn't suggest removed/deprecated clippy lint name(`unused_collect`) // Shouldn't suggest removed/deprecated clippy lint name(`unused_collect`)
#[warn(clippy::unused_colle)] #[warn(clippy::unused_colle)]
// Shouldn't suggest renamed clippy lint name(`const_static_lifetime`) // Shouldn't suggest renamed clippy lint name(`const_static_lifetime`)
#[warn(clippy::const_static_lifetim)] #[warn(clippy::const_static_lifetim)]
// issue #118183, should report `missing_docs` from rustc lint
#[warn(clippy::missing_docs)]
fn main() {} fn main() {}

View file

@ -35,7 +35,12 @@ error: unknown lint: `clippy::dead_cod`
--> $DIR/unknown_clippy_lints.rs:11:8 --> $DIR/unknown_clippy_lints.rs:11:8
| |
LL | #[warn(clippy::dead_cod)] LL | #[warn(clippy::dead_cod)]
| ^^^^^^^^^^^^^^^^ help: did you mean: `clippy::eq_op` | ^^^^^^^^^^^^^^^^
|
help: a lint with a similar name exists in `rustc` lints
|
LL | #[warn(dead_code)]
| ~~~~~~~~~
error: unknown lint: `clippy::unused_colle` error: unknown lint: `clippy::unused_colle`
--> $DIR/unknown_clippy_lints.rs:13:8 --> $DIR/unknown_clippy_lints.rs:13:8
@ -49,5 +54,16 @@ error: unknown lint: `clippy::const_static_lifetim`
LL | #[warn(clippy::const_static_lifetim)] LL | #[warn(clippy::const_static_lifetim)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `clippy::redundant_static_lifetimes` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `clippy::redundant_static_lifetimes`
error: aborting due to 8 previous errors error: unknown lint: `clippy::missing_docs`
--> $DIR/unknown_clippy_lints.rs:17:8
|
LL | #[warn(clippy::missing_docs)]
| ^^^^^^^^^^^^^^^^^^^^
|
help: a lint with a similar name exists in `rustc` lints
|
LL | #[warn(missing_docs)]
| ~~~~~~~~~~~~
error: aborting due to 9 previous errors