Merge commit 'd5e2a7aca5' into clippyup

This commit is contained in:
Philipp Krones 2023-03-24 14:04:35 +01:00
parent 58eb9964cc
commit 8df896c076
184 changed files with 3000 additions and 1635 deletions

View file

@ -146,7 +146,7 @@ pub fn get_unique_attr<'a>(
/// Return true if the attributes contain any of `proc_macro`,
/// `proc_macro_derive` or `proc_macro_attribute`, false otherwise
pub fn is_proc_macro(attrs: &[ast::Attribute]) -> bool {
attrs.iter().any(|attr| attr.is_proc_macro_attr())
attrs.iter().any(rustc_ast::Attribute::is_proc_macro_attr)
}
/// Return true if the attributes contain `#[doc(hidden)]`

View file

@ -199,10 +199,9 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS
},
// Memory allocation, custom operator, loop, or call to an unknown function
ExprKind::Unary(..)
| ExprKind::Binary(..)
| ExprKind::Loop(..)
| ExprKind::Call(..) => self.eagerness = Lazy,
ExprKind::Unary(..) | ExprKind::Binary(..) | ExprKind::Loop(..) | ExprKind::Call(..) => {
self.eagerness = Lazy;
},
ExprKind::ConstBlock(_)
| ExprKind::Array(_)

View file

@ -19,6 +19,7 @@ macro_rules! msrv_aliases {
// names may refer to stabilized feature flags or library items
msrv_aliases! {
1,68,0 { PATH_MAIN_SEPARATOR_STR }
1,65,0 { LET_ELSE }
1,62,0 { BOOL_THEN_SOME, DEFAULT_ENUM_ATTRIBUTE }
1,58,0 { FORMAT_ARGS_CAPTURE, PATTERN_TRAIT_CHAR_ARRAY }

View file

@ -67,6 +67,7 @@ pub const PARKING_LOT_MUTEX_GUARD: [&str; 3] = ["lock_api", "mutex", "MutexGuard
pub const PARKING_LOT_RWLOCK_READ_GUARD: [&str; 3] = ["lock_api", "rwlock", "RwLockReadGuard"];
pub const PARKING_LOT_RWLOCK_WRITE_GUARD: [&str; 3] = ["lock_api", "rwlock", "RwLockWriteGuard"];
pub const PATH_BUF_AS_PATH: [&str; 4] = ["std", "path", "PathBuf", "as_path"];
pub const PATH_MAIN_SEPARATOR: [&str; 3] = ["std", "path", "MAIN_SEPARATOR"];
pub const PATH_TO_PATH_BUF: [&str; 4] = ["std", "path", "Path", "to_path_buf"];
pub const PEEKABLE: [&str; 5] = ["core", "iter", "adapters", "peekable", "Peekable"];
pub const PERMISSIONS: [&str; 3] = ["std", "fs", "Permissions"];

View file

@ -176,9 +176,10 @@ fn check_rvalue<'tcx>(
// FIXME(dyn-star)
unimplemented!()
},
Rvalue::Cast(CastKind::Transmute, _, _) => {
Err((span, "transmute can attempt to turn pointers into integers, so is unstable in const fn".into()))
},
Rvalue::Cast(CastKind::Transmute, _, _) => Err((
span,
"transmute can attempt to turn pointers into integers, so 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)?;

View file

@ -12,24 +12,21 @@ use rustc_span::{BytePos, Pos, Span, SpanData, SyntaxContext, DUMMY_SP};
use std::borrow::Cow;
/// Like `snippet_block`, but add braces if the expr is not an `ExprKind::Block`.
/// Also takes an `Option<String>` which can be put inside the braces.
pub fn expr_block<'a, T: LintContext>(
pub fn expr_block<T: LintContext>(
cx: &T,
expr: &Expr<'_>,
option: Option<String>,
default: &'a str,
outer: SyntaxContext,
default: &str,
indent_relative_to: Option<Span>,
) -> Cow<'a, str> {
let code = snippet_block(cx, expr.span, default, indent_relative_to);
let string = option.unwrap_or_default();
if expr.span.from_expansion() {
Cow::Owned(format!("{{ {} }}", snippet_with_macro_callsite(cx, expr.span, default)))
app: &mut Applicability,
) -> String {
let (code, from_macro) = snippet_block_with_context(cx, expr.span, outer, default, indent_relative_to, app);
if from_macro {
format!("{{ {code} }}")
} else if let ExprKind::Block(_, _) = expr.kind {
Cow::Owned(format!("{code}{string}"))
} else if string.is_empty() {
Cow::Owned(format!("{{ {code} }}"))
format!("{code}")
} else {
Cow::Owned(format!("{{\n{code};\n{string}\n}}"))
format!("{{ {code} }}")
}
}
@ -229,12 +226,6 @@ fn snippet_with_applicability_sess<'a>(
)
}
/// Same as `snippet`, but should only be used when it's clear that the input span is
/// not a macro argument.
pub fn snippet_with_macro_callsite<'a, T: LintContext>(cx: &T, span: Span, default: &'a str) -> Cow<'a, str> {
snippet(cx, span.source_callsite(), default)
}
/// Converts a span to a code snippet. Returns `None` if not available.
pub fn snippet_opt(cx: &impl LintContext, span: Span) -> Option<String> {
snippet_opt_sess(cx.sess(), span)
@ -303,6 +294,19 @@ pub fn snippet_block_with_applicability<'a>(
reindent_multiline(snip, true, indent)
}
pub fn snippet_block_with_context<'a>(
cx: &impl LintContext,
span: Span,
outer: SyntaxContext,
default: &'a str,
indent_relative_to: Option<Span>,
app: &mut Applicability,
) -> (Cow<'a, str>, bool) {
let (snip, from_macro) = snippet_with_context(cx, span, outer, default, app);
let indent = indent_relative_to.and_then(|s| indent_of(cx, s));
(reindent_multiline(snip, true, indent), from_macro)
}
/// Same as `snippet_with_applicability`, but first walks the span up to the given context. This
/// will result in the macro call, rather then the expansion, if the span is from a child context.
/// If the span is not from a child context, it will be used directly instead.

View file

@ -1,9 +1,7 @@
//! Contains utility functions to generate suggestions.
#![deny(clippy::missing_docs_in_private_items)]
use crate::source::{
snippet, snippet_opt, snippet_with_applicability, snippet_with_context, snippet_with_macro_callsite,
};
use crate::source::{snippet, snippet_opt, snippet_with_applicability, snippet_with_context};
use crate::ty::expr_sig;
use crate::{get_parent_expr_for_hir, higher};
use rustc_ast::util::parser::AssocOp;
@ -89,12 +87,6 @@ impl<'a> Sugg<'a> {
})
}
/// Same as `hir`, but will use the pre expansion span if the `expr` was in a macro.
pub fn hir_with_macro_callsite(cx: &LateContext<'_>, expr: &hir::Expr<'_>, default: &'a str) -> Self {
let get_snippet = |span| snippet_with_macro_callsite(cx, span, default);
Self::hir_from_snippet(expr, get_snippet)
}
/// Same as `hir`, but first walks the span up to the given context. This will result in the
/// macro call, rather then the expansion, if the span is from a child context. If the span is
/// not from a child context, it will be used directly instead.

View file

@ -16,9 +16,9 @@ use rustc_infer::infer::{
use rustc_lint::LateContext;
use rustc_middle::mir::interpret::{ConstValue, Scalar};
use rustc_middle::ty::{
self, AdtDef, AliasTy, AssocKind, Binder, BoundRegion, FnSig, IntTy, List, ParamEnv, Predicate, PredicateKind,
Region, RegionKind, SubstsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
UintTy, VariantDef, VariantDiscr,
self, layout::ValidityRequirement, AdtDef, AliasTy, AssocKind, Binder, BoundRegion, FnSig, IntTy, List, ParamEnv,
Predicate, PredicateKind, Region, RegionKind, SubstsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
TypeVisitableExt, TypeVisitor, UintTy, VariantDef, VariantDiscr,
};
use rustc_middle::ty::{GenericArg, GenericArgKind};
use rustc_span::symbol::Ident;
@ -538,13 +538,12 @@ pub fn same_type_and_consts<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
}
/// Checks if a given type looks safe to be uninitialized.
pub fn is_uninit_value_valid_for_ty(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
match *ty.kind() {
ty::Array(component, _) => is_uninit_value_valid_for_ty(cx, component),
ty::Tuple(types) => types.iter().all(|ty| is_uninit_value_valid_for_ty(cx, ty)),
ty::Adt(adt, _) => cx.tcx.lang_items().maybe_uninit() == Some(adt.did()),
_ => false,
}
pub fn is_uninit_value_valid_for_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
cx.tcx
.check_validity_requirement((ValidityRequirement::Uninit, cx.param_env.and(ty)))
// For types containing generic parameters we cannot get a layout to check.
// Therefore, we are conservative and assume that they don't allow uninit.
.unwrap_or(false)
}
/// Gets an iterator over all predicates which apply to the given item.
@ -1121,3 +1120,47 @@ pub fn make_normalized_projection<'tcx>(
}
helper(tcx, param_env, make_projection(tcx, container_id, assoc_ty, substs)?)
}
/// Check if given type has inner mutability such as [`std::cell::Cell`] or [`std::cell::RefCell`]
/// etc.
pub fn is_interior_mut_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
match *ty.kind() {
ty::Ref(_, inner_ty, mutbl) => mutbl == Mutability::Mut || is_interior_mut_ty(cx, inner_ty),
ty::Slice(inner_ty) => is_interior_mut_ty(cx, inner_ty),
ty::Array(inner_ty, size) => {
size.try_eval_target_usize(cx.tcx, cx.param_env)
.map_or(true, |u| u != 0)
&& is_interior_mut_ty(cx, inner_ty)
},
ty::Tuple(fields) => fields.iter().any(|ty| is_interior_mut_ty(cx, ty)),
ty::Adt(def, substs) => {
// Special case for collections in `std` who's impl of `Hash` or `Ord` delegates to
// that of their type parameters. Note: we don't include `HashSet` and `HashMap`
// because they have no impl for `Hash` or `Ord`.
let def_id = def.did();
let is_std_collection = [
sym::Option,
sym::Result,
sym::LinkedList,
sym::Vec,
sym::VecDeque,
sym::BTreeMap,
sym::BTreeSet,
sym::Rc,
sym::Arc,
]
.iter()
.any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def_id));
let is_box = Some(def_id) == cx.tcx.lang_items().owned_box();
if is_std_collection || is_box {
// The type is mutable if any of its type parameters are
substs.types().any(|ty| is_interior_mut_ty(cx, ty))
} else {
!ty.has_escaping_bound_vars()
&& cx.tcx.layout_of(cx.param_env.and(ty)).is_ok()
&& !ty.is_freeze(cx.tcx, cx.param_env)
}
},
_ => false,
}
}

View file

@ -599,9 +599,7 @@ pub fn for_each_unconsumed_temporary<'tcx, B>(
| ExprKind::Let(&Let { init: e, .. }) => {
helper(typeck, false, e, f)?;
},
ExprKind::Block(&Block { expr: Some(e), .. }, _)
| ExprKind::Cast(e, _)
| ExprKind::Unary(_, e) => {
ExprKind::Block(&Block { expr: Some(e), .. }, _) | ExprKind::Cast(e, _) | ExprKind::Unary(_, e) => {
helper(typeck, true, e, f)?;
},
ExprKind::Call(callee, args) => {