summaryrefslogtreecommitdiffstats
path: root/src/tools/clippy/clippy_utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/clippy/clippy_utils')
-rw-r--r--src/tools/clippy/clippy_utils/Cargo.toml2
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/check_proc_macro.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/consts.rs9
-rw-r--r--src/tools/clippy/clippy_utils/src/diagnostics.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs49
-rw-r--r--src/tools/clippy/clippy_utils/src/macros.rs6
-rw-r--r--src/tools/clippy/clippy_utils/src/mir/maybe_storage_live.rs52
-rw-r--r--src/tools/clippy/clippy_utils/src/mir/mod.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs14
-rw-r--r--src/tools/clippy/clippy_utils/src/msrvs.rs6
-rw-r--r--src/tools/clippy/clippy_utils/src/paths.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs8
-rw-r--r--src/tools/clippy/clippy_utils/src/sugg.rs5
-rw-r--r--src/tools/clippy/clippy_utils/src/ty.rs40
-rw-r--r--src/tools/clippy/clippy_utils/src/visitors.rs11
17 files changed, 98 insertions, 120 deletions
diff --git a/src/tools/clippy/clippy_utils/Cargo.toml b/src/tools/clippy/clippy_utils/Cargo.toml
index fb9f4740e..ac6a566b9 100644
--- a/src/tools/clippy/clippy_utils/Cargo.toml
+++ b/src/tools/clippy/clippy_utils/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "clippy_utils"
-version = "0.1.67"
+version = "0.1.68"
edition = "2021"
publish = false
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs
index 49e5f283d..9d0263e93 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs
@@ -625,7 +625,7 @@ pub fn eq_ty(l: &Ty, r: &Ty) -> bool {
(Slice(l), Slice(r)) => eq_ty(l, r),
(Array(le, ls), Array(re, rs)) => eq_ty(le, re) && eq_expr(&ls.value, &rs.value),
(Ptr(l), Ptr(r)) => l.mutbl == r.mutbl && eq_ty(&l.ty, &r.ty),
- (Rptr(ll, l), Rptr(rl, r)) => {
+ (Ref(ll, l), Ref(rl, r)) => {
both(ll, rl, |l, r| eq_id(l.ident, r.ident)) && l.mutbl == r.mutbl && eq_ty(&l.ty, &r.ty)
},
(BareFn(l), BareFn(r)) => {
diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
index c6bf98b7b..43f0df145 100644
--- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
+++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
@@ -69,7 +69,9 @@ fn lit_search_pat(lit: &LitKind) -> (Pat, Pat) {
LitKind::Str(_, StrStyle::Cooked) => (Pat::Str("\""), Pat::Str("\"")),
LitKind::Str(_, StrStyle::Raw(0)) => (Pat::Str("r"), Pat::Str("\"")),
LitKind::Str(_, StrStyle::Raw(_)) => (Pat::Str("r#"), Pat::Str("#")),
- LitKind::ByteStr(_) => (Pat::Str("b\""), Pat::Str("\"")),
+ LitKind::ByteStr(_, StrStyle::Cooked) => (Pat::Str("b\""), Pat::Str("\"")),
+ LitKind::ByteStr(_, StrStyle::Raw(0)) => (Pat::Str("br\""), Pat::Str("\"")),
+ LitKind::ByteStr(_, StrStyle::Raw(_)) => (Pat::Str("br#\""), Pat::Str("#")),
LitKind::Byte(_) => (Pat::Str("b'"), Pat::Str("'")),
LitKind::Char(_) => (Pat::Str("'"), Pat::Str("'")),
LitKind::Int(_, LitIntType::Signed(IntTy::Isize)) => (Pat::Num, Pat::Str("isize")),
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index 315aea9aa..a67bd8d46 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -210,7 +210,7 @@ pub fn lit_to_mir_constant(lit: &LitKind, ty: Option<Ty<'_>>) -> Constant {
match *lit {
LitKind::Str(ref is, _) => Constant::Str(is.to_string()),
LitKind::Byte(b) => Constant::Int(u128::from(b)),
- LitKind::ByteStr(ref s) => Constant::Binary(Lrc::clone(s)),
+ LitKind::ByteStr(ref s, _) => Constant::Binary(Lrc::clone(s)),
LitKind::Char(c) => Constant::Char(c),
LitKind::Int(n, _) => Constant::Int(n),
LitKind::Float(ref is, LitFloatType::Suffixed(fty)) => match fty {
@@ -620,12 +620,7 @@ pub fn miri_to_const<'tcx>(tcx: TyCtxt<'tcx>, result: mir::ConstantKind<'tcx>) -
ty::Float(FloatTy::F64) => Some(Constant::F64(f64::from_bits(
int.try_into().expect("invalid f64 bit representation"),
))),
- ty::RawPtr(type_and_mut) => {
- if let ty::Uint(_) = type_and_mut.ty.kind() {
- return Some(Constant::RawPtr(int.assert_bits(int.size())));
- }
- None
- },
+ ty::RawPtr(_) => Some(Constant::RawPtr(int.assert_bits(int.size()))),
// FIXME: implement other conversions.
_ => None,
}
diff --git a/src/tools/clippy/clippy_utils/src/diagnostics.rs b/src/tools/clippy/clippy_utils/src/diagnostics.rs
index 16b160b6f..812f6fe71 100644
--- a/src/tools/clippy/clippy_utils/src/diagnostics.rs
+++ b/src/tools/clippy/clippy_utils/src/diagnostics.rs
@@ -17,7 +17,7 @@ use std::env;
fn docs_link(diag: &mut Diagnostic, lint: &'static Lint) {
if env::var("CLIPPY_DISABLE_DOCS_LINKS").is_err() {
if let Some(lint) = lint.name_lower().strip_prefix("clippy::") {
- diag.help(&format!(
+ diag.help(format!(
"for further information visit https://rust-lang.github.io/rust-clippy/{}/index.html#{lint}",
&option_env!("RUST_RELEASE_NUM").map_or("master".to_string(), |n| {
// extract just major + minor version and ignore patch versions
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index 07fb6af91..2bbe1a19b 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -430,7 +430,7 @@ impl HirEqInterExpr<'_, '_, '_> {
(&TyKind::Slice(l_vec), &TyKind::Slice(r_vec)) => self.eq_ty(l_vec, r_vec),
(&TyKind::Array(lt, ll), &TyKind::Array(rt, rl)) => self.eq_ty(lt, rt) && self.eq_array_length(ll, rl),
(TyKind::Ptr(l_mut), TyKind::Ptr(r_mut)) => l_mut.mutbl == r_mut.mutbl && self.eq_ty(l_mut.ty, r_mut.ty),
- (TyKind::Rptr(_, l_rmut), TyKind::Rptr(_, r_rmut)) => {
+ (TyKind::Ref(_, l_rmut), TyKind::Ref(_, r_rmut)) => {
l_rmut.mutbl == r_rmut.mutbl && self.eq_ty(l_rmut.ty, r_rmut.ty)
},
(TyKind::Path(l), TyKind::Path(r)) => self.eq_qpath(l, r),
@@ -950,7 +950,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
self.hash_ty(mut_ty.ty);
mut_ty.mutbl.hash(&mut self.s);
},
- TyKind::Rptr(lifetime, ref mut_ty) => {
+ TyKind::Ref(lifetime, ref mut_ty) => {
self.hash_lifetime(lifetime);
self.hash_ty(mut_ty.ty);
mut_ty.mutbl.hash(&mut self.s);
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 90192f46c..7a4a9036d 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -22,6 +22,9 @@ extern crate rustc_ast;
extern crate rustc_ast_pretty;
extern crate rustc_attr;
extern crate rustc_data_structures;
+// The `rustc_driver` crate seems to be required in order to use the `rust_ast` crate.
+#[allow(unused_extern_crates)]
+extern crate rustc_driver;
extern crate rustc_errors;
extern crate rustc_hir;
extern crate rustc_hir_typeck;
@@ -97,7 +100,7 @@ use rustc_middle::hir::place::PlaceBase;
use rustc_middle::ty as rustc_ty;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
use rustc_middle::ty::binding::BindingMode;
-use rustc_middle::ty::fast_reject::SimplifiedTypeGen::{
+use rustc_middle::ty::fast_reject::SimplifiedType::{
ArraySimplifiedType, BoolSimplifiedType, CharSimplifiedType, FloatSimplifiedType, IntSimplifiedType,
PtrSimplifiedType, SliceSimplifiedType, StrSimplifiedType, UintSimplifiedType,
};
@@ -116,6 +119,8 @@ use crate::consts::{constant, Constant};
use crate::ty::{can_partially_move_ty, expr_sig, is_copy, is_recursively_primitive_type, ty_is_fn_once_param};
use crate::visitors::for_each_expr;
+use rustc_middle::hir::nested_filter;
+
#[macro_export]
macro_rules! extract_msrv_attr {
($context:ident) => {
@@ -174,7 +179,7 @@ pub fn find_binding_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<
if_chain! {
if let Some(Node::Pat(pat)) = hir.find(hir_id);
if matches!(pat.kind, PatKind::Binding(BindingAnnotation::NONE, ..));
- let parent = hir.get_parent_node(hir_id);
+ let parent = hir.parent_id(hir_id);
if let Some(Node::Local(local)) = hir.find(parent);
then {
return local.init;
@@ -196,7 +201,7 @@ pub fn in_constant(cx: &LateContext<'_>, id: HirId) -> bool {
let parent_id = cx.tcx.hir().get_parent_item(id).def_id;
match cx.tcx.hir().get_by_def_id(parent_id) {
Node::Item(&Item {
- kind: ItemKind::Const(..) | ItemKind::Static(..),
+ kind: ItemKind::Const(..) | ItemKind::Static(..) | ItemKind::Enum(..),
..
})
| Node::TraitItem(&TraitItem {
@@ -1253,22 +1258,33 @@ pub fn get_item_name(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<Symbol> {
}
}
-pub struct ContainsName {
+pub struct ContainsName<'a, 'tcx> {
+ pub cx: &'a LateContext<'tcx>,
pub name: Symbol,
pub result: bool,
}
-impl<'tcx> Visitor<'tcx> for ContainsName {
+impl<'a, 'tcx> Visitor<'tcx> for ContainsName<'a, 'tcx> {
+ type NestedFilter = nested_filter::OnlyBodies;
+
fn visit_name(&mut self, name: Symbol) {
if self.name == name {
self.result = true;
}
}
+
+ fn nested_visit_map(&mut self) -> Self::Map {
+ self.cx.tcx.hir()
+ }
}
/// Checks if an `Expr` contains a certain name.
-pub fn contains_name(name: Symbol, expr: &Expr<'_>) -> bool {
- let mut cn = ContainsName { name, result: false };
+pub fn contains_name<'tcx>(name: Symbol, expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) -> bool {
+ let mut cn = ContainsName {
+ name,
+ result: false,
+ cx,
+ };
cn.visit_expr(expr);
cn.result
}
@@ -1287,7 +1303,7 @@ pub fn contains_return(expr: &hir::Expr<'_>) -> bool {
/// Gets the parent node, if any.
pub fn get_parent_node(tcx: TyCtxt<'_>, id: HirId) -> Option<Node<'_>> {
- tcx.hir().parent_iter(id).next().map(|(_, node)| node)
+ tcx.hir().find_parent(id)
}
/// Gets the parent expression, if any –- this is useful to constrain a lint.
@@ -1304,6 +1320,7 @@ pub fn get_parent_expr_for_hir<'tcx>(cx: &LateContext<'tcx>, hir_id: hir::HirId)
}
}
+/// Gets the enclosing block, if any.
pub fn get_enclosing_block<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Block<'tcx>> {
let map = &cx.tcx.hir();
let enclosing_node = map
@@ -2075,7 +2092,7 @@ pub fn is_no_core_crate(cx: &LateContext<'_>) -> bool {
/// }
/// ```
pub fn is_trait_impl_item(cx: &LateContext<'_>, hir_id: HirId) -> bool {
- if let Some(Node::Item(item)) = cx.tcx.hir().find(cx.tcx.hir().get_parent_node(hir_id)) {
+ if let Some(Node::Item(item)) = cx.tcx.hir().find_parent(hir_id) {
matches!(item.kind, ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }))
} else {
false
@@ -2244,6 +2261,18 @@ pub fn peel_n_hir_expr_refs<'a>(expr: &'a Expr<'a>, count: usize) -> (&'a Expr<'
(e, count - remaining)
}
+/// Peels off all unary operators of an expression. Returns the underlying expression and the number
+/// of operators removed.
+pub fn peel_hir_expr_unary<'a>(expr: &'a Expr<'a>) -> (&'a Expr<'a>, usize) {
+ let mut count: usize = 0;
+ let mut curr_expr = expr;
+ while let ExprKind::Unary(_, local_expr) = curr_expr.kind {
+ count = count.wrapping_add(1);
+ curr_expr = local_expr;
+ }
+ (curr_expr, count)
+}
+
/// Peels off all references on the expression. Returns the underlying expression and the number of
/// references removed.
pub fn peel_hir_expr_refs<'a>(expr: &'a Expr<'a>) -> (&'a Expr<'a>, usize) {
@@ -2264,7 +2293,7 @@ pub fn peel_hir_ty_refs<'a>(mut ty: &'a hir::Ty<'a>) -> (&'a hir::Ty<'a>, usize)
let mut count = 0;
loop {
match &ty.kind {
- TyKind::Rptr(_, ref_ty) => {
+ TyKind::Ref(_, ref_ty) => {
ty = ref_ty.ty;
count += 1;
},
diff --git a/src/tools/clippy/clippy_utils/src/macros.rs b/src/tools/clippy/clippy_utils/src/macros.rs
index d13b34a66..77c5f1155 100644
--- a/src/tools/clippy/clippy_utils/src/macros.rs
+++ b/src/tools/clippy/clippy_utils/src/macros.rs
@@ -208,6 +208,12 @@ pub fn is_panic(cx: &LateContext<'_>, def_id: DefId) -> bool {
)
}
+/// Is `def_id` of `assert!` or `debug_assert!`
+pub fn is_assert_macro(cx: &LateContext<'_>, def_id: DefId) -> bool {
+ let Some(name) = cx.tcx.get_diagnostic_name(def_id) else { return false };
+ matches!(name, sym::assert_macro | sym::debug_assert_macro)
+}
+
pub enum PanicExpn<'a> {
/// No arguments - `panic!()`
Empty,
diff --git a/src/tools/clippy/clippy_utils/src/mir/maybe_storage_live.rs b/src/tools/clippy/clippy_utils/src/mir/maybe_storage_live.rs
deleted file mode 100644
index d262b335d..000000000
--- a/src/tools/clippy/clippy_utils/src/mir/maybe_storage_live.rs
+++ /dev/null
@@ -1,52 +0,0 @@
-use rustc_index::bit_set::BitSet;
-use rustc_middle::mir;
-use rustc_mir_dataflow::{AnalysisDomain, CallReturnPlaces, GenKill, GenKillAnalysis};
-
-/// Determines liveness of each local purely based on `StorageLive`/`Dead`.
-#[derive(Copy, Clone)]
-pub(super) struct MaybeStorageLive;
-
-impl<'tcx> AnalysisDomain<'tcx> for MaybeStorageLive {
- type Domain = BitSet<mir::Local>;
- const NAME: &'static str = "maybe_storage_live";
-
- fn bottom_value(&self, body: &mir::Body<'tcx>) -> Self::Domain {
- // bottom = dead
- BitSet::new_empty(body.local_decls.len())
- }
-
- fn initialize_start_block(&self, body: &mir::Body<'tcx>, state: &mut Self::Domain) {
- for arg in body.args_iter() {
- state.insert(arg);
- }
- }
-}
-
-impl<'tcx> GenKillAnalysis<'tcx> for MaybeStorageLive {
- type Idx = mir::Local;
-
- fn statement_effect(&self, trans: &mut impl GenKill<Self::Idx>, stmt: &mir::Statement<'tcx>, _: mir::Location) {
- match stmt.kind {
- mir::StatementKind::StorageLive(l) => trans.gen(l),
- mir::StatementKind::StorageDead(l) => trans.kill(l),
- _ => (),
- }
- }
-
- fn terminator_effect(
- &self,
- _trans: &mut impl GenKill<Self::Idx>,
- _terminator: &mir::Terminator<'tcx>,
- _loc: mir::Location,
- ) {
- }
-
- fn call_return_effect(
- &self,
- _trans: &mut impl GenKill<Self::Idx>,
- _block: mir::BasicBlock,
- _return_places: CallReturnPlaces<'_, 'tcx>,
- ) {
- // Nothing to do when a call returns successfully
- }
-}
diff --git a/src/tools/clippy/clippy_utils/src/mir/mod.rs b/src/tools/clippy/clippy_utils/src/mir/mod.rs
index 818e603f6..26c0015e8 100644
--- a/src/tools/clippy/clippy_utils/src/mir/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/mir/mod.rs
@@ -5,8 +5,6 @@ use rustc_middle::mir::{
};
use rustc_middle::ty::TyCtxt;
-mod maybe_storage_live;
-
mod possible_borrower;
pub use possible_borrower::PossibleBorrowerMap;
diff --git a/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs b/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs
index 25717bf3d..9adae7733 100644
--- a/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs
+++ b/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs
@@ -1,14 +1,12 @@
-use super::{
- maybe_storage_live::MaybeStorageLive, possible_origin::PossibleOriginVisitor,
- transitive_relation::TransitiveRelation,
-};
+use super::{possible_origin::PossibleOriginVisitor, transitive_relation::TransitiveRelation};
use crate::ty::is_copy;
use rustc_data_structures::fx::FxHashMap;
use rustc_index::bit_set::{BitSet, HybridBitSet};
use rustc_lint::LateContext;
use rustc_middle::mir::{self, visit::Visitor as _, Mutability};
use rustc_middle::ty::{self, visit::TypeVisitor};
-use rustc_mir_dataflow::{Analysis, ResultsCursor};
+use rustc_mir_dataflow::{impls::MaybeStorageLive, Analysis, ResultsCursor};
+use std::borrow::Cow;
use std::ops::ControlFlow;
/// Collects the possible borrowers of each local.
@@ -39,7 +37,7 @@ impl<'a, 'b, 'tcx> PossibleBorrowerVisitor<'a, 'b, 'tcx> {
fn into_map(
self,
cx: &'a LateContext<'tcx>,
- maybe_live: ResultsCursor<'b, 'tcx, MaybeStorageLive>,
+ maybe_live: ResultsCursor<'b, 'tcx, MaybeStorageLive<'tcx>>,
) -> PossibleBorrowerMap<'b, 'tcx> {
let mut map = FxHashMap::default();
for row in (1..self.body.local_decls.len()).map(mir::Local::from_usize) {
@@ -170,7 +168,7 @@ fn rvalue_locals(rvalue: &mir::Rvalue<'_>, mut visit: impl FnMut(mir::Local)) {
pub struct PossibleBorrowerMap<'b, 'tcx> {
/// Mapping `Local -> its possible borrowers`
pub map: FxHashMap<mir::Local, HybridBitSet<mir::Local>>,
- maybe_live: ResultsCursor<'b, 'tcx, MaybeStorageLive>,
+ maybe_live: ResultsCursor<'b, 'tcx, MaybeStorageLive<'tcx>>,
// Caches to avoid allocation of `BitSet` on every query
pub bitset: (BitSet<mir::Local>, BitSet<mir::Local>),
}
@@ -182,7 +180,7 @@ impl<'a, 'b, 'tcx> PossibleBorrowerMap<'b, 'tcx> {
vis.visit_body(mir);
vis.into_map(cx)
};
- let maybe_storage_live_result = MaybeStorageLive
+ let maybe_storage_live_result = MaybeStorageLive::new(Cow::Owned(BitSet::new_empty(mir.local_decls.len())))
.into_engine(cx.tcx, mir)
.pass_name("redundant_clone")
.iterate_to_fixpoint()
diff --git a/src/tools/clippy/clippy_utils/src/msrvs.rs b/src/tools/clippy/clippy_utils/src/msrvs.rs
index 12a512f78..dbf9f3b62 100644
--- a/src/tools/clippy/clippy_utils/src/msrvs.rs
+++ b/src/tools/clippy/clippy_utils/src/msrvs.rs
@@ -20,8 +20,9 @@ macro_rules! msrv_aliases {
// names may refer to stabilized feature flags or library items
msrv_aliases! {
1,65,0 { LET_ELSE }
- 1,62,0 { BOOL_THEN_SOME }
- 1,58,0 { FORMAT_ARGS_CAPTURE }
+ 1,62,0 { BOOL_THEN_SOME, DEFAULT_ENUM_ATTRIBUTE }
+ 1,58,0 { FORMAT_ARGS_CAPTURE, PATTERN_TRAIT_CHAR_ARRAY }
+ 1,55,0 { SEEK_REWIND }
1,53,0 { OR_PATTERNS, MANUAL_BITS, BTREE_MAP_RETAIN, BTREE_SET_RETAIN, ARRAY_INTO_ITERATOR }
1,52,0 { STR_SPLIT_ONCE, REM_EUCLID_CONST }
1,51,0 { BORROW_AS_PTR, SEEK_FROM_CURRENT, UNSIGNED_ABS }
@@ -45,7 +46,6 @@ msrv_aliases! {
1,18,0 { HASH_MAP_RETAIN, HASH_SET_RETAIN }
1,17,0 { FIELD_INIT_SHORTHAND, STATIC_IN_CONST, EXPECT_ERR }
1,16,0 { STR_REPEAT }
- 1,55,0 { SEEK_REWIND }
}
fn parse_msrv(msrv: &str, sess: Option<&Session>, span: Option<Span>) -> Option<RustcVersion> {
diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs
index 6417f0f3c..95eebab75 100644
--- a/src/tools/clippy/clippy_utils/src/paths.rs
+++ b/src/tools/clippy/clippy_utils/src/paths.rs
@@ -20,7 +20,6 @@ pub const BTREEMAP_CONTAINS_KEY: [&str; 6] = ["alloc", "collections", "btree", "
pub const BTREEMAP_INSERT: [&str; 6] = ["alloc", "collections", "btree", "map", "BTreeMap", "insert"];
pub const BTREESET_ITER: [&str; 6] = ["alloc", "collections", "btree", "set", "BTreeSet", "iter"];
pub const CLONE_TRAIT_METHOD: [&str; 4] = ["core", "clone", "Clone", "clone"];
-pub const CORE_ITER_COLLECT: [&str; 6] = ["core", "iter", "traits", "iterator", "Iterator", "collect"];
pub const CORE_ITER_CLONED: [&str; 6] = ["core", "iter", "traits", "iterator", "Iterator", "cloned"];
pub const CORE_ITER_COPIED: [&str; 6] = ["core", "iter", "traits", "iterator", "Iterator", "copied"];
pub const CORE_ITER_FILTER: [&str; 6] = ["core", "iter", "traits", "iterator", "Iterator", "filter"];
@@ -48,7 +47,6 @@ pub const IDENT: [&str; 3] = ["rustc_span", "symbol", "Ident"];
#[cfg(feature = "internal")]
pub const IDENT_AS_STR: [&str; 4] = ["rustc_span", "symbol", "Ident", "as_str"];
pub const INSERT_STR: [&str; 4] = ["alloc", "string", "String", "insert_str"];
-pub const ITER_COUNT: [&str; 6] = ["core", "iter", "traits", "iterator", "Iterator", "count"];
pub const ITER_EMPTY: [&str; 5] = ["core", "iter", "sources", "empty", "Empty"];
pub const ITERTOOLS_NEXT_TUPLE: [&str; 3] = ["itertools", "Itertools", "next_tuple"];
#[cfg(feature = "internal")]
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 480e8e55c..e5d7da682 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -82,7 +82,7 @@ fn check_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) -> McfResult {
ty::Ref(_, _, hir::Mutability::Mut) => {
return Err((span, "mutable references in const fn are unstable".into()));
},
- ty::Opaque(..) => return Err((span, "`impl Trait` in const fn is unstable".into())),
+ ty::Alias(ty::Opaque, ..) => return Err((span, "`impl Trait` in const fn is unstable".into())),
ty::FnPtr(..) => {
return Err((span, "function pointers in const fn are unstable".into()));
},
@@ -301,11 +301,7 @@ fn check_terminator<'tcx>(
check_operand(tcx, value, span, body)
},
- TerminatorKind::SwitchInt {
- discr,
- switch_ty: _,
- targets: _,
- } => check_operand(tcx, discr, span, body),
+ TerminatorKind::SwitchInt { discr, targets: _ } => check_operand(tcx, discr, span, body),
TerminatorKind::Abort => Err((span, "abort is not stable in const fn".into())),
TerminatorKind::GeneratorDrop | TerminatorKind::Yield { .. } => {
diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs
index b66604f33..e7879bb19 100644
--- a/src/tools/clippy/clippy_utils/src/sugg.rs
+++ b/src/tools/clippy/clippy_utils/src/sugg.rs
@@ -185,7 +185,6 @@ impl<'a> Sugg<'a> {
) -> Self {
use rustc_ast::ast::RangeLimits;
- #[expect(clippy::match_wildcard_for_single_variants)]
match expr.kind {
_ if expr.span.ctxt() != ctxt => Sugg::NonParen(snippet_with_context(cx, expr.span, ctxt, default, app).0),
ast::ExprKind::AddrOf(..)
@@ -813,9 +812,9 @@ pub fn deref_closure_args(cx: &LateContext<'_>, closure: &hir::Expr<'_>) -> Opti
let closure_body = cx.tcx.hir().body(body);
// is closure arg a type annotated double reference (i.e.: `|x: &&i32| ...`)
// a type annotation is present if param `kind` is different from `TyKind::Infer`
- let closure_arg_is_type_annotated_double_ref = if let TyKind::Rptr(_, MutTy { ty, .. }) = fn_decl.inputs[0].kind
+ let closure_arg_is_type_annotated_double_ref = if let TyKind::Ref(_, MutTy { ty, .. }) = fn_decl.inputs[0].kind
{
- matches!(ty.kind, TyKind::Rptr(_, MutTy { .. }))
+ matches!(ty.kind, TyKind::Ref(_, MutTy { .. }))
} else {
false
};
diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs
index 05c6eb7f2..99fba4fe7 100644
--- a/src/tools/clippy/clippy_utils/src/ty.rs
+++ b/src/tools/clippy/clippy_utils/src/ty.rs
@@ -16,8 +16,8 @@ use rustc_infer::infer::{
use rustc_lint::LateContext;
use rustc_middle::mir::interpret::{ConstValue, Scalar};
use rustc_middle::ty::{
- self, AdtDef, AssocKind, Binder, BoundRegion, DefIdTree, FnSig, IntTy, List, ParamEnv, Predicate, PredicateKind,
- ProjectionTy, Region, RegionKind, SubstsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, UintTy,
+ self, AdtDef, AliasTy, AssocKind, Binder, BoundRegion, DefIdTree, FnSig, IntTy, List, ParamEnv, Predicate,
+ PredicateKind, Region, RegionKind, SubstsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, UintTy,
VariantDef, VariantDiscr,
};
use rustc_middle::ty::{GenericArg, GenericArgKind};
@@ -30,7 +30,7 @@ use std::iter;
use crate::{match_def_path, path_res, paths};
-// Checks if the given type implements copy.
+/// Checks if the given type implements copy.
pub fn is_copy<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
ty.is_copy_modulo_regions(cx.tcx, cx.param_env)
}
@@ -85,7 +85,7 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'
return true;
}
- if let ty::Opaque(def_id, _) = *inner_ty.kind() {
+ if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *inner_ty.kind() {
if !seen.insert(def_id) {
return false;
}
@@ -266,7 +266,7 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
is_must_use_ty(cx, *ty)
},
ty::Tuple(substs) => substs.iter().any(|ty| is_must_use_ty(cx, ty)),
- ty::Opaque(def_id, _) => {
+ ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => {
for (predicate, _) in cx.tcx.explicit_item_bounds(*def_id) {
if let ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) = predicate.kind().skip_binder() {
if cx.tcx.has_attr(trait_predicate.trait_ref.def_id, sym::must_use) {
@@ -496,7 +496,7 @@ pub fn type_is_unsafe_function<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bo
/// Returns the base type for HIR references and pointers.
pub fn walk_ptrs_hir_ty<'tcx>(ty: &'tcx hir::Ty<'tcx>) -> &'tcx hir::Ty<'tcx> {
match ty.kind {
- TyKind::Ptr(ref mut_ty) | TyKind::Rptr(_, ref mut_ty) => walk_ptrs_hir_ty(mut_ty.ty),
+ TyKind::Ptr(ref mut_ty) | TyKind::Ref(_, ref mut_ty) => walk_ptrs_hir_ty(mut_ty.ty),
_ => ty,
}
}
@@ -647,7 +647,9 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'t
Some(ExprFnSig::Closure(decl, subs.as_closure().sig()))
},
ty::FnDef(id, subs) => Some(ExprFnSig::Sig(cx.tcx.bound_fn_sig(id).subst(cx.tcx, subs), Some(id))),
- ty::Opaque(id, _) => sig_from_bounds(cx, ty, cx.tcx.item_bounds(id), cx.tcx.opt_parent(id)),
+ ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
+ sig_from_bounds(cx, ty, cx.tcx.item_bounds(def_id).subst(cx.tcx, substs), cx.tcx.opt_parent(def_id))
+ },
ty::FnPtr(sig) => Some(ExprFnSig::Sig(sig, None)),
ty::Dynamic(bounds, _, _) => {
let lang_items = cx.tcx.lang_items();
@@ -666,7 +668,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'t
_ => None,
}
},
- ty::Projection(proj) => match cx.tcx.try_normalize_erasing_regions(cx.param_env, ty) {
+ ty::Alias(ty::Projection, proj) => match cx.tcx.try_normalize_erasing_regions(cx.param_env, ty) {
Ok(normalized_ty) if normalized_ty != ty => ty_sig(cx, normalized_ty),
_ => sig_for_projection(cx, proj).or_else(|| sig_from_bounds(cx, ty, cx.param_env.caller_bounds(), None)),
},
@@ -701,8 +703,7 @@ fn sig_from_bounds<'tcx>(
inputs = Some(i);
},
PredicateKind::Clause(ty::Clause::Projection(p))
- if Some(p.projection_ty.item_def_id) == lang_items.fn_once_output()
- && p.projection_ty.self_ty() == ty =>
+ if Some(p.projection_ty.def_id) == lang_items.fn_once_output() && p.projection_ty.self_ty() == ty =>
{
if output.is_some() {
// Multiple different fn trait impls. Is this even allowed?
@@ -717,14 +718,14 @@ fn sig_from_bounds<'tcx>(
inputs.map(|ty| ExprFnSig::Trait(ty, output, predicates_id))
}
-fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: ProjectionTy<'tcx>) -> Option<ExprFnSig<'tcx>> {
+fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: AliasTy<'tcx>) -> Option<ExprFnSig<'tcx>> {
let mut inputs = None;
let mut output = None;
let lang_items = cx.tcx.lang_items();
for (pred, _) in cx
.tcx
- .bound_explicit_item_bounds(ty.item_def_id)
+ .bound_explicit_item_bounds(ty.def_id)
.subst_iter_copied(cx.tcx, ty.substs)
{
match pred.kind().skip_binder() {
@@ -742,7 +743,7 @@ fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: ProjectionTy<'tcx>) -> O
inputs = Some(i);
},
PredicateKind::Clause(ty::Clause::Projection(p))
- if Some(p.projection_ty.item_def_id) == lang_items.fn_once_output() =>
+ if Some(p.projection_ty.def_id) == lang_items.fn_once_output() =>
{
if output.is_some() {
// Multiple different fn trait impls. Is this even allowed?
@@ -996,13 +997,13 @@ pub fn make_projection<'tcx>(
container_id: DefId,
assoc_ty: Symbol,
substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
-) -> Option<ProjectionTy<'tcx>> {
+) -> Option<AliasTy<'tcx>> {
fn helper<'tcx>(
tcx: TyCtxt<'tcx>,
container_id: DefId,
assoc_ty: Symbol,
substs: SubstsRef<'tcx>,
- ) -> Option<ProjectionTy<'tcx>> {
+ ) -> Option<AliasTy<'tcx>> {
let Some(assoc_item) = tcx
.associated_items(container_id)
.find_by_name_and_kind(tcx, Ident::with_dummy_span(assoc_ty), AssocKind::Type, container_id)
@@ -1055,10 +1056,7 @@ pub fn make_projection<'tcx>(
}
}
- Some(ProjectionTy {
- substs,
- item_def_id: assoc_item.def_id,
- })
+ Some(tcx.mk_alias_ty(assoc_item.def_id, substs))
}
helper(
tcx,
@@ -1081,7 +1079,7 @@ pub fn make_normalized_projection<'tcx>(
assoc_ty: Symbol,
substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
) -> Option<Ty<'tcx>> {
- fn helper<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: ProjectionTy<'tcx>) -> Option<Ty<'tcx>> {
+ fn helper<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: AliasTy<'tcx>) -> Option<Ty<'tcx>> {
#[cfg(debug_assertions)]
if let Some((i, subst)) = ty
.substs
@@ -1097,7 +1095,7 @@ pub fn make_normalized_projection<'tcx>(
);
return None;
}
- match tcx.try_normalize_erasing_regions(param_env, tcx.mk_projection(ty.item_def_id, ty.substs)) {
+ match tcx.try_normalize_erasing_regions(param_env, tcx.mk_projection(ty.def_id, ty.substs)) {
Ok(ty) => Some(ty),
Err(e) => {
debug_assert!(false, "failed to normalize type `{ty}`: {e:#?}");
diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs
index 863fb60fc..14c01a60b 100644
--- a/src/tools/clippy/clippy_utils/src/visitors.rs
+++ b/src/tools/clippy/clippy_utils/src/visitors.rs
@@ -724,3 +724,14 @@ pub fn for_each_local_assignment<'tcx, B>(
ControlFlow::Continue(())
}
}
+
+pub fn contains_break_or_continue(expr: &Expr<'_>) -> bool {
+ for_each_expr(expr, |e| {
+ if matches!(e.kind, ExprKind::Break(..) | ExprKind::Continue(..)) {
+ ControlFlow::Break(())
+ } else {
+ ControlFlow::Continue(())
+ }
+ })
+ .is_some()
+}