Simplify some iterator combinators

This commit is contained in:
Michael Goulet 2022-12-10 20:31:01 +00:00
parent c7572670a1
commit 7690fe3bc6
12 changed files with 91 additions and 135 deletions

View File

@ -527,26 +527,21 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// that are *partially* initialized by assigning to a field of an uninitialized // that are *partially* initialized by assigning to a field of an uninitialized
// binding. We differentiate between them for more accurate wording here. // binding. We differentiate between them for more accurate wording here.
"isn't fully initialized" "isn't fully initialized"
} else if spans } else if !spans.iter().any(|i| {
.iter() // We filter these to avoid misleading wording in cases like the following,
.filter(|i| { // where `x` has an `init`, but it is in the same place we're looking at:
// We filter these to avoid misleading wording in cases like the following, // ```
// where `x` has an `init`, but it is in the same place we're looking at: // let x;
// ``` // x += 1;
// let x; // ```
// x += 1; !i.contains(span)
// ```
!i.contains(span)
// We filter these to avoid incorrect main message on `match-cfg-fake-edges.rs` // We filter these to avoid incorrect main message on `match-cfg-fake-edges.rs`
&& !visitor && !visitor
.errors .errors
.iter() .iter()
.map(|(sp, _)| *sp) .map(|(sp, _)| *sp)
.any(|sp| span < sp && !sp.contains(span)) .any(|sp| span < sp && !sp.contains(span))
}) }) {
.count()
== 0
{
show_assign_sugg = true; show_assign_sugg = true;
"isn't initialized" "isn't initialized"
} else { } else {

View File

@ -316,35 +316,29 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
// obligation comes from the `impl`. Find that `impl` so that we can point // obligation comes from the `impl`. Find that `impl` so that we can point
// at it in the suggestion. // at it in the suggestion.
let trait_did = trait_did.to_def_id(); let trait_did = trait_did.to_def_id();
match tcx match tcx.hir().trait_impls(trait_did).iter().find_map(|&impl_did| {
.hir() match tcx.hir().get_if_local(impl_did.to_def_id()) {
.trait_impls(trait_did) Some(Node::Item(Item {
.iter() kind: ItemKind::Impl(hir::Impl { self_ty, .. }),
.filter_map(|&impl_did| { ..
match tcx.hir().get_if_local(impl_did.to_def_id()) { })) if trait_objects.iter().all(|did| {
Some(Node::Item(Item { // FIXME: we should check `self_ty` against the receiver
kind: ItemKind::Impl(hir::Impl { self_ty, .. }), // type in the `UnifyReceiver` context, but for now, use
.. // this imperfect proxy. This will fail if there are
})) if trait_objects.iter().all(|did| { // multiple `impl`s for the same trait like
// FIXME: we should check `self_ty` against the receiver // `impl Foo for Box<dyn Bar>` and `impl Foo for dyn Bar`.
// type in the `UnifyReceiver` context, but for now, use // In that case, only the first one will get suggestions.
// this imperfect proxy. This will fail if there are let mut traits = vec![];
// multiple `impl`s for the same trait like let mut hir_v = HirTraitObjectVisitor(&mut traits, *did);
// `impl Foo for Box<dyn Bar>` and `impl Foo for dyn Bar`. hir_v.visit_ty(self_ty);
// In that case, only the first one will get suggestions. !traits.is_empty()
let mut traits = vec![]; }) =>
let mut hir_v = HirTraitObjectVisitor(&mut traits, *did); {
hir_v.visit_ty(self_ty); Some(self_ty)
!traits.is_empty()
}) =>
{
Some(self_ty)
}
_ => None,
} }
}) _ => None,
.next() }
{ }) {
Some(self_ty) => Some((trait_item.ident, self_ty)), Some(self_ty) => Some((trait_item.ident, self_ty)),
_ => None, _ => None,
} }

View File

@ -1244,7 +1244,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
) -> RValue<'gcc> { ) -> RValue<'gcc> {
// FIXME(antoyo): remove when having a proper API. // FIXME(antoyo): remove when having a proper API.
let gcc_func = unsafe { std::mem::transmute(func) }; let gcc_func = unsafe { std::mem::transmute(func) };
let call = if self.functions.borrow().values().find(|value| **value == gcc_func).is_some() { let call = if self.functions.borrow().values().any(|value| *value == gcc_func) {
self.function_call(func, args, funclet) self.function_call(func, args, funclet)
} }
else { else {

View File

@ -253,7 +253,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
pub fn rvalue_as_function(&self, value: RValue<'gcc>) -> Function<'gcc> { pub fn rvalue_as_function(&self, value: RValue<'gcc>) -> Function<'gcc> {
let function: Function<'gcc> = unsafe { std::mem::transmute(value) }; let function: Function<'gcc> = unsafe { std::mem::transmute(value) };
debug_assert!(self.functions.borrow().values().find(|value| **value == function).is_some(), debug_assert!(self.functions.borrow().values().any(|value| *value == function),
"{:?} ({:?}) is not a function", value, value.get_type()); "{:?} ({:?}) is not a function", value, value.get_type());
function function
} }

View File

@ -240,10 +240,8 @@ fn typeck_with_fallback<'tcx>(
}), }),
Node::Expr(&hir::Expr { kind: hir::ExprKind::InlineAsm(asm), .. }) Node::Expr(&hir::Expr { kind: hir::ExprKind::InlineAsm(asm), .. })
| Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), .. }) => { | Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), .. }) => {
let operand_ty = asm let operand_ty =
.operands asm.operands.iter().find_map(|(op, _op_sp)| match op {
.iter()
.filter_map(|(op, _op_sp)| match op {
hir::InlineAsmOperand::Const { anon_const } hir::InlineAsmOperand::Const { anon_const }
if anon_const.hir_id == id => if anon_const.hir_id == id =>
{ {
@ -259,8 +257,7 @@ fn typeck_with_fallback<'tcx>(
})) }))
} }
_ => None, _ => None,
}) });
.next();
operand_ty.unwrap_or_else(fallback) operand_ty.unwrap_or_else(fallback)
} }
_ => fallback(), _ => fallback(),

View File

@ -341,8 +341,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Find an identifier with which this trait was imported (note that `_` doesn't count). // Find an identifier with which this trait was imported (note that `_` doesn't count).
let any_id = import_items let any_id = import_items
.iter() .iter()
.filter_map(|item| if item.ident.name != Underscore { Some(item.ident) } else { None }) .find_map(|item| if item.ident.name != Underscore { Some(item.ident) } else { None });
.next();
if let Some(any_id) = any_id { if let Some(any_id) = any_id {
if any_id.name == Empty { if any_id.name == Empty {
// Glob import, so just use its name. // Glob import, so just use its name.

View File

@ -1111,7 +1111,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
// a raw pointer // a raw pointer
!step.self_ty.references_error() && !step.from_unsafe_deref !step.self_ty.references_error() && !step.from_unsafe_deref
}) })
.flat_map(|step| { .find_map(|step| {
let InferOk { value: self_ty, obligations: _ } = self let InferOk { value: self_ty, obligations: _ } = self
.fcx .fcx
.probe_instantiate_query_response( .probe_instantiate_query_response(
@ -1147,7 +1147,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
}) })
}) })
}) })
.next()
} }
/// For each type `T` in the step list, this attempts to find a method where /// For each type `T` in the step list, this attempts to find a method where

View File

@ -257,9 +257,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.tcx self.tcx
.inherent_impls(adt_def.did()) .inherent_impls(adt_def.did())
.iter() .iter()
.filter_map(|def_id| self.associated_value(*def_id, item_name)) .any(|def_id| self.associated_value(*def_id, item_name).is_some())
.count()
>= 1
} else { } else {
false false
} }

View File

@ -309,19 +309,12 @@ pub fn suggest_new_region_bound(
let did = item_id.owner_id.to_def_id(); let did = item_id.owner_id.to_def_id();
let ty = tcx.mk_opaque(did, ty::InternalSubsts::identity_for_item(tcx, did)); let ty = tcx.mk_opaque(did, ty::InternalSubsts::identity_for_item(tcx, did));
if let Some(span) = opaque if let Some(span) = opaque.bounds.iter().find_map(|arg| match arg {
.bounds GenericBound::Outlives(Lifetime {
.iter() res: LifetimeName::Static, ident, ..
.filter_map(|arg| match arg { }) => Some(ident.span),
GenericBound::Outlives(Lifetime { _ => None,
res: LifetimeName::Static, }) {
ident,
..
}) => Some(ident.span),
_ => None,
})
.next()
{
if let Some(explicit_static) = &explicit_static { if let Some(explicit_static) = &explicit_static {
err.span_suggestion_verbose( err.span_suggestion_verbose(
span, span,
@ -338,20 +331,14 @@ pub fn suggest_new_region_bound(
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,
); );
} }
} else if opaque } else if opaque.bounds.iter().any(|arg| match arg {
.bounds GenericBound::Outlives(Lifetime { ident, .. })
.iter() if ident.name.to_string() == lifetime_name =>
.filter_map(|arg| match arg { {
GenericBound::Outlives(Lifetime { ident, .. }) true
if ident.name.to_string() == lifetime_name => }
{ _ => false,
Some(ident.span) }) {
}
_ => None,
})
.next()
.is_some()
{
} else { } else {
err.span_suggestion_verbose( err.span_suggestion_verbose(
fn_return.span.shrink_to_hi(), fn_return.span.shrink_to_hi(),
@ -428,35 +415,29 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
// obligation comes from the `impl`. Find that `impl` so that we can point // obligation comes from the `impl`. Find that `impl` so that we can point
// at it in the suggestion. // at it in the suggestion.
let trait_did = trait_did.to_def_id(); let trait_did = trait_did.to_def_id();
match tcx match tcx.hir().trait_impls(trait_did).iter().find_map(|&impl_did| {
.hir() match tcx.hir().get_if_local(impl_did.to_def_id()) {
.trait_impls(trait_did) Some(Node::Item(Item {
.iter() kind: ItemKind::Impl(hir::Impl { self_ty, .. }),
.filter_map(|&impl_did| { ..
match tcx.hir().get_if_local(impl_did.to_def_id()) { })) if trait_objects.iter().all(|did| {
Some(Node::Item(Item { // FIXME: we should check `self_ty` against the receiver
kind: ItemKind::Impl(hir::Impl { self_ty, .. }), // type in the `UnifyReceiver` context, but for now, use
.. // this imperfect proxy. This will fail if there are
})) if trait_objects.iter().all(|did| { // multiple `impl`s for the same trait like
// FIXME: we should check `self_ty` against the receiver // `impl Foo for Box<dyn Bar>` and `impl Foo for dyn Bar`.
// type in the `UnifyReceiver` context, but for now, use // In that case, only the first one will get suggestions.
// this imperfect proxy. This will fail if there are let mut traits = vec![];
// multiple `impl`s for the same trait like let mut hir_v = HirTraitObjectVisitor(&mut traits, *did);
// `impl Foo for Box<dyn Bar>` and `impl Foo for dyn Bar`. hir_v.visit_ty(self_ty);
// In that case, only the first one will get suggestions. !traits.is_empty()
let mut traits = vec![]; }) =>
let mut hir_v = HirTraitObjectVisitor(&mut traits, *did); {
hir_v.visit_ty(self_ty); Some(self_ty)
!traits.is_empty()
}) =>
{
Some(self_ty)
}
_ => None,
} }
}) _ => None,
.next() }
{ }) {
Some(self_ty) => Some((trait_item.ident, self_ty)), Some(self_ty) => Some((trait_item.ident, self_ty)),
_ => None, _ => None,
} }

View File

@ -256,7 +256,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
cx.tcx, cx.tcx,
cx.tcx.explicit_item_bounds(def).iter().cloned(), cx.tcx.explicit_item_bounds(def).iter().cloned(),
) )
.filter_map(|obligation| { .find_map(|obligation| {
// We only look at the `DefId`, so it is safe to skip the binder here. // We only look at the `DefId`, so it is safe to skip the binder here.
if let ty::PredicateKind::Clause(ty::Clause::Trait( if let ty::PredicateKind::Clause(ty::Clause::Trait(
ref poly_trait_predicate, ref poly_trait_predicate,
@ -270,22 +270,17 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
} }
}) })
.map(|inner| MustUsePath::Opaque(Box::new(inner))) .map(|inner| MustUsePath::Opaque(Box::new(inner)))
.next()
} }
ty::Dynamic(binders, _, _) => binders ty::Dynamic(binders, _, _) => binders.iter().find_map(|predicate| {
.iter() if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder()
.filter_map(|predicate| { {
if let ty::ExistentialPredicate::Trait(ref trait_ref) = let def_id = trait_ref.def_id;
predicate.skip_binder() is_def_must_use(cx, def_id, span)
{ } else {
let def_id = trait_ref.def_id; None
is_def_must_use(cx, def_id, span) }
} else { .map(|inner| MustUsePath::TraitObject(Box::new(inner)))
None }),
}
.map(|inner| MustUsePath::TraitObject(Box::new(inner)))
})
.next(),
ty::Tuple(tys) => { ty::Tuple(tys) => {
let elem_exprs = if let hir::ExprKind::Tup(elem_exprs) = expr.kind { let elem_exprs = if let hir::ExprKind::Tup(elem_exprs) = expr.kind {
debug_assert_eq!(elem_exprs.len(), tys.len()); debug_assert_eq!(elem_exprs.len(), tys.len());

View File

@ -16,14 +16,13 @@ fn test_symbols() {
let m: &syn::ItemMacro = file let m: &syn::ItemMacro = file
.items .items
.iter() .iter()
.filter_map(|i| { .find_map(|i| {
if let syn::Item::Macro(m) = i { if let syn::Item::Macro(m) = i {
if m.mac.path == symbols_path { Some(m) } else { None } if m.mac.path == symbols_path { Some(m) } else { None }
} else { } else {
None None
} }
}) })
.next()
.expect("did not find `symbols!` macro invocation."); .expect("did not find `symbols!` macro invocation.");
let body_tokens = m.mac.tokens.clone(); let body_tokens = m.mac.tokens.clone();

View File

@ -820,13 +820,12 @@ impl<'a> Resolver<'a> {
// binding if it exists. What we really want here is having two separate scopes in // binding if it exists. What we really want here is having two separate scopes in
// a module - one for non-globs and one for globs, but until that's done use this // a module - one for non-globs and one for globs, but until that's done use this
// hack to avoid inconsistent resolution ICEs during import validation. // hack to avoid inconsistent resolution ICEs during import validation.
let binding = [resolution.binding, resolution.shadowed_glob] let binding = [resolution.binding, resolution.shadowed_glob].into_iter().find_map(
.into_iter() |binding| match (binding, ignore_binding) {
.filter_map(|binding| match (binding, ignore_binding) {
(Some(binding), Some(ignored)) if ptr::eq(binding, ignored) => None, (Some(binding), Some(ignored)) if ptr::eq(binding, ignored) => None,
_ => binding, _ => binding,
}) },
.next(); );
let Some(binding) = binding else { let Some(binding) = binding else {
return Err((Determined, Weak::No)); return Err((Determined, Weak::No));
}; };