diff options
| author | Philipp Krones <hello@philkrones.com> | 2022-06-04 12:53:27 +0200 |
|---|---|---|
| committer | Philipp Krones <hello@philkrones.com> | 2022-06-04 12:53:27 +0200 |
| commit | 7f402b15c78d32b8a536960816fa4f1d7f75ac4a (patch) | |
| tree | 0080c24f0e524afd66958a148f29deb4d604de36 /clippy_utils | |
| parent | 57304823dbd1c246d1166e85c156e694d2f7a184 (diff) | |
| parent | 8ef490871c0cc0a3aff00976c6f00c7eab6d90c7 (diff) | |
Merge remote-tracking branch 'upstream/master' into rustup
Diffstat (limited to 'clippy_utils')
| -rw-r--r-- | clippy_utils/src/consts.rs | 2 | ||||
| -rw-r--r-- | clippy_utils/src/diagnostics.rs | 12 | ||||
| -rw-r--r-- | clippy_utils/src/higher.rs | 2 | ||||
| -rw-r--r-- | clippy_utils/src/hir_utils.rs | 6 | ||||
| -rw-r--r-- | clippy_utils/src/lib.rs | 19 | ||||
| -rw-r--r-- | clippy_utils/src/msrvs.rs | 1 | ||||
| -rw-r--r-- | clippy_utils/src/paths.rs | 2 | ||||
| -rw-r--r-- | clippy_utils/src/qualify_min_const_fn.rs | 21 | ||||
| -rw-r--r-- | clippy_utils/src/source.rs | 23 | ||||
| -rw-r--r-- | clippy_utils/src/ty.rs | 22 |
10 files changed, 73 insertions, 37 deletions
diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index 9f162a117b2..d487868cafe 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -478,7 +478,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { fn ifthenelse(&mut self, cond: &Expr<'_>, then: &Expr<'_>, otherwise: Option<&Expr<'_>>) -> Option<Constant> { if let Some(Constant::Bool(b)) = self.expr(cond) { if b { - self.expr(&*then) + self.expr(then) } else { otherwise.as_ref().and_then(|expr| self.expr(expr)) } diff --git a/clippy_utils/src/diagnostics.rs b/clippy_utils/src/diagnostics.rs index 39595f589c7..0f8e9ab0cd9 100644 --- a/clippy_utils/src/diagnostics.rs +++ b/clippy_utils/src/diagnostics.rs @@ -155,13 +155,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) { cx.tcx.struct_span_lint_hir(lint, hir_id, sp, |diag| { let mut diag = diag.build(msg); docs_link(&mut diag, lint); @@ -278,9 +272,7 @@ pub fn span_lint_and_sugg_for_edges( let sugg_lines_count = sugg.lines().count(); if sugg_lines_count > MAX_SUGGESTION_HIGHLIGHT_LINES { let sm = cx.sess().source_map(); - if let (Ok(line_upper), Ok(line_bottom)) = - (sm.lookup_line(sp.lo()), sm.lookup_line(sp.hi())) - { + if let (Ok(line_upper), Ok(line_bottom)) = (sm.lookup_line(sp.lo()), sm.lookup_line(sp.hi())) { let split_idx = MAX_SUGGESTION_HIGHLIGHT_LINES / 2; let span_upper = sm.span_until_char( sp.with_hi(line_upper.sf.lines(|lines| lines[line_upper.line + split_idx])), diff --git a/clippy_utils/src/higher.rs b/clippy_utils/src/higher.rs index 1e0fc789af2..4604ae5c2c7 100644 --- a/clippy_utils/src/higher.rs +++ b/clippy_utils/src/higher.rs @@ -35,7 +35,7 @@ impl<'tcx> ForLoop<'tcx> { if let hir::ExprKind::Match(iterexpr, [arm], hir::MatchSource::ForLoopDesugar) = e.kind; if let hir::ExprKind::Call(_, [arg]) = iterexpr.kind; if let hir::ExprKind::Loop(block, ..) = arm.body.kind; - if let [stmt] = &*block.stmts; + if let [stmt] = block.stmts; if let hir::StmtKind::Expr(e) = stmt.kind; if let hir::ExprKind::Match(_, [_, some_arm], _) = e.kind; if let hir::PatKind::Struct(_, [field], _) = some_arm.pat.kind; diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index fc1a4e1f602..0603471c343 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -411,10 +411,10 @@ 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(ref l_mut), &TyKind::Ptr(ref r_mut)) => { - l_mut.mutbl == r_mut.mutbl && self.eq_ty(&*l_mut.ty, &*r_mut.ty) + l_mut.mutbl == r_mut.mutbl && self.eq_ty(l_mut.ty, r_mut.ty) }, (&TyKind::Rptr(_, ref l_rmut), &TyKind::Rptr(_, ref r_rmut)) => { - l_rmut.mutbl == r_rmut.mutbl && self.eq_ty(&*l_rmut.ty, &*r_rmut.ty) + l_rmut.mutbl == r_rmut.mutbl && self.eq_ty(l_rmut.ty, r_rmut.ty) }, (&TyKind::Path(ref l), &TyKind::Path(ref r)) => self.eq_qpath(l, r), (&TyKind::Tup(l), &TyKind::Tup(r)) => over(l, r, |l, r| self.eq_ty(l, r)), @@ -608,7 +608,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_name(i.ident.name); } if let Some(j) = *j { - self.hash_expr(&*j); + self.hash_expr(j); } }, ExprKind::Box(e) | ExprKind::DropTemps(e) | ExprKind::Yield(e, _) => { diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 833f8cde63a..5f051e3f444 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -1443,7 +1443,7 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool { }, PatKind::Tuple(pats, _) => are_refutable(cx, pats), PatKind::Struct(ref qpath, fields, _) => { - is_enum_variant(cx, qpath, pat.hir_id) || are_refutable(cx, fields.iter().map(|field| &*field.pat)) + is_enum_variant(cx, qpath, pat.hir_id) || are_refutable(cx, fields.iter().map(|field| field.pat)) }, PatKind::TupleStruct(ref qpath, pats, _) => is_enum_variant(cx, qpath, pat.hir_id) || are_refutable(cx, pats), PatKind::Slice(head, middle, tail) => { @@ -1658,7 +1658,7 @@ pub fn if_sequence<'tcx>(mut expr: &'tcx Expr<'tcx>) -> (Vec<&'tcx Expr<'tcx>>, let mut blocks: Vec<&Block<'_>> = Vec::new(); while let Some(higher::IfOrIfLet { cond, then, r#else }) = higher::IfOrIfLet::hir(expr) { - conds.push(&*cond); + conds.push(cond); if let ExprKind::Block(block, _) = then.kind { blocks.push(block); } else { @@ -1916,7 +1916,17 @@ pub fn fn_def_id(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<DefId> { .. }, .., - ) => cx.typeck_results().qpath_res(qpath, *path_hir_id).opt_def_id(), + ) => { + // Only return Fn-like DefIds, not the DefIds of statics/consts/etc that contain or + // deref to fn pointers, dyn Fn, impl Fn - #8850 + if let Res::Def(DefKind::Fn | DefKind::Ctor(..) | DefKind::AssocFn, id) = + cx.typeck_results().qpath_res(qpath, *path_hir_id) + { + Some(id) + } else { + None + } + }, _ => None, } } @@ -2073,7 +2083,8 @@ static TEST_ITEM_NAMES_CACHE: SyncOnceCell<Mutex<FxHashMap<LocalDefId, Vec<Symbo fn with_test_item_names<'tcx>(tcx: TyCtxt<'tcx>, module: LocalDefId, f: impl Fn(&[Symbol]) -> bool) -> bool { let cache = TEST_ITEM_NAMES_CACHE.get_or_init(|| Mutex::new(FxHashMap::default())); let mut map: MutexGuard<'_, FxHashMap<LocalDefId, Vec<Symbol>>> = cache.lock().unwrap(); - match map.entry(module) { + let value = map.entry(module); + match value { Entry::Occupied(entry) => f(entry.get()), Entry::Vacant(entry) => { let mut names = Vec::new(); diff --git a/clippy_utils/src/msrvs.rs b/clippy_utils/src/msrvs.rs index 134fd1ce505..b9ec2c19fdd 100644 --- a/clippy_utils/src/msrvs.rs +++ b/clippy_utils/src/msrvs.rs @@ -30,6 +30,7 @@ msrv_aliases! { 1,34,0 { TRY_FROM } 1,30,0 { ITERATOR_FIND_MAP, TOOL_ATTRIBUTES } 1,28,0 { FROM_BOOL } + 1,26,0 { RANGE_INCLUSIVE } 1,17,0 { FIELD_INIT_SHORTHAND, STATIC_IN_CONST, EXPECT_ERR } 1,16,0 { STR_REPEAT } 1,24,0 { IS_ASCII_DIGIT } diff --git a/clippy_utils/src/paths.rs b/clippy_utils/src/paths.rs index 9b9cbff2d14..89789c3d851 100644 --- a/clippy_utils/src/paths.rs +++ b/clippy_utils/src/paths.rs @@ -73,6 +73,7 @@ pub const LATE_CONTEXT: [&str; 2] = ["rustc_lint", "LateContext"]; pub const LATE_LINT_PASS: [&str; 3] = ["rustc_lint", "passes", "LateLintPass"]; #[cfg(feature = "internal")] pub const LINT: [&str; 2] = ["rustc_lint_defs", "Lint"]; +pub const MEM_SWAP: [&str; 3] = ["core", "mem", "swap"]; pub const MUTEX_GUARD: [&str; 4] = ["std", "sync", "mutex", "MutexGuard"]; pub const OPEN_OPTIONS: [&str; 3] = ["std", "fs", "OpenOptions"]; /// Preferably use the diagnostic item `sym::Option` where possible @@ -141,6 +142,7 @@ pub const SERDE_DESERIALIZE: [&str; 3] = ["serde", "de", "Deserialize"]; pub const SERDE_DE_VISITOR: [&str; 3] = ["serde", "de", "Visitor"]; pub const SLICE_FROM_RAW_PARTS: [&str; 4] = ["core", "slice", "raw", "from_raw_parts"]; pub const SLICE_FROM_RAW_PARTS_MUT: [&str; 4] = ["core", "slice", "raw", "from_raw_parts_mut"]; +pub const SLICE_GET: [&str; 4] = ["core", "slice", "<impl [T]>", "get"]; pub const SLICE_INTO_VEC: [&str; 4] = ["alloc", "slice", "<impl [T]>", "into_vec"]; pub const SLICE_ITER: [&str; 4] = ["core", "slice", "iter", "Iter"]; pub const STDERR: [&str; 4] = ["std", "io", "stdio", "stderr"]; diff --git a/clippy_utils/src/qualify_min_const_fn.rs b/clippy_utils/src/qualify_min_const_fn.rs index 58abef38ea8..498dcbb8900 100644 --- a/clippy_utils/src/qualify_min_const_fn.rs +++ b/clippy_utils/src/qualify_min_const_fn.rs @@ -121,24 +121,18 @@ fn check_rvalue<'tcx>( ) -> McfResult { match rvalue { Rvalue::ThreadLocalRef(_) => Err((span, "cannot access thread local storage in const fn".into())), - Rvalue::Repeat(operand, _) | Rvalue::Use(operand) => check_operand(tcx, operand, span, body), Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => { check_place(tcx, *place, span, body) }, - Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => { - Err((span, "casting pointers to ints is unstable in const fn".into())) - }, - Rvalue::Cast(CastKind::Misc, operand, _) => { - check_operand(tcx, operand, span, body) - }, - Rvalue::Cast( + Rvalue::Repeat(operand, _) + | Rvalue::Use(operand) + | Rvalue::Cast( CastKind::PointerFromExposedAddress + | CastKind::Misc | CastKind::Pointer(PointerCast::MutToConstPointer | PointerCast::ArrayToPointer), operand, - _ - ) => { - check_operand(tcx, operand, span, body) - }, + _, + ) => check_operand(tcx, operand, span, body), Rvalue::Cast( CastKind::Pointer( PointerCast::UnsafeFnPointer | PointerCast::ClosureFnPointer(_) | PointerCast::ReifyFnPointer, @@ -163,6 +157,9 @@ fn check_rvalue<'tcx>( Err((span, "unsizing casts are not allowed in const fn".into())) } }, + Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => { + Err((span, "casting pointers to ints is unstable in const fn".into())) + }, // binops are fine on integers Rvalue::BinaryOp(_, box (lhs, rhs)) | Rvalue::CheckedBinaryOp(_, box (lhs, rhs)) => { check_operand(tcx, lhs, span, body)?; diff --git a/clippy_utils/src/source.rs b/clippy_utils/src/source.rs index 04ef2f57447..f88a92fb11c 100644 --- a/clippy_utils/src/source.rs +++ b/clippy_utils/src/source.rs @@ -8,7 +8,7 @@ use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LintContext}; use rustc_span::hygiene; use rustc_span::source_map::SourceMap; -use rustc_span::{BytePos, Pos, Span, SyntaxContext}; +use rustc_span::{BytePos, Pos, Span, SpanData, SyntaxContext}; use std::borrow::Cow; /// Checks if the span starts with the given text. This will return false if the span crosses @@ -389,6 +389,27 @@ pub fn without_block_comments(lines: Vec<&str>) -> Vec<&str> { without } +/// Trims the whitespace from the start and the end of the span. +pub fn trim_span(sm: &SourceMap, span: Span) -> Span { + let data = span.data(); + let sf: &_ = &sm.lookup_source_file(data.lo); + let Some(src) = sf.src.as_deref() else { + return span; + }; + let Some(snip) = &src.get((data.lo - sf.start_pos).to_usize()..(data.hi - sf.start_pos).to_usize()) else { + return span; + }; + let trim_start = snip.len() - snip.trim_start().len(); + let trim_end = snip.len() - snip.trim_end().len(); + SpanData { + lo: data.lo + BytePos::from_usize(trim_start), + hi: data.hi - BytePos::from_usize(trim_end), + ctxt: data.ctxt, + parent: data.parent, + } + .span() +} + #[cfg(test)] mod test { use super::{reindent_multiline, without_block_comments}; diff --git a/clippy_utils/src/ty.rs b/clippy_utils/src/ty.rs index 75d27d3b594..a10515d2fec 100644 --- a/clippy_utils/src/ty.rs +++ b/clippy_utils/src/ty.rs @@ -13,7 +13,8 @@ use rustc_lint::LateContext; use rustc_middle::mir::interpret::{ConstValue, Scalar}; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst}; use rustc_middle::ty::{ - self, AdtDef, Binder, FnSig, IntTy, Predicate, PredicateKind, Ty, TyCtxt, TypeFoldable, UintTy, VariantDiscr, + self, AdtDef, Binder, FnSig, IntTy, ParamEnv, Predicate, PredicateKind, Ty, TyCtxt, TypeFoldable, UintTy, + VariantDiscr, }; use rustc_span::symbol::Ident; use rustc_span::{sym, Span, Symbol, DUMMY_SP}; @@ -152,17 +153,28 @@ pub fn implements_trait<'tcx>( trait_id: DefId, ty_params: &[GenericArg<'tcx>], ) -> bool { + implements_trait_with_env(cx.tcx, cx.param_env, ty, trait_id, ty_params) +} + +/// Same as `implements_trait` but allows using a `ParamEnv` different from the lint context. +pub fn implements_trait_with_env<'tcx>( + tcx: TyCtxt<'tcx>, + param_env: ParamEnv<'tcx>, + ty: Ty<'tcx>, + trait_id: DefId, + ty_params: &[GenericArg<'tcx>], +) -> bool { // Clippy shouldn't have infer types assert!(!ty.needs_infer()); - let ty = cx.tcx.erase_regions(ty); + let ty = tcx.erase_regions(ty); if ty.has_escaping_bound_vars() { return false; } - let ty_params = cx.tcx.mk_substs(ty_params.iter()); - cx.tcx.infer_ctxt().enter(|infcx| { + let ty_params = tcx.mk_substs(ty_params.iter()); + tcx.infer_ctxt().enter(|infcx| { infcx - .type_implements_trait(trait_id, ty, ty_params, cx.param_env) + .type_implements_trait(trait_id, ty, ty_params, param_env) .must_apply_modulo_regions() }) } |
