Auto merge of #11560 - y21:ui-toml-tests, r=Alexendoo
Add missing tests for configuration options
I noticed that a lot of lints didn't have test(s) for their configuration. This leads to issues like #11481 where the lint just does nothing with it.
This PR adds tests for *almost*[^1] all of the lints with a configuration that didn't have a test in ui-toml.
The tests that I wrote here are usually two cases: one for where it's right above or under the limit set by the config where it shouldn't lint and another one for right above where it should.
changelog: none
[^1]: allow-one-hash-in-raw-strings is ignored by needless_raw_string_hashes
diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs
index a88f2b5..0546807 100644
--- a/clippy_lints/src/attrs.rs
+++ b/clippy_lints/src/attrs.rs
@@ -616,7 +616,7 @@
attr.span,
"#[should_panic] attribute without a reason",
"consider specifying the expected panic",
- r#"#[should_panic(expected = /* panic message */)]"#.into(),
+ "#[should_panic(expected = /* panic message */)]".into(),
Applicability::HasPlaceholders,
);
}
diff --git a/clippy_lints/src/default_union_representation.rs b/clippy_lints/src/default_union_representation.rs
index bbce6e1..63ec819 100644
--- a/clippy_lints/src/default_union_representation.rs
+++ b/clippy_lints/src/default_union_representation.rs
@@ -1,8 +1,8 @@
use clippy_utils::diagnostics::span_lint_and_help;
-use rustc_hir::{self as hir, HirId, Item, ItemKind};
-use rustc_hir_analysis::hir_ty_to_ty;
+use rustc_hir::{HirId, Item, ItemKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::layout::LayoutOf;
+use rustc_middle::ty::{self, FieldDef, GenericArg, List};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;
@@ -52,7 +52,10 @@
impl<'tcx> LateLintPass<'tcx> for DefaultUnionRepresentation {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
- if is_union_with_two_non_zst_fields(cx, item) && !has_c_repr_attr(cx, item.hir_id()) {
+ if !item.span.from_expansion()
+ && is_union_with_two_non_zst_fields(cx, item)
+ && !has_c_repr_attr(cx, item.hir_id())
+ {
span_lint_and_help(
cx,
DEFAULT_UNION_REPRESENTATION,
@@ -73,18 +76,17 @@
/// if there is only one field left after ignoring ZST fields then the offset
/// of that field does not matter either.)
fn is_union_with_two_non_zst_fields(cx: &LateContext<'_>, item: &Item<'_>) -> bool {
- if let ItemKind::Union(data, _) = &item.kind {
- data.fields().iter().filter(|f| !is_zst(cx, f.ty)).count() >= 2
+ if let ItemKind::Union(..) = &item.kind
+ && let ty::Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind()
+ {
+ adt_def.all_fields().filter(|f| !is_zst(cx, f, args)).count() >= 2
} else {
false
}
}
-fn is_zst(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>) -> bool {
- if hir_ty.span.from_expansion() {
- return false;
- }
- let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+fn is_zst<'tcx>(cx: &LateContext<'tcx>, field: &FieldDef, args: &'tcx List<GenericArg<'tcx>>) -> bool {
+ let ty = field.ty(cx.tcx, args);
if let Ok(layout) = cx.layout_of(ty) {
layout.is_zst()
} else {
diff --git a/clippy_lints/src/error_impl_error.rs b/clippy_lints/src/error_impl_error.rs
index 379af9b..f24577c 100644
--- a/clippy_lints/src/error_impl_error.rs
+++ b/clippy_lints/src/error_impl_error.rs
@@ -3,7 +3,6 @@
use clippy_utils::ty::implements_trait;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::{Item, ItemKind};
-use rustc_hir_analysis::hir_ty_to_ty;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::Visibility;
use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -42,9 +41,10 @@
};
match item.kind {
- ItemKind::TyAlias(ty, _) if implements_trait(cx, hir_ty_to_ty(cx.tcx, ty), error_def_id, &[])
- && item.ident.name == sym::Error
- && is_visible_outside_module(cx, item.owner_id.def_id) =>
+ ItemKind::TyAlias(..) if item.ident.name == sym::Error
+ && is_visible_outside_module(cx, item.owner_id.def_id)
+ && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()
+ && implements_trait(cx, ty, error_def_id, &[]) =>
{
span_lint(
cx,
diff --git a/clippy_lints/src/large_const_arrays.rs b/clippy_lints/src/large_const_arrays.rs
index 9b26c35..a4f3d49 100644
--- a/clippy_lints/src/large_const_arrays.rs
+++ b/clippy_lints/src/large_const_arrays.rs
@@ -2,7 +2,6 @@
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{Item, ItemKind};
-use rustc_hir_analysis::hir_ty_to_ty;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::{self, ConstKind};
@@ -50,12 +49,12 @@
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
if_chain! {
if !item.span.from_expansion();
- if let ItemKind::Const(hir_ty, generics, _) = &item.kind;
+ if let ItemKind::Const(_, generics, _) = &item.kind;
// Since static items may not have generics, skip generic const items.
// FIXME(generic_const_items): I don't think checking `generics.hwcp` suffices as it
// doesn't account for empty where-clauses that only consist of keyword `where` IINM.
if generics.params.is_empty() && !generics.has_where_clause_predicates;
- let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+ let ty = cx.tcx.type_of(item.owner_id).instantiate_identity();
if let ty::Array(element_type, cst) = ty.kind();
if let ConstKind::Value(ty::ValTree::Leaf(element_count)) = cst.kind();
if let Ok(element_count) = element_count.try_to_target_usize(cx.tcx);
diff --git a/clippy_lints/src/large_futures.rs b/clippy_lints/src/large_futures.rs
index d67d589..19f1e08 100644
--- a/clippy_lints/src/large_futures.rs
+++ b/clippy_lints/src/large_futures.rs
@@ -17,26 +17,20 @@
///
/// ### Example
/// ```rust
- /// async fn wait(f: impl std::future::Future<Output = ()>) {}
+ /// async fn large_future(_x: [u8; 16 * 1024]) {}
///
- /// async fn big_fut(arg: [u8; 1024]) {}
- ///
- /// pub async fn test() {
- /// let fut = big_fut([0u8; 1024]);
- /// wait(fut).await;
+ /// pub async fn trigger() {
+ /// large_future([0u8; 16 * 1024]).await;
/// }
/// ```
///
/// `Box::pin` the big future instead.
///
/// ```rust
- /// async fn wait(f: impl std::future::Future<Output = ()>) {}
+ /// async fn large_future(_x: [u8; 16 * 1024]) {}
///
- /// async fn big_fut(arg: [u8; 1024]) {}
- ///
- /// pub async fn test() {
- /// let fut = Box::pin(big_fut([0u8; 1024]));
- /// wait(fut).await;
+ /// pub async fn trigger() {
+ /// Box::pin(large_future([0u8; 16 * 1024])).await;
/// }
/// ```
#[clippy::version = "1.70.0"]
diff --git a/clippy_lints/src/loops/utils.rs b/clippy_lints/src/loops/utils.rs
index 6edca2d..0a2bd89 100644
--- a/clippy_lints/src/loops/utils.rs
+++ b/clippy_lints/src/loops/utils.rs
@@ -5,7 +5,6 @@
use rustc_errors::Applicability;
use rustc_hir::intravisit::{walk_expr, walk_local, walk_pat, walk_stmt, Visitor};
use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, HirId, HirIdMap, Local, Mutability, Pat, PatKind, Stmt};
-use rustc_hir_analysis::hir_ty_to_ty;
use rustc_lint::LateContext;
use rustc_middle::hir::nested_filter;
use rustc_middle::ty::{self, Ty};
@@ -150,7 +149,7 @@
if l.pat.hir_id == self.var_id;
if let PatKind::Binding(.., ident, _) = l.pat.kind;
then {
- let ty = l.ty.map(|ty| hir_ty_to_ty(self.cx.tcx, ty));
+ let ty = l.ty.map(|_| self.cx.typeck_results().pat_ty(l.pat));
self.state = l.init.map_or(InitializeVisitorState::Declared(ident.name, ty), |init| {
InitializeVisitorState::Initialized {
diff --git a/clippy_lints/src/matches/needless_match.rs b/clippy_lints/src/matches/needless_match.rs
index c4f6852..44dc29c 100644
--- a/clippy_lints/src/matches/needless_match.rs
+++ b/clippy_lints/src/matches/needless_match.rs
@@ -8,8 +8,7 @@
};
use rustc_errors::Applicability;
use rustc_hir::LangItem::OptionNone;
-use rustc_hir::{Arm, BindingAnnotation, ByRef, Expr, ExprKind, FnRetTy, Guard, Node, Pat, PatKind, Path, QPath};
-use rustc_hir_analysis::hir_ty_to_ty;
+use rustc_hir::{Arm, BindingAnnotation, ByRef, Expr, ExprKind, Guard, ItemKind, Node, Pat, PatKind, Path, QPath};
use rustc_lint::LateContext;
use rustc_span::sym;
@@ -141,11 +140,15 @@
return same_type_and_consts(results.node_type(local.hir_id), results.expr_ty(expr));
},
// compare match_expr ty with RetTy in `fn foo() -> RetTy`
- Node::Item(..) => {
- if let Some(fn_decl) = p_node.fn_decl() {
- if let FnRetTy::Return(ret_ty) = fn_decl.output {
- return same_type_and_consts(hir_ty_to_ty(cx.tcx, ret_ty), cx.typeck_results().expr_ty(expr));
- }
+ Node::Item(item) => {
+ if let ItemKind::Fn(..) = item.kind {
+ let output = cx
+ .tcx
+ .fn_sig(item.owner_id)
+ .instantiate_identity()
+ .output()
+ .skip_binder();
+ return same_type_and_consts(output, cx.typeck_results().expr_ty(expr));
}
},
// check the parent expr for this whole block `{ match match_expr {..} }`
diff --git a/clippy_lints/src/matches/redundant_guards.rs b/clippy_lints/src/matches/redundant_guards.rs
index d470c05..0efeeac 100644
--- a/clippy_lints/src/matches/redundant_guards.rs
+++ b/clippy_lints/src/matches/redundant_guards.rs
@@ -70,10 +70,10 @@
);
}
// `Some(x) if x == Some(2)`
+ // `Some(x) if Some(2) == x`
else if let Guard::If(if_expr) = guard
&& let ExprKind::Binary(bin_op, local, pat) = if_expr.kind
&& matches!(bin_op.node, BinOpKind::Eq)
- && expr_can_be_pat(cx, pat)
// Ensure they have the same type. If they don't, we'd need deref coercion which isn't
// possible (currently) in a pattern. In some cases, you can use something like
// `as_deref` or similar but in general, we shouldn't lint this as it'd create an
@@ -81,7 +81,12 @@
//
// This isn't necessary in the other two checks, as they must be a pattern already.
&& cx.typeck_results().expr_ty(local) == cx.typeck_results().expr_ty(pat)
- && let Some(binding) = get_pat_binding(cx, local, outer_arm)
+ // Since we want to lint on both `x == Some(2)` and `Some(2) == x`, we might have to "swap"
+ // `local` and `pat`, depending on which side they are.
+ && let Some((binding, pat)) = get_pat_binding(cx, local, outer_arm)
+ .map(|binding| (binding, pat))
+ .or_else(|| get_pat_binding(cx, pat, outer_arm).map(|binding| (binding, local)))
+ && expr_can_be_pat(cx, pat)
{
let pat_span = match (pat.kind, binding.byref_ident) {
(ExprKind::AddrOf(BorrowKind::Ref, _, expr), Some(_)) => expr.span,
diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs
index bd07e6c..e7fcef9 100644
--- a/clippy_lints/src/methods/mod.rs
+++ b/clippy_lints/src/methods/mod.rs
@@ -126,7 +126,6 @@
use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
use rustc_hir::{Expr, ExprKind, Node, Stmt, StmtKind, TraitItem, TraitItemKind};
-use rustc_hir_analysis::hir_ty_to_ty;
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, TraitRef, Ty};
@@ -3926,18 +3925,20 @@
if_chain! {
if let TraitItemKind::Fn(ref sig, _) = item.kind;
if sig.decl.implicit_self.has_implicit_self();
- if let Some(first_arg_ty) = sig.decl.inputs.iter().next();
-
+ if let Some(first_arg_hir_ty) = sig.decl.inputs.first();
+ if let Some(&first_arg_ty) = cx.tcx.fn_sig(item.owner_id)
+ .instantiate_identity()
+ .inputs()
+ .skip_binder()
+ .first();
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.owner_id.to_def_id()).self_ty();
wrong_self_convention::check(
cx,
item.ident.name.as_str(),
self_ty,
first_arg_ty,
- first_arg_span,
+ first_arg_hir_ty.span,
false,
true,
);
diff --git a/clippy_lints/src/missing_const_for_fn.rs b/clippy_lints/src/missing_const_for_fn.rs
index 3b7ecca..f598a65 100644
--- a/clippy_lints/src/missing_const_for_fn.rs
+++ b/clippy_lints/src/missing_const_for_fn.rs
@@ -7,7 +7,6 @@
use rustc_hir::def_id::CRATE_DEF_ID;
use rustc_hir::intravisit::FnKind;
use rustc_hir::{Body, Constness, FnDecl, GenericParamKind};
-use rustc_hir_analysis::hir_ty_to_ty;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro;
use rustc_session::{declare_tool_lint, impl_lint_pass};
@@ -124,7 +123,7 @@
FnKind::Method(_, sig, ..) => {
if trait_ref_of_method(cx, def_id).is_some()
|| already_const(sig.header)
- || method_accepts_droppable(cx, sig.decl.inputs)
+ || method_accepts_droppable(cx, def_id)
{
return;
}
@@ -165,12 +164,11 @@
/// Returns true if any of the method parameters is a type that implements `Drop`. The method
/// can't be made const then, because `drop` can't be const-evaluated.
-fn method_accepts_droppable(cx: &LateContext<'_>, param_tys: &[hir::Ty<'_>]) -> bool {
+fn method_accepts_droppable(cx: &LateContext<'_>, def_id: LocalDefId) -> bool {
+ let sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder();
+
// If any of the params are droppable, return true
- param_tys.iter().any(|hir_ty| {
- let ty_ty = hir_ty_to_ty(cx.tcx, hir_ty);
- has_drop(cx, ty_ty)
- })
+ sig.inputs().iter().any(|&ty| has_drop(cx, ty))
}
// We don't have to lint on something that's already `const`
diff --git a/clippy_lints/src/needless_pass_by_ref_mut.rs b/clippy_lints/src/needless_pass_by_ref_mut.rs
index 36ca61c..57652e5 100644
--- a/clippy_lints/src/needless_pass_by_ref_mut.rs
+++ b/clippy_lints/src/needless_pass_by_ref_mut.rs
@@ -336,7 +336,12 @@
fn borrow(&mut self, cmt: &euv::PlaceWithHirId<'tcx>, _id: HirId, borrow: ty::BorrowKind) {
self.prev_bind = None;
if let euv::Place {
- base: euv::PlaceBase::Local(vid),
+ base:
+ euv::PlaceBase::Local(vid)
+ | euv::PlaceBase::Upvar(UpvarId {
+ var_path: UpvarPath { hir_id: vid },
+ ..
+ }),
base_ty,
..
} = &cmt.place
diff --git a/clippy_lints/src/no_effect.rs b/clippy_lints/src/no_effect.rs
index 5f2a324..aee1842 100644
--- a/clippy_lints/src/no_effect.rs
+++ b/clippy_lints/src/no_effect.rs
@@ -5,10 +5,8 @@
use rustc_errors::Applicability;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::{
- is_range_literal, BinOpKind, BlockCheckMode, Expr, ExprKind, FnRetTy, ItemKind, Node, PatKind, Stmt, StmtKind,
- UnsafeSource,
+ is_range_literal, BinOpKind, BlockCheckMode, Expr, ExprKind, ItemKind, Node, PatKind, Stmt, StmtKind, UnsafeSource,
};
-use rustc_hir_analysis::hir_ty_to_ty;
use rustc_infer::infer::TyCtxtInferExt as _;
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
@@ -99,14 +97,13 @@
|diag| {
for parent in cx.tcx.hir().parent_iter(stmt.hir_id) {
if let Node::Item(item) = parent.1
- && let ItemKind::Fn(sig, ..) = item.kind
- && let FnRetTy::Return(ret_ty) = sig.decl.output
+ && let ItemKind::Fn(..) = item.kind
&& let Some(Node::Block(block)) = get_parent_node(cx.tcx, stmt.hir_id)
&& let [.., final_stmt] = block.stmts
&& final_stmt.hir_id == stmt.hir_id
{
let expr_ty = cx.typeck_results().expr_ty(expr);
- let mut ret_ty = hir_ty_to_ty(cx.tcx, ret_ty);
+ let mut ret_ty = cx.tcx.fn_sig(item.owner_id).instantiate_identity().output().skip_binder();
// Remove `impl Future<Output = T>` to get `T`
if cx.tcx.ty_is_opaque_future(ret_ty) &&
@@ -115,7 +112,7 @@
ret_ty = true_ret_ty;
}
- if ret_ty == expr_ty {
+ if !ret_ty.is_unit() && ret_ty == expr_ty {
diag.span_suggestion(
stmt.span.shrink_to_lo(),
"did you mean to return it?",
diff --git a/clippy_lints/src/non_canonical_impls.rs b/clippy_lints/src/non_canonical_impls.rs
index c390e69..20b4b4f 100644
--- a/clippy_lints/src/non_canonical_impls.rs
+++ b/clippy_lints/src/non_canonical_impls.rs
@@ -4,8 +4,7 @@
use clippy_utils::{get_parent_node, is_res_lang_ctor, last_path_segment, match_def_path, path_res, std_or_core};
use rustc_errors::Applicability;
use rustc_hir::def_id::LocalDefId;
-use rustc_hir::{Expr, ExprKind, ImplItem, ImplItemKind, ItemKind, LangItem, Node, UnOp};
-use rustc_hir_analysis::hir_ty_to_ty;
+use rustc_hir::{Expr, ExprKind, ImplItem, ImplItemKind, LangItem, Node, UnOp};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::EarlyBinder;
use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -123,9 +122,6 @@
if cx.tcx.is_automatically_derived(item.owner_id.to_def_id()) {
return;
}
- let ItemKind::Impl(imp) = item.kind else {
- return;
- };
let ImplItemKind::Fn(_, impl_item_id) = cx.tcx.hir().impl_item(impl_item.impl_item_id()).kind else {
return;
};
@@ -181,12 +177,8 @@
if cx.tcx.is_diagnostic_item(sym::PartialOrd, trait_impl.def_id)
&& impl_item.ident.name == sym::partial_cmp
- && let Some(ord_def_id) = cx
- .tcx
- .diagnostic_items(trait_impl.def_id.krate)
- .name_to_id
- .get(&sym::Ord)
- && implements_trait(cx, hir_ty_to_ty(cx.tcx, imp.self_ty), *ord_def_id, &[])
+ && let Some(ord_def_id) = cx.tcx.get_diagnostic_item(sym::Ord)
+ && implements_trait(cx, trait_impl.self_ty(), ord_def_id, &[])
{
// If the `cmp` call likely needs to be fully qualified in the suggestion
// (like `std::cmp::Ord::cmp`). It's unfortunate we must put this here but we can't
diff --git a/clippy_lints/src/non_copy_const.rs b/clippy_lints/src/non_copy_const.rs
index 2431923..e106a95 100644
--- a/clippy_lints/src/non_copy_const.rs
+++ b/clippy_lints/src/non_copy_const.rs
@@ -13,7 +13,6 @@
use rustc_hir::{
BodyId, Expr, ExprKind, HirId, Impl, ImplItem, ImplItemKind, Item, ItemKind, Node, TraitItem, TraitItemKind, UnOp,
};
-use rustc_hir_analysis::hir_ty_to_ty;
use rustc_lint::{LateContext, LateLintPass, Lint};
use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult, GlobalId};
use rustc_middle::ty::adjustment::Adjust;
@@ -297,8 +296,8 @@
impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx Item<'_>) {
- if let ItemKind::Const(hir_ty, _generics, body_id) = it.kind {
- let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+ if let ItemKind::Const(.., body_id) = it.kind {
+ let ty = cx.tcx.type_of(it.owner_id).instantiate_identity();
if !ignored_macro(cx, it) && is_unfrozen(cx, ty) && is_value_unfrozen_poly(cx, body_id, ty) {
lint(cx, Source::Item { item: it.span });
}
@@ -306,8 +305,8 @@
}
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx TraitItem<'_>) {
- if let TraitItemKind::Const(hir_ty, body_id_opt) = &trait_item.kind {
- let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+ if let TraitItemKind::Const(_, body_id_opt) = &trait_item.kind {
+ let ty = cx.tcx.type_of(trait_item.owner_id).instantiate_identity();
// Normalize assoc types because ones originated from generic params
// bounded other traits could have their bound.
@@ -333,7 +332,7 @@
}
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) {
- if let ImplItemKind::Const(hir_ty, body_id) = &impl_item.kind {
+ if let ImplItemKind::Const(_, body_id) = &impl_item.kind {
let item_def_id = cx.tcx.hir().get_parent_item(impl_item.hir_id()).def_id;
let item = cx.tcx.hir().expect_item(item_def_id);
@@ -366,7 +365,7 @@
// we should use here as a frozen variant is a potential to be frozen
// similar to unknown layouts.
// e.g. `layout_of(...).is_err() || has_frozen_variant(...);`
- let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+ let ty = cx.tcx.type_of(impl_item.owner_id).instantiate_identity();
let normalized = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
if is_unfrozen(cx, normalized);
if is_value_unfrozen_poly(cx, *body_id, normalized);
@@ -381,7 +380,7 @@
}
},
ItemKind::Impl(Impl { of_trait: None, .. }) => {
- let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+ let ty = cx.tcx.type_of(impl_item.owner_id).instantiate_identity();
// Normalize assoc types originated from generic params.
let normalized = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs
index bf031ac..7dabdcd 100644
--- a/clippy_lints/src/ptr.rs
+++ b/clippy_lints/src/ptr.rs
@@ -16,7 +16,6 @@
ImplItemKind, ItemKind, Lifetime, Mutability, Node, Param, PatKind, QPath, TraitFn, TraitItem, TraitItemKind,
TyKind, Unsafety,
};
-use rustc_hir_analysis::hir_ty_to_ty;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::{Obligation, ObligationCause};
use rustc_lint::{LateContext, LateLintPass};
@@ -172,13 +171,8 @@
for arg in check_fn_args(
cx,
- cx.tcx
- .fn_sig(item.owner_id)
- .instantiate_identity()
- .skip_binder()
- .inputs(),
+ cx.tcx.fn_sig(item.owner_id).instantiate_identity().skip_binder(),
sig.decl.inputs,
- &sig.decl.output,
&[],
)
.filter(|arg| arg.mutability() == Mutability::Not)
@@ -237,7 +231,7 @@
let decl = sig.decl;
let sig = cx.tcx.fn_sig(item_id).instantiate_identity().skip_binder();
- let lint_args: Vec<_> = check_fn_args(cx, sig.inputs(), decl.inputs, &decl.output, body.params)
+ let lint_args: Vec<_> = check_fn_args(cx, sig, decl.inputs, body.params)
.filter(|arg| !is_trait_item || arg.mutability() == Mutability::Not)
.collect();
let results = check_ptr_arg_usage(cx, body, &lint_args);
@@ -443,12 +437,13 @@
#[expect(clippy::too_many_lines)]
fn check_fn_args<'cx, 'tcx: 'cx>(
cx: &'cx LateContext<'tcx>,
- tys: &'tcx [Ty<'tcx>],
+ fn_sig: ty::FnSig<'tcx>,
hir_tys: &'tcx [hir::Ty<'tcx>],
- ret_ty: &'tcx FnRetTy<'tcx>,
params: &'tcx [Param<'tcx>],
) -> impl Iterator<Item = PtrArg<'tcx>> + 'cx {
- tys.iter()
+ fn_sig
+ .inputs()
+ .iter()
.zip(hir_tys.iter())
.enumerate()
.filter_map(move |(i, (ty, hir_ty))| {
@@ -494,9 +489,7 @@
})
{
if !lifetime.is_anonymous()
- && let FnRetTy::Return(ret_ty) = ret_ty
- && let ret_ty = hir_ty_to_ty(cx.tcx, ret_ty)
- && ret_ty
+ && fn_sig.output()
.walk()
.filter_map(|arg| {
arg.as_region().and_then(|lifetime| {
diff --git a/clippy_lints/src/raw_strings.rs b/clippy_lints/src/raw_strings.rs
index a4fe501..3db9f75 100644
--- a/clippy_lints/src/raw_strings.rs
+++ b/clippy_lints/src/raw_strings.rs
@@ -96,8 +96,9 @@
);
},
);
-
- return;
+ if !matches!(cx.get_lint_level(NEEDLESS_RAW_STRINGS), rustc_lint::Allow) {
+ return;
+ }
}
let req = {
diff --git a/clippy_lints/src/utils/internal_lints/invalid_paths.rs b/clippy_lints/src/utils/internal_lints/invalid_paths.rs
index 4ed985f..2507722 100644
--- a/clippy_lints/src/utils/internal_lints/invalid_paths.rs
+++ b/clippy_lints/src/utils/internal_lints/invalid_paths.rs
@@ -5,10 +5,9 @@
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::Item;
-use rustc_hir_analysis::hir_ty_to_ty;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::fast_reject::SimplifiedType;
-use rustc_middle::ty::{self, FloatTy};
+use rustc_middle::ty::FloatTy;
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::symbol::Symbol;
@@ -34,25 +33,20 @@
let mod_name = &cx.tcx.item_name(local_def_id.to_def_id());
if_chain! {
if mod_name.as_str() == "paths";
- if let hir::ItemKind::Const(ty, _, body_id) = item.kind;
- let ty = hir_ty_to_ty(cx.tcx, ty);
- if let ty::Array(el_ty, _) = &ty.kind();
- if let ty::Ref(_, el_ty, _) = &el_ty.kind();
- if el_ty.is_str();
+ if let hir::ItemKind::Const(.., body_id) = item.kind;
let body = cx.tcx.hir().body(body_id);
let typeck_results = cx.tcx.typeck_body(body_id);
if let Some(Constant::Vec(path)) = constant_simple(cx, typeck_results, body.value);
- let path: Vec<&str> = path
+ if let Some(path) = path
.iter()
.map(|x| {
if let Constant::Str(s) = x {
- s.as_str()
+ Some(s.as_str())
} else {
- // We checked the type of the constant above
- unreachable!()
+ None
}
})
- .collect();
+ .collect::<Option<Vec<&str>>>();
if !check_path(cx, &path[..]);
then {
span_lint(cx, INVALID_PATHS, item.span, "invalid path");
diff --git a/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs b/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs
index bf835f8..86b77a7 100644
--- a/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs
+++ b/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs
@@ -5,9 +5,8 @@
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir as hir;
-use rustc_hir_analysis::hir_ty_to_ty;
use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::ty::{self, GenericArgKind};
+use rustc_middle::ty::{self, EarlyBinder, GenericArgKind};
use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! {
@@ -25,16 +24,14 @@
fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
if_chain! {
if let hir::ItemKind::Impl(hir::Impl {
- of_trait: Some(lint_pass_trait_ref),
- self_ty,
+ of_trait: Some(_),
items,
..
}) = &item.kind;
- if let Some(lint_pass_trait_def_id) = lint_pass_trait_ref.trait_def_id();
- let is_late_pass = match_def_path(cx, lint_pass_trait_def_id, &paths::LATE_LINT_PASS);
- if is_late_pass || match_def_path(cx, lint_pass_trait_def_id, &paths::EARLY_LINT_PASS);
- let self_ty = hir_ty_to_ty(cx.tcx, self_ty);
- if let ty::Adt(self_ty_def, _) = self_ty.kind();
+ if let Some(trait_ref) = cx.tcx.impl_trait_ref(item.owner_id).map(EarlyBinder::instantiate_identity);
+ let is_late_pass = match_def_path(cx, trait_ref.def_id, &paths::LATE_LINT_PASS);
+ if is_late_pass || match_def_path(cx, trait_ref.def_id, &paths::EARLY_LINT_PASS);
+ if let ty::Adt(self_ty_def, _) = trait_ref.self_ty().kind();
if self_ty_def.is_struct();
if self_ty_def.all_fields().any(|f| {
cx.tcx
diff --git a/tests/ui/needless_pass_by_ref_mut.rs b/tests/ui/needless_pass_by_ref_mut.rs
index da2a72c..9cddcb3 100644
--- a/tests/ui/needless_pass_by_ref_mut.rs
+++ b/tests/ui/needless_pass_by_ref_mut.rs
@@ -230,6 +230,18 @@
async fn async_vec2(b: &mut Vec<bool>) {
b.push(true);
}
+fn non_mut(n: &str) {}
+//Should warn
+pub async fn call_in_closure1(n: &mut str) {
+ (|| non_mut(n))()
+}
+fn str_mut(str: &mut String) -> bool {
+ str.pop().is_some()
+}
+//Should not warn
+pub async fn call_in_closure2(str: &mut String) {
+ (|| str_mut(str))();
+}
// Should not warn.
pub async fn closure(n: &mut usize) -> impl '_ + FnMut() {
diff --git a/tests/ui/needless_pass_by_ref_mut.stderr b/tests/ui/needless_pass_by_ref_mut.stderr
index 0fb9458..0c7fbd5 100644
--- a/tests/ui/needless_pass_by_ref_mut.stderr
+++ b/tests/ui/needless_pass_by_ref_mut.stderr
@@ -108,7 +108,15 @@
| ^^^^^^^^ help: consider changing to: `&i32`
error: this argument is a mutable reference, but not used mutably
- --> $DIR/needless_pass_by_ref_mut.rs:235:25
+ --> $DIR/needless_pass_by_ref_mut.rs:235:34
+ |
+LL | pub async fn call_in_closure1(n: &mut str) {
+ | ^^^^^^^^ help: consider changing to: `&str`
+ |
+ = warning: changing this function will impact semver compatibility
+
+error: this argument is a mutable reference, but not used mutably
+ --> $DIR/needless_pass_by_ref_mut.rs:247:25
|
LL | pub async fn closure(n: &mut usize) -> impl '_ + FnMut() {
| ^^^^^^^^^^ help: consider changing to: `&usize`
@@ -116,7 +124,7 @@
= warning: changing this function will impact semver compatibility
error: this argument is a mutable reference, but not used mutably
- --> $DIR/needless_pass_by_ref_mut.rs:242:20
+ --> $DIR/needless_pass_by_ref_mut.rs:254:20
|
LL | pub fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize {
| ^^^^^^^^^^ help: consider changing to: `&usize`
@@ -124,12 +132,12 @@
= warning: changing this function will impact semver compatibility
error: this argument is a mutable reference, but not used mutably
- --> $DIR/needless_pass_by_ref_mut.rs:253:26
+ --> $DIR/needless_pass_by_ref_mut.rs:265:26
|
LL | pub async fn closure4(n: &mut usize) {
| ^^^^^^^^^^ help: consider changing to: `&usize`
|
= warning: changing this function will impact semver compatibility
-error: aborting due to 20 previous errors
+error: aborting due to 21 previous errors
diff --git a/tests/ui/needless_raw_string_hashes.fixed b/tests/ui/needless_raw_string_hashes.fixed
index e980ade..c99c2f4 100644
--- a/tests/ui/needless_raw_string_hashes.fixed
+++ b/tests/ui/needless_raw_string_hashes.fixed
@@ -21,4 +21,7 @@
multiline
string
";
+
+ r"rust";
+ r"hello world";
}
diff --git a/tests/ui/needless_raw_string_hashes.rs b/tests/ui/needless_raw_string_hashes.rs
index 6113c5f..dcc2af6 100644
--- a/tests/ui/needless_raw_string_hashes.rs
+++ b/tests/ui/needless_raw_string_hashes.rs
@@ -21,4 +21,7 @@
multiline
string
"#;
+
+ r###"rust"###;
+ r#"hello world"#;
}
diff --git a/tests/ui/needless_raw_string_hashes.stderr b/tests/ui/needless_raw_string_hashes.stderr
index 5a8e3d0..4399c65 100644
--- a/tests/ui/needless_raw_string_hashes.stderr
+++ b/tests/ui/needless_raw_string_hashes.stderr
@@ -163,5 +163,29 @@
LL ~ ";
|
-error: aborting due to 13 previous errors
+error: unnecessary hashes around raw string literal
+ --> $DIR/needless_raw_string_hashes.rs:25:5
+ |
+LL | r###"rust"###;
+ | ^^^^^^^^^^^^^
+ |
+help: remove all the hashes around the literal
+ |
+LL - r###"rust"###;
+LL + r"rust";
+ |
+
+error: unnecessary hashes around raw string literal
+ --> $DIR/needless_raw_string_hashes.rs:26:5
+ |
+LL | r#"hello world"#;
+ | ^^^^^^^^^^^^^^^^
+ |
+help: remove all the hashes around the literal
+ |
+LL - r#"hello world"#;
+LL + r"hello world";
+ |
+
+error: aborting due to 15 previous errors
diff --git a/tests/ui/no_effect_return.rs b/tests/ui/no_effect_return.rs
index f6585aa..e46c0d7 100644
--- a/tests/ui/no_effect_return.rs
+++ b/tests/ui/no_effect_return.rs
@@ -76,6 +76,7 @@
fn i() -> () {
{
+ // does not suggest on function with explicit unit return type
();
//~^ ERROR: statement with no effect
}
diff --git a/tests/ui/no_effect_return.stderr b/tests/ui/no_effect_return.stderr
index b036e63..aed079f 100644
--- a/tests/ui/no_effect_return.stderr
+++ b/tests/ui/no_effect_return.stderr
@@ -54,15 +54,13 @@
| help: did you mean to return it?: `return`
error: statement with no effect
- --> $DIR/no_effect_return.rs:79:9
+ --> $DIR/no_effect_return.rs:80:9
|
LL | ();
- | -^^
- | |
- | help: did you mean to return it?: `return`
+ | ^^^
error: statement with no effect
- --> $DIR/no_effect_return.rs:88:9
+ --> $DIR/no_effect_return.rs:89:9
|
LL | ();
| ^^^
diff --git a/tests/ui/redundant_guards.fixed b/tests/ui/redundant_guards.fixed
index 20fcc12..f23116a 100644
--- a/tests/ui/redundant_guards.fixed
+++ b/tests/ui/redundant_guards.fixed
@@ -43,6 +43,7 @@
},
Some(Some(1)) => ..,
Some(Some(2)) => ..,
+ Some(Some(2)) => ..,
// Don't lint, since x is used in the body
Some(x) if let Some(1) = x => {
x;
@@ -56,11 +57,13 @@
Some(x) if matches!(y, 1 if true) => ..,
Some(x) if let 1 = y => ..,
Some(x) if y == 2 => ..,
+ Some(x) if 2 == y => ..,
_ => todo!(),
};
let a = A(1);
match a {
_ if a.0 == 1 => {},
+ _ if 1 == a.0 => {},
_ => todo!(),
}
let b = B { e: Some(A(0)) };
@@ -119,6 +122,7 @@
fn f(s: Option<std::ffi::OsString>) {
match s {
Some(x) if x == "a" => {},
+ Some(x) if "a" == x => {},
_ => {},
}
}
@@ -140,6 +144,7 @@
fn g(opt_s: Option<S>) {
match opt_s {
Some(x) if x == CONST_S => {},
+ Some(x) if CONST_S == x => {},
_ => {},
}
}
@@ -158,6 +163,7 @@
let c = Some(1);
match c {
Some(1) => {},
+ Some(1) => {},
Some(2) => {},
Some(3) => {},
_ => {},
@@ -166,6 +172,7 @@
let enum_a = A::Foo([98, 97, 114]);
match enum_a {
A::Foo(ref arr) if arr == b"foo" => {},
+ A::Foo(ref arr) if b"foo" == arr => {},
A::Foo(ref arr) if let b"bar" = arr => {},
A::Foo(ref arr) if matches!(arr, b"baz") => {},
_ => {},
@@ -177,6 +184,8 @@
};
match struct_b {
B { ref b, .. } if b == "bar" => {},
+ B { ref b, .. } if "bar" == b => {},
+ B { c: 1, .. } => {},
B { c: 1, .. } => {},
B { c: 1, .. } => {},
B { c: 1, .. } => {},
diff --git a/tests/ui/redundant_guards.rs b/tests/ui/redundant_guards.rs
index e63cd29..c0206b4 100644
--- a/tests/ui/redundant_guards.rs
+++ b/tests/ui/redundant_guards.rs
@@ -43,6 +43,7 @@
},
Some(x) if let Some(1) = x => ..,
Some(x) if x == Some(2) => ..,
+ Some(x) if Some(2) == x => ..,
// Don't lint, since x is used in the body
Some(x) if let Some(1) = x => {
x;
@@ -56,11 +57,13 @@
Some(x) if matches!(y, 1 if true) => ..,
Some(x) if let 1 = y => ..,
Some(x) if y == 2 => ..,
+ Some(x) if 2 == y => ..,
_ => todo!(),
};
let a = A(1);
match a {
_ if a.0 == 1 => {},
+ _ if 1 == a.0 => {},
_ => todo!(),
}
let b = B { e: Some(A(0)) };
@@ -119,6 +122,7 @@
fn f(s: Option<std::ffi::OsString>) {
match s {
Some(x) if x == "a" => {},
+ Some(x) if "a" == x => {},
_ => {},
}
}
@@ -140,6 +144,7 @@
fn g(opt_s: Option<S>) {
match opt_s {
Some(x) if x == CONST_S => {},
+ Some(x) if CONST_S == x => {},
_ => {},
}
}
@@ -158,6 +163,7 @@
let c = Some(1);
match c {
Some(ref x) if x == &1 => {},
+ Some(ref x) if &1 == x => {},
Some(ref x) if let &2 = x => {},
Some(ref x) if matches!(x, &3) => {},
_ => {},
@@ -166,6 +172,7 @@
let enum_a = A::Foo([98, 97, 114]);
match enum_a {
A::Foo(ref arr) if arr == b"foo" => {},
+ A::Foo(ref arr) if b"foo" == arr => {},
A::Foo(ref arr) if let b"bar" = arr => {},
A::Foo(ref arr) if matches!(arr, b"baz") => {},
_ => {},
@@ -177,7 +184,9 @@
};
match struct_b {
B { ref b, .. } if b == "bar" => {},
+ B { ref b, .. } if "bar" == b => {},
B { ref c, .. } if c == &1 => {},
+ B { ref c, .. } if &1 == c => {},
B { ref c, .. } if let &1 = c => {},
B { ref c, .. } if matches!(c, &1) => {},
_ => {},
diff --git a/tests/ui/redundant_guards.stderr b/tests/ui/redundant_guards.stderr
index f208e55..b8d7834 100644
--- a/tests/ui/redundant_guards.stderr
+++ b/tests/ui/redundant_guards.stderr
@@ -60,7 +60,19 @@
|
error: redundant guard
- --> $DIR/redundant_guards.rs:68:20
+ --> $DIR/redundant_guards.rs:46:20
+ |
+LL | Some(x) if Some(2) == x => ..,
+ | ^^^^^^^^^^^^
+ |
+help: try
+ |
+LL - Some(x) if Some(2) == x => ..,
+LL + Some(Some(2)) => ..,
+ |
+
+error: redundant guard
+ --> $DIR/redundant_guards.rs:71:20
|
LL | B { e } if matches!(e, Some(A(2))) => ..,
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -72,7 +84,7 @@
|
error: redundant guard
- --> $DIR/redundant_guards.rs:105:20
+ --> $DIR/redundant_guards.rs:108:20
|
LL | E::A(y) if y == "not from an or pattern" => {},
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -84,7 +96,7 @@
|
error: redundant guard
- --> $DIR/redundant_guards.rs:112:14
+ --> $DIR/redundant_guards.rs:115:14
|
LL | x if matches!(x, Some(0)) => ..,
| ^^^^^^^^^^^^^^^^^^^^
@@ -96,7 +108,7 @@
|
error: redundant guard
- --> $DIR/redundant_guards.rs:160:28
+ --> $DIR/redundant_guards.rs:165:28
|
LL | Some(ref x) if x == &1 => {},
| ^^^^^^^
@@ -108,7 +120,19 @@
|
error: redundant guard
- --> $DIR/redundant_guards.rs:161:28
+ --> $DIR/redundant_guards.rs:166:28
+ |
+LL | Some(ref x) if &1 == x => {},
+ | ^^^^^^^
+ |
+help: try
+ |
+LL - Some(ref x) if &1 == x => {},
+LL + Some(1) => {},
+ |
+
+error: redundant guard
+ --> $DIR/redundant_guards.rs:167:28
|
LL | Some(ref x) if let &2 = x => {},
| ^^^^^^^^^^
@@ -120,7 +144,7 @@
|
error: redundant guard
- --> $DIR/redundant_guards.rs:162:28
+ --> $DIR/redundant_guards.rs:168:28
|
LL | Some(ref x) if matches!(x, &3) => {},
| ^^^^^^^^^^^^^^^
@@ -132,7 +156,7 @@
|
error: redundant guard
- --> $DIR/redundant_guards.rs:180:32
+ --> $DIR/redundant_guards.rs:188:32
|
LL | B { ref c, .. } if c == &1 => {},
| ^^^^^^^
@@ -144,7 +168,19 @@
|
error: redundant guard
- --> $DIR/redundant_guards.rs:181:32
+ --> $DIR/redundant_guards.rs:189:32
+ |
+LL | B { ref c, .. } if &1 == c => {},
+ | ^^^^^^^
+ |
+help: try
+ |
+LL - B { ref c, .. } if &1 == c => {},
+LL + B { c: 1, .. } => {},
+ |
+
+error: redundant guard
+ --> $DIR/redundant_guards.rs:190:32
|
LL | B { ref c, .. } if let &1 = c => {},
| ^^^^^^^^^^
@@ -156,7 +192,7 @@
|
error: redundant guard
- --> $DIR/redundant_guards.rs:182:32
+ --> $DIR/redundant_guards.rs:191:32
|
LL | B { ref c, .. } if matches!(c, &1) => {},
| ^^^^^^^^^^^^^^^
@@ -167,5 +203,5 @@
LL + B { c: 1, .. } => {},
|
-error: aborting due to 14 previous errors
+error: aborting due to 17 previous errors