Auto merge of #11157 - flip1995:rustup, r=flip1995

Rustup

r? `@ghost`

changelog: none
This commit is contained in:
bors 2023-07-14 11:37:23 +00:00
commit 1d33469658
92 changed files with 519 additions and 490 deletions

View File

@ -1,6 +1,6 @@
[package]
name = "clippy"
version = "0.1.72"
version = "0.1.73"
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
repository = "https://github.com/rust-lang/rust-clippy"
readme = "README.md"

View File

@ -37,7 +37,7 @@ const fn new(name: &'static str, cargo_file: &'static str, lib_rs_file: &'static
pub fn setup_rustc_src(rustc_path: &str) {
let Ok(rustc_source_dir) = check_and_get_rustc_dir(rustc_path) else {
return
return;
};
for project in CLIPPY_PROJECTS {

View File

@ -340,7 +340,10 @@ fn finish(
let name_upper = name.to_uppercase();
let (mut lints, deprecated_lints, renamed_lints) = gather_all();
let Some(lint) = lints.iter().find(|l| l.name == name_lower) else { eprintln!("error: failed to find lint `{name}`"); return; };
let Some(lint) = lints.iter().find(|l| l.name == name_lower) else {
eprintln!("error: failed to find lint `{name}`");
return;
};
let mod_path = {
let mut mod_path = PathBuf::from(format!("clippy_lints/src/{}", lint.module));

View File

@ -1,6 +1,6 @@
[package]
name = "clippy_lints"
version = "0.1.72"
version = "0.1.73"
description = "A bunch of helpful lints to avoid common pitfalls in Rust"
repository = "https://github.com/rust-lang/rust-clippy"
readme = "README.md"

View File

@ -31,14 +31,20 @@
impl<'tcx> LateLintPass<'tcx> for AssertionsOnConstants {
fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
let Some(macro_call) = root_macro_call_first_node(cx, e) else { return };
let Some(macro_call) = root_macro_call_first_node(cx, e) else {
return;
};
let is_debug = match cx.tcx.get_diagnostic_name(macro_call.def_id) {
Some(sym::debug_assert_macro) => true,
Some(sym::assert_macro) => false,
_ => return,
};
let Some((condition, panic_expn)) = find_assert_args(cx, e, macro_call.expn) else { return };
let Some(Constant::Bool(val)) = constant(cx, cx.typeck_results(), condition) else { return };
let Some((condition, panic_expn)) = find_assert_args(cx, e, macro_call.expn) else {
return;
};
let Some(Constant::Bool(val)) = constant(cx, cx.typeck_results(), condition) else {
return;
};
if val {
span_lint_and_help(
cx,

View File

@ -61,7 +61,7 @@ fn is_impl_not_trait_with_bool_out<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -
)
})
.map_or(false, |assoc_item| {
let proj = cx.tcx.mk_projection(assoc_item.def_id, cx.tcx.mk_substs_trait(ty, []));
let proj = Ty::new_projection(cx.tcx, assoc_item.def_id, cx.tcx.mk_substs_trait(ty, []));
let nty = cx.tcx.normalize_erasing_regions(cx.param_env, proj);
nty.is_bool()
@ -70,14 +70,18 @@ fn is_impl_not_trait_with_bool_out<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -
impl<'tcx> LateLintPass<'tcx> for BoolAssertComparison {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
let Some(macro_call) = root_macro_call_first_node(cx, expr) else { return };
let Some(macro_call) = root_macro_call_first_node(cx, expr) else {
return;
};
let macro_name = cx.tcx.item_name(macro_call.def_id);
let eq_macro = match macro_name.as_str() {
"assert_eq" | "debug_assert_eq" => true,
"assert_ne" | "debug_assert_ne" => false,
_ => return,
};
let Some ((a, b, _)) = find_assert_eq_args(cx, expr, macro_call.expn) else { return };
let Some((a, b, _)) = find_assert_eq_args(cx, expr, macro_call.expn) else {
return;
};
let a_span = a.span.source_callsite();
let b_span = b.span.source_callsite();
@ -126,7 +130,9 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
let mut suggestions = vec![(name_span, non_eq_mac.to_string()), (lit_span, String::new())];
if bool_value ^ eq_macro {
let Some(sugg) = Sugg::hir_opt(cx, non_lit_expr) else { return };
let Some(sugg) = Sugg::hir_opt(cx, non_lit_expr) else {
return;
};
suggestions.push((non_lit_expr.span, (!sugg).to_string()));
}

View File

@ -71,7 +71,9 @@ pub fn new(allow_dbg_in_tests: bool) -> Self {
impl LateLintPass<'_> for DbgMacro {
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
let Some(macro_call) = root_macro_call_first_node(cx, expr) else { return };
let Some(macro_call) = root_macro_call_first_node(cx, expr) else {
return;
};
if cx.tcx.is_diagnostic_item(sym::dbg_macro, macro_call.def_id) {
// allows `dbg!` in test code if allow-dbg-in-test is set to true in clippy.toml
if self.allow_dbg_in_tests

View File

@ -171,7 +171,6 @@
crate::float_literal::LOSSY_FLOAT_LITERAL_INFO,
crate::floating_point_arithmetic::IMPRECISE_FLOPS_INFO,
crate::floating_point_arithmetic::SUBOPTIMAL_FLOPS_INFO,
crate::fn_null_check::FN_NULL_CHECK_INFO,
crate::format::USELESS_FORMAT_INFO,
crate::format_args::FORMAT_IN_FORMAT_ARGS_INFO,
crate::format_args::TO_STRING_IN_FORMAT_ARGS_INFO,

View File

@ -1129,7 +1129,9 @@ fn needless_borrow_impl_arg_position<'tcx>(
let destruct_trait_def_id = cx.tcx.lang_items().destruct_trait();
let sized_trait_def_id = cx.tcx.lang_items().sized_trait();
let Some(callee_def_id) = fn_def_id(cx, parent) else { return Position::Other(precedence) };
let Some(callee_def_id) = fn_def_id(cx, parent) else {
return Position::Other(precedence);
};
let fn_sig = cx.tcx.fn_sig(callee_def_id).subst_identity().skip_binder();
let substs_with_expr_ty = cx
.typeck_results()

View File

@ -8,7 +8,7 @@
self as hir, Body, Expr, ExprKind, GenericArg, Impl, ImplItemKind, Item, ItemKind, Node, PathSegment, QPath, TyKind,
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::adjustment::{Adjust, PointerCast};
use rustc_middle::ty::adjustment::{Adjust, PointerCoercion};
use rustc_middle::ty::{self, Adt, AdtDef, SubstsRef, Ty, TypeckResults};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::sym;
@ -115,7 +115,7 @@ fn check_struct<'tcx>(
let is_default_without_adjusts = |expr| {
is_default_equivalent(cx, expr)
&& typeck_results.expr_adjustments(expr).iter().all(|adj| {
!matches!(adj.kind, Adjust::Pointer(PointerCast::Unsize)
!matches!(adj.kind, Adjust::Pointer(PointerCoercion::Unsize)
if contains_trait_object(adj.target))
})
};

View File

@ -333,7 +333,9 @@ fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &h
Some(id) if trait_ref.trait_def_id() == Some(id) => id,
_ => return,
};
let Some(copy_id) = cx.tcx.lang_items().copy_trait() else { return };
let Some(copy_id) = cx.tcx.lang_items().copy_trait() else {
return;
};
let (ty_adt, ty_subs) = match *ty.kind() {
// Unions can't derive clone.
ty::Adt(adt, subs) if !adt.is_union() => (adt, subs),
@ -344,9 +346,9 @@ fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &h
if !is_copy(cx, ty) {
if ty_subs.non_erasable_generics().next().is_some() {
let has_copy_impl = cx.tcx.all_local_trait_impls(()).get(&copy_id).map_or(false, |impls| {
impls
.iter()
.any(|&id| matches!(cx.tcx.type_of(id).subst_identity().kind(), ty::Adt(adt, _) if ty_adt.did() == adt.did()))
impls.iter().any(|&id| {
matches!(cx.tcx.type_of(id).subst_identity().kind(), ty::Adt(adt, _) if ty_adt.did() == adt.did())
})
});
if !has_copy_impl {
return;

View File

@ -94,7 +94,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
path_def_id(cx, expr)
};
let Some(def_id) = uncalled_path.or_else(|| fn_def_id(cx, expr)) else {
return
return;
};
let conf = match self.disallowed.get(&def_id) {
Some(&index) => &self.conf_disallowed[index],

View File

@ -294,7 +294,9 @@ fn check_crate(&mut self, cx: &LateContext<'tcx>) {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
let attrs = cx.tcx.hir().attrs(item.hir_id());
let Some(headers) = check_attrs(cx, &self.valid_idents, attrs) else { return };
let Some(headers) = check_attrs(cx, &self.valid_idents, attrs) else {
return;
};
match item.kind {
hir::ItemKind::Fn(ref sig, _, body_id) => {
if !(is_entrypoint_fn(cx, item.owner_id.to_def_id()) || in_external_macro(cx.tcx.sess, item.span)) {
@ -338,7 +340,9 @@ fn check_item_post(&mut self, _cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) {
let attrs = cx.tcx.hir().attrs(item.hir_id());
let Some(headers) = check_attrs(cx, &self.valid_idents, attrs) else { return };
let Some(headers) = check_attrs(cx, &self.valid_idents, attrs) else {
return;
};
if let hir::TraitItemKind::Fn(ref sig, ..) = item.kind {
if !in_external_macro(cx.tcx.sess, item.span) {
lint_for_missing_headers(cx, item.owner_id, sig, headers, None, None);
@ -348,7 +352,9 @@ fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitIte
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) {
let attrs = cx.tcx.hir().attrs(item.hir_id());
let Some(headers) = check_attrs(cx, &self.valid_idents, attrs) else { return };
let Some(headers) = check_attrs(cx, &self.valid_idents, attrs) else {
return;
};
if self.in_trait_impl || in_external_macro(cx.tcx.sess, item.span) {
return;
}

View File

@ -65,16 +65,21 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
return;
}
let Some(higher::If { cond: cond_expr, then: then_expr, r#else: else_expr }) = higher::If::hir(expr) else {
return
let Some(higher::If {
cond: cond_expr,
then: then_expr,
r#else: else_expr,
}) = higher::If::hir(expr)
else {
return;
};
let Some((map_ty, contains_expr)) = try_parse_contains(cx, cond_expr) else {
return
return;
};
let Some(then_search) = find_insert_calls(cx, &contains_expr, then_expr) else {
return
return;
};
let mut app = Applicability::MachineApplicable;

View File

@ -1,102 +0,0 @@
use clippy_utils::consts::{constant, Constant};
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::{is_integer_literal, is_path_diagnostic_item};
use rustc_hir::{BinOpKind, Expr, ExprKind, TyKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;
declare_clippy_lint! {
/// ### What it does
/// Checks for comparing a function pointer to null.
///
/// ### Why is this bad?
/// Function pointers are assumed to not be null.
///
/// ### Example
/// ```rust,ignore
/// let fn_ptr: fn() = /* somehow obtained nullable function pointer */
///
/// if (fn_ptr as *const ()).is_null() { ... }
/// ```
/// Use instead:
/// ```rust,ignore
/// let fn_ptr: Option<fn()> = /* somehow obtained nullable function pointer */
///
/// if fn_ptr.is_none() { ... }
/// ```
#[clippy::version = "1.68.0"]
pub FN_NULL_CHECK,
correctness,
"`fn()` type assumed to be nullable"
}
declare_lint_pass!(FnNullCheck => [FN_NULL_CHECK]);
fn lint_expr(cx: &LateContext<'_>, expr: &Expr<'_>) {
span_lint_and_help(
cx,
FN_NULL_CHECK,
expr.span,
"function pointer assumed to be nullable, even though it isn't",
None,
"try wrapping your function pointer type in `Option<T>` instead, and using `is_none` to check for null pointer value",
);
}
fn is_fn_ptr_cast(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
if let ExprKind::Cast(cast_expr, cast_ty) = expr.kind
&& let TyKind::Ptr(_) = cast_ty.kind
{
cx.typeck_results().expr_ty_adjusted(cast_expr).is_fn()
} else {
false
}
}
impl<'tcx> LateLintPass<'tcx> for FnNullCheck {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
match expr.kind {
// Catching:
// (fn_ptr as *<const/mut> <ty>).is_null()
ExprKind::MethodCall(method_name, receiver, _, _)
if method_name.ident.as_str() == "is_null" && is_fn_ptr_cast(cx, receiver) =>
{
lint_expr(cx, expr);
},
ExprKind::Binary(op, left, right) if matches!(op.node, BinOpKind::Eq) => {
let to_check: &Expr<'_>;
if is_fn_ptr_cast(cx, left) {
to_check = right;
} else if is_fn_ptr_cast(cx, right) {
to_check = left;
} else {
return;
}
match to_check.kind {
// Catching:
// (fn_ptr as *<const/mut> <ty>) == (0 as <ty>)
ExprKind::Cast(cast_expr, _) if is_integer_literal(cast_expr, 0) => {
lint_expr(cx, expr);
},
// Catching:
// (fn_ptr as *<const/mut> <ty>) == std::ptr::null()
ExprKind::Call(func, []) if is_path_diagnostic_item(cx, func, sym::ptr_null) => {
lint_expr(cx, expr);
},
// Catching:
// (fn_ptr as *<const/mut> <ty>) == <const that evaluates to null_ptr>
_ if matches!(constant(cx, cx.typeck_results(), to_check), Some(Constant::RawPtr(0))) => {
lint_expr(cx, expr);
},
_ => {},
}
},
_ => {},
}
}
}

View File

@ -43,7 +43,9 @@
impl<'tcx> LateLintPass<'tcx> for UselessFormat {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
let Some(macro_call) = root_macro_call_first_node(cx, expr) else { return };
let Some(macro_call) = root_macro_call_first_node(cx, expr) else {
return;
};
if !cx.tcx.is_diagnostic_item(sym::format_macro, macro_call.def_id) {
return;
}

View File

@ -186,7 +186,9 @@ pub fn new(msrv: Msrv, allow_mixed_uninlined_format_args: bool) -> Self {
impl<'tcx> LateLintPass<'tcx> for FormatArgs {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
let Some(macro_call) = root_macro_call_first_node(cx, expr) else { return };
let Some(macro_call) = root_macro_call_first_node(cx, expr) else {
return;
};
if !is_format_macro(cx, macro_call.def_id) {
return;
}

View File

@ -127,7 +127,9 @@ fn check_impl_item_post(&mut self, cx: &LateContext<'_>, impl_item: &ImplItem<'_
}
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
let Some(format_trait_impl) = self.format_trait_impl else { return };
let Some(format_trait_impl) = self.format_trait_impl else {
return;
};
if format_trait_impl.name == sym::Display {
check_to_string_in_display(cx, expr);

View File

@ -164,10 +164,14 @@ fn convert_to_from(
return None;
}
let impl_item = cx.tcx.hir().impl_item(impl_item_ref.id);
let ImplItemKind::Fn(ref sig, body_id) = impl_item.kind else { return None };
let ImplItemKind::Fn(ref sig, body_id) = impl_item.kind else {
return None;
};
let body = cx.tcx.hir().body(body_id);
let [input] = body.params else { return None };
let PatKind::Binding(.., self_ident, None) = input.pat.kind else { return None };
let PatKind::Binding(.., self_ident, None) = input.pat.kind else {
return None;
};
let from = snippet_opt(cx, self_ty.span)?;
let into = snippet_opt(cx, target_ty.span)?;

View File

@ -13,8 +13,8 @@
pub fn check_fn(cx: &LateContext<'_>, kind: FnKind<'_>, decl: &FnDecl<'_>, body: &Body<'_>, span: Span) {
let FnKind::Method(ref ident, sig) = kind else {
return;
};
return;
};
// Takes only &(mut) self
if decl.inputs.len() != 1 {
@ -26,8 +26,8 @@ pub fn check_fn(cx: &LateContext<'_>, kind: FnKind<'_>, decl: &FnDecl<'_>, body:
let name = match decl.implicit_self {
ImplicitSelfKind::MutRef => {
let Some(name) = name.strip_suffix("_mut") else {
return;
};
return;
};
name
},
ImplicitSelfKind::Imm | ImplicitSelfKind::Mut | ImplicitSelfKind::ImmRef => name,
@ -77,7 +77,7 @@ pub fn check_fn(cx: &LateContext<'_>, kind: FnKind<'_>, decl: &FnDecl<'_>, body:
for adjusted_type in iter::once(typeck_results.expr_ty(self_data))
.chain(typeck_results.expr_adjustments(self_data).iter().map(|adj| adj.target))
{
let ty::Adt(def,_) = adjusted_type.kind() else {
let ty::Adt(def, _) = adjusted_type.kind() else {
continue;
};
@ -92,13 +92,15 @@ pub fn check_fn(cx: &LateContext<'_>, kind: FnKind<'_>, decl: &FnDecl<'_>, body:
}
let Some(used_field) = used_field else {
// Can happen if the field access is a tuple. We don't lint those because the getter name could not start with a number.
// Can happen if the field access is a tuple. We don't lint those because the getter name could not
// start with a number.
return;
};
let Some(correct_field) = correct_field else {
// There is no field corresponding to the getter name.
// FIXME: This can be a false positive if the correct field is reachable through deeper autodereferences than used_field is
// FIXME: This can be a false positive if the correct field is reachable through deeper
// autodereferences than used_field is
return;
};

View File

@ -23,7 +23,7 @@ pub(super) fn check_fn(
}
let Some(code_snippet) = snippet_opt(cx, body.value.span) else {
return
return;
};
let mut line_count: u64 = 0;
let mut in_comment = false;

View File

@ -119,7 +119,13 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
fn stmts_contains_early_return(stmts: &[Stmt<'_>]) -> bool {
stmts.iter().any(|stmt| {
let Stmt { kind: StmtKind::Semi(e), .. } = stmt else { return false };
let Stmt {
kind: StmtKind::Semi(e),
..
} = stmt
else {
return false;
};
contains_return(e)
})

View File

@ -131,7 +131,6 @@
mod fallible_impl_from;
mod float_literal;
mod floating_point_arithmetic;
mod fn_null_check;
mod format;
mod format_args;
mod format_impl;
@ -1003,7 +1002,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
semicolon_outside_block_ignore_multiline,
))
});
store.register_late_pass(|_| Box::new(fn_null_check::FnNullCheck));
store.register_late_pass(|_| Box::new(permissions_set_readonly_false::PermissionsSetReadonlyFalse));
store.register_late_pass(|_| Box::new(size_of_ref::SizeOfRef));
store.register_late_pass(|_| Box::new(multiple_unsafe_ops_per_block::MultipleUnsafeOpsPerBlock));

View File

@ -149,7 +149,7 @@ fn is_ref_iterable<'tcx>(
let self_ty = if mutbl.is_mut() {
self_ty
} else {
cx.tcx.mk_ref(region, TypeAndMut { ty, mutbl })
Ty::new_ref(cx.tcx,region, TypeAndMut { ty, mutbl })
};
if implements_trait(cx, self_ty, trait_id, &[])
&& let Some(ty) =
@ -164,7 +164,7 @@ fn is_ref_iterable<'tcx>(
&& !self_ty.is_ref()
{
// Attempt to borrow
let self_ty = cx.tcx.mk_ref(cx.tcx.lifetimes.re_erased, TypeAndMut {
let self_ty = Ty::new_ref(cx.tcx,cx.tcx.lifetimes.re_erased, TypeAndMut {
ty: self_ty,
mutbl,
});

View File

@ -332,7 +332,7 @@ fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
if let Some(e) = get_enclosing_loop_or_multi_call_closure(cx, loop_expr) {
let Res::Local(local_id) = iter_expr.path else {
return true
return true;
};
let mut v = NestedLoopVisitor {
cx,

View File

@ -191,7 +191,9 @@ fn replace_in_pattern(
match pat.kind {
PatKind::Binding(_ann, _id, binding_name, opt_subpt) => {
let Some(pat_to_put) = ident_map.get(&binding_name.name) else { break 'a };
let Some(pat_to_put) = ident_map.get(&binding_name.name) else {
break 'a;
};
let (sn_ptp, _) = snippet_with_context(cx, pat_to_put.span, span.ctxt(), "", app);
if let Some(subpt) = opt_subpt {
let subpt = replace_in_pattern(cx, span, ident_map, subpt, app, false);

View File

@ -239,7 +239,7 @@ fn from_pat(cx: &LateContext<'_>, arena: &'a DroplessArena, pat: &'a Pat<'_>) ->
},
PatKind::TupleStruct(ref path, pats, wild_idx) => {
let Some(adt) = cx.typeck_results().pat_ty(pat).ty_adt_def() else {
return Self::Wild
return Self::Wild;
};
let (var_id, variant) = if adt.is_enum() {
match cx.qpath_res(path, pat.hir_id).opt_def_id() {

View File

@ -1125,8 +1125,8 @@ fn contains_cfg_arm(cx: &LateContext<'_>, e: &Expr<'_>, scrutinee: &Expr<'_>, ar
//|^
let found = arm_spans.try_fold(start, |start, range| {
let Some((end, next_start)) = range else {
// Shouldn't happen as macros can't expand to match arms, but treat this as though a `cfg` attribute were
// found.
// Shouldn't happen as macros can't expand to match arms, but treat this as though a `cfg` attribute
// were found.
return Err(());
};
let span = SpanData {

View File

@ -46,6 +46,62 @@ fn try_get_generic_ty(ty: Ty<'_>, index: usize) -> Option<Ty<'_>> {
}
}
fn find_method_and_type<'tcx>(
cx: &LateContext<'tcx>,
check_pat: &Pat<'_>,
op_ty: Ty<'tcx>,
) -> Option<(&'static str, Ty<'tcx>)> {
match check_pat.kind {
PatKind::TupleStruct(ref qpath, args, rest) => {
let is_wildcard = matches!(args.first().map(|p| &p.kind), Some(PatKind::Wild));
let is_rest = matches!((args, rest.as_opt_usize()), ([], Some(_)));
if is_wildcard || is_rest {
let res = cx.typeck_results().qpath_res(qpath, check_pat.hir_id);
let Some(id) = res.opt_def_id().map(|ctor_id| cx.tcx.parent(ctor_id)) else {
return None;
};
let lang_items = cx.tcx.lang_items();
if Some(id) == lang_items.result_ok_variant() {
Some(("is_ok()", try_get_generic_ty(op_ty, 0).unwrap_or(op_ty)))
} else if Some(id) == lang_items.result_err_variant() {
Some(("is_err()", try_get_generic_ty(op_ty, 1).unwrap_or(op_ty)))
} else if Some(id) == lang_items.option_some_variant() {
Some(("is_some()", op_ty))
} else if Some(id) == lang_items.poll_ready_variant() {
Some(("is_ready()", op_ty))
} else if is_pat_variant(cx, check_pat, qpath, Item::Diag(sym::IpAddr, sym!(V4))) {
Some(("is_ipv4()", op_ty))
} else if is_pat_variant(cx, check_pat, qpath, Item::Diag(sym::IpAddr, sym!(V6))) {
Some(("is_ipv6()", op_ty))
} else {
None
}
} else {
None
}
},
PatKind::Path(ref path) => {
if let Res::Def(DefKind::Ctor(..), ctor_id) = cx.qpath_res(path, check_pat.hir_id)
&& let Some(variant_id) = cx.tcx.opt_parent(ctor_id)
{
let method = if cx.tcx.lang_items().option_none_variant() == Some(variant_id) {
"is_none()"
} else if cx.tcx.lang_items().poll_pending_variant() == Some(variant_id) {
"is_pending()"
} else {
return None;
};
// `None` and `Pending` don't have an inner type.
Some((method, cx.tcx.types.unit))
} else {
None
}
},
_ => None,
}
}
fn find_sugg_for_if_let<'tcx>(
cx: &LateContext<'tcx>,
expr: &'tcx Expr<'_>,
@ -63,52 +119,8 @@ fn find_sugg_for_if_let<'tcx>(
let op_ty = cx.typeck_results().expr_ty(let_expr);
// Determine which function should be used, and the type contained by the corresponding
// variant.
let (good_method, inner_ty) = match check_pat.kind {
PatKind::TupleStruct(ref qpath, args, rest) => {
let is_wildcard = matches!(args.first().map(|p| &p.kind), Some(PatKind::Wild));
let is_rest = matches!((args, rest.as_opt_usize()), ([], Some(_)));
if is_wildcard || is_rest {
let res = cx.typeck_results().qpath_res(qpath, check_pat.hir_id);
let Some(id) = res.opt_def_id().map(|ctor_id| cx.tcx.parent(ctor_id)) else { return };
let lang_items = cx.tcx.lang_items();
if Some(id) == lang_items.result_ok_variant() {
("is_ok()", try_get_generic_ty(op_ty, 0).unwrap_or(op_ty))
} else if Some(id) == lang_items.result_err_variant() {
("is_err()", try_get_generic_ty(op_ty, 1).unwrap_or(op_ty))
} else if Some(id) == lang_items.option_some_variant() {
("is_some()", op_ty)
} else if Some(id) == lang_items.poll_ready_variant() {
("is_ready()", op_ty)
} else if is_pat_variant(cx, check_pat, qpath, Item::Diag(sym::IpAddr, sym!(V4))) {
("is_ipv4()", op_ty)
} else if is_pat_variant(cx, check_pat, qpath, Item::Diag(sym::IpAddr, sym!(V6))) {
("is_ipv6()", op_ty)
} else {
return;
}
} else {
return;
}
},
PatKind::Path(ref path) => {
if let Res::Def(DefKind::Ctor(..), ctor_id) = cx.qpath_res(path, check_pat.hir_id)
&& let Some(variant_id) = cx.tcx.opt_parent(ctor_id)
{
let method = if cx.tcx.lang_items().option_none_variant() == Some(variant_id) {
"is_none()"
} else if cx.tcx.lang_items().poll_pending_variant() == Some(variant_id) {
"is_pending()"
} else {
return;
};
// `None` and `Pending` don't have an inner type.
(method, cx.tcx.types.unit)
} else {
return;
}
},
_ => return,
let Some((good_method, inner_ty)) = find_method_and_type(cx, check_pat, op_ty) else {
return;
};
// If this is the last expression in a block or there is an else clause then the whole
@ -337,7 +349,9 @@ enum Item {
}
fn is_pat_variant(cx: &LateContext<'_>, pat: &Pat<'_>, path: &QPath<'_>, expected_item: Item) -> bool {
let Some(id) = cx.typeck_results().qpath_res(path, pat.hir_id).opt_def_id() else { return false };
let Some(id) = cx.typeck_results().qpath_res(path, pat.hir_id).opt_def_id() else {
return false;
};
match expected_item {
Item::Lang(expected_lang_item) => cx

View File

@ -21,7 +21,9 @@ pub fn check(
return;
}
let Some(mm) = is_min_or_max(cx, unwrap_arg) else { return };
let Some(mm) = is_min_or_max(cx, unwrap_arg) else {
return;
};
if ty.is_signed() {
use self::MinMax::{Max, Min};

View File

@ -4204,7 +4204,7 @@ fn matches_ref<'a>(cx: &LateContext<'a>, mutability: hir::Mutability, parent_ty:
};
let Some(trait_def_id) = cx.tcx.get_diagnostic_item(trait_sym) else {
return false
return false;
};
implements_trait(cx, ty, trait_def_id, &[parent_ty.into()])
}

View File

@ -214,7 +214,7 @@ fn iterates_same_ty<'tcx>(cx: &LateContext<'tcx>, iter_ty: Ty<'tcx>, collect_ty:
&& let Some(into_iter_item_proj) = make_projection(cx.tcx, into_iter_trait, item, [collect_ty])
&& let Ok(into_iter_item_ty) = cx.tcx.try_normalize_erasing_regions(
cx.param_env,
cx.tcx.mk_projection(into_iter_item_proj.def_id, into_iter_item_proj.substs)
Ty::new_projection(cx.tcx,into_iter_item_proj.def_id, into_iter_item_proj.substs)
)
{
iter_item_ty == into_iter_item_ty
@ -237,7 +237,7 @@ fn is_contains_sig(cx: &LateContext<'_>, call_id: HirId, iter_expr: &Expr<'_>) -
.associated_items(iter_trait)
.find_by_name_and_kind(cx.tcx, Ident::with_dummy_span(Symbol::intern("Item")), AssocKind::Type, iter_trait)
&& let substs = cx.tcx.mk_substs(&[GenericArg::from(typeck.expr_ty_adjusted(iter_expr))])
&& let proj_ty = cx.tcx.mk_projection(iter_item.def_id, substs)
&& let proj_ty = Ty::new_projection(cx.tcx,iter_item.def_id, substs)
&& let Ok(item_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, proj_ty)
{
item_ty == EarlyBinder::bind(search_ty).subst(cx.tcx, cx.typeck_results().node_substs(call_id))

View File

@ -17,7 +17,9 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, name
if is_type_diagnostic_item(cx, outer_ty, sym::Option) && outer_ty == typeck.expr_ty(recv) {
if name == "as_deref_mut" && recv.is_syntactic_place_expr() {
let Res::Local(binding_id) = path_res(cx, recv) else { return };
let Res::Local(binding_id) = path_res(cx, recv) else {
return;
};
if local_used_after_expr(cx, binding_id, recv) {
return;

View File

@ -272,7 +272,7 @@ fn check_other_call_arg<'tcx>(
if let Some((n_refs, receiver_ty)) = if n_refs > 0 || is_copy(cx, receiver_ty) {
Some((n_refs, receiver_ty))
} else if trait_predicate.def_id() != deref_trait_id {
Some((1, cx.tcx.mk_ref(
Some((1, Ty::new_ref(cx.tcx,
cx.tcx.lifetimes.re_erased,
ty::TypeAndMut {
ty: receiver_ty,

View File

@ -46,7 +46,9 @@
impl<'tcx> LateLintPass<'tcx> for MissingAssertMessage {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
let Some(macro_call) = root_macro_call_first_node(cx, expr) else { return };
let Some(macro_call) = root_macro_call_first_node(cx, expr) else {
return;
};
let single_argument = match cx.tcx.get_diagnostic_name(macro_call.def_id) {
Some(sym::assert_macro | sym::debug_assert_macro) => true,
Some(
@ -61,10 +63,14 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
}
let panic_expn = if single_argument {
let Some((_, panic_expn)) = find_assert_args(cx, expr, macro_call.expn) else { return };
let Some((_, panic_expn)) = find_assert_args(cx, expr, macro_call.expn) else {
return;
};
panic_expn
} else {
let Some((_, _, panic_expn)) = find_assert_eq_args(cx, expr, macro_call.expn) else { return };
let Some((_, _, panic_expn)) = find_assert_eq_args(cx, expr, macro_call.expn) else {
return;
};
panic_expn
};

View File

@ -80,7 +80,9 @@ fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) {
let files = cx.sess().source_map().files();
let Some(trim_to_src) = cx.sess().opts.working_dir.local_path() else { return };
let Some(trim_to_src) = cx.sess().opts.working_dir.local_path() else {
return;
};
// `folder_segments` is all unique folder path segments `path/to/foo.rs` gives
// `[path, to]` but not foo

View File

@ -39,7 +39,9 @@
impl<'tcx> LateLintPass<'tcx> for DebugAssertWithMutCall {
fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
let Some(macro_call) = root_macro_call_first_node(cx, e) else { return };
let Some(macro_call) = root_macro_call_first_node(cx, e) else {
return;
};
let macro_name = cx.tcx.item_name(macro_call.def_id);
if !matches!(
macro_name.as_str(),
@ -47,7 +49,9 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
) {
return;
}
let Some((lhs, rhs, _)) = find_assert_eq_args(cx, e, macro_call.expn) else { return };
let Some((lhs, rhs, _)) = find_assert_eq_args(cx, e, macro_call.expn) else {
return;
};
for arg in [lhs, rhs] {
let mut visitor = MutArgVisitor::new(cx);
visitor.visit_expr(arg);

View File

@ -52,7 +52,9 @@ fn check_pat(&mut self, cx: &LateContext<'tcx>, ref_pat: &'tcx Pat<'_>) {
}
// Only lint immutable refs, because `&mut ref T` may be useful.
let PatKind::Ref(pat, Mutability::Not) = ref_pat.kind else { return };
let PatKind::Ref(pat, Mutability::Not) = ref_pat.kind else {
return;
};
match pat.kind {
// Check sub_pat got a `ref` keyword (excluding `ref mut`).

View File

@ -49,7 +49,7 @@
impl<'tcx> LateLintPass<'tcx> for NeedlessForEach {
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
let (StmtKind::Expr(expr) | StmtKind::Semi(expr)) = stmt.kind else {
return
return;
};
if_chain! {

View File

@ -86,7 +86,9 @@ fn contains_let(cond: &Expr<'_>) -> bool {
}
fn stmt_needs_ordered_drop(cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool {
let StmtKind::Local(local) = stmt.kind else { return false };
let StmtKind::Local(local) = stmt.kind else {
return false;
};
!local.pat.walk_short(|pat| {
if let PatKind::Binding(.., None) = pat.kind {
!needs_ordered_drop(cx, cx.typeck_results().pat_ty(pat))

View File

@ -17,7 +17,7 @@
use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::mir::FakeReadCause;
use rustc_middle::ty::{self, TypeVisitableExt};
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::def_id::LocalDefId;
use rustc_span::symbol::kw;
@ -168,7 +168,7 @@ fn check_fn(
(
preds.iter().any(|t| cx.tcx.is_diagnostic_item(sym::Borrow, t.def_id())),
!preds.is_empty() && {
let ty_empty_region = cx.tcx.mk_imm_ref(cx.tcx.lifetimes.re_erased, ty);
let ty_empty_region = Ty::new_imm_ref(cx.tcx, cx.tcx.lifetimes.re_erased, ty);
preds.iter().all(|t| {
let ty_params = t.trait_ref.substs.iter().skip(1).collect::<Vec<_>>();
implements_trait(cx, ty_empty_region, t.def_id(), &ty_params)

View File

@ -15,12 +15,12 @@
};
use rustc_hir_analysis::hir_ty_to_ty;
use rustc_lint::{LateContext, LateLintPass, Lint};
use rustc_middle::mir;
use rustc_middle::mir::interpret::{ConstValue, ErrorHandled};
use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult, GlobalId};
use rustc_middle::ty::adjustment::Adjust;
use rustc_middle::ty::{self, Ty};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::{sym, InnerSpan, Span};
use rustc_target::abi::VariantIdx;
// FIXME: this is a correctness problem but there's no suitable
// warn-by-default category.
@ -141,21 +141,48 @@ fn is_unfrozen<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
fn is_value_unfrozen_raw<'tcx>(
cx: &LateContext<'tcx>,
result: Result<ConstValue<'tcx>, ErrorHandled>,
result: Result<Option<ty::ValTree<'tcx>>, ErrorHandled>,
ty: Ty<'tcx>,
) -> bool {
fn inner<'tcx>(cx: &LateContext<'tcx>, val: mir::ConstantKind<'tcx>) -> bool {
match val.ty().kind() {
fn inner<'tcx>(cx: &LateContext<'tcx>, val: ty::ValTree<'tcx>, ty: Ty<'tcx>) -> bool {
match *ty.kind() {
// the fact that we have to dig into every structs to search enums
// leads us to the point checking `UnsafeCell` directly is the only option.
ty::Adt(ty_def, ..) if ty_def.is_unsafe_cell() => true,
// As of 2022-09-08 miri doesn't track which union field is active so there's no safe way to check the
// contained value.
ty::Adt(def, ..) if def.is_union() => false,
ty::Array(..) | ty::Adt(..) | ty::Tuple(..) => {
let val = cx.tcx.destructure_mir_constant(cx.param_env, val);
val.fields.iter().any(|field| inner(cx, *field))
ty::Array(ty, _) => val.unwrap_branch().iter().any(|field| inner(cx, *field, ty)),
ty::Adt(def, _) if def.is_union() => false,
ty::Adt(def, substs) if def.is_enum() => {
let (&variant_index, fields) = val.unwrap_branch().split_first().unwrap();
let variant_index = VariantIdx::from_u32(variant_index.unwrap_leaf().try_to_u32().ok().unwrap());
fields
.iter()
.copied()
.zip(
def.variants()[variant_index]
.fields
.iter()
.map(|field| field.ty(cx.tcx, substs)),
)
.any(|(field, ty)| inner(cx, field, ty))
},
ty::Adt(def, substs) => val
.unwrap_branch()
.iter()
.zip(
def.non_enum_variant()
.fields
.iter()
.map(|field| field.ty(cx.tcx, substs)),
)
.any(|(field, ty)| inner(cx, *field, ty)),
ty::Tuple(tys) => val
.unwrap_branch()
.iter()
.zip(tys)
.any(|(field, ty)| inner(cx, *field, ty)),
_ => false,
}
}
@ -184,24 +211,49 @@ fn inner<'tcx>(cx: &LateContext<'tcx>, val: mir::ConstantKind<'tcx>) -> bool {
// I chose this way because unfrozen enums as assoc consts are rare (or, hopefully, none).
err == ErrorHandled::TooGeneric
},
|val| inner(cx, mir::ConstantKind::from_value(val, ty)),
|val| val.map_or(true, |val| inner(cx, val, ty)),
)
}
fn is_value_unfrozen_poly<'tcx>(cx: &LateContext<'tcx>, body_id: BodyId, ty: Ty<'tcx>) -> bool {
let result = cx.tcx.const_eval_poly(body_id.hir_id.owner.to_def_id());
let def_id = body_id.hir_id.owner.to_def_id();
let substs = ty::InternalSubsts::identity_for_item(cx.tcx, def_id);
let instance = ty::Instance::new(def_id, substs);
let cid = rustc_middle::mir::interpret::GlobalId {
instance,
promoted: None,
};
let param_env = cx.tcx.param_env(def_id).with_reveal_all_normalized(cx.tcx);
let result = cx.tcx.const_eval_global_id_for_typeck(param_env, cid, None);
is_value_unfrozen_raw(cx, result, ty)
}
fn is_value_unfrozen_expr<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId, def_id: DefId, ty: Ty<'tcx>) -> bool {
let substs = cx.typeck_results().node_substs(hir_id);
let result = cx
.tcx
.const_eval_resolve(cx.param_env, mir::UnevaluatedConst::new(def_id, substs), None);
let result = const_eval_resolve(cx.tcx, cx.param_env, ty::UnevaluatedConst::new(def_id, substs), None);
is_value_unfrozen_raw(cx, result, ty)
}
pub fn const_eval_resolve<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
ct: ty::UnevaluatedConst<'tcx>,
span: Option<Span>,
) -> EvalToValTreeResult<'tcx> {
match ty::Instance::resolve(tcx, param_env, ct.def, ct.substs) {
Ok(Some(instance)) => {
let cid = GlobalId {
instance,
promoted: None,
};
tcx.const_eval_global_id_for_typeck(param_env, cid, span)
},
Ok(None) => Err(ErrorHandled::TooGeneric),
Err(err) => Err(ErrorHandled::Reported(err.into())),
}
}
#[derive(Copy, Clone)]
enum Source {
Item { item: Span },
@ -356,7 +408,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
// Make sure it is a const item.
let Res::Def(DefKind::Const | DefKind::AssocConst, item_def_id) = cx.qpath_res(qpath, expr.hir_id) else {
return
return;
};
// Climb up to resolve any field access and explicit referencing.

View File

@ -194,7 +194,9 @@ fn manage_method_call<'tcx>(
ps: &hir::PathSegment<'tcx>,
receiver: &hir::Expr<'tcx>,
) {
let Some(arg) = args.first() else { return; };
let Some(arg) = args.first() else {
return;
};
if constant_simple(cx, cx.typeck_results(), receiver).is_some() {
return;
}
@ -219,7 +221,9 @@ fn manage_unary_ops<'tcx>(
un_expr: &hir::Expr<'tcx>,
un_op: hir::UnOp,
) {
let hir::UnOp::Neg = un_op else { return; };
let hir::UnOp::Neg = un_op else {
return;
};
if constant(cx, cx.typeck_results(), un_expr).is_some() {
return;
}

View File

@ -76,7 +76,9 @@
impl<'tcx> LateLintPass<'tcx> for PanicUnimplemented {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
let Some(macro_call) = root_macro_call_first_node(cx, expr) else { return };
let Some(macro_call) = root_macro_call_first_node(cx, expr) else {
return;
};
if is_panic(cx, macro_call.def_id) {
if cx.tcx.hir().is_inside_const_context(expr.hir_id) {
return;

View File

@ -13,7 +13,7 @@
use rustc_hir::intravisit::FnKind;
use rustc_hir::{BindingAnnotation, Body, FnDecl, Impl, ItemKind, MutTy, Mutability, Node, PatKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::adjustment::{Adjust, PointerCast};
use rustc_middle::ty::adjustment::{Adjust, PointerCoercion};
use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::{self, RegionKind};
use rustc_session::{declare_tool_lint, impl_lint_pass};
@ -194,7 +194,7 @@ fn check_poly_fn(&mut self, cx: &LateContext<'tcx>, def_id: LocalDefId, decl: &F
.adjustments()
.items()
.flat_map(|(_, a)| a)
.any(|a| matches!(a.kind, Adjust::Pointer(PointerCast::UnsafeFnPointer)))
.any(|a| matches!(a.kind, Adjust::Pointer(PointerCoercion::UnsafeFnPointer)))
{
continue;
}

View File

@ -388,11 +388,12 @@ impl<'tcx> DerefTy<'tcx> {
fn ty(&self, cx: &LateContext<'tcx>) -> Ty<'tcx> {
match *self {
Self::Str => cx.tcx.types.str_,
Self::Path => cx.tcx.mk_adt(
Self::Path => Ty::new_adt(
cx.tcx,
cx.tcx.adt_def(cx.tcx.get_diagnostic_item(sym::Path).unwrap()),
List::empty(),
),
Self::Slice(_, ty) => cx.tcx.mk_slice(ty),
Self::Slice(_, ty) => Ty::new_slice(cx.tcx, ty),
}
}

View File

@ -50,12 +50,12 @@ impl<'tcx> LateLintPass<'tcx> for PtrOffsetWithCast {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
// Check if the expressions is a ptr.offset or ptr.wrapping_offset method call
let Some((receiver_expr, arg_expr, method)) = expr_as_ptr_offset_call(cx, expr) else {
return
return;
};
// Check if the argument to the method call is a cast from usize
let Some(cast_lhs_expr) = expr_as_cast_from_usize(cx, arg_expr) else {
return
return;
};
let msg = format!("use of `{method}` with a `usize` casted to an `isize`");

View File

@ -49,9 +49,15 @@
impl LateLintPass<'_> for RcCloneInVecInit {
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
let Some(macro_call) = root_macro_call_first_node(cx, expr) else { return; };
let Some(VecArgs::Repeat(elem, len)) = VecArgs::hir(cx, expr) else { return; };
let Some((symbol, func_span)) = ref_init(cx, elem) else { return; };
let Some(macro_call) = root_macro_call_first_node(cx, expr) else {
return;
};
let Some(VecArgs::Repeat(elem, len)) = VecArgs::hir(cx, expr) else {
return;
};
let Some((symbol, func_span)) = ref_init(cx, elem) else {
return;
};
emit_lint(cx, symbol, macro_call.span, elem, len, func_span);
}

View File

@ -9,6 +9,7 @@
use rustc_lint::{LateContext, LateLintPass, Lint};
use rustc_middle::ty::adjustment::{Adjust, AutoBorrow, AutoBorrowMutability};
use rustc_middle::ty::subst::GenericArg;
use rustc_middle::ty::Ty;
use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! {
@ -134,7 +135,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
} else if let Some(target_id) = cx.tcx.lang_items().deref_target() {
if let Ok(deref_ty) = cx.tcx.try_normalize_erasing_regions(
cx.param_env,
cx.tcx.mk_projection(target_id, cx.tcx.mk_substs(&[GenericArg::from(indexed_ty)])),
Ty::new_projection(cx.tcx,target_id, cx.tcx.mk_substs(&[GenericArg::from(indexed_ty)])),
) {
if deref_ty == expr_ty {
let snip = snippet_with_context(cx, indexed.span, ctxt, "..", &mut app).0;

View File

@ -42,6 +42,7 @@
("clippy::for_loops_over_fallibles", "for_loops_over_fallibles"),
("clippy::forget_copy", "forgetting_copy_types"),
("clippy::forget_ref", "forgetting_references"),
("clippy::fn_null_check", "incorrect_fn_null_checks"),
("clippy::into_iter_on_array", "array_into_iter"),
("clippy::invalid_atomic_ordering", "invalid_atomic_ordering"),
("clippy::invalid_ref", "invalid_value"),

View File

@ -148,12 +148,18 @@ fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &Stmt<'_>) {
expr: None,
stmts: [.., stmt],
..
} = block else { return };
} = block
else {
return;
};
let &Stmt {
kind: StmtKind::Semi(expr),
span,
..
} = stmt else { return };
} = stmt
else {
return;
};
self.semicolon_outside_block(cx, block, expr, span);
},
StmtKind::Semi(Expr {

View File

@ -106,7 +106,9 @@ pub(crate) struct Shadow {
impl<'tcx> LateLintPass<'tcx> for Shadow {
fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {
let PatKind::Binding(_, id, ident, _) = pat.kind else { return };
let PatKind::Binding(_, id, ident, _) = pat.kind else {
return;
};
if pat.span.desugaring_kind().is_some() || pat.span.from_expansion() {
return;

View File

@ -24,7 +24,7 @@ pub(super) fn check<'tcx>(
"transmute from a pointer to a pointer",
|diag| {
if let Some(arg) = sugg::Sugg::hir_opt(cx, arg) {
let sugg = arg.as_ty(cx.tcx.mk_ptr(*to_ty));
let sugg = arg.as_ty(Ty::new_ptr(cx.tcx, *to_ty));
diag.span_suggestion(e.span, "try", sugg, Applicability::Unspecified);
}
},

View File

@ -64,8 +64,8 @@ pub(super) fn check<'tcx>(
};
let ty_to_and_mut = ty::TypeAndMut { ty: *ty_to, mutbl: *to_mutbl };
let sugg_paren = arg
.as_ty(cx.tcx.mk_ptr(ty_from_and_mut))
.as_ty(cx.tcx.mk_ptr(ty_to_and_mut));
.as_ty(Ty::new_ptr(cx.tcx,ty_from_and_mut))
.as_ty(Ty::new_ptr(cx.tcx,ty_to_and_mut));
let sugg = if *to_mutbl == Mutability::Mut {
sugg_paren.mut_addr_deref()
} else {

View File

@ -43,7 +43,7 @@ pub(super) fn check<'tcx>(
let sugg = if *ptr_ty == rty_and_mut {
arg.as_ty(to_ty)
} else {
arg.as_ty(cx.tcx.mk_ptr(rty_and_mut)).as_ty(to_ty)
arg.as_ty(Ty::new_ptr(cx.tcx, rty_and_mut)).as_ty(to_ty)
};
diag.span_suggestion(e.span, "try", sugg, Applicability::Unspecified);

View File

@ -23,7 +23,9 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
app,
);
} else {
let Some(ty) = qpath_generic_tys(qpath).next() else { return false };
let Some(ty) = qpath_generic_tys(qpath).next() else {
return false;
};
let Some(id) = path_def_id(cx, ty) else { return false };
if !cx.tcx.is_diagnostic_item(sym::Vec, id) {
return false;

View File

@ -40,7 +40,9 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
return true;
}
let Some(ty) = qpath_generic_tys(qpath).next() else { return false };
let Some(ty) = qpath_generic_tys(qpath).next() else {
return false;
};
let Some(id) = path_def_id(cx, ty) else { return false };
let (inner_sym, ty) = match cx.tcx.get_diagnostic_name(id) {
Some(sym::Arc) => ("Arc", ty),
@ -50,7 +52,7 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
};
let TyKind::Path(inner_qpath) = &ty.kind else {
return false
return false;
};
let inner_span = match qpath_generic_tys(inner_qpath).next() {
Some(hir_ty) => {

View File

@ -158,11 +158,12 @@ fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) {
}
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &hir::Stmt<'tcx>) {
let (
hir::StmtKind::Local(&hir::Local { init: Some(expr), .. })
| hir::StmtKind::Expr(expr)
| hir::StmtKind::Semi(expr)
) = stmt.kind else { return };
let (hir::StmtKind::Local(&hir::Local { init: Some(expr), .. })
| hir::StmtKind::Expr(expr)
| hir::StmtKind::Semi(expr)) = stmt.kind
else {
return;
};
if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, stmt.hir_id)
&& !in_external_macro(cx.tcx.sess, stmt.span)
&& let HasSafetyComment::Yes(pos) = stmt_has_safety_comment(cx, stmt.span, stmt.hir_id)

View File

@ -14,7 +14,9 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
"assert_ne" | "debug_assert_ne" => "fail",
_ => return,
};
let Some ((left, _, _)) = find_assert_eq_args(cx, expr, macro_call.expn) else { return };
let Some((left, _, _)) = find_assert_eq_args(cx, expr, macro_call.expn) else {
return;
};
if !cx.typeck_results().expr_ty(left).is_unit() {
return;
}

View File

@ -65,7 +65,9 @@ fn check_fn_item(&mut self, cx: &LateContext<'_>, decl: &FnDecl<'_>, def_id: Loc
return;
}
let FnRetTy::Return(return_ty_hir) = &decl.output else { return };
let FnRetTy::Return(return_ty_hir) = &decl.output else {
return;
};
let return_ty = cx
.tcx
@ -105,25 +107,33 @@ fn check_fn_item(&mut self, cx: &LateContext<'_>, decl: &FnDecl<'_>, def_id: Loc
impl LateLintPass<'_> for UnnecessaryBoxReturns {
fn check_trait_item(&mut self, cx: &LateContext<'_>, item: &TraitItem<'_>) {
let TraitItemKind::Fn(signature, _) = &item.kind else { return };
let TraitItemKind::Fn(signature, _) = &item.kind else {
return;
};
self.check_fn_item(cx, signature.decl, item.owner_id.def_id, item.ident.name);
}
fn check_impl_item(&mut self, cx: &LateContext<'_>, item: &rustc_hir::ImplItem<'_>) {
// Ignore implementations of traits, because the lint should be on the
// trait, not on the implementation of it.
let Node::Item(parent) = cx.tcx.hir().get_parent(item.hir_id()) else { return };
let Node::Item(parent) = cx.tcx.hir().get_parent(item.hir_id()) else {
return;
};
let ItemKind::Impl(parent) = parent.kind else { return };
if parent.of_trait.is_some() {
return;
}
let ImplItemKind::Fn(signature, ..) = &item.kind else { return };
let ImplItemKind::Fn(signature, ..) = &item.kind else {
return;
};
self.check_fn_item(cx, signature.decl, item.owner_id.def_id, item.ident.name);
}
fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
let ItemKind::Fn(signature, ..) = &item.kind else { return };
let ItemKind::Fn(signature, ..) = &item.kind else {
return;
};
self.check_fn_item(cx, signature.decl, item.owner_id.def_id, item.ident.name);
}
}

View File

@ -163,9 +163,7 @@ fn visit_pat(&mut self, p: &mut P<Pat>) {
noop_visit_pat(p, self);
// Don't have an or-pattern? Just quit early on.
let Or(alternatives) = &mut p.kind else {
return
};
let Or(alternatives) = &mut p.kind else { return };
// Collapse or-patterns directly nested in or-patterns.
let mut idx = 0;

View File

@ -48,7 +48,7 @@
impl<'tcx> LateLintPass<'tcx> for UnusedIoAmount {
fn check_stmt(&mut self, cx: &LateContext<'_>, s: &hir::Stmt<'_>) {
let (hir::StmtKind::Semi(expr) | hir::StmtKind::Expr(expr)) = s.kind else {
return
return;
};
match expr.kind {

View File

@ -115,7 +115,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
match e.kind {
ExprKind::Match(_, arms, MatchSource::TryDesugar) => {
let (ExprKind::Ret(Some(e)) | ExprKind::Break(_, Some(e))) = arms[0].body.kind else {
return
return;
};
if let ExprKind::Call(_, [arg, ..]) = e.kind {
self.try_desugar_arm.push(arg.hir_id);

View File

@ -71,7 +71,9 @@ fn has_span_from_proc_macro(cx: &EarlyContext<'_>, args: &FormatArgs) -> bool {
for between_span in between_spans {
let mut seen_comma = false;
let Some(snippet) = snippet_opt(cx, between_span) else { return true };
let Some(snippet) = snippet_opt(cx, between_span) else {
return true;
};
for token in tokenize(&snippet) {
match token.kind {
TokenKind::LineComment { .. } | TokenKind::BlockComment { .. } | TokenKind::Whitespace => {},

View File

@ -46,7 +46,9 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
} else {
return;
};
let ExprKind::Block(then_block, _) = then.kind else { return };
let ExprKind::Block(then_block, _) = then.kind else {
return;
};
let if_chain_span = is_expn_of(expr.span, "if_chain");
if !els {
check_nested_if_chains(cx, expr, then_block, if_chain_span);

View File

@ -74,7 +74,7 @@ fn display_err(&self, cx: &LateContext<'_>) {
let mut needs_mut = false;
let res = for_each_local_use_after_expr(cx, self.local_id, self.last_push_expr, |e| {
let Some(parent) = get_parent_expr(cx, e) else {
return ControlFlow::Continue(())
return ControlFlow::Continue(());
};
let adjusted_ty = cx.typeck_results().expr_ty_adjusted(e);
let adjusted_mut = adjusted_ty.ref_mutability().unwrap_or(Mutability::Not);

View File

@ -272,9 +272,15 @@ fn check_item_post(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
}
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
let Some(macro_call) = root_macro_call_first_node(cx, expr) else { return };
let Some(diag_name) = cx.tcx.get_diagnostic_name(macro_call.def_id) else { return };
let Some(name) = diag_name.as_str().strip_suffix("_macro") else { return };
let Some(macro_call) = root_macro_call_first_node(cx, expr) else {
return;
};
let Some(diag_name) = cx.tcx.get_diagnostic_name(macro_call.def_id) else {
return;
};
let Some(name) = diag_name.as_str().strip_suffix("_macro") else {
return;
};
let is_build_script = cx
.sess()
@ -343,7 +349,9 @@ fn is_debug_impl(cx: &LateContext<'_>, item: &Item<'_>) -> bool {
}
fn check_newline(cx: &LateContext<'_>, format_args: &FormatArgs, macro_call: &MacroCall, name: &str) {
let Some(FormatArgsPiece::Literal(last)) = format_args.template.last() else { return };
let Some(FormatArgsPiece::Literal(last)) = format_args.template.last() else {
return;
};
let count_vertical_whitespace = || {
format_args
@ -379,7 +387,9 @@ fn check_newline(cx: &LateContext<'_>, format_args: &FormatArgs, macro_call: &Ma
&format!("using `{name}!()` with a format string that ends in a single newline"),
|diag| {
let name_span = cx.sess().source_map().span_until_char(macro_call.span, '!');
let Some(format_snippet) = snippet_opt(cx, format_string_span) else { return };
let Some(format_snippet) = snippet_opt(cx, format_string_span) else {
return;
};
if format_args.template.len() == 1 && last.as_str() == "\n" {
// print!("\n"), write!(f, "\n")

View File

@ -1,6 +1,6 @@
[package]
name = "clippy_utils"
version = "0.1.72"
version = "0.1.73"
edition = "2021"
publish = false

View File

@ -153,7 +153,7 @@ pub fn partial_cmp(tcx: TyCtxt<'_>, cmp_type: Ty<'_>, left: &Self, right: &Self)
},
(Self::Vec(l), Self::Vec(r)) => {
let (ty::Array(cmp_type, _) | ty::Slice(cmp_type)) = *cmp_type.kind() else {
return None
return None;
};
iter::zip(l, r)
.map(|(li, ri)| Self::partial_cmp(tcx, cmp_type, li, ri))
@ -687,7 +687,7 @@ pub fn miri_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::ConstantKind<'t
mir::ConstantKind::Val(ConstValue::ByRef { alloc, offset: _ }, _) => match result.ty().kind() {
ty::Adt(adt_def, _) if adt_def.is_struct() => Some(Constant::Adt(result)),
ty::Array(sub_type, len) => match sub_type.kind() {
ty::Float(FloatTy::F32) => match len.kind().try_to_target_usize(lcx.tcx) {
ty::Float(FloatTy::F32) => match len.try_to_target_usize(lcx.tcx) {
Some(len) => alloc
.inner()
.inspect_with_uninit_and_ptr_outside_interpreter(0..(4 * usize::try_from(len).unwrap()))
@ -698,7 +698,7 @@ pub fn miri_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::ConstantKind<'t
.map(Constant::Vec),
_ => None,
},
ty::Float(FloatTy::F64) => match len.kind().try_to_target_usize(lcx.tcx) {
ty::Float(FloatTy::F64) => match len.try_to_target_usize(lcx.tcx) {
Some(len) => alloc
.inner()
.inspect_with_uninit_and_ptr_outside_interpreter(0..(8 * usize::try_from(len).unwrap()))
@ -723,13 +723,14 @@ fn field_of_struct<'tcx>(
result: mir::ConstantKind<'tcx>,
field: &Ident,
) -> Option<mir::ConstantKind<'tcx>> {
let dc = lcx.tcx.destructure_mir_constant(lcx.param_env, result);
if let Some(dc_variant) = dc.variant
if let mir::ConstantKind::Val(result, ty) = result
&& let Some(dc) = lcx.tcx.try_destructure_mir_constant_for_diagnostics((result, ty))
&& let Some(dc_variant) = dc.variant
&& let Some(variant) = adt_def.variants().get(dc_variant)
&& let Some(field_idx) = variant.fields.iter().position(|el| el.name == field.name)
&& let Some(dc_field) = dc.fields.get(field_idx)
&& let Some(&(val, ty)) = dc.fields.get(field_idx)
{
Some(*dc_field)
Some(mir::ConstantKind::Val(val, ty))
}
else {
None

View File

@ -2516,7 +2516,9 @@ pub fn tokenize_with_text(s: &str) -> impl Iterator<Item = (TokenKind, &str)> {
/// Checks whether a given span has any comment token
/// This checks for all types of comment: line "//", block "/**", doc "///" "//!"
pub fn span_contains_comment(sm: &SourceMap, span: Span) -> bool {
let Ok(snippet) = sm.span_to_snippet(span) else { return false };
let Ok(snippet) = sm.span_to_snippet(span) else {
return false;
};
return tokenize(&snippet).any(|token| {
matches!(
token.kind,

View File

@ -192,7 +192,9 @@ pub fn first_node_in_macro(cx: &LateContext<'_>, node: &impl HirNode) -> Option<
/// Is `def_id` of `std::panic`, `core::panic` or any inner implementation macros
pub fn is_panic(cx: &LateContext<'_>, def_id: DefId) -> bool {
let Some(name) = cx.tcx.get_diagnostic_name(def_id) else { return false };
let Some(name) = cx.tcx.get_diagnostic_name(def_id) else {
return false;
};
matches!(
name,
sym::core_panic_macro
@ -205,7 +207,9 @@ 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 };
let Some(name) = cx.tcx.get_diagnostic_name(def_id) else {
return false;
};
matches!(name, sym::assert_macro | sym::debug_assert_macro)
}
@ -223,13 +227,19 @@ pub enum PanicExpn<'a> {
impl<'a> PanicExpn<'a> {
pub fn parse(expr: &'a Expr<'a>) -> Option<Self> {
let ExprKind::Call(callee, [arg, rest @ ..]) = &expr.kind else { return None };
let ExprKind::Path(QPath::Resolved(_, path)) = &callee.kind else { return None };
let ExprKind::Call(callee, [arg, rest @ ..]) = &expr.kind else {
return None;
};
let ExprKind::Path(QPath::Resolved(_, path)) = &callee.kind else {
return None;
};
let result = match path.segments.last().unwrap().ident.as_str() {
"panic" if arg.span.ctxt() == expr.span.ctxt() => Self::Empty,
"panic" | "panic_str" => Self::Str(arg),
"panic_display" => {
let ExprKind::AddrOf(_, _, e) = &arg.kind else { return None };
let ExprKind::AddrOf(_, _, e) = &arg.kind else {
return None;
};
Self::Display(e)
},
"panic_fmt" => Self::Format(arg),

View File

@ -15,7 +15,7 @@
Terminator, TerminatorKind,
};
use rustc_middle::traits::{ImplSource, ObligationCause};
use rustc_middle::ty::adjustment::PointerCast;
use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::{self, BoundConstness, TraitRef, Ty, TyCtxt};
use rustc_semver::RustcVersion;
@ -119,18 +119,20 @@ fn check_rvalue<'tcx>(
| CastKind::FloatToFloat
| CastKind::FnPtrToPtr
| CastKind::PtrToPtr
| CastKind::Pointer(PointerCast::MutToConstPointer | PointerCast::ArrayToPointer),
| CastKind::PointerCoercion(PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer),
operand,
_,
) => check_operand(tcx, operand, span, body),
Rvalue::Cast(
CastKind::Pointer(
PointerCast::UnsafeFnPointer | PointerCast::ClosureFnPointer(_) | PointerCast::ReifyFnPointer,
CastKind::PointerCoercion(
PointerCoercion::UnsafeFnPointer
| PointerCoercion::ClosureFnPointer(_)
| PointerCoercion::ReifyFnPointer,
),
_,
_,
) => Err((span, "function pointer casts are not allowed in const fn".into())),
Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), op, cast_ty) => {
Rvalue::Cast(CastKind::PointerCoercion(PointerCoercion::Unsize), op, cast_ty) => {
let pointee_ty = if let Some(deref_ty) = cast_ty.builtin_deref(true) {
deref_ty.ty
} else {

View File

@ -938,8 +938,7 @@ pub fn ty_is_fn_once_param<'tcx>(tcx: TyCtxt<'_>, ty: Ty<'tcx>, predicates: &'tc
return false;
};
let lang = tcx.lang_items();
let (Some(fn_once_id), Some(fn_mut_id), Some(fn_id))
= (lang.fn_once_trait(), lang.fn_mut_trait(), lang.fn_trait())
let (Some(fn_once_id), Some(fn_mut_id), Some(fn_id)) = (lang.fn_once_trait(), lang.fn_mut_trait(), lang.fn_trait())
else {
return false;
};
@ -1031,10 +1030,12 @@ fn helper<'tcx>(
assoc_ty: Symbol,
substs: SubstsRef<'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)
else {
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,
) else {
debug_assert!(false, "type `{assoc_ty}` not found in `{container_id:?}`");
return None;
};
@ -1122,7 +1123,7 @@ fn helper<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: AliasTy<'tcx>)
);
return None;
}
match tcx.try_normalize_erasing_regions(param_env, tcx.mk_projection(ty.def_id, ty.substs)) {
match tcx.try_normalize_erasing_regions(param_env, Ty::new_projection(tcx, ty.def_id, ty.substs)) {
Ok(ty) => Some(ty),
Err(e) => {
debug_assert!(false, "failed to normalize type `{ty}`: {e:#?}");
@ -1205,7 +1206,7 @@ fn helper<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: AliasTy<'tcx>)
.infer_ctxt()
.build()
.at(&cause, param_env)
.query_normalize(tcx.mk_projection(ty.def_id, ty.substs))
.query_normalize(Ty::new_projection(tcx, ty.def_id, ty.substs))
{
Ok(ty) => Some(ty.value),
Err(e) => {

View File

@ -154,7 +154,9 @@ pub fn contains_return_break_continue_macro(expression: &Expr<'_>) -> bool {
}
pub fn local_used_after_expr(cx: &LateContext<'_>, local_id: HirId, after: &Expr<'_>) -> bool {
let Some(block) = utils::get_enclosing_block(cx, local_id) else { return false };
let Some(block) = utils::get_enclosing_block(cx, local_id) else {
return false;
};
// for _ in 1..3 {
// local

View File

@ -1,6 +1,6 @@
[package]
name = "declare_clippy_lint"
version = "0.1.72"
version = "0.1.73"
edition = "2021"
publish = false

View File

@ -1,3 +1,3 @@
[toolchain]
channel = "nightly-2023-06-29"
channel = "nightly-2023-07-14"
components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]

View File

@ -121,7 +121,7 @@ fn base_config(test_dir: &str) -> compiletest::Config {
compiletest::OutputConflictHandling::Error("cargo test -- -- --bless".into())
},
target: None,
out_dir: "target/ui_test".into(),
out_dir: PathBuf::from(std::env::var_os("CARGO_TARGET_DIR").unwrap_or("target".into())).join("ui_test"),
..compiletest::Config::rustc(Path::new("tests").join(test_dir))
};
@ -217,10 +217,7 @@ fn run_ui_toml() {
config.stderr_filter(
&regex::escape(
&std::path::Path::new(file!())
.parent()
.unwrap()
.canonicalize()
&fs::canonicalize("tests")
.unwrap()
.parent()
.unwrap()
@ -266,6 +263,7 @@ fn run_ui_cargo() {
.push(("RUSTFLAGS".into(), Some("-Dwarnings".into())));
// We need to do this while we still have a rustc in the `program` field.
config.fill_host_and_target().unwrap();
config.dependencies_crate_manifest_path = None;
config.program.program.set_file_name(if cfg!(windows) {
"cargo-clippy.exe"
} else {
@ -275,10 +273,7 @@ fn run_ui_cargo() {
config.stderr_filter(
&regex::escape(
&std::path::Path::new(file!())
.parent()
.unwrap()
.canonicalize()
&fs::canonicalize("tests")
.unwrap()
.parent()
.unwrap()

View File

@ -0,0 +1,12 @@
error: a `const` item should never be interior mutable
--> $DIR/ice-9445.rs:1:1
|
LL | const UNINIT: core::mem::MaybeUninit<core::cell::Cell<&'static ()>> = core::mem::MaybeUninit::uninit();
| -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| make this a static item (maybe with lazy_static)
|
= note: `-D clippy::declare-interior-mutable-const` implied by `-D warnings`
error: aborting due to previous error

View File

@ -1,22 +0,0 @@
#![allow(unused)]
#![warn(clippy::fn_null_check)]
#![allow(clippy::cmp_null)]
#![allow(clippy::needless_if)]
#![allow(clippy::ptr_eq)]
#![allow(clippy::zero_ptr)]
pub const ZPTR: *const () = 0 as *const _;
pub const NOT_ZPTR: *const () = 1 as *const _;
fn main() {
let fn_ptr = main;
if (fn_ptr as *mut ()).is_null() {}
if (fn_ptr as *const u8).is_null() {}
if (fn_ptr as *const ()) == std::ptr::null() {}
if (fn_ptr as *const ()) == (0 as *const ()) {}
if (fn_ptr as *const ()) == ZPTR {}
// no lint
if (fn_ptr as *const ()) == NOT_ZPTR {}
}

View File

@ -1,43 +0,0 @@
error: function pointer assumed to be nullable, even though it isn't
--> $DIR/fn_null_check.rs:14:8
|
LL | if (fn_ptr as *mut ()).is_null() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try wrapping your function pointer type in `Option<T>` instead, and using `is_none` to check for null pointer value
= note: `-D clippy::fn-null-check` implied by `-D warnings`
error: function pointer assumed to be nullable, even though it isn't
--> $DIR/fn_null_check.rs:15:8
|
LL | if (fn_ptr as *const u8).is_null() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try wrapping your function pointer type in `Option<T>` instead, and using `is_none` to check for null pointer value
error: function pointer assumed to be nullable, even though it isn't
--> $DIR/fn_null_check.rs:16:8
|
LL | if (fn_ptr as *const ()) == std::ptr::null() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try wrapping your function pointer type in `Option<T>` instead, and using `is_none` to check for null pointer value
error: function pointer assumed to be nullable, even though it isn't
--> $DIR/fn_null_check.rs:17:8
|
LL | if (fn_ptr as *const ()) == (0 as *const ()) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try wrapping your function pointer type in `Option<T>` instead, and using `is_none` to check for null pointer value
error: function pointer assumed to be nullable, even though it isn't
--> $DIR/fn_null_check.rs:18:8
|
LL | if (fn_ptr as *const ()) == ZPTR {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try wrapping your function pointer type in `Option<T>` instead, and using `is_none` to check for null pointer value
error: aborting due to 5 previous errors

View File

@ -279,7 +279,9 @@ macro_rules! create_binding_if_some_nf {
create_binding_if_some_nf!(v, g());
// Already a let-else
let Some(a) = (if let Some(b) = Some(Some(())) { b } else { return }) else { panic!() };
let Some(a) = (if let Some(b) = Some(Some(())) { b } else { return }) else {
panic!()
};
// If a type annotation is present, don't lint as
// expressing the type might be too hard
@ -304,9 +306,7 @@ macro_rules! macro_call {
let _x = if let Some(x) = Some(1) {
x
} else {
let Some(_z) = Some(3) else {
return
};
let Some(_z) = Some(3) else { return };
1
};

View File

@ -352,7 +352,7 @@ LL + };
|
error: this could be rewritten as `let...else`
--> $DIR/manual_let_else.rs:297:5
--> $DIR/manual_let_else.rs:299:5
|
LL | / let _ = match ff {
LL | | Some(value) => value,

View File

@ -10,7 +10,8 @@ fn main() {
b"aaa";
br#""aaa""#;
br#"\s"#;
c"aaa";
cr#""aaa""#;
cr#"\s"#;
// currently disabled: https://github.com/rust-lang/rust/issues/113333
// cr#"aaa"#;
// cr#""aaa""#;
// cr#"\s"#;
}

View File

@ -10,7 +10,8 @@ fn main() {
br#"aaa"#;
br#""aaa""#;
br#"\s"#;
cr#"aaa"#;
cr#""aaa""#;
cr#"\s"#;
// currently disabled: https://github.com/rust-lang/rust/issues/113333
// cr#"aaa"#;
// cr#""aaa""#;
// cr#"\s"#;
}

View File

@ -12,11 +12,5 @@ error: unnecessary raw string literal
LL | br#"aaa"#;
| ^^^^^^^^^ help: try: `b"aaa"`
error: unnecessary raw string literal
--> $DIR/needless_raw_string.rs:13:5
|
LL | cr#"aaa"#;
| ^^^^^^^^^ help: try: `c"aaa"`
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors

View File

@ -12,12 +12,9 @@ fn main() {
br#"Hello "world"!"#;
br####" "### "## "# "####;
br###" "aa" "# "## "###;
cr#"aaa"#;
cr#"Hello "world"!"#;
cr####" "### "## "# "####;
cr###" "aa" "# "## "###;
// Issue #11068, do not lint
r##"a"#"a"##;
br##"a"#"a"##;
cr##"a"#"a"##;
// currently disabled: https://github.com/rust-lang/rust/issues/113333
// cr#"aaa"#;
// cr##"Hello "world"!"##;
// cr######" "### "## "# "######;
// cr######" "aa" "# "## "######;
}

View File

@ -12,12 +12,9 @@ fn main() {
br##"Hello "world"!"##;
br######" "### "## "# "######;
br######" "aa" "# "## "######;
cr#"aaa"#;
cr##"Hello "world"!"##;
cr######" "### "## "# "######;
cr######" "aa" "# "## "######;
// Issue #11068, do not lint
r##"a"#"a"##;
br##"a"#"a"##;
cr##"a"#"a"##;
// currently disabled: https://github.com/rust-lang/rust/issues/113333
// cr#"aaa"#;
// cr##"Hello "world"!"##;
// cr######" "### "## "# "######;
// cr######" "aa" "# "## "######;
}

View File

@ -36,23 +36,5 @@ error: unnecessary hashes around raw string literal
LL | br######" "aa" "# "## "######;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `br###" "aa" "# "## "###`
error: unnecessary hashes around raw string literal
--> $DIR/needless_raw_string_hashes.rs:16:5
|
LL | cr##"Hello "world"!"##;
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `cr#"Hello "world"!"#`
error: unnecessary hashes around raw string literal
--> $DIR/needless_raw_string_hashes.rs:17:5
|
LL | cr######" "### "## "# "######;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cr####" "### "## "# "####`
error: unnecessary hashes around raw string literal
--> $DIR/needless_raw_string_hashes.rs:18:5
|
LL | cr######" "aa" "# "## "######;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cr###" "aa" "# "## "###`
error: aborting due to 9 previous errors
error: aborting due to 6 previous errors

View File

@ -37,6 +37,7 @@
#![allow(for_loops_over_fallibles)]
#![allow(forgetting_copy_types)]
#![allow(forgetting_references)]
#![allow(incorrect_fn_null_checks)]
#![allow(array_into_iter)]
#![allow(invalid_atomic_ordering)]
#![allow(invalid_value)]
@ -89,6 +90,7 @@
#![warn(for_loops_over_fallibles)]
#![warn(forgetting_copy_types)]
#![warn(forgetting_references)]
#![warn(incorrect_fn_null_checks)]
#![warn(array_into_iter)]
#![warn(invalid_atomic_ordering)]
#![warn(invalid_value)]

View File

@ -37,6 +37,7 @@
#![allow(for_loops_over_fallibles)]
#![allow(forgetting_copy_types)]
#![allow(forgetting_references)]
#![allow(incorrect_fn_null_checks)]
#![allow(array_into_iter)]
#![allow(invalid_atomic_ordering)]
#![allow(invalid_value)]
@ -89,6 +90,7 @@
#![warn(clippy::for_loops_over_fallibles)]
#![warn(clippy::forget_copy)]
#![warn(clippy::forget_ref)]
#![warn(clippy::fn_null_check)]
#![warn(clippy::into_iter_on_array)]
#![warn(clippy::invalid_atomic_ordering)]
#![warn(clippy::invalid_ref)]

View File

@ -1,5 +1,5 @@
error: lint `clippy::almost_complete_letter_range` has been renamed to `clippy::almost_complete_range`
--> $DIR/rename.rs:52:9
--> $DIR/rename.rs:53:9
|
LL | #![warn(clippy::almost_complete_letter_range)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::almost_complete_range`
@ -7,310 +7,316 @@ LL | #![warn(clippy::almost_complete_letter_range)]
= note: `-D renamed-and-removed-lints` implied by `-D warnings`
error: lint `clippy::blacklisted_name` has been renamed to `clippy::disallowed_names`
--> $DIR/rename.rs:53:9
--> $DIR/rename.rs:54:9
|
LL | #![warn(clippy::blacklisted_name)]
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_names`
error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_if_conditions`
--> $DIR/rename.rs:54:9
--> $DIR/rename.rs:55:9
|
LL | #![warn(clippy::block_in_if_condition_expr)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions`
error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_if_conditions`
--> $DIR/rename.rs:55:9
--> $DIR/rename.rs:56:9
|
LL | #![warn(clippy::block_in_if_condition_stmt)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions`
error: lint `clippy::box_vec` has been renamed to `clippy::box_collection`
--> $DIR/rename.rs:56:9
--> $DIR/rename.rs:57:9
|
LL | #![warn(clippy::box_vec)]
| ^^^^^^^^^^^^^^^ help: use the new name: `clippy::box_collection`
error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes`
--> $DIR/rename.rs:57:9
--> $DIR/rename.rs:58:9
|
LL | #![warn(clippy::const_static_lifetime)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_static_lifetimes`
error: lint `clippy::cyclomatic_complexity` has been renamed to `clippy::cognitive_complexity`
--> $DIR/rename.rs:58:9
--> $DIR/rename.rs:59:9
|
LL | #![warn(clippy::cyclomatic_complexity)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::cognitive_complexity`
error: lint `clippy::derive_hash_xor_eq` has been renamed to `clippy::derived_hash_with_manual_eq`
--> $DIR/rename.rs:59:9
--> $DIR/rename.rs:60:9
|
LL | #![warn(clippy::derive_hash_xor_eq)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::derived_hash_with_manual_eq`
error: lint `clippy::disallowed_method` has been renamed to `clippy::disallowed_methods`
--> $DIR/rename.rs:60:9
--> $DIR/rename.rs:61:9
|
LL | #![warn(clippy::disallowed_method)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_methods`
error: lint `clippy::disallowed_type` has been renamed to `clippy::disallowed_types`
--> $DIR/rename.rs:61:9
--> $DIR/rename.rs:62:9
|
LL | #![warn(clippy::disallowed_type)]
| ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_types`
error: lint `clippy::eval_order_dependence` has been renamed to `clippy::mixed_read_write_in_expression`
--> $DIR/rename.rs:62:9
--> $DIR/rename.rs:63:9
|
LL | #![warn(clippy::eval_order_dependence)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::mixed_read_write_in_expression`
error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion`
--> $DIR/rename.rs:63:9
--> $DIR/rename.rs:64:9
|
LL | #![warn(clippy::identity_conversion)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion`
error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok`
--> $DIR/rename.rs:64:9
--> $DIR/rename.rs:65:9
|
LL | #![warn(clippy::if_let_some_result)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok`
error: lint `clippy::integer_arithmetic` has been renamed to `clippy::arithmetic_side_effects`
--> $DIR/rename.rs:65:9
--> $DIR/rename.rs:66:9
|
LL | #![warn(clippy::integer_arithmetic)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::arithmetic_side_effects`
error: lint `clippy::logic_bug` has been renamed to `clippy::overly_complex_bool_expr`
--> $DIR/rename.rs:66:9
--> $DIR/rename.rs:67:9
|
LL | #![warn(clippy::logic_bug)]
| ^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::overly_complex_bool_expr`
error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default`
--> $DIR/rename.rs:67:9
--> $DIR/rename.rs:68:9
|
LL | #![warn(clippy::new_without_default_derive)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default`
error: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map`
--> $DIR/rename.rs:68:9
--> $DIR/rename.rs:69:9
|
LL | #![warn(clippy::option_and_then_some)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map`
error: lint `clippy::option_expect_used` has been renamed to `clippy::expect_used`
--> $DIR/rename.rs:69:9
--> $DIR/rename.rs:70:9
|
LL | #![warn(clippy::option_expect_used)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used`
error: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or`
--> $DIR/rename.rs:70:9
--> $DIR/rename.rs:71:9
|
LL | #![warn(clippy::option_map_unwrap_or)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
error: lint `clippy::option_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or`
--> $DIR/rename.rs:71:9
--> $DIR/rename.rs:72:9
|
LL | #![warn(clippy::option_map_unwrap_or_else)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
error: lint `clippy::option_unwrap_used` has been renamed to `clippy::unwrap_used`
--> $DIR/rename.rs:72:9
--> $DIR/rename.rs:73:9
|
LL | #![warn(clippy::option_unwrap_used)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`
error: lint `clippy::ref_in_deref` has been renamed to `clippy::needless_borrow`
--> $DIR/rename.rs:73:9
--> $DIR/rename.rs:74:9
|
LL | #![warn(clippy::ref_in_deref)]
| ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_borrow`
error: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used`
--> $DIR/rename.rs:74:9
--> $DIR/rename.rs:75:9
|
LL | #![warn(clippy::result_expect_used)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used`
error: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or`
--> $DIR/rename.rs:75:9
--> $DIR/rename.rs:76:9
|
LL | #![warn(clippy::result_map_unwrap_or_else)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
error: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used`
--> $DIR/rename.rs:76:9
--> $DIR/rename.rs:77:9
|
LL | #![warn(clippy::result_unwrap_used)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`
error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str`
--> $DIR/rename.rs:77:9
--> $DIR/rename.rs:78:9
|
LL | #![warn(clippy::single_char_push_str)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::single_char_add_str`
error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions`
--> $DIR/rename.rs:78:9
--> $DIR/rename.rs:79:9
|
LL | #![warn(clippy::stutter)]
| ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions`
error: lint `clippy::to_string_in_display` has been renamed to `clippy::recursive_format_impl`
--> $DIR/rename.rs:79:9
--> $DIR/rename.rs:80:9
|
LL | #![warn(clippy::to_string_in_display)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::recursive_format_impl`
error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters`
--> $DIR/rename.rs:80:9
--> $DIR/rename.rs:81:9
|
LL | #![warn(clippy::zero_width_space)]
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters`
error: lint `clippy::cast_ref_to_mut` has been renamed to `cast_ref_to_mut`
--> $DIR/rename.rs:81:9
--> $DIR/rename.rs:82:9
|
LL | #![warn(clippy::cast_ref_to_mut)]
| ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `cast_ref_to_mut`
error: lint `clippy::clone_double_ref` has been renamed to `suspicious_double_ref_op`
--> $DIR/rename.rs:82:9
--> $DIR/rename.rs:83:9
|
LL | #![warn(clippy::clone_double_ref)]
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `suspicious_double_ref_op`
error: lint `clippy::cmp_nan` has been renamed to `invalid_nan_comparisons`
--> $DIR/rename.rs:83:9
--> $DIR/rename.rs:84:9
|
LL | #![warn(clippy::cmp_nan)]
| ^^^^^^^^^^^^^^^ help: use the new name: `invalid_nan_comparisons`
error: lint `clippy::drop_bounds` has been renamed to `drop_bounds`
--> $DIR/rename.rs:84:9
--> $DIR/rename.rs:85:9
|
LL | #![warn(clippy::drop_bounds)]
| ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds`
error: lint `clippy::drop_copy` has been renamed to `dropping_copy_types`
--> $DIR/rename.rs:85:9
--> $DIR/rename.rs:86:9
|
LL | #![warn(clippy::drop_copy)]
| ^^^^^^^^^^^^^^^^^ help: use the new name: `dropping_copy_types`
error: lint `clippy::drop_ref` has been renamed to `dropping_references`
--> $DIR/rename.rs:86:9
--> $DIR/rename.rs:87:9
|
LL | #![warn(clippy::drop_ref)]
| ^^^^^^^^^^^^^^^^ help: use the new name: `dropping_references`
error: lint `clippy::for_loop_over_option` has been renamed to `for_loops_over_fallibles`
--> $DIR/rename.rs:87:9
--> $DIR/rename.rs:88:9
|
LL | #![warn(clippy::for_loop_over_option)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
error: lint `clippy::for_loop_over_result` has been renamed to `for_loops_over_fallibles`
--> $DIR/rename.rs:88:9
--> $DIR/rename.rs:89:9
|
LL | #![warn(clippy::for_loop_over_result)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
error: lint `clippy::for_loops_over_fallibles` has been renamed to `for_loops_over_fallibles`
--> $DIR/rename.rs:89:9
--> $DIR/rename.rs:90:9
|
LL | #![warn(clippy::for_loops_over_fallibles)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
error: lint `clippy::forget_copy` has been renamed to `forgetting_copy_types`
--> $DIR/rename.rs:90:9
--> $DIR/rename.rs:91:9
|
LL | #![warn(clippy::forget_copy)]
| ^^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_copy_types`
error: lint `clippy::forget_ref` has been renamed to `forgetting_references`
--> $DIR/rename.rs:91:9
--> $DIR/rename.rs:92:9
|
LL | #![warn(clippy::forget_ref)]
| ^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_references`
error: lint `clippy::fn_null_check` has been renamed to `incorrect_fn_null_checks`
--> $DIR/rename.rs:93:9
|
LL | #![warn(clippy::fn_null_check)]
| ^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `incorrect_fn_null_checks`
error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter`
--> $DIR/rename.rs:92:9
--> $DIR/rename.rs:94:9
|
LL | #![warn(clippy::into_iter_on_array)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter`
error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering`
--> $DIR/rename.rs:93:9
--> $DIR/rename.rs:95:9
|
LL | #![warn(clippy::invalid_atomic_ordering)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering`
error: lint `clippy::invalid_ref` has been renamed to `invalid_value`
--> $DIR/rename.rs:94:9
--> $DIR/rename.rs:96:9
|
LL | #![warn(clippy::invalid_ref)]
| ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value`
error: lint `clippy::invalid_utf8_in_unchecked` has been renamed to `invalid_from_utf8_unchecked`
--> $DIR/rename.rs:95:9
--> $DIR/rename.rs:97:9
|
LL | #![warn(clippy::invalid_utf8_in_unchecked)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_from_utf8_unchecked`
error: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop`
--> $DIR/rename.rs:96:9
--> $DIR/rename.rs:98:9
|
LL | #![warn(clippy::let_underscore_drop)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `let_underscore_drop`
error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums`
--> $DIR/rename.rs:97:9
--> $DIR/rename.rs:99:9
|
LL | #![warn(clippy::mem_discriminant_non_enum)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums`
error: lint `clippy::panic_params` has been renamed to `non_fmt_panics`
--> $DIR/rename.rs:98:9
--> $DIR/rename.rs:100:9
|
LL | #![warn(clippy::panic_params)]
| ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics`
error: lint `clippy::positional_named_format_parameters` has been renamed to `named_arguments_used_positionally`
--> $DIR/rename.rs:99:9
--> $DIR/rename.rs:101:9
|
LL | #![warn(clippy::positional_named_format_parameters)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally`
error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `temporary_cstring_as_ptr`
--> $DIR/rename.rs:100:9
--> $DIR/rename.rs:102:9
|
LL | #![warn(clippy::temporary_cstring_as_ptr)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `temporary_cstring_as_ptr`
error: lint `clippy::undropped_manually_drops` has been renamed to `undropped_manually_drops`
--> $DIR/rename.rs:101:9
--> $DIR/rename.rs:103:9
|
LL | #![warn(clippy::undropped_manually_drops)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `undropped_manually_drops`
error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints`
--> $DIR/rename.rs:102:9
--> $DIR/rename.rs:104:9
|
LL | #![warn(clippy::unknown_clippy_lints)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints`
error: lint `clippy::unused_label` has been renamed to `unused_labels`
--> $DIR/rename.rs:103:9
--> $DIR/rename.rs:105:9
|
LL | #![warn(clippy::unused_label)]
| ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels`
error: aborting due to 52 previous errors
error: aborting due to 53 previous errors

View File

@ -116,5 +116,7 @@ fn function_returning_option() -> Option<i32> {
// No warning
fn let_else_stmts() {
let Some(x) = function_returning_option() else { return; };
let Some(x) = function_returning_option() else {
return;
};
}