Merge commit 'd5e2a7aca5' into clippyup
This commit is contained in:
parent
58eb9964cc
commit
8df896c076
184 changed files with 3000 additions and 1635 deletions
|
|
@ -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)]`
|
||||
|
|
|
|||
|
|
@ -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(_)
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
|
|
|||
|
|
@ -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"];
|
||||
|
|
|
|||
|
|
@ -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)?;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue