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

Rustup

r? `@ghost`

I ran out of time and will have to do the Clippy->Rust sync tomorrow.

changelog: none
This commit is contained in:
bors 2022-10-20 14:43:03 +00:00
commit a4e872602b
47 changed files with 187 additions and 512 deletions

View File

@ -856,11 +856,10 @@ fn walk_parents<'tcx>(
// Trait methods taking `self`
arg_ty
} && impl_ty.is_ref()
&& cx.tcx.infer_ctxt().enter(|infcx|
infcx
.type_implements_trait(trait_id, impl_ty, subs, cx.param_env)
.must_apply_modulo_regions()
)
&& let infcx = cx.tcx.infer_ctxt().build()
&& infcx
.type_implements_trait(trait_id, impl_ty, subs, cx.param_env)
.must_apply_modulo_regions()
{
return Some(Position::MethodReceiverRefImpl)
}
@ -1158,9 +1157,8 @@ fn needless_borrow_impl_arg_position<'tcx>(
let predicate = EarlyBinder(predicate).subst(cx.tcx, &substs_with_referent_ty);
let obligation = Obligation::new(ObligationCause::dummy(), cx.param_env, predicate);
cx.tcx
.infer_ctxt()
.enter(|infcx| infcx.predicate_must_hold_modulo_regions(&obligation))
let infcx = cx.tcx.infer_ctxt().build();
infcx.predicate_must_hold_modulo_regions(&obligation)
})
};

View File

@ -106,9 +106,8 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
};
let fn_def_id = cx.tcx.hir().local_def_id(hir_id);
cx.tcx.infer_ctxt().enter(|infcx| {
ExprUseVisitor::new(&mut v, &infcx, fn_def_id, cx.param_env, cx.typeck_results()).consume_body(body);
});
let infcx = cx.tcx.infer_ctxt().build();
ExprUseVisitor::new(&mut v, &infcx, fn_def_id, cx.param_env, cx.typeck_results()).consume_body(body);
for node in v.set {
span_lint_hir(

View File

@ -7,7 +7,7 @@ use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{EarlyBinder, Opaque, PredicateKind::Trait};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::{sym, Span};
use rustc_trait_selection::traits::error_reporting::suggestions::InferCtxtExt;
use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt;
use rustc_trait_selection::traits::{self, FulfillmentError};
declare_clippy_lint! {
@ -77,10 +77,9 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
if is_future {
let send_trait = cx.tcx.get_diagnostic_item(sym::Send).unwrap();
let span = decl.output.span();
let send_errors = cx.tcx.infer_ctxt().enter(|infcx| {
let cause = traits::ObligationCause::misc(span, hir_id);
traits::fully_solve_bound(&infcx, cause, cx.param_env, ret_ty, send_trait)
});
let infcx = cx.tcx.infer_ctxt().build();
let cause = traits::ObligationCause::misc(span, hir_id);
let send_errors = traits::fully_solve_bound(&infcx, cause, cx.param_env, ret_ty, send_trait);
if !send_errors.is_empty() {
span_lint_and_then(
cx,
@ -88,18 +87,18 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
span,
"future cannot be sent between threads safely",
|db| {
cx.tcx.infer_ctxt().enter(|infcx| {
for FulfillmentError { obligation, .. } in send_errors {
infcx.maybe_note_obligation_cause_for_async_await(db, &obligation);
if let Trait(trait_pred) = obligation.predicate.kind().skip_binder() {
db.note(&format!(
"`{}` doesn't implement `{}`",
trait_pred.self_ty(),
trait_pred.trait_ref.print_only_trait_path(),
));
}
for FulfillmentError { obligation, .. } in send_errors {
infcx
.err_ctxt()
.maybe_note_obligation_cause_for_async_await(db, &obligation);
if let Trait(trait_pred) = obligation.predicate.kind().skip_binder() {
db.note(&format!(
"`{}` doesn't implement `{}`",
trait_pred.self_ty(),
trait_pred.trait_ref.print_only_trait_path(),
));
}
});
}
},
);
}

View File

@ -19,7 +19,6 @@ declare_clippy_lint! {
///
/// ### Example
/// ```rust,no_run
/// # #![allow(const_err)]
/// let x = [1, 2, 3, 4];
///
/// x[9];

View File

@ -113,7 +113,6 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
LintId::of(loops::EMPTY_LOOP),
LintId::of(loops::EXPLICIT_COUNTER_LOOP),
LintId::of(loops::FOR_KV_MAP),
LintId::of(loops::FOR_LOOPS_OVER_FALLIBLES),
LintId::of(loops::ITER_NEXT_LOOP),
LintId::of(loops::MANUAL_FIND),
LintId::of(loops::MANUAL_FLATTEN),

View File

@ -230,7 +230,6 @@ store.register_lints(&[
loops::EXPLICIT_INTO_ITER_LOOP,
loops::EXPLICIT_ITER_LOOP,
loops::FOR_KV_MAP,
loops::FOR_LOOPS_OVER_FALLIBLES,
loops::ITER_NEXT_LOOP,
loops::MANUAL_FIND,
loops::MANUAL_FLATTEN,

View File

@ -22,7 +22,6 @@ store.register_group(true, "clippy::suspicious", Some("clippy_suspicious"), vec!
LintId::of(formatting::SUSPICIOUS_ELSE_FORMATTING),
LintId::of(formatting::SUSPICIOUS_UNARY_OP_FORMATTING),
LintId::of(loops::EMPTY_LOOP),
LintId::of(loops::FOR_LOOPS_OVER_FALLIBLES),
LintId::of(loops::MUT_RANGE_BOUND),
LintId::of(methods::NO_EFFECT_REPLACE),
LintId::of(methods::SUSPICIOUS_MAP),

View File

@ -482,7 +482,7 @@ pub fn read_conf(sess: &Session) -> Conf {
}
for warning in warnings {
sess.struct_warn(&format!(
sess.struct_warn(format!(
"error reading Clippy's configuration file `{}`: {}",
file_name.display(),
format_error(warning)

View File

@ -1,65 +0,0 @@
use super::FOR_LOOPS_OVER_FALLIBLES;
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::source::snippet;
use clippy_utils::ty::is_type_diagnostic_item;
use rustc_hir::{Expr, Pat};
use rustc_lint::LateContext;
use rustc_span::symbol::sym;
/// Checks for `for` loops over `Option`s and `Result`s.
pub(super) fn check(cx: &LateContext<'_>, pat: &Pat<'_>, arg: &Expr<'_>, method_name: Option<&str>) {
let ty = cx.typeck_results().expr_ty(arg);
if is_type_diagnostic_item(cx, ty, sym::Option) {
let help_string = if let Some(method_name) = method_name {
format!(
"consider replacing `for {0} in {1}.{method_name}()` with `if let Some({0}) = {1}`",
snippet(cx, pat.span, "_"),
snippet(cx, arg.span, "_")
)
} else {
format!(
"consider replacing `for {0} in {1}` with `if let Some({0}) = {1}`",
snippet(cx, pat.span, "_"),
snippet(cx, arg.span, "_")
)
};
span_lint_and_help(
cx,
FOR_LOOPS_OVER_FALLIBLES,
arg.span,
&format!(
"for loop over `{0}`, which is an `Option`. This is more readably written as an \
`if let` statement",
snippet(cx, arg.span, "_")
),
None,
&help_string,
);
} else if is_type_diagnostic_item(cx, ty, sym::Result) {
let help_string = if let Some(method_name) = method_name {
format!(
"consider replacing `for {0} in {1}.{method_name}()` with `if let Ok({0}) = {1}`",
snippet(cx, pat.span, "_"),
snippet(cx, arg.span, "_")
)
} else {
format!(
"consider replacing `for {0} in {1}` with `if let Ok({0}) = {1}`",
snippet(cx, pat.span, "_"),
snippet(cx, arg.span, "_")
)
};
span_lint_and_help(
cx,
FOR_LOOPS_OVER_FALLIBLES,
arg.span,
&format!(
"for loop over `{0}`, which is a `Result`. This is more readably written as an \
`if let` statement",
snippet(cx, arg.span, "_")
),
None,
&help_string,
);
}
}

View File

@ -5,7 +5,7 @@ use rustc_hir::Expr;
use rustc_lint::LateContext;
use rustc_span::sym;
pub(super) fn check(cx: &LateContext<'_>, arg: &Expr<'_>) -> bool {
pub(super) fn check(cx: &LateContext<'_>, arg: &Expr<'_>) {
if is_trait_method(cx, arg, sym::Iterator) {
span_lint(
cx,
@ -14,8 +14,5 @@ pub(super) fn check(cx: &LateContext<'_>, arg: &Expr<'_>) -> bool {
"you are iterating over `Iterator::next()` which is an Option; this will compile but is \
probably not what you want",
);
true
} else {
false
}
}

View File

@ -3,7 +3,6 @@ mod explicit_counter_loop;
mod explicit_into_iter_loop;
mod explicit_iter_loop;
mod for_kv_map;
mod for_loops_over_fallibles;
mod iter_next_loop;
mod manual_find;
mod manual_flatten;
@ -173,49 +172,6 @@ declare_clippy_lint! {
"for-looping over `_.next()` which is probably not intended"
}
declare_clippy_lint! {
/// ### What it does
/// Checks for `for` loops over `Option` or `Result` values.
///
/// ### Why is this bad?
/// Readability. This is more clearly expressed as an `if
/// let`.
///
/// ### Example
/// ```rust
/// # let opt = Some(1);
/// # let res: Result<i32, std::io::Error> = Ok(1);
/// for x in opt {
/// // ..
/// }
///
/// for x in &res {
/// // ..
/// }
///
/// for x in res.iter() {
/// // ..
/// }
/// ```
///
/// Use instead:
/// ```rust
/// # let opt = Some(1);
/// # let res: Result<i32, std::io::Error> = Ok(1);
/// if let Some(x) = opt {
/// // ..
/// }
///
/// if let Ok(x) = res {
/// // ..
/// }
/// ```
#[clippy::version = "1.45.0"]
pub FOR_LOOPS_OVER_FALLIBLES,
suspicious,
"for-looping over an `Option` or a `Result`, which is more clearly expressed as an `if let`"
}
declare_clippy_lint! {
/// ### What it does
/// Detects `loop + match` combinations that are easier
@ -648,7 +604,6 @@ declare_lint_pass!(Loops => [
EXPLICIT_ITER_LOOP,
EXPLICIT_INTO_ITER_LOOP,
ITER_NEXT_LOOP,
FOR_LOOPS_OVER_FALLIBLES,
WHILE_LET_LOOP,
NEEDLESS_COLLECT,
EXPLICIT_COUNTER_LOOP,
@ -739,30 +694,22 @@ fn check_for_loop<'tcx>(
manual_find::check(cx, pat, arg, body, span, expr);
}
fn check_for_loop_arg(cx: &LateContext<'_>, pat: &Pat<'_>, arg: &Expr<'_>) {
let mut next_loop_linted = false; // whether or not ITER_NEXT_LOOP lint was used
fn check_for_loop_arg(cx: &LateContext<'_>, _: &Pat<'_>, arg: &Expr<'_>) {
if let ExprKind::MethodCall(method, self_arg, [], _) = arg.kind {
let method_name = method.ident.as_str();
// check for looping over x.iter() or x.iter_mut(), could use &x or &mut x
match method_name {
"iter" | "iter_mut" => {
explicit_iter_loop::check(cx, self_arg, arg, method_name);
for_loops_over_fallibles::check(cx, pat, self_arg, Some(method_name));
},
"into_iter" => {
explicit_iter_loop::check(cx, self_arg, arg, method_name);
explicit_into_iter_loop::check(cx, self_arg, arg);
for_loops_over_fallibles::check(cx, pat, self_arg, Some(method_name));
},
"next" => {
next_loop_linted = iter_next_loop::check(cx, arg);
iter_next_loop::check(cx, arg);
},
_ => {},
}
}
if !next_loop_linted {
for_loops_over_fallibles::check(cx, pat, arg, None);
}
}

View File

@ -65,16 +65,15 @@ fn check_for_mutation<'tcx>(
span_low: None,
span_high: None,
};
cx.tcx.infer_ctxt().enter(|infcx| {
ExprUseVisitor::new(
&mut delegate,
&infcx,
body.hir_id.owner.def_id,
cx.param_env,
cx.typeck_results(),
)
.walk_expr(body);
});
let infcx = cx.tcx.infer_ctxt().build();
ExprUseVisitor::new(
&mut delegate,
&infcx,
body.hir_id.owner.def_id,
cx.param_env,
cx.typeck_results(),
)
.walk_expr(body);
delegate.mutation_span()
}

View File

@ -363,7 +363,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
&& let output_ty = return_ty(cx, item.hir_id())
&& let local_def_id = cx.tcx.hir().local_def_id(item.hir_id())
&& Inherited::build(cx.tcx, local_def_id).enter(|inherited| {
let fn_ctxt = FnCtxt::new(&inherited, cx.param_env, item.hir_id());
let fn_ctxt = FnCtxt::new(inherited, cx.param_env, item.hir_id());
fn_ctxt.can_coerce(ty, output_ty)
}) {
if has_lifetime(output_ty) && has_lifetime(ty) {
@ -420,9 +420,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
if trait_predicates.any(|predicate| {
let predicate = EarlyBinder(predicate).subst(cx.tcx, new_subst);
let obligation = Obligation::new(ObligationCause::dummy(), cx.param_env, predicate);
!cx.tcx
.infer_ctxt()
.enter(|infcx| infcx.predicate_must_hold_modulo_regions(&obligation))
!cx.tcx.infer_ctxt().build().predicate_must_hold_modulo_regions(&obligation)
}) {
return false;
}

View File

@ -148,7 +148,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
let desc = match impl_item.kind {
hir::ImplItemKind::Fn(..) => "a method",
hir::ImplItemKind::Const(..) | hir::ImplItemKind::TyAlias(_) => return,
hir::ImplItemKind::Const(..) | hir::ImplItemKind::Type(_) => return,
};
let assoc_item = cx.tcx.associated_item(impl_item.def_id);

View File

@ -138,10 +138,8 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
..
} = {
let mut ctx = MovedVariablesCtxt::default();
cx.tcx.infer_ctxt().enter(|infcx| {
euv::ExprUseVisitor::new(&mut ctx, &infcx, fn_def_id, cx.param_env, cx.typeck_results())
.consume_body(body);
});
let infcx = cx.tcx.infer_ctxt().build();
euv::ExprUseVisitor::new(&mut ctx, &infcx, fn_def_id, cx.param_env, cx.typeck_results()).consume_body(body);
ctx
};

View File

@ -123,16 +123,15 @@ fn imm_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> hir::HirIdSet
}
let mut s = S(hir::HirIdSet::default());
cx.tcx.infer_ctxt().enter(|infcx| {
let mut v = ExprUseVisitor::new(
&mut s,
&infcx,
cx.tcx.hir().body_owner_def_id(cx.enclosing_body.unwrap()),
cx.param_env,
cx.typeck_results(),
);
v.consume_expr(e);
});
let infcx = cx.tcx.infer_ctxt().build();
let mut v = ExprUseVisitor::new(
&mut s,
&infcx,
cx.tcx.hir().body_owner_def_id(cx.enclosing_body.unwrap()),
cx.param_env,
cx.typeck_results(),
);
v.consume_expr(e);
s.0
}
@ -156,15 +155,14 @@ fn mut_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> hir::HirIdSet
}
let mut s = S(hir::HirIdSet::default());
cx.tcx.infer_ctxt().enter(|infcx| {
let mut v = ExprUseVisitor::new(
&mut s,
&infcx,
cx.tcx.hir().body_owner_def_id(cx.enclosing_body.unwrap()),
cx.param_env,
cx.typeck_results(),
);
v.consume_expr(e);
});
let infcx = cx.tcx.infer_ctxt().build();
let mut v = ExprUseVisitor::new(
&mut s,
&infcx,
cx.tcx.hir().body_owner_def_id(cx.enclosing_body.unwrap()),
cx.param_env,
cx.typeck_results(),
);
v.consume_expr(e);
s.0
}

View File

@ -689,23 +689,22 @@ fn matches_preds<'tcx>(
ty: Ty<'tcx>,
preds: &'tcx [Binder<'tcx, ExistentialPredicate<'tcx>>],
) -> bool {
cx.tcx.infer_ctxt().enter(|infcx| {
preds.iter().all(|&p| match cx.tcx.erase_late_bound_regions(p) {
ExistentialPredicate::Trait(p) => infcx
.type_implements_trait(p.def_id, ty, p.substs, cx.param_env)
.must_apply_modulo_regions(),
ExistentialPredicate::Projection(p) => infcx.predicate_must_hold_modulo_regions(&Obligation::new(
ObligationCause::dummy(),
cx.param_env,
cx.tcx.mk_predicate(Binder::bind_with_vars(
PredicateKind::Projection(p.with_self_ty(cx.tcx, ty)),
List::empty(),
)),
let infcx = cx.tcx.infer_ctxt().build();
preds.iter().all(|&p| match cx.tcx.erase_late_bound_regions(p) {
ExistentialPredicate::Trait(p) => infcx
.type_implements_trait(p.def_id, ty, p.substs, cx.param_env)
.must_apply_modulo_regions(),
ExistentialPredicate::Projection(p) => infcx.predicate_must_hold_modulo_regions(&Obligation::new(
ObligationCause::dummy(),
cx.param_env,
cx.tcx.mk_predicate(Binder::bind_with_vars(
PredicateKind::Projection(p.with_self_ty(cx.tcx, ty)),
List::empty(),
)),
ExistentialPredicate::AutoTrait(p) => infcx
.type_implements_trait(p, ty, List::empty(), cx.param_env)
.must_apply_modulo_regions(),
})
)),
ExistentialPredicate::AutoTrait(p) => infcx
.type_implements_trait(p, ty, List::empty(), cx.param_env)
.must_apply_modulo_regions(),
})
}

View File

@ -11,8 +11,8 @@ pub static RENAMED_LINTS: &[(&str, &str)] = &[
("clippy::disallowed_method", "clippy::disallowed_methods"),
("clippy::disallowed_type", "clippy::disallowed_types"),
("clippy::eval_order_dependence", "clippy::mixed_read_write_in_expression"),
("clippy::for_loop_over_option", "clippy::for_loops_over_fallibles"),
("clippy::for_loop_over_result", "clippy::for_loops_over_fallibles"),
("clippy::for_loop_over_option", "for_loops_over_fallibles"),
("clippy::for_loop_over_result", "for_loops_over_fallibles"),
("clippy::identity_conversion", "clippy::useless_conversion"),
("clippy::if_let_some_result", "clippy::match_result_ok"),
("clippy::logic_bug", "clippy::overly_complex_bool_expr"),
@ -31,6 +31,7 @@ pub static RENAMED_LINTS: &[(&str, &str)] = &[
("clippy::to_string_in_display", "clippy::recursive_format_impl"),
("clippy::zero_width_space", "clippy::invisible_characters"),
("clippy::drop_bounds", "drop_bounds"),
("clippy::for_loops_over_fallibles", "for_loops_over_fallibles"),
("clippy::into_iter_on_array", "array_into_iter"),
("clippy::invalid_atomic_ordering", "invalid_atomic_ordering"),
("clippy::invalid_ref", "invalid_value"),

View File

@ -1,8 +1,5 @@
use rustc_hir::Expr;
use rustc_hir_analysis::check::{
cast::{self, CastCheckResult},
FnCtxt, Inherited,
};
use rustc_hir_analysis::check::{cast, FnCtxt, Inherited};
use rustc_lint::LateContext;
use rustc_middle::ty::{cast::CastKind, Ty};
use rustc_span::DUMMY_SP;
@ -48,7 +45,7 @@ fn check_cast<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>
let local_def_id = hir_id.owner.def_id;
Inherited::build(cx.tcx, local_def_id).enter(|inherited| {
let fn_ctxt = FnCtxt::new(&inherited, cx.param_env, hir_id);
let fn_ctxt = FnCtxt::new(inherited, cx.param_env, hir_id);
// If we already have errors, we can't be sure we can pointer cast.
assert!(
@ -56,7 +53,7 @@ fn check_cast<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>
"Newly created FnCtxt contained errors"
);
if let CastCheckResult::Deferred(check) = cast::check_cast(
if let Ok(check) = cast::CastCheck::new(
&fn_ctxt, e, from_ty, to_ty,
// We won't show any error to the user, so we don't care what the span is here.
DUMMY_SP, DUMMY_SP,

View File

@ -374,7 +374,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
// Methods are covered by check_fn.
// Type aliases are ignored because oftentimes it's impossible to
// make type alias declaration in trait simpler, see #1013
ImplItemKind::Fn(..) | ImplItemKind::TyAlias(..) => (),
ImplItemKind::Fn(..) | ImplItemKind::Type(..) => (),
}
}

View File

@ -438,14 +438,14 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
eq_defaultness(*ld, *rd) && eq_fn_sig(lf, rf) && eq_generics(lg, rg) && both(lb, rb, |l, r| eq_block(l, r))
},
(
TyAlias(box ast::TyAlias {
Type(box ast::TyAlias {
defaultness: ld,
generics: lg,
bounds: lb,
ty: lt,
..
}),
TyAlias(box ast::TyAlias {
Type(box ast::TyAlias {
defaultness: rd,
generics: rg,
bounds: rb,

View File

@ -220,7 +220,7 @@ fn trait_item_search_pat(item: &TraitItem<'_>) -> (Pat, Pat) {
fn impl_item_search_pat(item: &ImplItem<'_>) -> (Pat, Pat) {
let (start_pat, end_pat) = match &item.kind {
ImplItemKind::Const(..) => (Pat::Str("const"), Pat::Str(";")),
ImplItemKind::TyAlias(..) => (Pat::Str("type"), Pat::Str(";")),
ImplItemKind::Type(..) => (Pat::Str("type"), Pat::Str(";")),
ImplItemKind::Fn(sig, ..) => (fn_header_search_pat(sig.header), Pat::Str("")),
};
if item.vis_span.is_empty() {

View File

@ -2108,9 +2108,9 @@ pub fn fn_def_id(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<DefId> {
}
}
/// Returns Option<String> where String is a textual representation of the type encapsulated in the
/// slice iff the given expression is a slice of primitives (as defined in the
/// `is_recursively_primitive_type` function) and None otherwise.
/// Returns `Option<String>` where String is a textual representation of the type encapsulated in
/// the slice iff the given expression is a slice of primitives (as defined in the
/// `is_recursively_primitive_type` function) and `None` otherwise.
pub fn is_slice_of_primitives(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<String> {
let expr_type = cx.typeck_results().expr_ty_adjusted(expr);
let expr_kind = expr_type.kind();

View File

@ -129,7 +129,12 @@ fn check_rvalue<'tcx>(
| Rvalue::Use(operand)
| Rvalue::Cast(
CastKind::PointerFromExposedAddress
| CastKind::Misc
| CastKind::IntToInt
| CastKind::FloatToInt
| CastKind::IntToFloat
| CastKind::FloatToFloat
| CastKind::FnPtrToPtr
| CastKind::PtrToPtr
| CastKind::Pointer(PointerCast::MutToConstPointer | PointerCast::ArrayToPointer),
operand,
_,

View File

@ -823,10 +823,9 @@ pub fn deref_closure_args<'tcx>(cx: &LateContext<'_>, closure: &'tcx hir::Expr<'
};
let fn_def_id = cx.tcx.hir().local_def_id(closure.hir_id);
cx.tcx.infer_ctxt().enter(|infcx| {
ExprUseVisitor::new(&mut visitor, &infcx, fn_def_id, cx.param_env, cx.typeck_results())
.consume_body(closure_body);
});
let infcx = cx.tcx.infer_ctxt().build();
ExprUseVisitor::new(&mut visitor, &infcx, fn_def_id, cx.param_env, cx.typeck_results())
.consume_body(closure_body);
if !visitor.suggestion_start.is_empty() {
return Some(DerefClosure {

View File

@ -172,11 +172,10 @@ pub fn implements_trait_with_env<'tcx>(
return false;
}
let ty_params = tcx.mk_substs(ty_params.iter());
tcx.infer_ctxt().enter(|infcx| {
infcx
.type_implements_trait(trait_id, ty, ty_params, param_env)
.must_apply_modulo_regions()
})
let infcx = tcx.infer_ctxt().build();
infcx
.type_implements_trait(trait_id, ty, ty_params, param_env)
.must_apply_modulo_regions()
}
/// Checks whether this type implements `Drop`.
@ -242,27 +241,26 @@ fn is_normalizable_helper<'tcx>(
}
// prevent recursive loops, false-negative is better than endless loop leading to stack overflow
cache.insert(ty, false);
let result = cx.tcx.infer_ctxt().enter(|infcx| {
let cause = rustc_middle::traits::ObligationCause::dummy();
if infcx.at(&cause, param_env).normalize(ty).is_ok() {
match ty.kind() {
ty::Adt(def, substs) => def.variants().iter().all(|variant| {
variant
.fields
.iter()
.all(|field| is_normalizable_helper(cx, param_env, field.ty(cx.tcx, substs), cache))
}),
_ => ty.walk().all(|generic_arg| match generic_arg.unpack() {
GenericArgKind::Type(inner_ty) if inner_ty != ty => {
is_normalizable_helper(cx, param_env, inner_ty, cache)
},
_ => true, // if inner_ty == ty, we've already checked it
}),
}
} else {
false
let infcx = cx.tcx.infer_ctxt().build();
let cause = rustc_middle::traits::ObligationCause::dummy();
let result = if infcx.at(&cause, param_env).normalize(ty).is_ok() {
match ty.kind() {
ty::Adt(def, substs) => def.variants().iter().all(|variant| {
variant
.fields
.iter()
.all(|field| is_normalizable_helper(cx, param_env, field.ty(cx.tcx, substs), cache))
}),
_ => ty.walk().all(|generic_arg| match generic_arg.unpack() {
GenericArgKind::Type(inner_ty) if inner_ty != ty => {
is_normalizable_helper(cx, param_env, inner_ty, cache)
},
_ => true, // if inner_ty == ty, we've already checked it
}),
}
});
} else {
false
};
cache.insert(ty, result);
result
}

View File

@ -18,16 +18,15 @@ pub fn mutated_variables<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) ->
used_mutably: HirIdSet::default(),
skip: false,
};
cx.tcx.infer_ctxt().enter(|infcx| {
ExprUseVisitor::new(
&mut delegate,
&infcx,
expr.hir_id.owner.def_id,
cx.param_env,
cx.typeck_results(),
)
.walk_expr(expr);
});
let infcx = cx.tcx.infer_ctxt().build();
ExprUseVisitor::new(
&mut delegate,
&infcx,
expr.hir_id.owner.def_id,
cx.param_env,
cx.typeck_results(),
)
.walk_expr(expr);
if delegate.skip {
return None;

View File

@ -1,3 +1,3 @@
[toolchain]
channel = "nightly-2022-10-06"
channel = "nightly-2022-10-20"
components = ["cargo", "llvm-tools-preview", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]

View File

@ -172,7 +172,6 @@ docs! {
"fn_to_numeric_cast_any",
"fn_to_numeric_cast_with_truncation",
"for_kv_map",
"for_loops_over_fallibles",
"forget_copy",
"forget_non_drop",
"forget_ref",

View File

@ -1,32 +0,0 @@
### What it does
Checks for `for` loops over `Option` or `Result` values.
### Why is this bad?
Readability. This is more clearly expressed as an `if
let`.
### Example
```
for x in opt {
// ..
}
for x in &res {
// ..
}
for x in res.iter() {
// ..
}
```
Use instead:
```
if let Some(x) = opt {
// ..
}
if let Ok(x) = res {
// ..
}
```

View File

@ -1,4 +1,4 @@
#![deny(arithmetic_overflow, const_err)]
#![deny(arithmetic_overflow)]
fn main() {
let _x = -1_i32 >> -1;
let _y = 1u32 >> 10000000000000u32;

View File

@ -7,7 +7,7 @@ LL | let _x = -1_i32 >> -1;
note: the lint level is defined here
--> $DIR/ice-9463.rs:1:9
|
LL | #![deny(arithmetic_overflow, const_err)]
LL | #![deny(arithmetic_overflow)]
| ^^^^^^^^^^^^^^^^^^^
error: this arithmetic operation will overflow

View File

@ -8,6 +8,7 @@
clippy::for_kv_map
)]
#[allow(clippy::linkedlist, clippy::unnecessary_mut_passed, clippy::similar_names)]
#[allow(for_loops_over_fallibles)]
fn main() {
let vec = vec![1, 2, 3, 4];

View File

@ -1,5 +1,5 @@
error: you are iterating over `Iterator::next()` which is an Option; this will compile but is probably not what you want
--> $DIR/for_loop_unfixable.rs:14:15
--> $DIR/for_loop_unfixable.rs:15:15
|
LL | for _v in vec.iter().next() {}
| ^^^^^^^^^^^^^^^^^

View File

@ -1,73 +0,0 @@
#![warn(clippy::for_loops_over_fallibles)]
#![allow(clippy::uninlined_format_args)]
fn for_loops_over_fallibles() {
let option = Some(1);
let mut result = option.ok_or("x not found");
let v = vec![0, 1, 2];
// check over an `Option`
for x in option {
println!("{}", x);
}
// check over an `Option`
for x in option.iter() {
println!("{}", x);
}
// check over a `Result`
for x in result {
println!("{}", x);
}
// check over a `Result`
for x in result.iter_mut() {
println!("{}", x);
}
// check over a `Result`
for x in result.into_iter() {
println!("{}", x);
}
for x in option.ok_or("x not found") {
println!("{}", x);
}
// make sure LOOP_OVER_NEXT lint takes clippy::precedence when next() is the last call
// in the chain
for x in v.iter().next() {
println!("{}", x);
}
// make sure we lint when next() is not the last call in the chain
for x in v.iter().next().and(Some(0)) {
println!("{}", x);
}
for x in v.iter().next().ok_or("x not found") {
println!("{}", x);
}
// check for false positives
// for loop false positive
for x in v {
println!("{}", x);
}
// while let false positive for Option
while let Some(x) = option {
println!("{}", x);
break;
}
// while let false positive for Result
while let Ok(x) = result {
println!("{}", x);
break;
}
}
fn main() {}

View File

@ -1,95 +0,0 @@
error: for loop over `option`, which is an `Option`. This is more readably written as an `if let` statement
--> $DIR/for_loops_over_fallibles.rs:10:14
|
LL | for x in option {
| ^^^^^^
|
= help: consider replacing `for x in option` with `if let Some(x) = option`
= note: `-D clippy::for-loops-over-fallibles` implied by `-D warnings`
error: for loop over `option`, which is an `Option`. This is more readably written as an `if let` statement
--> $DIR/for_loops_over_fallibles.rs:15:14
|
LL | for x in option.iter() {
| ^^^^^^
|
= help: consider replacing `for x in option.iter()` with `if let Some(x) = option`
error: for loop over `result`, which is a `Result`. This is more readably written as an `if let` statement
--> $DIR/for_loops_over_fallibles.rs:20:14
|
LL | for x in result {
| ^^^^^^
|
= help: consider replacing `for x in result` with `if let Ok(x) = result`
error: for loop over `result`, which is a `Result`. This is more readably written as an `if let` statement
--> $DIR/for_loops_over_fallibles.rs:25:14
|
LL | for x in result.iter_mut() {
| ^^^^^^
|
= help: consider replacing `for x in result.iter_mut()` with `if let Ok(x) = result`
error: for loop over `result`, which is a `Result`. This is more readably written as an `if let` statement
--> $DIR/for_loops_over_fallibles.rs:30:14
|
LL | for x in result.into_iter() {
| ^^^^^^
|
= help: consider replacing `for x in result.into_iter()` with `if let Ok(x) = result`
error: for loop over `option.ok_or("x not found")`, which is a `Result`. This is more readably written as an `if let` statement
--> $DIR/for_loops_over_fallibles.rs:34:14
|
LL | for x in option.ok_or("x not found") {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider replacing `for x in option.ok_or("x not found")` with `if let Ok(x) = option.ok_or("x not found")`
error: you are iterating over `Iterator::next()` which is an Option; this will compile but is probably not what you want
--> $DIR/for_loops_over_fallibles.rs:40:14
|
LL | for x in v.iter().next() {
| ^^^^^^^^^^^^^^^
|
= note: `#[deny(clippy::iter_next_loop)]` on by default
error: for loop over `v.iter().next().and(Some(0))`, which is an `Option`. This is more readably written as an `if let` statement
--> $DIR/for_loops_over_fallibles.rs:45:14
|
LL | for x in v.iter().next().and(Some(0)) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider replacing `for x in v.iter().next().and(Some(0))` with `if let Some(x) = v.iter().next().and(Some(0))`
error: for loop over `v.iter().next().ok_or("x not found")`, which is a `Result`. This is more readably written as an `if let` statement
--> $DIR/for_loops_over_fallibles.rs:49:14
|
LL | for x in v.iter().next().ok_or("x not found") {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider replacing `for x in v.iter().next().ok_or("x not found")` with `if let Ok(x) = v.iter().next().ok_or("x not found")`
error: this loop never actually loops
--> $DIR/for_loops_over_fallibles.rs:61:5
|
LL | / while let Some(x) = option {
LL | | println!("{}", x);
LL | | break;
LL | | }
| |_____^
|
= note: `#[deny(clippy::never_loop)]` on by default
error: this loop never actually loops
--> $DIR/for_loops_over_fallibles.rs:67:5
|
LL | / while let Ok(x) = result {
LL | | println!("{}", x);
LL | | break;
LL | | }
| |_____^
error: aborting due to 11 previous errors

View File

@ -3,7 +3,7 @@
// We also check the out_of_bounds_indexing lint here, because it lints similar things and
// we want to avoid false positives.
#![warn(clippy::out_of_bounds_indexing)]
#![allow(const_err, unconditional_panic, clippy::no_effect, clippy::unnecessary_operation)]
#![allow(unconditional_panic, clippy::no_effect, clippy::unnecessary_operation)]
const ARR: [i32; 2] = [1, 2];
const REF: &i32 = &ARR[idx()]; // Ok, should not produce stderr.

View File

@ -59,6 +59,12 @@ LL | v[M];
|
= help: consider using `.get(n)` or `.get_mut(n)` instead
error: aborting due to 8 previous errors
error[E0080]: evaluation of constant value failed
--> $DIR/indexing_slicing_index.rs:10:24
|
LL | const REF_ERR: &i32 = &ARR[idx4()]; // Ok, let rustc handle const contexts.
| ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4
error: aborting due to 9 previous errors
For more information about this error, try `rustc --explain E0080`.

View File

@ -7,7 +7,7 @@
clippy::unit_arg,
clippy::match_ref_pats,
clippy::redundant_pattern_matching,
clippy::for_loops_over_fallibles,
for_loops_over_fallibles,
dead_code
)]

View File

@ -7,7 +7,7 @@
clippy::unit_arg,
clippy::match_ref_pats,
clippy::redundant_pattern_matching,
clippy::for_loops_over_fallibles,
for_loops_over_fallibles,
dead_code
)]

View File

@ -1,5 +1,4 @@
#![feature(exclusive_range_pattern)]
#![feature(half_open_range_patterns)]
#![warn(clippy::match_overlapping_arm)]
#![allow(clippy::redundant_pattern_matching)]
#![allow(clippy::if_same_then_else, clippy::equatable_if_let)]

View File

@ -1,96 +1,96 @@
error: some ranges overlap
--> $DIR/match_overlapping_arm.rs:13:9
--> $DIR/match_overlapping_arm.rs:12:9
|
LL | 0..=10 => println!("0..=10"),
| ^^^^^^
|
note: overlaps with this
--> $DIR/match_overlapping_arm.rs:14:9
--> $DIR/match_overlapping_arm.rs:13:9
|
LL | 0..=11 => println!("0..=11"),
| ^^^^^^
= note: `-D clippy::match-overlapping-arm` implied by `-D warnings`
error: some ranges overlap
--> $DIR/match_overlapping_arm.rs:19:9
--> $DIR/match_overlapping_arm.rs:18:9
|
LL | 0..=5 => println!("0..=5"),
| ^^^^^
|
note: overlaps with this
--> $DIR/match_overlapping_arm.rs:21:9
--> $DIR/match_overlapping_arm.rs:20:9
|
LL | FOO..=11 => println!("FOO..=11"),
| ^^^^^^^^
error: some ranges overlap
--> $DIR/match_overlapping_arm.rs:56:9
--> $DIR/match_overlapping_arm.rs:55:9
|
LL | 0..11 => println!("0..11"),
| ^^^^^
|
note: overlaps with this
--> $DIR/match_overlapping_arm.rs:57:9
--> $DIR/match_overlapping_arm.rs:56:9
|
LL | 0..=11 => println!("0..=11"),
| ^^^^^^
error: some ranges overlap
--> $DIR/match_overlapping_arm.rs:81:9
--> $DIR/match_overlapping_arm.rs:80:9
|
LL | 0..=10 => println!("0..=10"),
| ^^^^^^
|
note: overlaps with this
--> $DIR/match_overlapping_arm.rs:80:9
--> $DIR/match_overlapping_arm.rs:79:9
|
LL | 5..14 => println!("5..14"),
| ^^^^^
error: some ranges overlap
--> $DIR/match_overlapping_arm.rs:86:9
--> $DIR/match_overlapping_arm.rs:85:9
|
LL | 0..7 => println!("0..7"),
| ^^^^
|
note: overlaps with this
--> $DIR/match_overlapping_arm.rs:87:9
--> $DIR/match_overlapping_arm.rs:86:9
|
LL | 0..=10 => println!("0..=10"),
| ^^^^^^
error: some ranges overlap
--> $DIR/match_overlapping_arm.rs:98:9
--> $DIR/match_overlapping_arm.rs:97:9
|
LL | ..=23 => println!("..=23"),
| ^^^^^
|
note: overlaps with this
--> $DIR/match_overlapping_arm.rs:99:9
--> $DIR/match_overlapping_arm.rs:98:9
|
LL | ..26 => println!("..26"),
| ^^^^
error: some ranges overlap
--> $DIR/match_overlapping_arm.rs:107:9
--> $DIR/match_overlapping_arm.rs:106:9
|
LL | 21..=30 => (),
| ^^^^^^^
|
note: overlaps with this
--> $DIR/match_overlapping_arm.rs:108:9
--> $DIR/match_overlapping_arm.rs:107:9
|
LL | 21..=40 => (),
| ^^^^^^^
error: some ranges overlap
--> $DIR/match_overlapping_arm.rs:121:9
--> $DIR/match_overlapping_arm.rs:120:9
|
LL | 0..=0x0000_0000_0000_00ff => (),
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: overlaps with this
--> $DIR/match_overlapping_arm.rs:122:9
--> $DIR/match_overlapping_arm.rs:121:9
|
LL | 0..=0x0000_0000_0000_ffff => (),
| ^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -1,5 +1,5 @@
#![warn(clippy::out_of_bounds_indexing)]
#![allow(clippy::no_effect, const_err)]
#![allow(clippy::no_effect)]
fn main() {
let x = [1, 2, 3, 4];

View File

@ -1,5 +1,5 @@
#![warn(clippy::out_of_bounds_indexing)]
#![allow(clippy::no_effect, clippy::unnecessary_operation, const_err)]
#![allow(clippy::no_effect, clippy::unnecessary_operation)]
fn main() {
let x = [1, 2, 3, 4];

View File

@ -12,7 +12,7 @@
#![allow(clippy::disallowed_methods)]
#![allow(clippy::disallowed_types)]
#![allow(clippy::mixed_read_write_in_expression)]
#![allow(clippy::for_loops_over_fallibles)]
#![allow(for_loops_over_fallibles)]
#![allow(clippy::useless_conversion)]
#![allow(clippy::match_result_ok)]
#![allow(clippy::overly_complex_bool_expr)]
@ -45,8 +45,8 @@
#![warn(clippy::disallowed_methods)]
#![warn(clippy::disallowed_types)]
#![warn(clippy::mixed_read_write_in_expression)]
#![warn(clippy::for_loops_over_fallibles)]
#![warn(clippy::for_loops_over_fallibles)]
#![warn(for_loops_over_fallibles)]
#![warn(for_loops_over_fallibles)]
#![warn(clippy::useless_conversion)]
#![warn(clippy::match_result_ok)]
#![warn(clippy::overly_complex_bool_expr)]
@ -65,6 +65,7 @@
#![warn(clippy::recursive_format_impl)]
#![warn(clippy::invisible_characters)]
#![warn(drop_bounds)]
#![warn(for_loops_over_fallibles)]
#![warn(array_into_iter)]
#![warn(invalid_atomic_ordering)]
#![warn(invalid_value)]

View File

@ -12,7 +12,7 @@
#![allow(clippy::disallowed_methods)]
#![allow(clippy::disallowed_types)]
#![allow(clippy::mixed_read_write_in_expression)]
#![allow(clippy::for_loops_over_fallibles)]
#![allow(for_loops_over_fallibles)]
#![allow(clippy::useless_conversion)]
#![allow(clippy::match_result_ok)]
#![allow(clippy::overly_complex_bool_expr)]
@ -65,6 +65,7 @@
#![warn(clippy::to_string_in_display)]
#![warn(clippy::zero_width_space)]
#![warn(clippy::drop_bounds)]
#![warn(clippy::for_loops_over_fallibles)]
#![warn(clippy::into_iter_on_array)]
#![warn(clippy::invalid_atomic_ordering)]
#![warn(clippy::invalid_ref)]

View File

@ -54,17 +54,17 @@ error: lint `clippy::eval_order_dependence` has been renamed to `clippy::mixed_r
LL | #![warn(clippy::eval_order_dependence)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::mixed_read_write_in_expression`
error: lint `clippy::for_loop_over_option` has been renamed to `clippy::for_loops_over_fallibles`
error: lint `clippy::for_loop_over_option` has been renamed to `for_loops_over_fallibles`
--> $DIR/rename.rs:48:9
|
LL | #![warn(clippy::for_loop_over_option)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::for_loops_over_fallibles`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
error: lint `clippy::for_loop_over_result` has been renamed to `clippy::for_loops_over_fallibles`
error: lint `clippy::for_loop_over_result` has been renamed to `for_loops_over_fallibles`
--> $DIR/rename.rs:49:9
|
LL | #![warn(clippy::for_loop_over_result)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::for_loops_over_fallibles`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion`
--> $DIR/rename.rs:50:9
@ -174,59 +174,65 @@ error: lint `clippy::drop_bounds` has been renamed to `drop_bounds`
LL | #![warn(clippy::drop_bounds)]
| ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds`
error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter`
error: lint `clippy::for_loops_over_fallibles` has been renamed to `for_loops_over_fallibles`
--> $DIR/rename.rs:68:9
|
LL | #![warn(clippy::for_loops_over_fallibles)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter`
--> $DIR/rename.rs:69:9
|
LL | #![warn(clippy::into_iter_on_array)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter`
error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering`
--> $DIR/rename.rs:69:9
--> $DIR/rename.rs:70:9
|
LL | #![warn(clippy::invalid_atomic_ordering)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering`
error: lint `clippy::invalid_ref` has been renamed to `invalid_value`
--> $DIR/rename.rs:70:9
--> $DIR/rename.rs:71:9
|
LL | #![warn(clippy::invalid_ref)]
| ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value`
error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums`
--> $DIR/rename.rs:71:9
--> $DIR/rename.rs:72:9
|
LL | #![warn(clippy::mem_discriminant_non_enum)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums`
error: lint `clippy::panic_params` has been renamed to `non_fmt_panics`
--> $DIR/rename.rs:72:9
--> $DIR/rename.rs:73:9
|
LL | #![warn(clippy::panic_params)]
| ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics`
error: lint `clippy::positional_named_format_parameters` has been renamed to `named_arguments_used_positionally`
--> $DIR/rename.rs:73:9
--> $DIR/rename.rs:74:9
|
LL | #![warn(clippy::positional_named_format_parameters)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally`
error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `temporary_cstring_as_ptr`
--> $DIR/rename.rs:74:9
--> $DIR/rename.rs:75:9
|
LL | #![warn(clippy::temporary_cstring_as_ptr)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `temporary_cstring_as_ptr`
error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints`
--> $DIR/rename.rs:75:9
--> $DIR/rename.rs:76:9
|
LL | #![warn(clippy::unknown_clippy_lints)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints`
error: lint `clippy::unused_label` has been renamed to `unused_labels`
--> $DIR/rename.rs:76:9
--> $DIR/rename.rs:77:9
|
LL | #![warn(clippy::unused_label)]
| ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels`
error: aborting due to 38 previous errors
error: aborting due to 39 previous errors