Merge from rustc
This commit is contained in:
commit
078f228085
767 changed files with 4608 additions and 8034 deletions
|
|
@ -5,7 +5,7 @@ use crate::doc::{NEEDLESS_DOCTEST_MAIN, TEST_ATTR_IN_DOCTEST};
|
|||
use clippy_utils::diagnostics::span_lint;
|
||||
use rustc_ast::{CoroutineKind, Fn, FnRetTy, Item, ItemKind};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_errors::emitter::EmitterWriter;
|
||||
use rustc_errors::emitter::HumanEmitter;
|
||||
use rustc_errors::DiagCtxt;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_parse::maybe_new_parser_from_source_str;
|
||||
|
|
@ -44,7 +44,7 @@ pub fn check(
|
|||
|
||||
let fallback_bundle =
|
||||
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 = HumanEmitter::new(Box::new(io::sink()), fallback_bundle);
|
||||
let dcx = DiagCtxt::with_emitter(Box::new(emitter)).disable_warnings();
|
||||
#[expect(clippy::arc_with_non_send_sync)] // `Lrc` is expected by with_dcx
|
||||
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use core::fmt::{self, Write};
|
|||
use rustc_errors::Applicability;
|
||||
use rustc_hir::hir_id::HirIdSet;
|
||||
use rustc_hir::intravisit::{walk_expr, Visitor};
|
||||
use rustc_hir::{Block, Expr, ExprKind, Guard, HirId, Let, Pat, Stmt, StmtKind, UnOp};
|
||||
use rustc_hir::{Block, Expr, ExprKind, HirId, Pat, Stmt, StmtKind, UnOp};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::declare_lint_pass;
|
||||
use rustc_span::{Span, SyntaxContext, DUMMY_SP};
|
||||
|
|
@ -465,7 +465,7 @@ impl<'tcx> Visitor<'tcx> for InsertSearcher<'_, 'tcx> {
|
|||
let mut is_map_used = self.is_map_used;
|
||||
for arm in arms {
|
||||
self.visit_pat(arm.pat);
|
||||
if let Some(Guard::If(guard) | Guard::IfLet(&Let { init: guard, .. })) = arm.guard {
|
||||
if let Some(guard) = arm.guard {
|
||||
self.visit_non_tail_expr(guard);
|
||||
}
|
||||
is_map_used |= self.visit_cond_arm(arm.body);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use clippy_utils::{
|
|||
use itertools::Itertools;
|
||||
use rustc_errors::{Applicability, Diagnostic};
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::{Arm, BinOpKind, Block, Expr, ExprKind, Guard, HirId, PatKind, PathSegment, PrimTy, QPath, StmtKind};
|
||||
use rustc_hir::{Arm, BinOpKind, Block, Expr, ExprKind, HirId, PatKind, PathSegment, PrimTy, QPath, StmtKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_session::impl_lint_pass;
|
||||
|
|
@ -394,7 +394,7 @@ fn is_match_pattern<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Opt
|
|||
// Find possible min/max branches
|
||||
let minmax_values = |a: &'tcx Arm<'tcx>| {
|
||||
if let PatKind::Binding(_, var_hir_id, _, None) = &a.pat.kind
|
||||
&& let Some(Guard::If(e)) = a.guard
|
||||
&& let Some(e) = a.guard
|
||||
{
|
||||
Some((e, var_hir_id, a.body))
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use clippy_utils::{
|
|||
};
|
||||
use rustc_errors::MultiSpan;
|
||||
use rustc_hir::LangItem::OptionNone;
|
||||
use rustc_hir::{Arm, Expr, Guard, HirId, Let, Pat, PatKind};
|
||||
use rustc_hir::{Arm, Expr, HirId, Pat, PatKind};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::Span;
|
||||
|
||||
|
|
@ -16,7 +16,7 @@ use super::COLLAPSIBLE_MATCH;
|
|||
pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) {
|
||||
if let Some(els_arm) = arms.iter().rfind(|arm| arm_is_wild_like(cx, arm)) {
|
||||
for arm in arms {
|
||||
check_arm(cx, true, arm.pat, arm.body, arm.guard.as_ref(), Some(els_arm.body));
|
||||
check_arm(cx, true, arm.pat, arm.body, arm.guard, Some(els_arm.body));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -35,7 +35,7 @@ fn check_arm<'tcx>(
|
|||
outer_is_match: bool,
|
||||
outer_pat: &'tcx Pat<'tcx>,
|
||||
outer_then_body: &'tcx Expr<'tcx>,
|
||||
outer_guard: Option<&'tcx Guard<'tcx>>,
|
||||
outer_guard: Option<&'tcx Expr<'tcx>>,
|
||||
outer_else_body: Option<&'tcx Expr<'tcx>>,
|
||||
) {
|
||||
let inner_expr = peel_blocks_with_stmt(outer_then_body);
|
||||
|
|
@ -71,7 +71,7 @@ fn check_arm<'tcx>(
|
|||
// the binding must not be used in the if guard
|
||||
&& outer_guard.map_or(
|
||||
true,
|
||||
|(Guard::If(e) | Guard::IfLet(Let { init: e, .. }))| !is_local_used(cx, *e, binding_id)
|
||||
|e| !is_local_used(cx, e, binding_id)
|
||||
)
|
||||
// ...or anywhere in the inner expression
|
||||
&& match inner {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use clippy_utils::source::snippet_with_applicability;
|
|||
use clippy_utils::{is_lint_allowed, is_wild, span_contains_comment};
|
||||
use rustc_ast::{Attribute, LitKind};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Arm, BorrowKind, Expr, ExprKind, Guard, Pat, PatKind, QPath};
|
||||
use rustc_hir::{Arm, BorrowKind, Expr, ExprKind, Pat, PatKind, QPath};
|
||||
use rustc_lint::{LateContext, LintContext};
|
||||
use rustc_middle::ty;
|
||||
use rustc_span::source_map::Spanned;
|
||||
|
|
@ -41,14 +41,8 @@ pub(super) fn check_match<'tcx>(
|
|||
find_matches_sugg(
|
||||
cx,
|
||||
scrutinee,
|
||||
arms.iter().map(|arm| {
|
||||
(
|
||||
cx.tcx.hir().attrs(arm.hir_id),
|
||||
Some(arm.pat),
|
||||
arm.body,
|
||||
arm.guard.as_ref(),
|
||||
)
|
||||
}),
|
||||
arms.iter()
|
||||
.map(|arm| (cx.tcx.hir().attrs(arm.hir_id), Some(arm.pat), arm.body, arm.guard)),
|
||||
e,
|
||||
false,
|
||||
)
|
||||
|
|
@ -67,14 +61,7 @@ where
|
|||
I: Clone
|
||||
+ DoubleEndedIterator
|
||||
+ ExactSizeIterator
|
||||
+ Iterator<
|
||||
Item = (
|
||||
&'a [Attribute],
|
||||
Option<&'a Pat<'b>>,
|
||||
&'a Expr<'b>,
|
||||
Option<&'a Guard<'b>>,
|
||||
),
|
||||
>,
|
||||
+ Iterator<Item = (&'a [Attribute], Option<&'a Pat<'b>>, &'a Expr<'b>, Option<&'a Expr<'b>>)>,
|
||||
{
|
||||
if !span_contains_comment(cx.sess().source_map(), expr.span)
|
||||
&& iter.len() >= 2
|
||||
|
|
@ -115,7 +102,7 @@ where
|
|||
})
|
||||
.join(" | ")
|
||||
};
|
||||
let pat_and_guard = if let Some(Guard::If(g)) = first_guard {
|
||||
let pat_and_guard = if let Some(g) = first_guard {
|
||||
format!(
|
||||
"{pat} if {}",
|
||||
snippet_with_applicability(cx, g.span, "..", &mut applicability)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use clippy_utils::{
|
|||
};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::LangItem::OptionNone;
|
||||
use rustc_hir::{Arm, BindingAnnotation, ByRef, Expr, ExprKind, Guard, ItemKind, Node, Pat, PatKind, Path, QPath};
|
||||
use rustc_hir::{Arm, BindingAnnotation, ByRef, Expr, ExprKind, ItemKind, Node, Pat, PatKind, Path, QPath};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::sym;
|
||||
|
||||
|
|
@ -66,18 +66,9 @@ fn check_all_arms(cx: &LateContext<'_>, match_expr: &Expr<'_>, arms: &[Arm<'_>])
|
|||
let arm_expr = peel_blocks_with_stmt(arm.body);
|
||||
|
||||
if let Some(guard_expr) = &arm.guard {
|
||||
match guard_expr {
|
||||
// gives up if `pat if expr` can have side effects
|
||||
Guard::If(if_cond) => {
|
||||
if if_cond.can_have_side_effects() {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
// gives up `pat if let ...` arm
|
||||
Guard::IfLet(_) => {
|
||||
return false;
|
||||
},
|
||||
};
|
||||
if guard_expr.can_have_side_effects() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if let PatKind::Wild = arm.pat.kind {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use clippy_utils::visitors::{for_each_expr, is_local_used};
|
|||
use rustc_ast::{BorrowKind, LitKind};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::{Arm, BinOpKind, Expr, ExprKind, Guard, MatchSource, Node, Pat, PatKind};
|
||||
use rustc_hir::{Arm, BinOpKind, Expr, ExprKind, MatchSource, Node, Pat, PatKind};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::{Span, Symbol};
|
||||
|
|
@ -21,20 +21,19 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) {
|
|||
};
|
||||
|
||||
// `Some(x) if matches!(x, y)`
|
||||
if let Guard::If(if_expr) = guard
|
||||
&& let ExprKind::Match(
|
||||
scrutinee,
|
||||
[
|
||||
arm,
|
||||
Arm {
|
||||
pat: Pat {
|
||||
kind: PatKind::Wild, ..
|
||||
},
|
||||
..
|
||||
if let ExprKind::Match(
|
||||
scrutinee,
|
||||
[
|
||||
arm,
|
||||
Arm {
|
||||
pat: Pat {
|
||||
kind: PatKind::Wild, ..
|
||||
},
|
||||
],
|
||||
MatchSource::Normal,
|
||||
) = if_expr.kind
|
||||
..
|
||||
},
|
||||
],
|
||||
MatchSource::Normal,
|
||||
) = guard.kind
|
||||
&& let Some(binding) = get_pat_binding(cx, scrutinee, outer_arm)
|
||||
{
|
||||
let pat_span = match (arm.pat.kind, binding.byref_ident) {
|
||||
|
|
@ -45,14 +44,14 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) {
|
|||
emit_redundant_guards(
|
||||
cx,
|
||||
outer_arm,
|
||||
if_expr.span,
|
||||
guard.span,
|
||||
snippet(cx, pat_span, "<binding>"),
|
||||
&binding,
|
||||
arm.guard,
|
||||
);
|
||||
}
|
||||
// `Some(x) if let Some(2) = x`
|
||||
else if let Guard::IfLet(let_expr) = guard
|
||||
else if let ExprKind::Let(let_expr) = guard.kind
|
||||
&& let Some(binding) = get_pat_binding(cx, let_expr.init, outer_arm)
|
||||
{
|
||||
let pat_span = match (let_expr.pat.kind, binding.byref_ident) {
|
||||
|
|
@ -71,8 +70,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) {
|
|||
}
|
||||
// `Some(x) if x == Some(2)`
|
||||
// `Some(x) if Some(2) == x`
|
||||
else if let Guard::If(if_expr) = guard
|
||||
&& let ExprKind::Binary(bin_op, local, pat) = if_expr.kind
|
||||
else if let ExprKind::Binary(bin_op, local, pat) = guard.kind
|
||||
&& matches!(bin_op.node, BinOpKind::Eq)
|
||||
// Ensure they have the same type. If they don't, we'd need deref coercion which isn't
|
||||
// possible (currently) in a pattern. In some cases, you can use something like
|
||||
|
|
@ -96,16 +94,15 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) {
|
|||
emit_redundant_guards(
|
||||
cx,
|
||||
outer_arm,
|
||||
if_expr.span,
|
||||
guard.span,
|
||||
snippet(cx, pat_span, "<binding>"),
|
||||
&binding,
|
||||
None,
|
||||
);
|
||||
} else if let Guard::If(if_expr) = guard
|
||||
&& let ExprKind::MethodCall(path, recv, args, ..) = if_expr.kind
|
||||
} else if let ExprKind::MethodCall(path, recv, args, ..) = guard.kind
|
||||
&& let Some(binding) = get_pat_binding(cx, recv, outer_arm)
|
||||
{
|
||||
check_method_calls(cx, outer_arm, path.ident.name, recv, args, if_expr, &binding);
|
||||
check_method_calls(cx, outer_arm, path.ident.name, recv, args, guard, &binding);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -216,7 +213,7 @@ fn emit_redundant_guards<'tcx>(
|
|||
guard_span: Span,
|
||||
binding_replacement: Cow<'static, str>,
|
||||
pat_binding: &PatBindingInfo,
|
||||
inner_guard: Option<Guard<'_>>,
|
||||
inner_guard: Option<&Expr<'_>>,
|
||||
) {
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
|
|
@ -242,12 +239,7 @@ fn emit_redundant_guards<'tcx>(
|
|||
(
|
||||
guard_span.source_callsite().with_lo(outer_arm.pat.span.hi()),
|
||||
inner_guard.map_or_else(String::new, |guard| {
|
||||
let (prefix, span) = match guard {
|
||||
Guard::If(e) => ("if", e.span),
|
||||
Guard::IfLet(l) => ("if let", l.span),
|
||||
};
|
||||
|
||||
format!(" {prefix} {}", snippet(cx, span, "<guard>"))
|
||||
format!(" if {}", snippet(cx, guard.span, "<guard>"))
|
||||
}),
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use rustc_ast::ast::LitKind;
|
|||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::LangItem::{self, OptionNone, OptionSome, PollPending, PollReady, ResultErr, ResultOk};
|
||||
use rustc_hir::{Arm, Expr, ExprKind, Guard, Node, Pat, PatKind, QPath, UnOp};
|
||||
use rustc_hir::{Arm, Expr, ExprKind, Node, Pat, PatKind, QPath, UnOp};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty::{self, GenericArgKind, Ty};
|
||||
use rustc_span::{sym, Span, Symbol};
|
||||
|
|
@ -277,8 +277,6 @@ pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op
|
|||
let mut sugg = format!("{}.{good_method}", snippet(cx, result_expr.span, "_"));
|
||||
|
||||
if let Some(guard) = maybe_guard {
|
||||
let Guard::If(guard) = *guard else { return }; // `...is_none() && let ...` is a syntax error
|
||||
|
||||
// wow, the HIR for match guards in `PAT if let PAT = expr && expr => ...` is annoying!
|
||||
// `guard` here is `Guard::If` with the let expression somewhere deep in the tree of exprs,
|
||||
// counter to the intuition that it should be `Guard::IfLet`, so we need another check
|
||||
|
|
@ -319,7 +317,7 @@ fn found_good_method<'tcx>(
|
|||
cx: &LateContext<'_>,
|
||||
arms: &'tcx [Arm<'tcx>],
|
||||
node: (&PatKind<'_>, &PatKind<'_>),
|
||||
) -> Option<(&'static str, Option<&'tcx Guard<'tcx>>)> {
|
||||
) -> Option<(&'static str, Option<&'tcx Expr<'tcx>>)> {
|
||||
match node {
|
||||
(
|
||||
PatKind::TupleStruct(ref path_left, patterns_left, _),
|
||||
|
|
@ -409,7 +407,7 @@ fn get_good_method<'tcx>(
|
|||
cx: &LateContext<'_>,
|
||||
arms: &'tcx [Arm<'tcx>],
|
||||
path_left: &QPath<'_>,
|
||||
) -> Option<(&'static str, Option<&'tcx Guard<'tcx>>)> {
|
||||
) -> Option<(&'static str, Option<&'tcx Expr<'tcx>>)> {
|
||||
if let Some(name) = get_ident(path_left) {
|
||||
let (expected_item_left, should_be_left, should_be_right) = match name.as_str() {
|
||||
"Ok" => (Item::Lang(ResultOk), "is_ok()", "is_err()"),
|
||||
|
|
@ -478,7 +476,7 @@ fn find_good_method_for_match<'a, 'tcx>(
|
|||
expected_item_right: Item,
|
||||
should_be_left: &'a str,
|
||||
should_be_right: &'a str,
|
||||
) -> Option<(&'a str, Option<&'tcx Guard<'tcx>>)> {
|
||||
) -> Option<(&'a str, Option<&'tcx Expr<'tcx>>)> {
|
||||
let first_pat = arms[0].pat;
|
||||
let second_pat = arms[1].pat;
|
||||
|
||||
|
|
@ -496,8 +494,8 @@ fn find_good_method_for_match<'a, 'tcx>(
|
|||
|
||||
match body_node_pair {
|
||||
(ExprKind::Lit(lit_left), ExprKind::Lit(lit_right)) => match (&lit_left.node, &lit_right.node) {
|
||||
(LitKind::Bool(true), LitKind::Bool(false)) => Some((should_be_left, arms[0].guard.as_ref())),
|
||||
(LitKind::Bool(false), LitKind::Bool(true)) => Some((should_be_right, arms[1].guard.as_ref())),
|
||||
(LitKind::Bool(true), LitKind::Bool(false)) => Some((should_be_left, arms[0].guard)),
|
||||
(LitKind::Bool(false), LitKind::Bool(true)) => Some((should_be_right, arms[1].guard)),
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
|
|
@ -511,7 +509,7 @@ fn find_good_method_for_matches_macro<'a, 'tcx>(
|
|||
expected_item_left: Item,
|
||||
should_be_left: &'a str,
|
||||
should_be_right: &'a str,
|
||||
) -> Option<(&'a str, Option<&'tcx Guard<'tcx>>)> {
|
||||
) -> Option<(&'a str, Option<&'tcx Expr<'tcx>>)> {
|
||||
let first_pat = arms[0].pat;
|
||||
|
||||
let body_node_pair = if is_pat_variant(cx, first_pat, path_left, expected_item_left) {
|
||||
|
|
@ -522,8 +520,8 @@ fn find_good_method_for_matches_macro<'a, 'tcx>(
|
|||
|
||||
match body_node_pair {
|
||||
(ExprKind::Lit(lit_left), ExprKind::Lit(lit_right)) => match (&lit_left.node, &lit_right.node) {
|
||||
(LitKind::Bool(true), LitKind::Bool(false)) => Some((should_be_left, arms[0].guard.as_ref())),
|
||||
(LitKind::Bool(false), LitKind::Bool(true)) => Some((should_be_right, arms[1].guard.as_ref())),
|
||||
(LitKind::Bool(true), LitKind::Bool(false)) => Some((should_be_left, arms[0].guard)),
|
||||
(LitKind::Bool(false), LitKind::Bool(true)) => Some((should_be_right, arms[1].guard)),
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ pub(super) enum Op<'a> {
|
|||
|
||||
// rm `.cloned()`
|
||||
// e.g. `map` `for_each` `all` `any`
|
||||
NeedlessMove(&'a str, &'a Expr<'a>),
|
||||
NeedlessMove(&'a Expr<'a>),
|
||||
|
||||
// later `.cloned()`
|
||||
// and add `&` to the parameter of closure parameter
|
||||
|
|
@ -59,7 +59,7 @@ pub(super) fn check<'tcx>(
|
|||
return;
|
||||
}
|
||||
|
||||
if let Op::NeedlessMove(_, expr) = op {
|
||||
if let Op::NeedlessMove(expr) = op {
|
||||
let rustc_hir::ExprKind::Closure(closure) = expr.kind else {
|
||||
return;
|
||||
};
|
||||
|
|
@ -104,7 +104,7 @@ pub(super) fn check<'tcx>(
|
|||
}
|
||||
|
||||
let (lint, msg, trailing_clone) = match op {
|
||||
Op::RmCloned | Op::NeedlessMove(_, _) => (REDUNDANT_CLONE, "unneeded cloning of iterator items", ""),
|
||||
Op::RmCloned | Op::NeedlessMove(_) => (REDUNDANT_CLONE, "unneeded cloning of iterator items", ""),
|
||||
Op::LaterCloned | Op::FixClosure(_, _) => (
|
||||
ITER_OVEREAGER_CLONED,
|
||||
"unnecessarily eager cloning of iterator items",
|
||||
|
|
@ -133,7 +133,7 @@ pub(super) fn check<'tcx>(
|
|||
diag.span_suggestion(replace_span, "try", snip, Applicability::MachineApplicable);
|
||||
}
|
||||
},
|
||||
Op::NeedlessMove(_, _) => {
|
||||
Op::NeedlessMove(_) => {
|
||||
let method_span = expr.span.with_lo(cloned_call.span.hi());
|
||||
if let Some(snip) = snippet_opt(cx, method_span) {
|
||||
let replace_span = expr.span.with_lo(cloned_recv.span.hi());
|
||||
|
|
|
|||
|
|
@ -4186,7 +4186,7 @@ impl Methods {
|
|||
expr,
|
||||
recv,
|
||||
recv2,
|
||||
iter_overeager_cloned::Op::NeedlessMove(name, arg),
|
||||
iter_overeager_cloned::Op::NeedlessMove(arg),
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
|
@ -4204,7 +4204,7 @@ impl Methods {
|
|||
expr,
|
||||
recv,
|
||||
recv2,
|
||||
iter_overeager_cloned::Op::NeedlessMove(name, arg),
|
||||
iter_overeager_cloned::Op::NeedlessMove(arg),
|
||||
false,
|
||||
),
|
||||
Some(("chars", recv, _, _, _))
|
||||
|
|
@ -4379,7 +4379,7 @@ impl Methods {
|
|||
expr,
|
||||
recv,
|
||||
recv2,
|
||||
iter_overeager_cloned::Op::NeedlessMove(name, arg),
|
||||
iter_overeager_cloned::Op::NeedlessMove(arg),
|
||||
false,
|
||||
),
|
||||
_ => {},
|
||||
|
|
@ -4433,7 +4433,7 @@ impl Methods {
|
|||
expr,
|
||||
recv,
|
||||
recv2,
|
||||
iter_overeager_cloned::Op::NeedlessMove(name, m_arg),
|
||||
iter_overeager_cloned::Op::NeedlessMove(m_arg),
|
||||
false,
|
||||
),
|
||||
_ => {},
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use clippy_utils::diagnostics::{span_lint, span_lint_and_note};
|
||||
use clippy_utils::{get_parent_expr, path_to_local, path_to_local_id};
|
||||
use rustc_hir::intravisit::{walk_expr, Visitor};
|
||||
use rustc_hir::{BinOpKind, Block, Expr, ExprKind, Guard, HirId, Local, Node, Stmt, StmtKind};
|
||||
use rustc_hir::{BinOpKind, Block, Expr, ExprKind, HirId, Local, Node, Stmt, StmtKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty;
|
||||
use rustc_session::declare_lint_pass;
|
||||
|
|
@ -119,7 +119,7 @@ impl<'a, 'tcx> DivergenceVisitor<'a, 'tcx> {
|
|||
ExprKind::Match(e, arms, _) => {
|
||||
self.visit_expr(e);
|
||||
for arm in arms {
|
||||
if let Some(Guard::If(if_expr)) = arm.guard {
|
||||
if let Some(if_expr) = arm.guard {
|
||||
self.visit_expr(if_expr);
|
||||
}
|
||||
// make sure top level arm expressions aren't linted
|
||||
|
|
|
|||
|
|
@ -80,7 +80,6 @@ enum IfBlockType<'hir> {
|
|||
Ty<'hir>,
|
||||
Symbol,
|
||||
&'hir Expr<'hir>,
|
||||
Option<&'hir Expr<'hir>>,
|
||||
),
|
||||
/// An `if let Xxx(a) = b { c } else { d }` expression.
|
||||
///
|
||||
|
|
@ -143,7 +142,7 @@ fn check_let_some_else_return_none(cx: &LateContext<'_>, stmt: &Stmt<'_>) {
|
|||
|
||||
fn is_early_return(smbl: Symbol, cx: &LateContext<'_>, if_block: &IfBlockType<'_>) -> bool {
|
||||
match *if_block {
|
||||
IfBlockType::IfIs(caller, caller_ty, call_sym, if_then, _) => {
|
||||
IfBlockType::IfIs(caller, caller_ty, call_sym, if_then) => {
|
||||
// If the block could be identified as `if x.is_none()/is_err()`,
|
||||
// we then only need to check the if_then return to see if it is none/err.
|
||||
is_type_diagnostic_item(cx, caller_ty, smbl)
|
||||
|
|
@ -235,7 +234,7 @@ impl QuestionMark {
|
|||
&& !is_else_clause(cx.tcx, expr)
|
||||
&& let ExprKind::MethodCall(segment, caller, ..) = &cond.kind
|
||||
&& let caller_ty = cx.typeck_results().expr_ty(caller)
|
||||
&& let if_block = IfBlockType::IfIs(caller, caller_ty, segment.ident.name, then, r#else)
|
||||
&& let if_block = IfBlockType::IfIs(caller, caller_ty, segment.ident.name, then)
|
||||
&& (is_early_return(sym::Option, cx, &if_block) || is_early_return(sym::Result, cx, &if_block))
|
||||
{
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
|
|
|
|||
|
|
@ -26,18 +26,18 @@ pub(super) fn check<'tcx>(
|
|||
|
||||
// `Repr(C)` <-> unordered type.
|
||||
// If the first field of the `Repr(C)` type matches then the transmute is ok
|
||||
(ReducedTy::OrderedFields(_, Some(from_sub_ty)), ReducedTy::UnorderedFields(to_sub_ty))
|
||||
| (ReducedTy::UnorderedFields(from_sub_ty), ReducedTy::OrderedFields(_, Some(to_sub_ty))) => {
|
||||
(ReducedTy::OrderedFields(Some(from_sub_ty)), ReducedTy::UnorderedFields(to_sub_ty))
|
||||
| (ReducedTy::UnorderedFields(from_sub_ty), ReducedTy::OrderedFields(Some(to_sub_ty))) => {
|
||||
from_ty = from_sub_ty;
|
||||
to_ty = to_sub_ty;
|
||||
continue;
|
||||
},
|
||||
(ReducedTy::OrderedFields(_, Some(from_sub_ty)), ReducedTy::Other(to_sub_ty)) if reduced_tys.to_fat_ptr => {
|
||||
(ReducedTy::OrderedFields(Some(from_sub_ty)), ReducedTy::Other(to_sub_ty)) if reduced_tys.to_fat_ptr => {
|
||||
from_ty = from_sub_ty;
|
||||
to_ty = to_sub_ty;
|
||||
continue;
|
||||
},
|
||||
(ReducedTy::Other(from_sub_ty), ReducedTy::OrderedFields(_, Some(to_sub_ty)))
|
||||
(ReducedTy::Other(from_sub_ty), ReducedTy::OrderedFields(Some(to_sub_ty)))
|
||||
if reduced_tys.from_fat_ptr =>
|
||||
{
|
||||
from_ty = from_sub_ty;
|
||||
|
|
@ -235,8 +235,8 @@ enum ReducedTy<'tcx> {
|
|||
TypeErasure { raw_ptr_only: bool },
|
||||
/// The type is a struct containing either zero non-zero sized fields, or multiple non-zero
|
||||
/// sized fields with a defined order.
|
||||
/// The second value is the first non-zero sized type.
|
||||
OrderedFields(Ty<'tcx>, Option<Ty<'tcx>>),
|
||||
/// The value is the first non-zero sized type.
|
||||
OrderedFields(Option<Ty<'tcx>>),
|
||||
/// The type is a struct containing multiple non-zero sized fields with no defined order.
|
||||
UnorderedFields(Ty<'tcx>),
|
||||
/// Any other type.
|
||||
|
|
@ -259,7 +259,7 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
|
|||
ty::Tuple(args) => {
|
||||
let mut iter = args.iter();
|
||||
let Some(sized_ty) = iter.find(|&ty| !is_zero_sized_ty(cx, ty)) else {
|
||||
return ReducedTy::OrderedFields(ty, None);
|
||||
return ReducedTy::OrderedFields(None);
|
||||
};
|
||||
if iter.all(|ty| is_zero_sized_ty(cx, ty)) {
|
||||
ty = sized_ty;
|
||||
|
|
@ -281,7 +281,7 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
|
|||
continue;
|
||||
}
|
||||
if def.repr().inhibit_struct_field_reordering_opt() {
|
||||
ReducedTy::OrderedFields(ty, Some(sized_ty))
|
||||
ReducedTy::OrderedFields(Some(sized_ty))
|
||||
} else {
|
||||
ReducedTy::UnorderedFields(ty)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -318,17 +318,11 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
|
|||
self.pat(field!(arm.pat));
|
||||
match arm.value.guard {
|
||||
None => chain!(self, "{arm}.guard.is_none()"),
|
||||
Some(hir::Guard::If(expr)) => {
|
||||
Some(expr) => {
|
||||
bind!(self, expr);
|
||||
chain!(self, "let Some(Guard::If({expr})) = {arm}.guard");
|
||||
chain!(self, "let Some({expr}) = {arm}.guard");
|
||||
self.expr(expr);
|
||||
},
|
||||
Some(hir::Guard::IfLet(let_expr)) => {
|
||||
bind!(self, let_expr);
|
||||
chain!(self, "let Some(Guard::IfLet({let_expr}) = {arm}.guard");
|
||||
self.pat(field!(let_expr.pat));
|
||||
self.expr(field!(let_expr.init));
|
||||
},
|
||||
}
|
||||
self.expr(field!(arm.body));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use rustc_hir::def::Res;
|
|||
use rustc_hir::MatchSource::TryDesugar;
|
||||
use rustc_hir::{
|
||||
ArrayLen, BinOpKind, BindingAnnotation, Block, BodyId, Closure, Expr, ExprField, ExprKind, FnRetTy, GenericArg,
|
||||
GenericArgs, Guard, HirId, HirIdMap, InlineAsmOperand, Let, Lifetime, LifetimeName, Pat, PatField, PatKind, Path,
|
||||
GenericArgs, HirId, HirIdMap, InlineAsmOperand, Let, Lifetime, LifetimeName, Pat, PatField, PatKind, Path,
|
||||
PathSegment, PrimTy, QPath, Stmt, StmtKind, Ty, TyKind, TypeBinding,
|
||||
};
|
||||
use rustc_lexer::{tokenize, TokenKind};
|
||||
|
|
@ -320,7 +320,7 @@ impl HirEqInterExpr<'_, '_, '_> {
|
|||
&& self.eq_expr(le, re)
|
||||
&& over(la, ra, |l, r| {
|
||||
self.eq_pat(l.pat, r.pat)
|
||||
&& both(&l.guard, &r.guard, |l, r| self.eq_guard(l, r))
|
||||
&& both(&l.guard, &r.guard, |l, r| self.eq_expr(l, r))
|
||||
&& self.eq_expr(l.body, r.body)
|
||||
})
|
||||
},
|
||||
|
|
@ -410,16 +410,6 @@ impl HirEqInterExpr<'_, '_, '_> {
|
|||
left.ident.name == right.ident.name && self.eq_expr(left.expr, right.expr)
|
||||
}
|
||||
|
||||
fn eq_guard(&mut self, left: &Guard<'_>, right: &Guard<'_>) -> bool {
|
||||
match (left, right) {
|
||||
(Guard::If(l), Guard::If(r)) => self.eq_expr(l, r),
|
||||
(Guard::IfLet(l), Guard::IfLet(r)) => {
|
||||
self.eq_pat(l.pat, r.pat) && both(&l.ty, &r.ty, |l, r| self.eq_ty(l, r)) && self.eq_expr(l.init, r.init)
|
||||
},
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn eq_generic_arg(&mut self, left: &GenericArg<'_>, right: &GenericArg<'_>) -> bool {
|
||||
match (left, right) {
|
||||
(GenericArg::Const(l), GenericArg::Const(r)) => self.eq_body(l.value.body, r.value.body),
|
||||
|
|
@ -876,7 +866,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
|||
for arm in arms {
|
||||
self.hash_pat(arm.pat);
|
||||
if let Some(ref e) = arm.guard {
|
||||
self.hash_guard(e);
|
||||
self.hash_expr(e);
|
||||
}
|
||||
self.hash_expr(arm.body);
|
||||
}
|
||||
|
|
@ -1056,14 +1046,6 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn hash_guard(&mut self, g: &Guard<'_>) {
|
||||
match g {
|
||||
Guard::If(expr) | Guard::IfLet(Let { init: expr, .. }) => {
|
||||
self.hash_expr(expr);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hash_lifetime(&mut self, lifetime: &Lifetime) {
|
||||
lifetime.ident.name.hash(&mut self.s);
|
||||
std::mem::discriminant(&lifetime.res).hash(&mut self.s);
|
||||
|
|
|
|||
|
|
@ -3164,7 +3164,7 @@ pub fn is_never_expr<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> Option<
|
|||
self.is_never = false;
|
||||
if let Some(guard) = arm.guard {
|
||||
let in_final_expr = mem::replace(&mut self.in_final_expr, false);
|
||||
self.visit_expr(guard.body());
|
||||
self.visit_expr(guard);
|
||||
self.in_final_expr = in_final_expr;
|
||||
// The compiler doesn't consider diverging guards as causing the arm to diverge.
|
||||
self.is_never = false;
|
||||
|
|
@ -3223,7 +3223,7 @@ pub fn is_never_expr<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> Option<
|
|||
fn visit_arm(&mut self, arm: &Arm<'tcx>) {
|
||||
if let Some(guard) = arm.guard {
|
||||
let in_final_expr = mem::replace(&mut self.in_final_expr, false);
|
||||
self.visit_expr(guard.body());
|
||||
self.visit_expr(guard);
|
||||
self.in_final_expr = in_final_expr;
|
||||
}
|
||||
self.visit_expr(arm.body);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
// As the most common case is the `http` crate, it replicates `http::HeaderName`'s structure.
|
||||
|
||||
#![allow(clippy::declare_interior_mutable_const)]
|
||||
#![allow(unused_tuple_struct_fields)]
|
||||
|
||||
use std::sync::atomic::AtomicUsize;
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ LL | fn bug<T>() -> impl Iterator<Item = [(); { |x: [u8]| x }]> {
|
|||
|
|
||||
= help: the trait `std::marker::Sized` is not implemented for `[u8]`
|
||||
= help: unsized fn params are gated as an unstable feature
|
||||
help: function arguments must have a statically known size, borrowed types always have a known size
|
||||
help: function arguments must have a statically known size, borrowed slices always have a known size
|
||||
|
|
||||
LL | fn bug<T>() -> impl Iterator<Item = [(); { |x: &[u8]| x }]> {
|
||||
| +
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@ help: consider importing one of these items
|
|||
|
|
||||
LL + use core::marker::PhantomData;
|
||||
|
|
||||
LL + use serde::__private::PhantomData;
|
||||
|
|
||||
LL + use std::marker::PhantomData;
|
||||
|
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
#![warn(clippy::useless_format)]
|
||||
#![allow(
|
||||
unused_tuple_struct_fields,
|
||||
clippy::print_literal,
|
||||
clippy::redundant_clone,
|
||||
clippy::to_string_in_format_args,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
#![warn(clippy::useless_format)]
|
||||
#![allow(
|
||||
unused_tuple_struct_fields,
|
||||
clippy::print_literal,
|
||||
clippy::redundant_clone,
|
||||
clippy::to_string_in_format_args,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: useless use of `format!`
|
||||
--> $DIR/format.rs:20:5
|
||||
--> $DIR/format.rs:19:5
|
||||
|
|
||||
LL | format!("foo");
|
||||
| ^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()`
|
||||
|
|
@ -8,19 +8,19 @@ LL | format!("foo");
|
|||
= help: to override `-D warnings` add `#[allow(clippy::useless_format)]`
|
||||
|
||||
error: useless use of `format!`
|
||||
--> $DIR/format.rs:21:5
|
||||
--> $DIR/format.rs:20:5
|
||||
|
|
||||
LL | format!("{{}}");
|
||||
| ^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"{}".to_string()`
|
||||
|
||||
error: useless use of `format!`
|
||||
--> $DIR/format.rs:22:5
|
||||
--> $DIR/format.rs:21:5
|
||||
|
|
||||
LL | format!("{{}} abc {{}}");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"{} abc {}".to_string()`
|
||||
|
||||
error: useless use of `format!`
|
||||
--> $DIR/format.rs:23:5
|
||||
--> $DIR/format.rs:22:5
|
||||
|
|
||||
LL | / format!(
|
||||
LL | | r##"foo {{}}
|
||||
|
|
@ -35,67 +35,67 @@ LL ~ " bar"##.to_string();
|
|||
|
|
||||
|
||||
error: useless use of `format!`
|
||||
--> $DIR/format.rs:28:13
|
||||
--> $DIR/format.rs:27:13
|
||||
|
|
||||
LL | let _ = format!("");
|
||||
| ^^^^^^^^^^^ help: consider using `String::new()`: `String::new()`
|
||||
|
||||
error: useless use of `format!`
|
||||
--> $DIR/format.rs:30:5
|
||||
--> $DIR/format.rs:29:5
|
||||
|
|
||||
LL | format!("{}", "foo");
|
||||
| ^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()`
|
||||
|
||||
error: useless use of `format!`
|
||||
--> $DIR/format.rs:38:5
|
||||
--> $DIR/format.rs:37:5
|
||||
|
|
||||
LL | format!("{}", arg);
|
||||
| ^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `arg.to_string()`
|
||||
|
||||
error: useless use of `format!`
|
||||
--> $DIR/format.rs:68:5
|
||||
--> $DIR/format.rs:67:5
|
||||
|
|
||||
LL | format!("{}", 42.to_string());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `42.to_string()`
|
||||
|
||||
error: useless use of `format!`
|
||||
--> $DIR/format.rs:70:5
|
||||
--> $DIR/format.rs:69:5
|
||||
|
|
||||
LL | format!("{}", x.display().to_string());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.display().to_string()`
|
||||
|
||||
error: useless use of `format!`
|
||||
--> $DIR/format.rs:74:18
|
||||
--> $DIR/format.rs:73:18
|
||||
|
|
||||
LL | let _ = Some(format!("{}", a + "bar"));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `a + "bar"`
|
||||
|
||||
error: useless use of `format!`
|
||||
--> $DIR/format.rs:78:22
|
||||
--> $DIR/format.rs:77:22
|
||||
|
|
||||
LL | let _s: String = format!("{}", &*v.join("\n"));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `(&*v.join("\n")).to_string()`
|
||||
|
||||
error: useless use of `format!`
|
||||
--> $DIR/format.rs:84:13
|
||||
--> $DIR/format.rs:83:13
|
||||
|
|
||||
LL | let _ = format!("{x}");
|
||||
| ^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()`
|
||||
|
||||
error: useless use of `format!`
|
||||
--> $DIR/format.rs:86:13
|
||||
--> $DIR/format.rs:85:13
|
||||
|
|
||||
LL | let _ = format!("{y}", y = x);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()`
|
||||
|
||||
error: useless use of `format!`
|
||||
--> $DIR/format.rs:90:13
|
||||
--> $DIR/format.rs:89:13
|
||||
|
|
||||
LL | let _ = format!("{abc}");
|
||||
| ^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `abc.to_string()`
|
||||
|
||||
error: useless use of `format!`
|
||||
--> $DIR/format.rs:92:13
|
||||
--> $DIR/format.rs:91:13
|
||||
|
|
||||
LL | let _ = format!("{xx}");
|
||||
| ^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `xx.to_string()`
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#![warn(clippy::from_iter_instead_of_collect)]
|
||||
#![allow(unused_imports, unused_tuple_struct_fields)]
|
||||
#![allow(unused_imports)]
|
||||
#![allow(clippy::useless_vec)]
|
||||
|
||||
use std::collections::{BTreeMap, BTreeSet, HashMap, VecDeque};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#![warn(clippy::from_iter_instead_of_collect)]
|
||||
#![allow(unused_imports, unused_tuple_struct_fields)]
|
||||
#![allow(unused_imports)]
|
||||
#![allow(clippy::useless_vec)]
|
||||
|
||||
use std::collections::{BTreeMap, BTreeSet, HashMap, VecDeque};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#![feature(never_type)]
|
||||
#![allow(
|
||||
unused_mut,
|
||||
unused_tuple_struct_fields,
|
||||
clippy::redundant_allocation,
|
||||
clippy::needless_pass_by_ref_mut
|
||||
)]
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#![feature(never_type)]
|
||||
#![allow(
|
||||
unused_mut,
|
||||
unused_tuple_struct_fields,
|
||||
clippy::redundant_allocation,
|
||||
clippy::needless_pass_by_ref_mut
|
||||
)]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: this function could have a `#[must_use]` attribute
|
||||
--> $DIR/must_use_candidates.rs:16:1
|
||||
--> $DIR/must_use_candidates.rs:15:1
|
||||
|
|
||||
LL | pub fn pure(i: u8) -> u8 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn pure(i: u8) -> u8`
|
||||
|
|
@ -8,25 +8,25 @@ LL | pub fn pure(i: u8) -> u8 {
|
|||
= help: to override `-D warnings` add `#[allow(clippy::must_use_candidate)]`
|
||||
|
||||
error: this method could have a `#[must_use]` attribute
|
||||
--> $DIR/must_use_candidates.rs:21:5
|
||||
--> $DIR/must_use_candidates.rs:20:5
|
||||
|
|
||||
LL | pub fn inherent_pure(&self) -> u8 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn inherent_pure(&self) -> u8`
|
||||
|
||||
error: this function could have a `#[must_use]` attribute
|
||||
--> $DIR/must_use_candidates.rs:52:1
|
||||
--> $DIR/must_use_candidates.rs:51:1
|
||||
|
|
||||
LL | pub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool`
|
||||
|
||||
error: this function could have a `#[must_use]` attribute
|
||||
--> $DIR/must_use_candidates.rs:64:1
|
||||
--> $DIR/must_use_candidates.rs:63:1
|
||||
|
|
||||
LL | pub fn rcd(_x: Rc<u32>) -> bool {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn rcd(_x: Rc<u32>) -> bool`
|
||||
|
||||
error: this function could have a `#[must_use]` attribute
|
||||
--> $DIR/must_use_candidates.rs:72:1
|
||||
--> $DIR/must_use_candidates.rs:71:1
|
||||
|
|
||||
LL | pub fn arcd(_x: Arc<u32>) -> bool {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn arcd(_x: Arc<u32>) -> bool`
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#![warn(clippy::init_numbered_fields)]
|
||||
#![allow(unused_tuple_struct_fields)]
|
||||
|
||||
#[derive(Default)]
|
||||
struct TupleStruct(u32, u32, u8);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#![warn(clippy::init_numbered_fields)]
|
||||
#![allow(unused_tuple_struct_fields)]
|
||||
|
||||
#[derive(Default)]
|
||||
struct TupleStruct(u32, u32, u8);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: used a field initializer for a tuple struct
|
||||
--> $DIR/numbered_fields.rs:18:13
|
||||
--> $DIR/numbered_fields.rs:17:13
|
||||
|
|
||||
LL | let _ = TupleStruct {
|
||||
| _____________^
|
||||
|
|
@ -13,7 +13,7 @@ LL | | };
|
|||
= help: to override `-D warnings` add `#[allow(clippy::init_numbered_fields)]`
|
||||
|
||||
error: used a field initializer for a tuple struct
|
||||
--> $DIR/numbered_fields.rs:25:13
|
||||
--> $DIR/numbered_fields.rs:24:13
|
||||
|
|
||||
LL | let _ = TupleStruct {
|
||||
| _____________^
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
#![warn(clippy::option_if_let_else)]
|
||||
#![allow(
|
||||
unused_tuple_struct_fields,
|
||||
clippy::ref_option_ref,
|
||||
clippy::equatable_if_let,
|
||||
clippy::let_unit_value,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
#![warn(clippy::option_if_let_else)]
|
||||
#![allow(
|
||||
unused_tuple_struct_fields,
|
||||
clippy::ref_option_ref,
|
||||
clippy::equatable_if_let,
|
||||
clippy::let_unit_value,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: use Option::map_or instead of an if let/else
|
||||
--> $DIR/option_if_let_else.rs:11:5
|
||||
--> $DIR/option_if_let_else.rs:10:5
|
||||
|
|
||||
LL | / if let Some(x) = string {
|
||||
LL | | (true, x)
|
||||
|
|
@ -12,19 +12,19 @@ LL | | }
|
|||
= help: to override `-D warnings` add `#[allow(clippy::option_if_let_else)]`
|
||||
|
||||
error: use Option::map_or instead of an if let/else
|
||||
--> $DIR/option_if_let_else.rs:29:13
|
||||
--> $DIR/option_if_let_else.rs:28:13
|
||||
|
|
||||
LL | let _ = if let Some(s) = *string { s.len() } else { 0 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `string.map_or(0, |s| s.len())`
|
||||
|
||||
error: use Option::map_or instead of an if let/else
|
||||
--> $DIR/option_if_let_else.rs:30:13
|
||||
--> $DIR/option_if_let_else.rs:29:13
|
||||
|
|
||||
LL | let _ = if let Some(s) = &num { s } else { &0 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)`
|
||||
|
||||
error: use Option::map_or instead of an if let/else
|
||||
--> $DIR/option_if_let_else.rs:31:13
|
||||
--> $DIR/option_if_let_else.rs:30:13
|
||||
|
|
||||
LL | let _ = if let Some(s) = &mut num {
|
||||
| _____________^
|
||||
|
|
@ -44,13 +44,13 @@ LL ~ });
|
|||
|
|
||||
|
||||
error: use Option::map_or instead of an if let/else
|
||||
--> $DIR/option_if_let_else.rs:37:13
|
||||
--> $DIR/option_if_let_else.rs:36:13
|
||||
|
|
||||
LL | let _ = if let Some(ref s) = num { s } else { &0 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)`
|
||||
|
||||
error: use Option::map_or instead of an if let/else
|
||||
--> $DIR/option_if_let_else.rs:38:13
|
||||
--> $DIR/option_if_let_else.rs:37:13
|
||||
|
|
||||
LL | let _ = if let Some(mut s) = num {
|
||||
| _____________^
|
||||
|
|
@ -70,7 +70,7 @@ LL ~ });
|
|||
|
|
||||
|
||||
error: use Option::map_or instead of an if let/else
|
||||
--> $DIR/option_if_let_else.rs:44:13
|
||||
--> $DIR/option_if_let_else.rs:43:13
|
||||
|
|
||||
LL | let _ = if let Some(ref mut s) = num {
|
||||
| _____________^
|
||||
|
|
@ -90,7 +90,7 @@ LL ~ });
|
|||
|
|
||||
|
||||
error: use Option::map_or instead of an if let/else
|
||||
--> $DIR/option_if_let_else.rs:53:5
|
||||
--> $DIR/option_if_let_else.rs:52:5
|
||||
|
|
||||
LL | / if let Some(x) = arg {
|
||||
LL | | let y = x * x;
|
||||
|
|
@ -109,7 +109,7 @@ LL + })
|
|||
|
|
||||
|
||||
error: use Option::map_or_else instead of an if let/else
|
||||
--> $DIR/option_if_let_else.rs:66:13
|
||||
--> $DIR/option_if_let_else.rs:65:13
|
||||
|
|
||||
LL | let _ = if let Some(x) = arg {
|
||||
| _____________^
|
||||
|
|
@ -121,7 +121,7 @@ LL | | };
|
|||
| |_____^ help: try: `arg.map_or_else(side_effect, |x| x)`
|
||||
|
||||
error: use Option::map_or_else instead of an if let/else
|
||||
--> $DIR/option_if_let_else.rs:75:13
|
||||
--> $DIR/option_if_let_else.rs:74:13
|
||||
|
|
||||
LL | let _ = if let Some(x) = arg {
|
||||
| _____________^
|
||||
|
|
@ -144,7 +144,7 @@ LL ~ }, |x| x * x * x * x);
|
|||
|
|
||||
|
||||
error: use Option::map_or_else instead of an if let/else
|
||||
--> $DIR/option_if_let_else.rs:108:13
|
||||
--> $DIR/option_if_let_else.rs:107:13
|
||||
|
|
||||
LL | / if let Some(idx) = s.find('.') {
|
||||
LL | | vec![s[..idx].to_string(), s[idx..].to_string()]
|
||||
|
|
@ -154,7 +154,7 @@ LL | | }
|
|||
| |_____________^ help: try: `s.find('.').map_or_else(|| vec![s.to_string()], |idx| vec![s[..idx].to_string(), s[idx..].to_string()])`
|
||||
|
||||
error: use Option::map_or_else instead of an if let/else
|
||||
--> $DIR/option_if_let_else.rs:119:5
|
||||
--> $DIR/option_if_let_else.rs:118:5
|
||||
|
|
||||
LL | / if let Ok(binding) = variable {
|
||||
LL | | println!("Ok {binding}");
|
||||
|
|
@ -177,13 +177,13 @@ LL + })
|
|||
|
|
||||
|
||||
error: use Option::map_or instead of an if let/else
|
||||
--> $DIR/option_if_let_else.rs:143:13
|
||||
--> $DIR/option_if_let_else.rs:142:13
|
||||
|
|
||||
LL | let _ = if let Some(x) = optional { x + 2 } else { 5 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `optional.map_or(5, |x| x + 2)`
|
||||
|
||||
error: use Option::map_or instead of an if let/else
|
||||
--> $DIR/option_if_let_else.rs:153:13
|
||||
--> $DIR/option_if_let_else.rs:152:13
|
||||
|
|
||||
LL | let _ = if let Some(x) = Some(0) {
|
||||
| _____________^
|
||||
|
|
@ -205,13 +205,13 @@ LL ~ });
|
|||
|
|
||||
|
||||
error: use Option::map_or instead of an if let/else
|
||||
--> $DIR/option_if_let_else.rs:181:13
|
||||
--> $DIR/option_if_let_else.rs:180:13
|
||||
|
|
||||
LL | let _ = if let Some(x) = Some(0) { s.len() + x } else { s.len() };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(0).map_or(s.len(), |x| s.len() + x)`
|
||||
|
||||
error: use Option::map_or instead of an if let/else
|
||||
--> $DIR/option_if_let_else.rs:185:13
|
||||
--> $DIR/option_if_let_else.rs:184:13
|
||||
|
|
||||
LL | let _ = if let Some(x) = Some(0) {
|
||||
| _____________^
|
||||
|
|
@ -231,7 +231,7 @@ LL ~ });
|
|||
|
|
||||
|
||||
error: use Option::map_or instead of an if let/else
|
||||
--> $DIR/option_if_let_else.rs:224:13
|
||||
--> $DIR/option_if_let_else.rs:223:13
|
||||
|
|
||||
LL | let _ = match s {
|
||||
| _____________^
|
||||
|
|
@ -241,7 +241,7 @@ LL | | };
|
|||
| |_____^ help: try: `s.map_or(1, |string| string.len())`
|
||||
|
||||
error: use Option::map_or instead of an if let/else
|
||||
--> $DIR/option_if_let_else.rs:228:13
|
||||
--> $DIR/option_if_let_else.rs:227:13
|
||||
|
|
||||
LL | let _ = match Some(10) {
|
||||
| _____________^
|
||||
|
|
@ -251,7 +251,7 @@ LL | | };
|
|||
| |_____^ help: try: `Some(10).map_or(5, |a| a + 1)`
|
||||
|
||||
error: use Option::map_or instead of an if let/else
|
||||
--> $DIR/option_if_let_else.rs:234:13
|
||||
--> $DIR/option_if_let_else.rs:233:13
|
||||
|
|
||||
LL | let _ = match res {
|
||||
| _____________^
|
||||
|
|
@ -261,7 +261,7 @@ LL | | };
|
|||
| |_____^ help: try: `res.map_or(1, |a| a + 1)`
|
||||
|
||||
error: use Option::map_or instead of an if let/else
|
||||
--> $DIR/option_if_let_else.rs:238:13
|
||||
--> $DIR/option_if_let_else.rs:237:13
|
||||
|
|
||||
LL | let _ = match res {
|
||||
| _____________^
|
||||
|
|
@ -271,13 +271,13 @@ LL | | };
|
|||
| |_____^ help: try: `res.map_or(1, |a| a + 1)`
|
||||
|
||||
error: use Option::map_or instead of an if let/else
|
||||
--> $DIR/option_if_let_else.rs:242:13
|
||||
--> $DIR/option_if_let_else.rs:241:13
|
||||
|
|
||||
LL | let _ = if let Ok(a) = res { a + 1 } else { 5 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `res.map_or(5, |a| a + 1)`
|
||||
|
||||
error: use Option::map_or instead of an if let/else
|
||||
--> $DIR/option_if_let_else.rs:259:17
|
||||
--> $DIR/option_if_let_else.rs:258:17
|
||||
|
|
||||
LL | let _ = match initial {
|
||||
| _________________^
|
||||
|
|
@ -287,7 +287,7 @@ LL | | };
|
|||
| |_________^ help: try: `initial.as_ref().map_or(42, |value| do_something(value))`
|
||||
|
||||
error: use Option::map_or instead of an if let/else
|
||||
--> $DIR/option_if_let_else.rs:266:17
|
||||
--> $DIR/option_if_let_else.rs:265:17
|
||||
|
|
||||
LL | let _ = match initial {
|
||||
| _________________^
|
||||
|
|
@ -297,7 +297,7 @@ LL | | };
|
|||
| |_________^ help: try: `initial.as_mut().map_or(42, |value| do_something2(value))`
|
||||
|
||||
error: use Option::map_or_else instead of an if let/else
|
||||
--> $DIR/option_if_let_else.rs:289:24
|
||||
--> $DIR/option_if_let_else.rs:288:24
|
||||
|
|
||||
LL | let mut _hashmap = if let Some(hm) = &opt {
|
||||
| ________________________^
|
||||
|
|
@ -308,7 +308,7 @@ LL | | };
|
|||
| |_____^ help: try: `opt.as_ref().map_or_else(HashMap::new, |hm| hm.clone())`
|
||||
|
||||
error: use Option::map_or_else instead of an if let/else
|
||||
--> $DIR/option_if_let_else.rs:295:19
|
||||
--> $DIR/option_if_let_else.rs:294:19
|
||||
|
|
||||
LL | let mut _hm = if let Some(hm) = &opt { hm.clone() } else { new_map!() };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.as_ref().map_or_else(|| new_map!(), |hm| hm.clone())`
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#![warn(clippy::unreadable_literal)]
|
||||
#![allow(unused_tuple_struct_fields)]
|
||||
|
||||
struct Foo(u64);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#![warn(clippy::unreadable_literal)]
|
||||
#![allow(unused_tuple_struct_fields)]
|
||||
|
||||
struct Foo(u64);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: long literal lacking separators
|
||||
--> $DIR/unreadable_literal.rs:32:17
|
||||
--> $DIR/unreadable_literal.rs:31:17
|
||||
|
|
||||
LL | let _bad = (0b110110_i64, 0x12345678_usize, 123456_f32, 1.234567_f32);
|
||||
| ^^^^^^^^^^^^ help: consider: `0b11_0110_i64`
|
||||
|
|
@ -8,55 +8,55 @@ LL | let _bad = (0b110110_i64, 0x12345678_usize, 123456_f32, 1.234567_f32);
|
|||
= help: to override `-D warnings` add `#[allow(clippy::unreadable_literal)]`
|
||||
|
||||
error: long literal lacking separators
|
||||
--> $DIR/unreadable_literal.rs:32:31
|
||||
--> $DIR/unreadable_literal.rs:31:31
|
||||
|
|
||||
LL | let _bad = (0b110110_i64, 0x12345678_usize, 123456_f32, 1.234567_f32);
|
||||
| ^^^^^^^^^^^^^^^^ help: consider: `0x1234_5678_usize`
|
||||
|
||||
error: long literal lacking separators
|
||||
--> $DIR/unreadable_literal.rs:32:49
|
||||
--> $DIR/unreadable_literal.rs:31:49
|
||||
|
|
||||
LL | let _bad = (0b110110_i64, 0x12345678_usize, 123456_f32, 1.234567_f32);
|
||||
| ^^^^^^^^^^ help: consider: `123_456_f32`
|
||||
|
||||
error: long literal lacking separators
|
||||
--> $DIR/unreadable_literal.rs:32:61
|
||||
--> $DIR/unreadable_literal.rs:31:61
|
||||
|
|
||||
LL | let _bad = (0b110110_i64, 0x12345678_usize, 123456_f32, 1.234567_f32);
|
||||
| ^^^^^^^^^^^^ help: consider: `1.234_567_f32`
|
||||
|
||||
error: long literal lacking separators
|
||||
--> $DIR/unreadable_literal.rs:34:20
|
||||
--> $DIR/unreadable_literal.rs:33:20
|
||||
|
|
||||
LL | let _bad_sci = 1.123456e1;
|
||||
| ^^^^^^^^^^ help: consider: `1.123_456e1`
|
||||
|
||||
error: long literal lacking separators
|
||||
--> $DIR/unreadable_literal.rs:36:18
|
||||
--> $DIR/unreadable_literal.rs:35:18
|
||||
|
|
||||
LL | let _fail1 = 0xabcdef;
|
||||
| ^^^^^^^^ help: consider: `0x00ab_cdef`
|
||||
|
||||
error: long literal lacking separators
|
||||
--> $DIR/unreadable_literal.rs:37:23
|
||||
--> $DIR/unreadable_literal.rs:36:23
|
||||
|
|
||||
LL | let _fail2: u32 = 0xBAFEBAFE;
|
||||
| ^^^^^^^^^^ help: consider: `0xBAFE_BAFE`
|
||||
|
||||
error: long literal lacking separators
|
||||
--> $DIR/unreadable_literal.rs:38:18
|
||||
--> $DIR/unreadable_literal.rs:37:18
|
||||
|
|
||||
LL | let _fail3 = 0xabcdeff;
|
||||
| ^^^^^^^^^ help: consider: `0x0abc_deff`
|
||||
|
||||
error: long literal lacking separators
|
||||
--> $DIR/unreadable_literal.rs:39:24
|
||||
--> $DIR/unreadable_literal.rs:38:24
|
||||
|
|
||||
LL | let _fail4: i128 = 0xabcabcabcabcabcabc;
|
||||
| ^^^^^^^^^^^^^^^^^^^^ help: consider: `0x00ab_cabc_abca_bcab_cabc`
|
||||
|
||||
error: long literal lacking separators
|
||||
--> $DIR/unreadable_literal.rs:40:18
|
||||
--> $DIR/unreadable_literal.rs:39:18
|
||||
|
|
||||
LL | let _fail5 = 1.100300400;
|
||||
| ^^^^^^^^^^^ help: consider: `1.100_300_400`
|
||||
|
|
|
|||
|
|
@ -387,6 +387,10 @@ pub struct Config {
|
|||
// Needed both to construct build_helper::git::GitConfig
|
||||
pub git_repository: String,
|
||||
pub nightly_branch: String,
|
||||
|
||||
/// True if the profiler runtime is enabled for this target.
|
||||
/// Used by the "needs-profiler-support" header in test files.
|
||||
pub profiler_support: bool,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
|
|
|
|||
|
|
@ -178,6 +178,9 @@ pub struct TestProps {
|
|||
// Whether to tell `rustc` to remap the "src base" directory to a fake
|
||||
// directory.
|
||||
pub remap_src_base: bool,
|
||||
/// Extra flags to pass to `llvm-cov` when producing coverage reports.
|
||||
/// Only used by the "coverage-run" test mode.
|
||||
pub llvm_cov_flags: Vec<String>,
|
||||
}
|
||||
|
||||
mod directives {
|
||||
|
|
@ -216,6 +219,7 @@ mod directives {
|
|||
pub const MIR_UNIT_TEST: &'static str = "unit-test";
|
||||
pub const REMAP_SRC_BASE: &'static str = "remap-src-base";
|
||||
pub const COMPARE_OUTPUT_LINES_BY_SUBSET: &'static str = "compare-output-lines-by-subset";
|
||||
pub const LLVM_COV_FLAGS: &'static str = "llvm-cov-flags";
|
||||
// This isn't a real directive, just one that is probably mistyped often
|
||||
pub const INCORRECT_COMPILER_FLAGS: &'static str = "compiler-flags";
|
||||
}
|
||||
|
|
@ -265,6 +269,7 @@ impl TestProps {
|
|||
stderr_per_bitwidth: false,
|
||||
mir_unit_test: None,
|
||||
remap_src_base: false,
|
||||
llvm_cov_flags: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -321,16 +326,23 @@ impl TestProps {
|
|||
|r| r,
|
||||
);
|
||||
|
||||
if let Some(flags) = config.parse_name_value_directive(ln, COMPILE_FLAGS) {
|
||||
self.compile_flags.extend(
|
||||
flags
|
||||
.split("'")
|
||||
.enumerate()
|
||||
.flat_map(|(i, f)| {
|
||||
fn split_flags(flags: &str) -> Vec<String> {
|
||||
// Individual flags can be single-quoted to preserve spaces; see
|
||||
// <https://github.com/rust-lang/rust/pull/115948/commits/957c5db6>.
|
||||
flags
|
||||
.split("'")
|
||||
.enumerate()
|
||||
.flat_map(
|
||||
|(i, f)| {
|
||||
if i % 2 == 1 { vec![f] } else { f.split_whitespace().collect() }
|
||||
})
|
||||
.map(|s| s.to_owned()),
|
||||
);
|
||||
},
|
||||
)
|
||||
.map(move |s| s.to_owned())
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
if let Some(flags) = config.parse_name_value_directive(ln, COMPILE_FLAGS) {
|
||||
self.compile_flags.extend(split_flags(&flags));
|
||||
}
|
||||
if config.parse_name_value_directive(ln, INCORRECT_COMPILER_FLAGS).is_some() {
|
||||
panic!("`compiler-flags` directive should be spelled `compile-flags`");
|
||||
|
|
@ -488,6 +500,10 @@ impl TestProps {
|
|||
COMPARE_OUTPUT_LINES_BY_SUBSET,
|
||||
&mut self.compare_output_lines_by_subset,
|
||||
);
|
||||
|
||||
if let Some(flags) = config.parse_name_value_directive(ln, LLVM_COV_FLAGS) {
|
||||
self.llvm_cov_flags.extend(split_flags(&flags));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::common::{CompareMode, Config, Debugger};
|
||||
use crate::common::{CompareMode, Config, Debugger, Mode};
|
||||
use crate::header::IgnoreDecision;
|
||||
use std::collections::HashSet;
|
||||
|
||||
|
|
@ -208,6 +208,17 @@ pub(super) fn parse_cfg_name_directive<'a>(
|
|||
},
|
||||
message: "when comparing with {name}",
|
||||
}
|
||||
// Coverage tests run the same test file in multiple modes.
|
||||
// If a particular test should not be run in one of the modes, ignore it
|
||||
// with "ignore-mode-coverage-map" or "ignore-mode-coverage-run".
|
||||
condition! {
|
||||
name: format!("mode-{}", config.mode.to_str()),
|
||||
allowed_names: ContainsPrefixed {
|
||||
prefix: "mode-",
|
||||
inner: Mode::STR_VARIANTS,
|
||||
},
|
||||
message: "when the test mode is {name}",
|
||||
}
|
||||
|
||||
if prefix == "ignore" && outcome == MatchOutcome::Invalid {
|
||||
// Don't error out for ignore-tidy-* diretives, as those are not handled by compiletest.
|
||||
|
|
|
|||
|
|
@ -238,7 +238,7 @@ impl CachedNeedsConditions {
|
|||
sanitizer_memtag: sanitizers.contains(&Sanitizer::Memtag),
|
||||
sanitizer_shadow_call_stack: sanitizers.contains(&Sanitizer::ShadowCallStack),
|
||||
sanitizer_safestack: sanitizers.contains(&Sanitizer::Safestack),
|
||||
profiler_support: std::env::var_os("RUSTC_PROFILER_SUPPORT").is_some(),
|
||||
profiler_support: config.profiler_support,
|
||||
xray: config.target_cfg().xray,
|
||||
|
||||
// For tests using the `needs-rust-lld` directive (e.g. for `-Clink-self-contained=+linker`),
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use std::io::Read;
|
||||
use std::path::Path;
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::common::{Config, Debugger};
|
||||
use crate::common::{Config, Debugger, Mode};
|
||||
use crate::header::{parse_normalization_string, EarlyProps, HeadersCache};
|
||||
|
||||
fn make_test_description<R: Read>(
|
||||
|
|
@ -55,6 +56,7 @@ fn test_parse_normalization_string() {
|
|||
|
||||
#[derive(Default)]
|
||||
struct ConfigBuilder {
|
||||
mode: Option<String>,
|
||||
channel: Option<String>,
|
||||
host: Option<String>,
|
||||
target: Option<String>,
|
||||
|
|
@ -62,9 +64,15 @@ struct ConfigBuilder {
|
|||
llvm_version: Option<String>,
|
||||
git_hash: bool,
|
||||
system_llvm: bool,
|
||||
profiler_support: bool,
|
||||
}
|
||||
|
||||
impl ConfigBuilder {
|
||||
fn mode(&mut self, s: &str) -> &mut Self {
|
||||
self.mode = Some(s.to_owned());
|
||||
self
|
||||
}
|
||||
|
||||
fn channel(&mut self, s: &str) -> &mut Self {
|
||||
self.channel = Some(s.to_owned());
|
||||
self
|
||||
|
|
@ -100,10 +108,16 @@ impl ConfigBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
fn profiler_support(&mut self, s: bool) -> &mut Self {
|
||||
self.profiler_support = s;
|
||||
self
|
||||
}
|
||||
|
||||
fn build(&mut self) -> Config {
|
||||
let args = &[
|
||||
"compiletest",
|
||||
"--mode=ui",
|
||||
"--mode",
|
||||
self.mode.as_deref().unwrap_or("ui"),
|
||||
"--suite=ui",
|
||||
"--compile-lib-path=",
|
||||
"--run-lib-path=",
|
||||
|
|
@ -142,6 +156,9 @@ impl ConfigBuilder {
|
|||
if self.system_llvm {
|
||||
args.push("--system-llvm".to_owned());
|
||||
}
|
||||
if self.profiler_support {
|
||||
args.push("--profiler-support".to_owned());
|
||||
}
|
||||
|
||||
args.push("--rustc-path".to_string());
|
||||
// This is a subtle/fragile thing. On rust-lang CI, there is no global
|
||||
|
|
@ -340,6 +357,15 @@ fn sanitizers() {
|
|||
assert!(check_ignore(&config, "// needs-sanitizer-thread"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn profiler_support() {
|
||||
let config: Config = cfg().profiler_support(false).build();
|
||||
assert!(check_ignore(&config, "// needs-profiler-support"));
|
||||
|
||||
let config: Config = cfg().profiler_support(true).build();
|
||||
assert!(!check_ignore(&config, "// needs-profiler-support"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn asm_support() {
|
||||
let asms = [
|
||||
|
|
@ -530,3 +556,17 @@ fn families() {
|
|||
assert!(!check_ignore(&config, &format!("// ignore-{other}")));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ignore_mode() {
|
||||
for &mode in Mode::STR_VARIANTS {
|
||||
// Indicate profiler support so that "coverage-run" tests aren't skipped.
|
||||
let config: Config = cfg().mode(mode).profiler_support(true).build();
|
||||
let other = if mode == "coverage-run" { "coverage-map" } else { "coverage-run" };
|
||||
assert_ne!(mode, other);
|
||||
assert_eq!(config.mode, Mode::from_str(mode).unwrap());
|
||||
assert_ne!(config.mode, Mode::from_str(other).unwrap());
|
||||
assert!(check_ignore(&config, &format!("// ignore-mode-{mode}")));
|
||||
assert!(!check_ignore(&config, &format!("// ignore-mode-{other}")));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -142,6 +142,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
|||
.optflag("", "force-rerun", "rerun tests even if the inputs are unchanged")
|
||||
.optflag("", "only-modified", "only run tests that result been modified")
|
||||
.optflag("", "nocapture", "")
|
||||
.optflag("", "profiler-support", "is the profiler runtime enabled for this target")
|
||||
.optflag("h", "help", "show this message")
|
||||
.reqopt("", "channel", "current Rust channel", "CHANNEL")
|
||||
.optflag("", "git-hash", "run tests which rely on commit version being compiled into the binaries")
|
||||
|
|
@ -315,6 +316,8 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
|||
|
||||
git_repository: matches.opt_str("git-repository").unwrap(),
|
||||
nightly_branch: matches.opt_str("nightly-branch").unwrap(),
|
||||
|
||||
profiler_support: matches.opt_present("profiler-support"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -575,6 +575,8 @@ impl<'test> TestCx<'test> {
|
|||
cmd.arg("--object");
|
||||
cmd.arg(bin);
|
||||
}
|
||||
|
||||
cmd.args(&self.props.llvm_cov_flags);
|
||||
});
|
||||
if !proc_res.status.success() {
|
||||
self.fatal_proc_rec("llvm-cov show failed!", &proc_res);
|
||||
|
|
|
|||
|
|
@ -454,12 +454,12 @@ pub fn report_msg<'tcx>(
|
|||
let span = stacktrace.first().map_or(DUMMY_SP, |fi| fi.span);
|
||||
let sess = machine.tcx.sess;
|
||||
let level = match diag_level {
|
||||
DiagLevel::Error => Level::Error { lint: false },
|
||||
DiagLevel::Error => Level::Error,
|
||||
DiagLevel::Warning => Level::Warning(None),
|
||||
DiagLevel::Note => Level::Note,
|
||||
};
|
||||
let mut err = DiagnosticBuilder::<()>::new(sess.dcx(), level, title);
|
||||
err.set_span(span);
|
||||
err.span(span);
|
||||
|
||||
// Show main message.
|
||||
if span != DUMMY_SP {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
//@[stack]error-in-other-file: which is strongly protected
|
||||
//@[tree]error-in-other-file: /deallocation through .* is forbidden/
|
||||
struct Newtype<'a>(&'a mut i32, i32);
|
||||
struct Newtype<'a>(#[allow(dead_code)] &'a mut i32, #[allow(dead_code)] i32);
|
||||
|
||||
fn dealloc_while_running(_n: Newtype<'_>, dealloc: impl FnOnce()) {
|
||||
dealloc();
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
//@[stack]error-in-other-file: which is strongly protected
|
||||
//@[tree]error-in-other-file: /deallocation through .* is forbidden/
|
||||
|
||||
struct Newtype<'a>(&'a mut i32);
|
||||
struct Newtype<'a>(#[allow(dead_code)] &'a mut i32);
|
||||
|
||||
fn dealloc_while_running(_n: Newtype<'_>, dealloc: impl FnOnce()) {
|
||||
dealloc();
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
use std::sync::atomic::{AtomicI64, Ordering};
|
||||
|
||||
#[repr(align(8))]
|
||||
struct AlignedI64(i64);
|
||||
struct AlignedI64(#[allow(dead_code)] i64);
|
||||
|
||||
fn main() {
|
||||
static X: AlignedI64 = AlignedI64(0);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// should find the bug even without retagging
|
||||
//@compile-flags: -Zmiri-disable-stacked-borrows
|
||||
|
||||
struct SliceWithHead(u8, [u8]);
|
||||
struct SliceWithHead(#[allow(dead_code)] u8, #[allow(dead_code)] [u8]);
|
||||
|
||||
fn main() {
|
||||
let buf = [0u32; 1];
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
// Some targets treat arrays and structs very differently. We would probably catch that on those
|
||||
// targets since we check the `PassMode`; here we ensure that we catch it on *all* targets
|
||||
// (in particular, on x86-64 the pass mode is `Indirect` for both of these).
|
||||
struct S(i32, i32, i32, i32);
|
||||
struct S(#[allow(dead_code)] i32, #[allow(dead_code)] i32, #[allow(dead_code)] i32, #[allow(dead_code)] i32);
|
||||
type A = [i32; 4];
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
trait Empty {}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct FunnyPointer(dyn Empty);
|
||||
pub struct FunnyPointer(#[allow(dead_code)] dyn Empty);
|
||||
|
||||
#[repr(C)]
|
||||
pub struct Meta {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
//@compile-flags: -Cdebug-assertions=no
|
||||
|
||||
#[repr(transparent)]
|
||||
struct HasDrop(u8);
|
||||
struct HasDrop(#[allow(dead_code)] u8);
|
||||
|
||||
impl Drop for HasDrop {
|
||||
fn drop(&mut self) {}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ mod utils;
|
|||
|
||||
#[repr(align(8))]
|
||||
#[derive(Copy, Clone)]
|
||||
struct Align8(u64);
|
||||
struct Align8(#[allow(dead_code)] u64);
|
||||
|
||||
fn main() {
|
||||
let buffer = [0u32; 128]; // get some 4-aligned memory
|
||||
|
|
@ -35,7 +35,7 @@ fn main() {
|
|||
if cfg!(read_unaligned_ptr) {
|
||||
#[repr(align(16))]
|
||||
#[derive(Copy, Clone)]
|
||||
struct Align16(u128);
|
||||
struct Align16(#[allow(dead_code)] u128);
|
||||
|
||||
let align16 = if align8.addr() % 16 == 0 { align8 } else { align8.wrapping_add(2) };
|
||||
assert!(align16.addr() % 16 == 0);
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ fn test_align_to() {
|
|||
{
|
||||
#[repr(align(8))]
|
||||
#[derive(Copy, Clone)]
|
||||
struct Align8(u64);
|
||||
struct Align8(#[allow(dead_code)] u64);
|
||||
|
||||
let (_l, m, _r) = unsafe { s.align_to::<Align8>() };
|
||||
assert!(m.len() > 0);
|
||||
|
|
@ -97,7 +97,7 @@ fn huge_align() {
|
|||
const SIZE: usize = 1 << 30;
|
||||
#[cfg(target_pointer_width = "16")]
|
||||
const SIZE: usize = 1 << 13;
|
||||
struct HugeSize([u8; SIZE - 1]);
|
||||
struct HugeSize(#[allow(dead_code)] [u8; SIZE - 1]);
|
||||
let _ = std::ptr::invalid::<HugeSize>(SIZE).align_offset(SIZE);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ fn test1() {
|
|||
}
|
||||
|
||||
// Make the allocator itself so big that the Box is not even a ScalarPair any more.
|
||||
struct OnceAllocRef<'s, 'a>(&'s OnceAlloc<'a>, u64);
|
||||
struct OnceAllocRef<'s, 'a>(&'s OnceAlloc<'a>, #[allow(dead_code)] u64);
|
||||
|
||||
unsafe impl<'shared, 'a: 'shared> Allocator for OnceAllocRef<'shared, 'a> {
|
||||
fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ fn boxed_pair_to_vec() {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Foo(u64);
|
||||
struct Foo(#[allow(dead_code)] u64);
|
||||
fn reinterstruct(box_pair: Box<PairFoo>) -> Vec<Foo> {
|
||||
let ref_pair = Box::leak(box_pair) as *mut PairFoo;
|
||||
let ptr_foo = unsafe { std::ptr::addr_of_mut!((*ref_pair).fst) };
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// test that ordinary fat pointer operations work.
|
||||
|
||||
struct Wrapper<T: ?Sized>(u32, T);
|
||||
struct Wrapper<T: ?Sized>(#[allow(dead_code)] u32, T);
|
||||
|
||||
struct FatPtrContainer<'a> {
|
||||
ptr: &'a [u8],
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
use std::mem;
|
||||
|
||||
#[repr(packed(4))]
|
||||
struct Slice([u32]);
|
||||
struct Slice(#[allow(dead_code)] [u32]);
|
||||
|
||||
#[repr(packed(2), C)]
|
||||
struct PackedSized {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#[repr(u8)]
|
||||
enum Foo {
|
||||
Foo(u8),
|
||||
Foo(#[allow(dead_code)] u8),
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
use std::mem;
|
||||
|
||||
const SZ: usize = 100;
|
||||
struct P<T: ?Sized>([u8; SZ], T);
|
||||
struct P<T: ?Sized>(#[allow(dead_code)] [u8; SZ], T);
|
||||
|
||||
type Ack<T> = P<P<T>>;
|
||||
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ fn test_inner_packed() {
|
|||
struct Inner(u32);
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct Outer(u8, Inner);
|
||||
struct Outer(#[allow(dead_code)] u8, Inner);
|
||||
|
||||
let o = Outer(0, Inner(42));
|
||||
let _x = o.1;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//@compile-flags: -Zmiri-retag-fields=none
|
||||
|
||||
struct Newtype<'a>(&'a mut i32);
|
||||
struct Newtype<'a>(#[allow(dead_code)] &'a mut i32);
|
||||
|
||||
fn dealloc_while_running(_n: Newtype<'_>, dealloc: impl FnOnce()) {
|
||||
dealloc();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//@compile-flags: -Zmiri-retag-fields=scalar
|
||||
|
||||
struct Newtype<'a>(&'a mut i32, i32, i32);
|
||||
struct Newtype<'a>(#[allow(dead_code)] &'a mut i32, #[allow(dead_code)] i32, #[allow(dead_code)] i32);
|
||||
|
||||
fn dealloc_while_running(_n: Newtype<'_>, dealloc: impl FnOnce()) {
|
||||
dealloc();
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@ fn not_unpin_not_protected() {
|
|||
// the self-referential-coroutine situation, it does not seem worth the potential trouble.)
|
||||
use std::marker::PhantomPinned;
|
||||
|
||||
pub struct NotUnpin(i32, PhantomPinned);
|
||||
pub struct NotUnpin(#[allow(dead_code)] i32, PhantomPinned);
|
||||
|
||||
fn inner(x: &mut NotUnpin, f: fn(&mut NotUnpin)) {
|
||||
// `f` may mutate, but it may not deallocate!
|
||||
|
|
|
|||
|
|
@ -318,7 +318,7 @@ fn not_unpin_not_protected() {
|
|||
// the self-referential-coroutine situation, it does not seem worth the potential trouble.)
|
||||
use std::marker::PhantomPinned;
|
||||
|
||||
pub struct NotUnpin(i32, PhantomPinned);
|
||||
pub struct NotUnpin(#[allow(dead_code)] i32, PhantomPinned);
|
||||
|
||||
fn inner(x: &mut NotUnpin, f: fn(&mut NotUnpin)) {
|
||||
// `f` may mutate, but it may not deallocate!
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ impl Drop for Foo {
|
|||
static mut FOO: bool = false;
|
||||
|
||||
enum Bar {
|
||||
A(Box<i32>),
|
||||
A(#[allow(dead_code)] Box<i32>),
|
||||
B(Foo),
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1947,7 +1947,7 @@ fn rewrite_unary_op(
|
|||
}
|
||||
|
||||
pub(crate) enum RhsAssignKind<'ast> {
|
||||
Expr(&'ast ast::ExprKind, Span),
|
||||
Expr(&'ast ast::ExprKind, #[allow(dead_code)] Span),
|
||||
Bounds,
|
||||
Ty,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::path::Path;
|
|||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
use rustc_data_structures::sync::{IntoDynSyncSend, Lrc};
|
||||
use rustc_errors::emitter::{DynEmitter, Emitter, EmitterWriter};
|
||||
use rustc_errors::emitter::{DynEmitter, Emitter, HumanEmitter};
|
||||
use rustc_errors::translation::Translate;
|
||||
use rustc_errors::{ColorConfig, DiagCtxt, Diagnostic, Level as DiagnosticLevel};
|
||||
use rustc_session::parse::ParseSess as RawParseSess;
|
||||
|
|
@ -139,7 +139,7 @@ fn default_dcx(
|
|||
rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
|
||||
false,
|
||||
);
|
||||
Box::new(EmitterWriter::stderr(emit_color, fallback_bundle).sm(Some(source_map.clone())))
|
||||
Box::new(HumanEmitter::stderr(emit_color, fallback_bundle).sm(Some(source_map.clone())))
|
||||
};
|
||||
DiagCtxt::with_emitter(Box::new(SilentOnIgnoredFilesEmitter {
|
||||
has_non_ignorable_parser_errors: false,
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use std::path::{Path, PathBuf};
|
|||
|
||||
const ENTRY_LIMIT: usize = 900;
|
||||
// FIXME: The following limits should be reduced eventually.
|
||||
const ISSUES_ENTRY_LIMIT: usize = 1852;
|
||||
const ISSUES_ENTRY_LIMIT: usize = 1849;
|
||||
const ROOT_ENTRY_LIMIT: usize = 867;
|
||||
|
||||
const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue