1
Fork 0

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

Rustup

r? `@ghost`

changelog: none
This commit is contained in:
bors 2023-12-28 18:25:36 +00:00
commit ac4c2094a6
41 changed files with 202 additions and 128 deletions

View file

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

View file

@ -1,6 +1,6 @@
[package] [package]
name = "clippy_config" name = "clippy_config"
version = "0.1.76" version = "0.1.77"
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View file

@ -636,11 +636,12 @@ impl Conf {
match path { match path {
Ok((_, warnings)) => { Ok((_, warnings)) => {
for warning in warnings { for warning in warnings {
sess.warn(warning.clone()); sess.dcx().warn(warning.clone());
} }
}, },
Err(error) => { Err(error) => {
sess.err(format!("error finding Clippy's configuration file: {error}")); sess.dcx()
.err(format!("error finding Clippy's configuration file: {error}"));
}, },
} }
@ -652,7 +653,7 @@ impl Conf {
Ok((Some(path), _)) => match sess.source_map().load_file(path) { Ok((Some(path), _)) => match sess.source_map().load_file(path) {
Ok(file) => deserialize(&file), Ok(file) => deserialize(&file),
Err(error) => { Err(error) => {
sess.err(format!("failed to read `{}`: {error}", path.display())); sess.dcx().err(format!("failed to read `{}`: {error}", path.display()));
TryConf::default() TryConf::default()
}, },
}, },
@ -663,14 +664,14 @@ impl Conf {
// all conf errors are non-fatal, we just use the default conf in case of error // all conf errors are non-fatal, we just use the default conf in case of error
for error in errors { for error in errors {
sess.span_err( sess.dcx().span_err(
error.span, error.span,
format!("error reading Clippy's configuration file: {}", error.message), format!("error reading Clippy's configuration file: {}", error.message),
); );
} }
for warning in warnings { for warning in warnings {
sess.span_warn( sess.dcx().span_warn(
warning.span, warning.span,
format!("error reading Clippy's configuration file: {}", warning.message), format!("error reading Clippy's configuration file: {}", warning.message),
); );

View file

@ -84,7 +84,7 @@ impl Msrv {
(None, Some(cargo_msrv)) => self.stack = vec![cargo_msrv], (None, Some(cargo_msrv)) => self.stack = vec![cargo_msrv],
(Some(clippy_msrv), Some(cargo_msrv)) => { (Some(clippy_msrv), Some(cargo_msrv)) => {
if clippy_msrv != cargo_msrv { if clippy_msrv != cargo_msrv {
sess.warn(format!( sess.dcx().warn(format!(
"the MSRV in `clippy.toml` and `Cargo.toml` differ; using `{clippy_msrv}` from `clippy.toml`" "the MSRV in `clippy.toml` and `Cargo.toml` differ; using `{clippy_msrv}` from `clippy.toml`"
)); ));
} }
@ -107,7 +107,8 @@ impl Msrv {
if let Some(msrv_attr) = msrv_attrs.next() { if let Some(msrv_attr) = msrv_attrs.next() {
if let Some(duplicate) = msrv_attrs.last() { if let Some(duplicate) = msrv_attrs.last() {
sess.struct_span_err(duplicate.span, "`clippy::msrv` is defined multiple times") sess.dcx()
.struct_span_err(duplicate.span, "`clippy::msrv` is defined multiple times")
.span_note(msrv_attr.span, "first definition found here") .span_note(msrv_attr.span, "first definition found here")
.emit(); .emit();
} }
@ -117,9 +118,10 @@ impl Msrv {
return Some(version); return Some(version);
} }
sess.span_err(msrv_attr.span, format!("`{msrv}` is not a valid Rust version")); sess.dcx()
.span_err(msrv_attr.span, format!("`{msrv}` is not a valid Rust version"));
} else { } else {
sess.span_err(msrv_attr.span, "bad clippy attribute"); sess.dcx().span_err(msrv_attr.span, "bad clippy attribute");
} }
} }

View file

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

View file

@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_hir_and_then;
use clippy_utils::source::snippet; use clippy_utils::source::snippet;
use clippy_utils::ty::implements_trait; use clippy_utils::ty::implements_trait;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{Body, BodyId, CoroutineKind, CoroutineSource, ExprKind, QPath}; use rustc_hir::{Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, QPath};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::declare_lint_pass; use rustc_session::declare_lint_pass;
@ -44,16 +44,22 @@ declare_clippy_lint! {
declare_lint_pass!(AsyncYieldsAsync => [ASYNC_YIELDS_ASYNC]); declare_lint_pass!(AsyncYieldsAsync => [ASYNC_YIELDS_ASYNC]);
impl<'tcx> LateLintPass<'tcx> for AsyncYieldsAsync { impl<'tcx> LateLintPass<'tcx> for AsyncYieldsAsync {
fn check_body(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
use CoroutineSource::{Block, Closure};
// For functions, with explicitly defined types, don't warn. // For functions, with explicitly defined types, don't warn.
// XXXkhuey maybe we should? // XXXkhuey maybe we should?
if let Some(CoroutineKind::Async(Block | Closure)) = body.coroutine_kind { if let ExprKind::Closure(Closure {
kind:
ClosureKind::Coroutine(CoroutineKind::Desugared(
CoroutineDesugaring::Async,
CoroutineSource::Block | CoroutineSource::Closure,
)),
body: body_id,
..
}) = expr.kind
{
if let Some(future_trait_def_id) = cx.tcx.lang_items().future_trait() { if let Some(future_trait_def_id) = cx.tcx.lang_items().future_trait() {
let body_id = BodyId { let typeck_results = cx.tcx.typeck_body(*body_id);
hir_id: body.value.hir_id, let body = cx.tcx.hir().body(*body_id);
};
let typeck_results = cx.tcx.typeck_body(body_id);
let expr_ty = typeck_results.expr_ty(body.value); let expr_ty = typeck_results.expr_ty(body.value);
if implements_trait(cx, expr_ty, future_trait_def_id, &[]) { if implements_trait(cx, expr_ty, future_trait_def_id, &[]) {

View file

@ -2,8 +2,8 @@ use clippy_config::types::DisallowedPath;
use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::{match_def_path, paths}; use clippy_utils::{match_def_path, paths};
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_hir as hir;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::{Body, CoroutineKind, CoroutineSource};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::mir::CoroutineLayout; use rustc_middle::mir::CoroutineLayout;
use rustc_session::impl_lint_pass; use rustc_session::impl_lint_pass;
@ -183,8 +183,8 @@ impl AwaitHolding {
} }
} }
impl LateLintPass<'_> for AwaitHolding { impl<'tcx> LateLintPass<'tcx> for AwaitHolding {
fn check_crate(&mut self, cx: &LateContext<'_>) { fn check_crate(&mut self, cx: &LateContext<'tcx>) {
for conf in &self.conf_invalid_types { for conf in &self.conf_invalid_types {
let segs: Vec<_> = conf.path().split("::").collect(); let segs: Vec<_> = conf.path().split("::").collect();
for id in clippy_utils::def_path_def_ids(cx, &segs) { for id in clippy_utils::def_path_def_ids(cx, &segs) {
@ -193,11 +193,14 @@ impl LateLintPass<'_> for AwaitHolding {
} }
} }
fn check_body(&mut self, cx: &LateContext<'_>, body: &'_ Body<'_>) { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
use CoroutineSource::{Block, Closure, Fn}; if let hir::ExprKind::Closure(hir::Closure {
if let Some(CoroutineKind::Async(Block | Closure | Fn)) = body.coroutine_kind { kind: hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)),
let def_id = cx.tcx.hir().body_owner_def_id(body.id()); def_id,
if let Some(coroutine_layout) = cx.tcx.mir_coroutine_witnesses(def_id) { ..
}) = expr.kind
{
if let Some(coroutine_layout) = cx.tcx.mir_coroutine_witnesses(*def_id) {
self.check_interior_types(cx, coroutine_layout); self.check_interior_types(cx, coroutine_layout);
} }
} }

View file

@ -6,7 +6,7 @@ use clippy_utils::diagnostics::span_lint;
use rustc_ast::{CoroutineKind, Fn, FnRetTy, Item, ItemKind}; use rustc_ast::{CoroutineKind, Fn, FnRetTy, Item, ItemKind};
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::Lrc;
use rustc_errors::emitter::EmitterWriter; use rustc_errors::emitter::EmitterWriter;
use rustc_errors::Handler; use rustc_errors::DiagCtxt;
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_parse::maybe_new_parser_from_source_str; use rustc_parse::maybe_new_parser_from_source_str;
use rustc_parse::parser::ForceCollect; use rustc_parse::parser::ForceCollect;
@ -45,10 +45,10 @@ pub fn check(
let fallback_bundle = let fallback_bundle =
rustc_errors::fallback_fluent_bundle(rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), false); rustc_errors::fallback_fluent_bundle(rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), false);
let emitter = EmitterWriter::new(Box::new(io::sink()), fallback_bundle); let emitter = EmitterWriter::new(Box::new(io::sink()), fallback_bundle);
let handler = Handler::with_emitter(Box::new(emitter)).disable_warnings(); let dcx = DiagCtxt::with_emitter(Box::new(emitter)).disable_warnings();
#[expect(clippy::arc_with_non_send_sync)] // `Lrc` is expected by with_span_handler #[expect(clippy::arc_with_non_send_sync)] // `Lrc` is expected by with_dcx
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
let sess = ParseSess::with_span_handler(handler, sm); let sess = ParseSess::with_dcx(dcx, sm);
let mut parser = match maybe_new_parser_from_source_str(&sess, filename, code) { let mut parser = match maybe_new_parser_from_source_str(&sess, filename, code) {
Ok(p) => p, Ok(p) => p,

View file

@ -436,7 +436,7 @@ impl LateLintPass<'_> for ItemNameRepetitions {
{ {
match item.kind { match item.kind {
ItemKind::Enum(def, _) => check_variant(cx, self.enum_threshold, &def, item_name, item.span), ItemKind::Enum(def, _) => check_variant(cx, self.enum_threshold, &def, item_name, item.span),
ItemKind::Struct(VariantData::Struct(fields, _), _) => { ItemKind::Struct(VariantData::Struct { fields, .. }, _) => {
check_fields(cx, self.struct_threshold, item, fields); check_fields(cx, self.struct_threshold, item, fields);
}, },
_ => (), _ => (),

View file

@ -8,8 +8,8 @@ use rustc_hir::def::Res;
use rustc_hir::def_id::{DefId, DefIdSet}; use rustc_hir::def_id::{DefId, DefIdSet};
use rustc_hir::{ use rustc_hir::{
AssocItemKind, BinOpKind, Expr, ExprKind, FnRetTy, GenericArg, GenericBound, ImplItem, ImplItemKind, AssocItemKind, BinOpKind, Expr, ExprKind, FnRetTy, GenericArg, GenericBound, ImplItem, ImplItemKind,
ImplicitSelfKind, Item, ItemKind, LangItem, Mutability, Node, PatKind, PathSegment, PrimTy, QPath, TraitItemRef, ImplicitSelfKind, Item, ItemKind, Mutability, Node, OpaqueTyOrigin, PatKind, PathSegment, PrimTy, QPath,
TyKind, TypeBindingKind, TraitItemRef, TyKind, TypeBindingKind,
}; };
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self, AssocKind, FnSig, Ty}; use rustc_middle::ty::{self, AssocKind, FnSig, Ty};
@ -289,8 +289,10 @@ fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&
kind: ItemKind::OpaqueTy(opaque), kind: ItemKind::OpaqueTy(opaque),
.. ..
} = item } = item
&& opaque.bounds.len() == 1 && let OpaqueTyOrigin::AsyncFn(_) = opaque.origin
&& let GenericBound::LangItemTrait(LangItem::Future, _, _, generic_args) = &opaque.bounds[0] && let [GenericBound::Trait(trait_ref, _)] = &opaque.bounds
&& let Some(segment) = trait_ref.trait_ref.path.segments.last()
&& let Some(generic_args) = segment.args
&& generic_args.bindings.len() == 1 && generic_args.bindings.len() == 1
&& let TypeBindingKind::Equality { && let TypeBindingKind::Equality {
term: term:

View file

@ -3,8 +3,9 @@ use clippy_utils::source::{position_before_rarrow, snippet_block, snippet_opt};
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::intravisit::FnKind; use rustc_hir::intravisit::FnKind;
use rustc_hir::{ use rustc_hir::{
Block, Body, Closure, CoroutineKind, CoroutineSource, Expr, ExprKind, FnDecl, FnRetTy, GenericArg, GenericBound, Block, Body, Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, FnDecl,
ImplItem, Item, ItemKind, LifetimeName, Node, Term, TraitRef, Ty, TyKind, TypeBindingKind, FnRetTy, GenericArg, GenericBound, ImplItem, Item, ItemKind, LifetimeName, Node, Term, TraitRef, Ty, TyKind,
TypeBindingKind,
}; };
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::declare_lint_pass; use rustc_session::declare_lint_pass;
@ -172,15 +173,14 @@ fn captures_all_lifetimes(inputs: &[Ty<'_>], output_lifetimes: &[LifetimeName])
} }
fn desugared_async_block<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) -> Option<&'tcx Body<'tcx>> { fn desugared_async_block<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) -> Option<&'tcx Body<'tcx>> {
if let Some(block_expr) = block.expr if let Some(Expr {
&& let Expr { kind: ExprKind::Closure(&Closure { kind, body, .. }),
kind: ExprKind::Closure(&Closure { body, .. }), ..
.. }) = block.expr
} = block_expr && let ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Block)) =
&& let closure_body = cx.tcx.hir().body(body) kind
&& closure_body.coroutine_kind == Some(CoroutineKind::Async(CoroutineSource::Block))
{ {
return Some(closure_body); return Some(cx.tcx.hir().body(body));
} }
None None

View file

@ -103,7 +103,7 @@ impl EarlyLintPass for ManualNonExhaustiveStruct {
if let ast::ItemKind::Struct(variant_data, _) = &item.kind { if let ast::ItemKind::Struct(variant_data, _) = &item.kind {
let (fields, delimiter) = match variant_data { let (fields, delimiter) = match variant_data {
ast::VariantData::Struct(fields, _) => (&**fields, '{'), ast::VariantData::Struct { fields, .. } => (&**fields, '{'),
ast::VariantData::Tuple(fields, _) => (&**fields, '('), ast::VariantData::Tuple(fields, _) => (&**fields, '('),
ast::VariantData::Unit(_) => return, ast::VariantData::Unit(_) => return,
}; };

View file

@ -32,7 +32,6 @@ pub(super) fn check<'tcx>(
&& let Body { && let Body {
params: [p], params: [p],
value: body_expr, value: body_expr,
coroutine_kind: _,
} = cx.tcx.hir().body(c.body) } = cx.tcx.hir().body(c.body)
&& let PatKind::Tuple([key_pat, val_pat], _) = p.pat.kind && let PatKind::Tuple([key_pat, val_pat], _) = p.pat.kind
&& let (replacement_kind, annotation, bound_ident) = match (&key_pat.kind, &val_pat.kind) { && let (replacement_kind, annotation, bound_ident) = match (&key_pat.kind, &val_pat.kind) {

View file

@ -153,7 +153,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
if let Err((span, err)) = is_min_const_fn(cx.tcx, mir, &self.msrv) { if let Err((span, err)) = is_min_const_fn(cx.tcx, mir, &self.msrv) {
if cx.tcx.is_const_fn_raw(def_id.to_def_id()) { if cx.tcx.is_const_fn_raw(def_id.to_def_id()) {
cx.tcx.sess.span_err(span, err); cx.tcx.dcx().span_err(span, err);
} }
} else { } else {
span_lint(cx, MISSING_CONST_FOR_FN, span, "this could be a `const fn`"); span_lint(cx, MISSING_CONST_FOR_FN, span, "this could be a `const fn`");

View file

@ -220,7 +220,11 @@ where
F: FnMut(&ast::Block, Option<&ast::Label>), F: FnMut(&ast::Block, Option<&ast::Label>),
{ {
if let ast::ExprKind::While(_, loop_block, label) if let ast::ExprKind::While(_, loop_block, label)
| ast::ExprKind::ForLoop(_, _, loop_block, label) | ast::ExprKind::ForLoop {
body: loop_block,
label,
..
}
| ast::ExprKind::Loop(loop_block, label, ..) = &expr.kind | ast::ExprKind::Loop(loop_block, label, ..) = &expr.kind
{ {
func(loop_block, label.as_ref()); func(loop_block, label.as_ref());

View file

@ -3,7 +3,7 @@ use clippy_utils::path_res;
use clippy_utils::source::snippet; use clippy_utils::source::snippet;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_hir::{Block, Body, CoroutineKind, CoroutineSource, Expr, ExprKind, LangItem, MatchSource, QPath}; use rustc_hir::{Block, Body, Expr, ExprKind, LangItem, MatchSource, QPath};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::declare_lint_pass; use rustc_session::declare_lint_pass;
@ -86,22 +86,20 @@ impl LateLintPass<'_> for NeedlessQuestionMark {
} }
fn check_body(&mut self, cx: &LateContext<'_>, body: &'_ Body<'_>) { fn check_body(&mut self, cx: &LateContext<'_>, body: &'_ Body<'_>) {
if let Some(CoroutineKind::Async(CoroutineSource::Fn)) = body.coroutine_kind { if let ExprKind::Block(
if let ExprKind::Block( Block {
Block { expr:
expr: Some(Expr {
Some(Expr { kind: ExprKind::DropTemps(async_body),
kind: ExprKind::DropTemps(async_body), ..
.. }),
}), ..
.. },
}, _,
_, ) = body.value.kind
) = body.value.kind {
{ if let ExprKind::Block(Block { expr: Some(expr), .. }, ..) = async_body.kind {
if let ExprKind::Block(Block { expr: Some(expr), .. }, ..) = async_body.kind { check(cx, expr.peel_blocks());
check(cx, expr);
}
} }
} else { } else {
check(cx, body.value.peel_blocks()); check(cx, body.value.peel_blocks());

View file

@ -6,7 +6,9 @@ use clippy_utils::source::{snippet, walk_span_to_context};
use clippy_utils::ty::implements_trait; use clippy_utils::ty::implements_trait;
use clippy_utils::visitors::for_each_expr; use clippy_utils::visitors::for_each_expr;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir::{Closure, CoroutineKind, CoroutineSource, Expr, ExprKind, MatchSource}; use rustc_hir::{
Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, MatchSource,
};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro; use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::UpvarCapture; use rustc_middle::ty::UpvarCapture;
@ -73,9 +75,15 @@ impl<'tcx> LateLintPass<'tcx> for RedundantAsyncBlock {
/// If `expr` is a desugared `async` block, return the original expression if it does not capture /// If `expr` is a desugared `async` block, return the original expression if it does not capture
/// any variable by ref. /// any variable by ref.
fn desugar_async_block<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> { fn desugar_async_block<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> {
if let ExprKind::Closure(Closure { body, def_id, .. }) = expr.kind if let ExprKind::Closure(Closure { body, def_id, kind, .. }) = expr.kind
&& let body = cx.tcx.hir().body(*body) && let body = cx.tcx.hir().body(*body)
&& matches!(body.coroutine_kind, Some(CoroutineKind::Async(CoroutineSource::Block))) && matches!(
kind,
ClosureKind::Coroutine(CoroutineKind::Desugared(
CoroutineDesugaring::Async,
CoroutineSource::Block
))
)
{ {
cx.typeck_results() cx.typeck_results()
.closure_min_captures .closure_min_captures

View file

@ -5,7 +5,7 @@ use clippy_utils::sugg::Sugg;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::intravisit::{Visitor as HirVisitor, Visitor}; use rustc_hir::intravisit::{Visitor as HirVisitor, Visitor};
use rustc_hir::{intravisit as hir_visit, CoroutineKind, CoroutineSource, Node}; use rustc_hir::{intravisit as hir_visit, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Node};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::nested_filter; use rustc_middle::hir::nested_filter;
use rustc_middle::lint::in_external_macro; use rustc_middle::lint::in_external_macro;
@ -63,11 +63,11 @@ impl<'tcx> Visitor<'tcx> for ReturnVisitor {
/// Checks if the body is owned by an async closure. /// Checks if the body is owned by an async closure.
/// Returns true for `async || whatever_expression`, but false for `|| async { whatever_expression /// Returns true for `async || whatever_expression`, but false for `|| async { whatever_expression
/// }`. /// }`.
fn is_async_closure(cx: &LateContext<'_>, body: &hir::Body<'_>) -> bool { fn is_async_closure(body: &hir::Body<'_>) -> bool {
if let hir::ExprKind::Closure(innermost_closure_generated_by_desugar) = body.value.kind if let hir::ExprKind::Closure(innermost_closure_generated_by_desugar) = body.value.kind
&& let desugared_inner_closure_body = cx.tcx.hir().body(innermost_closure_generated_by_desugar.body)
// checks whether it is `async || whatever_expression` // checks whether it is `async || whatever_expression`
&& let Some(CoroutineKind::Async(CoroutineSource::Closure)) = desugared_inner_closure_body.coroutine_kind && let ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Closure))
= innermost_closure_generated_by_desugar.kind
{ {
true true
} else { } else {
@ -103,7 +103,7 @@ fn find_innermost_closure<'tcx>(
data = Some(( data = Some((
body.value, body.value,
closure.fn_decl, closure.fn_decl,
if is_async_closure(cx, body) { if is_async_closure(body) {
ty::Asyncness::Yes ty::Asyncness::Yes
} else { } else {
ty::Asyncness::No ty::Asyncness::No

View file

@ -111,7 +111,7 @@ impl<'ast> Visitor<'ast> for BreakVisitor {
ExprKind::If(_, ref then, Some(ref els)) => self.check_block(then) && self.check_expr(els), ExprKind::If(_, ref then, Some(ref els)) => self.check_block(then) && self.check_expr(els),
ExprKind::If(_, _, None) ExprKind::If(_, _, None)
// ignore loops for simplicity // ignore loops for simplicity
| ExprKind::While(..) | ExprKind::ForLoop(..) | ExprKind::Loop(..) => false, | ExprKind::While(..) | ExprKind::ForLoop { .. } | ExprKind::Loop(..) => false,
_ => { _ => {
walk_expr(self, expr); walk_expr(self, expr);
return; return;

View file

@ -554,7 +554,7 @@ fn ident_difference_expr_with_base_location(
| (Closure(_), Closure(_)) | (Closure(_), Closure(_))
| (Match(_, _), Match(_, _)) | (Match(_, _), Match(_, _))
| (Loop(_, _, _), Loop(_, _, _)) | (Loop(_, _, _), Loop(_, _, _))
| (ForLoop(_, _, _, _), ForLoop(_, _, _, _)) | (ForLoop { .. }, ForLoop { .. })
| (While(_, _, _), While(_, _, _)) | (While(_, _, _), While(_, _, _))
| (If(_, _, _), If(_, _, _)) | (If(_, _, _), If(_, _, _))
| (Let(_, _, _, _), Let(_, _, _, _)) | (Let(_, _, _, _), Let(_, _, _, _))

View file

@ -293,7 +293,7 @@ fn extend_with_struct_pat(
qself1: &Option<P<ast::QSelf>>, qself1: &Option<P<ast::QSelf>>,
path1: &ast::Path, path1: &ast::Path,
fps1: &mut [ast::PatField], fps1: &mut [ast::PatField],
rest1: bool, rest1: ast::PatFieldsRest,
start: usize, start: usize,
alternatives: &mut ThinVec<P<Pat>>, alternatives: &mut ThinVec<P<Pat>>,
) -> bool { ) -> bool {

View file

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_hir_and_then; use clippy_utils::diagnostics::span_lint_hir_and_then;
use clippy_utils::is_def_id_trait_method; use clippy_utils::is_def_id_trait_method;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::intravisit::{walk_body, walk_expr, walk_fn, FnKind, Visitor}; use rustc_hir::intravisit::{walk_expr, walk_fn, FnKind, Visitor};
use rustc_hir::{Body, Expr, ExprKind, FnDecl, Node, YieldSource}; use rustc_hir::{Body, Expr, ExprKind, FnDecl, Node, YieldSource};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::nested_filter; use rustc_middle::hir::nested_filter;
@ -78,26 +78,32 @@ impl<'a, 'tcx> Visitor<'tcx> for AsyncFnVisitor<'a, 'tcx> {
self.await_in_async_block = Some(ex.span); self.await_in_async_block = Some(ex.span);
} }
} }
walk_expr(self, ex);
}
fn nested_visit_map(&mut self) -> Self::Map { let is_async_block = matches!(
self.cx.tcx.hir() ex.kind,
} ExprKind::Closure(rustc_hir::Closure {
kind: rustc_hir::ClosureKind::Coroutine(rustc_hir::CoroutineKind::Desugared(
fn visit_body(&mut self, b: &'tcx Body<'tcx>) { rustc_hir::CoroutineDesugaring::Async,
let is_async_block = matches!(b.coroutine_kind, Some(rustc_hir::CoroutineKind::Async(_))); _
)),
..
})
);
if is_async_block { if is_async_block {
self.async_depth += 1; self.async_depth += 1;
} }
walk_body(self, b); walk_expr(self, ex);
if is_async_block { if is_async_block {
self.async_depth -= 1; self.async_depth -= 1;
} }
} }
fn nested_visit_map(&mut self) -> Self::Map {
self.cx.tcx.hir()
}
} }
impl<'tcx> LateLintPass<'tcx> for UnusedAsync { impl<'tcx> LateLintPass<'tcx> for UnusedAsync {

View file

@ -7,7 +7,8 @@ use rustc_ast::LitIntType;
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::{ use rustc_hir::{
ArrayLen, BindingAnnotation, CaptureBy, Closure, ExprKind, FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, TyKind, ArrayLen, BindingAnnotation, CaptureBy, Closure, ClosureKind, CoroutineKind, ExprKind, FnRetTy, HirId, Lit,
PatKind, QPath, StmtKind, TyKind,
}; };
use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_session::declare_lint_pass; use rustc_session::declare_lint_pass;
@ -477,7 +478,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
capture_clause, capture_clause,
fn_decl, fn_decl,
body: body_id, body: body_id,
movability, kind,
.. ..
}) => { }) => {
let capture_clause = match capture_clause { let capture_clause = match capture_clause {
@ -485,7 +486,17 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
CaptureBy::Ref => "Ref", CaptureBy::Ref => "Ref",
}; };
let movability = OptionPat::new(movability.map(|m| format!("Movability::{m:?}"))); let closure_kind = match kind {
ClosureKind::Closure => "ClosureKind::Closure".to_string(),
ClosureKind::Coroutine(coroutine_kind) => match coroutine_kind {
CoroutineKind::Desugared(desugaring, source) => format!(
"ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::{desugaring:?}, CoroutineSource::{source:?}))"
),
CoroutineKind::Coroutine(movability) => {
format!("ClosureKind::Coroutine(CoroutineKind::Coroutine(Movability::{movability:?})")
},
},
};
let ret_ty = match fn_decl.output { let ret_ty = match fn_decl.output {
FnRetTy::DefaultReturn(_) => "FnRetTy::DefaultReturn(_)", FnRetTy::DefaultReturn(_) => "FnRetTy::DefaultReturn(_)",
@ -493,7 +504,9 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
}; };
bind!(self, fn_decl, body_id); bind!(self, fn_decl, body_id);
kind!("Closure(CaptureBy::{capture_clause}, {fn_decl}, {body_id}, _, {movability})"); kind!(
"Closure {{ capture_clause: CaptureBy::{capture_clause}, fn_decl: {fn_decl}, body: {body_id}, closure_kind: {closure_kind}, .. }}"
);
chain!(self, "let {ret_ty} = {fn_decl}.output"); chain!(self, "let {ret_ty} = {fn_decl}.output");
self.body(body_id); self.body(body_id);
}, },

View file

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

View file

@ -134,6 +134,7 @@ pub fn eq_struct_rest(l: &StructRest, r: &StructRest) -> bool {
} }
} }
#[allow(clippy::too_many_lines)] // Just a big match statement
pub fn eq_expr(l: &Expr, r: &Expr) -> bool { pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
use ExprKind::*; use ExprKind::*;
if !over(&l.attrs, &r.attrs, eq_attr) { if !over(&l.attrs, &r.attrs, eq_attr) {
@ -169,9 +170,22 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
(Let(lp, le, _, _), Let(rp, re, _, _)) => eq_pat(lp, rp) && eq_expr(le, re), (Let(lp, le, _, _), Let(rp, re, _, _)) => eq_pat(lp, rp) && eq_expr(le, re),
(If(lc, lt, le), If(rc, rt, re)) => eq_expr(lc, rc) && eq_block(lt, rt) && eq_expr_opt(le, re), (If(lc, lt, le), If(rc, rt, re)) => eq_expr(lc, rc) && eq_block(lt, rt) && eq_expr_opt(le, re),
(While(lc, lt, ll), While(rc, rt, rl)) => eq_label(ll, rl) && eq_expr(lc, rc) && eq_block(lt, rt), (While(lc, lt, ll), While(rc, rt, rl)) => eq_label(ll, rl) && eq_expr(lc, rc) && eq_block(lt, rt),
(ForLoop(lp, li, lt, ll), ForLoop(rp, ri, rt, rl)) => { (
eq_label(ll, rl) && eq_pat(lp, rp) && eq_expr(li, ri) && eq_block(lt, rt) ForLoop {
}, pat: lp,
iter: li,
body: lt,
label: ll,
kind: lk,
},
ForLoop {
pat: rp,
iter: ri,
body: rt,
label: rl,
kind: rk,
},
) => eq_label(ll, rl) && eq_pat(lp, rp) && eq_expr(li, ri) && eq_block(lt, rt) && lk == rk,
(Loop(lt, ll, _), Loop(rt, rl, _)) => eq_label(ll, rl) && eq_block(lt, rt), (Loop(lt, ll, _), Loop(rt, rl, _)) => eq_label(ll, rl) && eq_block(lt, rt),
(Block(lb, ll), Block(rb, rl)) => eq_label(ll, rl) && eq_block(lb, rb), (Block(lb, ll), Block(rb, rl)) => eq_label(ll, rl) && eq_block(lb, rb),
(TryBlock(l), TryBlock(r)) => eq_block(l, r), (TryBlock(l), TryBlock(r)) => eq_block(l, r),
@ -546,7 +560,9 @@ pub fn eq_variant_data(l: &VariantData, r: &VariantData) -> bool {
use VariantData::*; use VariantData::*;
match (l, r) { match (l, r) {
(Unit(_), Unit(_)) => true, (Unit(_), Unit(_)) => true,
(Struct(l, _), Struct(r, _)) | (Tuple(l, _), Tuple(r, _)) => over(l, r, eq_struct_field), (Struct { fields: l, .. }, Struct { fields: r, .. }) | (Tuple(l, _), Tuple(r, _)) => {
over(l, r, eq_struct_field)
},
_ => false, _ => false,
} }
} }

View file

@ -76,12 +76,14 @@ pub fn get_attr<'a>(
}) })
.map_or_else( .map_or_else(
|| { || {
sess.span_err(attr_segments[1].ident.span, "usage of unknown attribute"); sess.dcx()
.span_err(attr_segments[1].ident.span, "usage of unknown attribute");
false false
}, },
|deprecation_status| { |deprecation_status| {
let mut diag = let mut diag = sess
sess.struct_span_err(attr_segments[1].ident.span, "usage of deprecated attribute"); .dcx()
.struct_span_err(attr_segments[1].ident.span, "usage of deprecated attribute");
match *deprecation_status { match *deprecation_status {
DeprecationStatus::Deprecated => { DeprecationStatus::Deprecated => {
diag.emit(); diag.emit();
@ -116,10 +118,10 @@ fn parse_attrs<F: FnMut(u64)>(sess: &Session, attrs: &[ast::Attribute], name: &'
if let Ok(value) = FromStr::from_str(value.as_str()) { if let Ok(value) = FromStr::from_str(value.as_str()) {
f(value); f(value);
} else { } else {
sess.span_err(attr.span, "not a number"); sess.dcx().span_err(attr.span, "not a number");
} }
} else { } else {
sess.span_err(attr.span, "bad clippy attribute"); sess.dcx().span_err(attr.span, "bad clippy attribute");
} }
} }
} }
@ -132,7 +134,8 @@ pub fn get_unique_attr<'a>(
let mut unique_attr: Option<&ast::Attribute> = None; let mut unique_attr: Option<&ast::Attribute> = None;
for attr in get_attr(sess, attrs, name) { for attr in get_attr(sess, attrs, name) {
if let Some(duplicate) = unique_attr { if let Some(duplicate) = unique_attr {
sess.struct_span_err(attr.span, format!("`{name}` is defined multiple times")) sess.dcx()
.struct_span_err(attr.span, format!("`{name}` is defined multiple times"))
.span_note(duplicate.span, "first definition found here") .span_note(duplicate.span, "first definition found here")
.emit(); .emit();
} else { } else {

View file

@ -200,7 +200,7 @@ fn item_search_pat(item: &Item<'_>) -> (Pat, Pat) {
ItemKind::ForeignMod { .. } => (Pat::Str("extern"), Pat::Str("}")), ItemKind::ForeignMod { .. } => (Pat::Str("extern"), Pat::Str("}")),
ItemKind::TyAlias(..) | ItemKind::OpaqueTy(_) => (Pat::Str("type"), Pat::Str(";")), ItemKind::TyAlias(..) | ItemKind::OpaqueTy(_) => (Pat::Str("type"), Pat::Str(";")),
ItemKind::Enum(..) => (Pat::Str("enum"), Pat::Str("}")), ItemKind::Enum(..) => (Pat::Str("enum"), Pat::Str("}")),
ItemKind::Struct(VariantData::Struct(..), _) => (Pat::Str("struct"), Pat::Str("}")), ItemKind::Struct(VariantData::Struct { .. }, _) => (Pat::Str("struct"), Pat::Str("}")),
ItemKind::Struct(..) => (Pat::Str("struct"), Pat::Str(";")), ItemKind::Struct(..) => (Pat::Str("struct"), Pat::Str(";")),
ItemKind::Union(..) => (Pat::Str("union"), Pat::Str("}")), ItemKind::Union(..) => (Pat::Str("union"), Pat::Str("}")),
ItemKind::Trait(_, Unsafety::Unsafe, ..) ItemKind::Trait(_, Unsafety::Unsafe, ..)
@ -255,7 +255,7 @@ fn field_def_search_pat(def: &FieldDef<'_>) -> (Pat, Pat) {
fn variant_search_pat(v: &Variant<'_>) -> (Pat, Pat) { fn variant_search_pat(v: &Variant<'_>) -> (Pat, Pat) {
match v.data { match v.data {
VariantData::Struct(..) => (Pat::Sym(v.ident.name), Pat::Str("}")), VariantData::Struct { .. } => (Pat::Sym(v.ident.name), Pat::Str("}")),
VariantData::Tuple(..) => (Pat::Sym(v.ident.name), Pat::Str("")), VariantData::Tuple(..) => (Pat::Sym(v.ident.name), Pat::Str("")),
VariantData::Unit(..) => (Pat::Sym(v.ident.name), Pat::Sym(v.ident.name)), VariantData::Unit(..) => (Pat::Sym(v.ident.name), Pat::Sym(v.ident.name)),
} }

View file

@ -49,7 +49,6 @@ pub fn span_lint<T: LintContext>(cx: &T, lint: &'static Lint, sp: impl Into<Mult
#[expect(clippy::disallowed_methods)] #[expect(clippy::disallowed_methods)]
cx.struct_span_lint(lint, sp, msg.to_string(), |diag| { cx.struct_span_lint(lint, sp, msg.to_string(), |diag| {
docs_link(diag, lint); docs_link(diag, lint);
diag
}); });
} }
@ -90,7 +89,6 @@ pub fn span_lint_and_help<T: LintContext>(
diag.help(help); diag.help(help);
} }
docs_link(diag, lint); docs_link(diag, lint);
diag
}); });
} }
@ -134,7 +132,6 @@ pub fn span_lint_and_note<T: LintContext>(
diag.note(note); diag.note(note);
} }
docs_link(diag, lint); docs_link(diag, lint);
diag
}); });
} }
@ -152,7 +149,6 @@ where
cx.struct_span_lint(lint, sp, msg.to_string(), |diag| { cx.struct_span_lint(lint, sp, msg.to_string(), |diag| {
f(diag); f(diag);
docs_link(diag, lint); docs_link(diag, lint);
diag
}); });
} }
@ -160,7 +156,6 @@ pub fn span_lint_hir(cx: &LateContext<'_>, lint: &'static Lint, hir_id: HirId, s
#[expect(clippy::disallowed_methods)] #[expect(clippy::disallowed_methods)]
cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg.to_string(), |diag| { cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg.to_string(), |diag| {
docs_link(diag, lint); docs_link(diag, lint);
diag
}); });
} }
@ -176,7 +171,6 @@ pub fn span_lint_hir_and_then(
cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg.to_string(), |diag| { cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg.to_string(), |diag| {
f(diag); f(diag);
docs_link(diag, lint); docs_link(diag, lint);
diag
}); });
} }

View file

@ -197,7 +197,7 @@ impl<'a> Sugg<'a> {
| ast::ExprKind::Continue(..) | ast::ExprKind::Continue(..)
| ast::ExprKind::Yield(..) | ast::ExprKind::Yield(..)
| ast::ExprKind::Field(..) | ast::ExprKind::Field(..)
| ast::ExprKind::ForLoop(..) | ast::ExprKind::ForLoop { .. }
| ast::ExprKind::Index(..) | ast::ExprKind::Index(..)
| ast::ExprKind::InlineAsm(..) | ast::ExprKind::InlineAsm(..)
| ast::ExprKind::OffsetOf(..) | ast::ExprKind::OffsetOf(..)

View file

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

View file

@ -1,3 +1,3 @@
[toolchain] [toolchain]
channel = "nightly-2023-12-16" channel = "nightly-2023-12-28"
components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]

View file

@ -18,7 +18,7 @@ extern crate rustc_span;
use rustc_interface::interface; use rustc_interface::interface;
use rustc_session::config::ErrorOutputType; use rustc_session::config::ErrorOutputType;
use rustc_session::parse::ParseSess; use rustc_session::parse::ParseSess;
use rustc_session::EarlyErrorHandler; use rustc_session::EarlyDiagCtxt;
use rustc_span::symbol::Symbol; use rustc_span::symbol::Symbol;
use std::env; use std::env;
@ -174,9 +174,9 @@ const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust-clippy/issues/ne
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
#[allow(clippy::ignored_unit_patterns)] #[allow(clippy::ignored_unit_patterns)]
pub fn main() { pub fn main() {
let handler = EarlyErrorHandler::new(ErrorOutputType::default()); let early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default());
rustc_driver::init_rustc_env_logger(&handler); rustc_driver::init_rustc_env_logger(&early_dcx);
let using_internal_features = rustc_driver::install_ice_hook(BUG_REPORT_URL, |handler| { let using_internal_features = rustc_driver::install_ice_hook(BUG_REPORT_URL, |handler| {
// FIXME: this macro calls unwrap internally but is called in a panicking context! It's not // FIXME: this macro calls unwrap internally but is called in a panicking context! It's not

View file

@ -11,7 +11,7 @@ use rustc_lint::{Lint, LintContext};
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
pub fn a(cx: impl LintContext, lint: &'static Lint, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) { pub fn a(cx: impl LintContext, lint: &'static Lint, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) {
cx.struct_span_lint(lint, span, msg, |b| b); cx.struct_span_lint(lint, span, msg, |_| {});
} }
pub fn b( pub fn b(
@ -21,7 +21,7 @@ pub fn b(
span: impl Into<MultiSpan>, span: impl Into<MultiSpan>,
msg: impl Into<DiagnosticMessage>, msg: impl Into<DiagnosticMessage>,
) { ) {
tcx.struct_span_lint_hir(lint, hir_id, span, msg, |b| b); tcx.struct_span_lint_hir(lint, hir_id, span, msg, |_| {});
} }
fn main() {} fn main() {}

View file

@ -1,8 +1,8 @@
error: use of a disallowed method `rustc_lint::context::LintContext::struct_span_lint` error: use of a disallowed method `rustc_lint::context::LintContext::struct_span_lint`
--> $DIR/disallow_struct_span_lint.rs:14:5 --> $DIR/disallow_struct_span_lint.rs:14:5
| |
LL | cx.struct_span_lint(lint, span, msg, |b| b); LL | cx.struct_span_lint(lint, span, msg, |_| {});
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= note: `-D clippy::disallowed-methods` implied by `-D warnings` = note: `-D clippy::disallowed-methods` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::disallowed_methods)]` = help: to override `-D warnings` add `#[allow(clippy::disallowed_methods)]`
@ -10,8 +10,8 @@ LL | cx.struct_span_lint(lint, span, msg, |b| b);
error: use of a disallowed method `rustc_middle::ty::context::TyCtxt::struct_span_lint_hir` error: use of a disallowed method `rustc_middle::ty::context::TyCtxt::struct_span_lint_hir`
--> $DIR/disallow_struct_span_lint.rs:24:5 --> $DIR/disallow_struct_span_lint.rs:24:5
| |
LL | tcx.struct_span_lint_hir(lint, hir_id, span, msg, |b| b); LL | tcx.struct_span_lint_hir(lint, hir_id, span, msg, |_| {});
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -40,10 +40,10 @@ if let ExprKind::Block(block, None) = expr.kind
{ {
// report your lint here // report your lint here
} }
if let ExprKind::Closure(CaptureBy::Value { .. }, fn_decl, body_id, _, None) = expr.kind if let ExprKind::Closure { capture_clause: CaptureBy::Value { .. }, fn_decl: fn_decl, body: body_id, closure_kind: ClosureKind::Closure, .. } = expr.kind
&& let FnRetTy::DefaultReturn(_) = fn_decl.output && let FnRetTy::DefaultReturn(_) = fn_decl.output
&& expr1 = &cx.tcx.hir().body(body_id).value && expr1 = &cx.tcx.hir().body(body_id).value
&& let ExprKind::Closure(CaptureBy::Value { .. }, fn_decl1, body_id1, _, Some(Movability::Static)) = expr1.kind && let ExprKind::Closure { capture_clause: CaptureBy::Value { .. }, fn_decl: fn_decl1, body: body_id1, closure_kind: ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Closure)), .. } = expr1.kind
&& let FnRetTy::DefaultReturn(_) = fn_decl1.output && let FnRetTy::DefaultReturn(_) = fn_decl1.output
&& expr2 = &cx.tcx.hir().body(body_id1).value && expr2 = &cx.tcx.hir().body(body_id1).value
&& let ExprKind::Block(block, None) = expr2.kind && let ExprKind::Block(block, None) = expr2.kind

View file

@ -1,6 +1,6 @@
if let StmtKind::Local(local) = stmt.kind if let StmtKind::Local(local) = stmt.kind
&& let Some(init) = local.init && let Some(init) = local.init
&& let ExprKind::Closure(CaptureBy::Ref, fn_decl, body_id, _, None) = init.kind && let ExprKind::Closure { capture_clause: CaptureBy::Ref, fn_decl: fn_decl, body: body_id, closure_kind: ClosureKind::Closure, .. } = init.kind
&& let FnRetTy::DefaultReturn(_) = fn_decl.output && let FnRetTy::DefaultReturn(_) = fn_decl.output
&& expr = &cx.tcx.hir().body(body_id).value && expr = &cx.tcx.hir().body(body_id).value
&& let ExprKind::Block(block, None) = expr.kind && let ExprKind::Block(block, None) = expr.kind
@ -12,6 +12,7 @@ if let StmtKind::Local(local) = stmt.kind
&& args.len() == 1 && args.len() == 1
&& let ExprKind::Call(func1, args1) = args[0].kind && let ExprKind::Call(func1, args1) = args[0].kind
&& let ExprKind::Path(ref qpath1) = func1.kind && let ExprKind::Path(ref qpath1) = func1.kind
&& match_qpath(qpath1, &["format_arguments", "new_v1"])
&& args1.len() == 2 && args1.len() == 2
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner) = args1[0].kind && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner) = args1[0].kind
&& let ExprKind::Array(elements) = inner.kind && let ExprKind::Array(elements) = inner.kind
@ -27,6 +28,7 @@ if let StmtKind::Local(local) = stmt.kind
&& elements1.len() == 1 && elements1.len() == 1
&& let ExprKind::Call(func2, args2) = elements1[0].kind && let ExprKind::Call(func2, args2) = elements1[0].kind
&& let ExprKind::Path(ref qpath2) = func2.kind && let ExprKind::Path(ref qpath2) = func2.kind
&& match_qpath(qpath2, &["format_argument", "new_display"])
&& args2.len() == 1 && args2.len() == 1
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner2) = args2[0].kind && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner2) = args2[0].kind
&& let ExprKind::Path(ref qpath3) = inner2.kind && let ExprKind::Path(ref qpath3) = inner2.kind

View file

@ -22,6 +22,7 @@ if let Some(higher::ForLoop { pat: pat, arg: arg, body: body, .. }) = higher::Fo
&& args.len() == 1 && args.len() == 1
&& let ExprKind::Call(func1, args1) = args[0].kind && let ExprKind::Call(func1, args1) = args[0].kind
&& let ExprKind::Path(ref qpath2) = func1.kind && let ExprKind::Path(ref qpath2) = func1.kind
&& match_qpath(qpath2, &["format_arguments", "new_v1"])
&& args1.len() == 2 && args1.len() == 2
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner) = args1[0].kind && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner) = args1[0].kind
&& let ExprKind::Array(elements) = inner.kind && let ExprKind::Array(elements) = inner.kind
@ -37,6 +38,7 @@ if let Some(higher::ForLoop { pat: pat, arg: arg, body: body, .. }) = higher::Fo
&& elements1.len() == 1 && elements1.len() == 1
&& let ExprKind::Call(func2, args2) = elements1[0].kind && let ExprKind::Call(func2, args2) = elements1[0].kind
&& let ExprKind::Path(ref qpath3) = func2.kind && let ExprKind::Path(ref qpath3) = func2.kind
&& match_qpath(qpath3, &["format_argument", "new_display"])
&& args2.len() == 1 && args2.len() == 1
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner2) = args2[0].kind && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner2) = args2[0].kind
&& let ExprKind::Path(ref qpath4) = inner2.kind && let ExprKind::Path(ref qpath4) = inner2.kind

View file

@ -135,3 +135,7 @@ async fn async_deref_ref(s: Option<&String>) -> Option<&str> {
async fn async_result_bad(s: TR) -> Result<usize, bool> { async fn async_result_bad(s: TR) -> Result<usize, bool> {
s.magic s.magic
} }
async fn async_wrapped<T>(a: Option<T>) -> Option<T> {
{ a }
}

View file

@ -135,3 +135,7 @@ async fn async_deref_ref(s: Option<&String>) -> Option<&str> {
async fn async_result_bad(s: TR) -> Result<usize, bool> { async fn async_result_bad(s: TR) -> Result<usize, bool> {
Ok(s.magic?) Ok(s.magic?)
} }
async fn async_wrapped<T>(a: Option<T>) -> Option<T> {
{ Some(a?) }
}

View file

@ -90,5 +90,11 @@ error: question mark operator is useless here
LL | Ok(s.magic?) LL | Ok(s.magic?)
| ^^^^^^^^^^^^ help: try removing question mark and `Ok()`: `s.magic` | ^^^^^^^^^^^^ help: try removing question mark and `Ok()`: `s.magic`
error: aborting due to 14 previous errors error: question mark operator is useless here
--> $DIR/needless_question_mark.rs:140:7
|
LL | { Some(a?) }
| ^^^^^^^^ help: try removing question mark and `Some()`: `a`
error: aborting due to 15 previous errors

View file

@ -19,6 +19,7 @@ new_pr = true
[assign] [assign]
contributing_url = "https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md" contributing_url = "https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md"
users_on_vacation = ["blyxyas"]
[assign.owners] [assign.owners]
"/.github" = ["@flip1995"] "/.github" = ["@flip1995"]