Skip to content

Simplify some iterator combinators #105541

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 15 additions & 20 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -527,26 +527,21 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// that are *partially* initialized by assigning to a field of an uninitialized
// binding. We differentiate between them for more accurate wording here.
"isn't fully initialized"
} else if spans
.iter()
.filter(|i| {
// 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;
// ```
!i.contains(span)
// We filter these to avoid incorrect main message on `match-cfg-fake-edges.rs`
&& !visitor
.errors
.iter()
.map(|(sp, _)| *sp)
.any(|sp| span < sp && !sp.contains(span))
})
.count()
== 0
{
} else if !spans.iter().any(|i| {
// 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;
// ```
!i.contains(span)
// We filter these to avoid incorrect main message on `match-cfg-fake-edges.rs`
&& !visitor
.errors
.iter()
.map(|(sp, _)| *sp)
.any(|sp| span < sp && !sp.contains(span))
}) {
show_assign_sugg = true;
"isn't initialized"
} else {
Expand Down
69 changes: 2 additions & 67 deletions compiler/rustc_borrowck/src/diagnostics/region_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor;
use rustc_hir::{self as hir, Item, ItemKind, Node};
use rustc_infer::infer::{
error_reporting::nice_region_error::{
self, find_anon_type, find_param_with_region, suggest_adding_lifetime_params,
Expand Down Expand Up @@ -291,71 +291,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
outlives_suggestion.add_suggestion(self);
}

fn get_impl_ident_and_self_ty_from_trait(
&self,
def_id: DefId,
trait_objects: &FxIndexSet<DefId>,
) -> Option<(Ident, &'tcx hir::Ty<'tcx>)> {
let tcx = self.infcx.tcx;
match tcx.hir().get_if_local(def_id) {
Some(Node::ImplItem(impl_item)) => {
match tcx.hir().find_by_def_id(tcx.hir().get_parent_item(impl_item.hir_id()).def_id)
{
Some(Node::Item(Item {
kind: ItemKind::Impl(hir::Impl { self_ty, .. }),
..
})) => Some((impl_item.ident, self_ty)),
_ => None,
}
}
Some(Node::TraitItem(trait_item)) => {
let trait_did = tcx.hir().get_parent_item(trait_item.hir_id());
match tcx.hir().find_by_def_id(trait_did.def_id) {
Some(Node::Item(Item { kind: ItemKind::Trait(..), .. })) => {
// The method being called is defined in the `trait`, but the `'static`
// obligation comes from the `impl`. Find that `impl` so that we can point
// at it in the suggestion.
let trait_did = trait_did.to_def_id();
match tcx
.hir()
.trait_impls(trait_did)
.iter()
.filter_map(|&impl_did| {
match tcx.hir().get_if_local(impl_did.to_def_id()) {
Some(Node::Item(Item {
kind: ItemKind::Impl(hir::Impl { self_ty, .. }),
..
})) if trait_objects.iter().all(|did| {
// FIXME: we should check `self_ty` against the receiver
// type in the `UnifyReceiver` context, but for now, use
// this imperfect proxy. This will fail if there are
// multiple `impl`s for the same trait like
// `impl Foo for Box<dyn Bar>` and `impl Foo for dyn Bar`.
// In that case, only the first one will get suggestions.
let mut traits = vec![];
let mut hir_v = HirTraitObjectVisitor(&mut traits, *did);
hir_v.visit_ty(self_ty);
!traits.is_empty()
}) =>
{
Some(self_ty)
}
_ => None,
}
})
.next()
{
Some(self_ty) => Some((trait_item.ident, self_ty)),
_ => None,
}
}
_ => None,
}
}
_ => None,
}
}

/// Report an error because the universal region `fr` was required to outlive
/// `outlived_fr` but it is not known to do so. For example:
///
Expand Down Expand Up @@ -850,7 +785,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
visitor.visit_ty(param.param_ty);

let Some((ident, self_ty)) =
self.get_impl_ident_and_self_ty_from_trait(instance.def_id(), &visitor.0) else {return};
NiceRegionError::get_impl_ident_and_self_ty_from_trait(tcx, instance.def_id(), &visitor.0) else { return; };

self.suggest_constrain_dyn_trait_in_impl(diag, &visitor.0, ident, self_ty);
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_gcc/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1244,7 +1244,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
) -> RValue<'gcc> {
// FIXME(antoyo): remove when having a proper API.
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)
}
else {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_gcc/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {

pub fn rvalue_as_function(&self, value: RValue<'gcc>) -> Function<'gcc> {
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());
function
}
Expand Down
9 changes: 3 additions & 6 deletions compiler/rustc_hir_typeck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,10 +240,8 @@ fn typeck_with_fallback<'tcx>(
}),
Node::Expr(&hir::Expr { kind: hir::ExprKind::InlineAsm(asm), .. })
| Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), .. }) => {
let operand_ty = asm
.operands
.iter()
.filter_map(|(op, _op_sp)| match op {
let operand_ty =
asm.operands.iter().find_map(|(op, _op_sp)| match op {
hir::InlineAsmOperand::Const { anon_const }
if anon_const.hir_id == id =>
{
Expand All @@ -259,8 +257,7 @@ fn typeck_with_fallback<'tcx>(
}))
}
_ => None,
})
.next();
});
operand_ty.unwrap_or_else(fallback)
}
_ => fallback(),
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_hir_typeck/src/method/prelude2021.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,8 +341,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Find an identifier with which this trait was imported (note that `_` doesn't count).
let any_id = import_items
.iter()
.filter_map(|item| if item.ident.name != Underscore { Some(item.ident) } else { None })
.next();
.find_map(|item| if item.ident.name != Underscore { Some(item.ident) } else { None });
if let Some(any_id) = any_id {
if any_id.name == Empty {
// Glob import, so just use its name.
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_hir_typeck/src/method/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1111,7 +1111,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
// a raw pointer
!step.self_ty.references_error() && !step.from_unsafe_deref
})
.flat_map(|step| {
.find_map(|step| {
let InferOk { value: self_ty, obligations: _ } = self
.fcx
.probe_instantiate_query_response(
Expand Down Expand Up @@ -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
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,9 +257,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.tcx
.inherent_impls(adt_def.did())
.iter()
.filter_map(|def_id| self.associated_value(*def_id, item_name))
.count()
>= 1
.any(|def_id| self.associated_value(*def_id, item_name).is_some())
} else {
false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
let mut v = TraitObjectVisitor(FxIndexSet::default());
v.visit_ty(param.param_ty);
if let Some((ident, self_ty)) =
self.get_impl_ident_and_self_ty_from_trait(item_def_id, &v.0)
NiceRegionError::get_impl_ident_and_self_ty_from_trait(tcx, item_def_id, &v.0)
&& self.suggest_constrain_dyn_trait_in_impl(&mut err, &v.0, ident, self_ty)
{
override_error_code = Some(ident.name);
Expand Down Expand Up @@ -309,19 +309,12 @@ pub fn suggest_new_region_bound(
let did = item_id.owner_id.to_def_id();
let ty = tcx.mk_opaque(did, ty::InternalSubsts::identity_for_item(tcx, did));

if let Some(span) = opaque
.bounds
.iter()
.filter_map(|arg| match arg {
GenericBound::Outlives(Lifetime {
res: LifetimeName::Static,
ident,
..
}) => Some(ident.span),
_ => None,
})
.next()
{
if let Some(span) = opaque.bounds.iter().find_map(|arg| match arg {
GenericBound::Outlives(Lifetime {
res: LifetimeName::Static, ident, ..
}) => Some(ident.span),
_ => None,
}) {
if let Some(explicit_static) = &explicit_static {
err.span_suggestion_verbose(
span,
Expand All @@ -338,20 +331,14 @@ pub fn suggest_new_region_bound(
Applicability::MaybeIncorrect,
);
}
} else if opaque
.bounds
.iter()
.filter_map(|arg| match arg {
GenericBound::Outlives(Lifetime { ident, .. })
if ident.name.to_string() == lifetime_name =>
{
Some(ident.span)
}
_ => None,
})
.next()
.is_some()
{
} else if opaque.bounds.iter().any(|arg| match arg {
GenericBound::Outlives(Lifetime { ident, .. })
if ident.name.to_string() == lifetime_name =>
{
true
}
_ => false,
}) {
} else {
err.span_suggestion_verbose(
fn_return.span.shrink_to_hi(),
Expand Down Expand Up @@ -403,66 +390,54 @@ pub fn suggest_new_region_bound(
}

impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
fn get_impl_ident_and_self_ty_from_trait(
&self,
pub fn get_impl_ident_and_self_ty_from_trait(
tcx: TyCtxt<'tcx>,
def_id: DefId,
trait_objects: &FxIndexSet<DefId>,
) -> Option<(Ident, &'tcx hir::Ty<'tcx>)> {
let tcx = self.tcx();
match tcx.hir().get_if_local(def_id) {
Some(Node::ImplItem(impl_item)) => {
match tcx.hir().find_by_def_id(tcx.hir().get_parent_item(impl_item.hir_id()).def_id)
match tcx.hir().get_if_local(def_id)? {
Node::ImplItem(impl_item) => {
let impl_did = tcx.hir().get_parent_item(impl_item.hir_id());
if let hir::OwnerNode::Item(Item {
kind: ItemKind::Impl(hir::Impl { self_ty, .. }),
..
}) = tcx.hir().owner(impl_did)
{
Some(Node::Item(Item {
kind: ItemKind::Impl(hir::Impl { self_ty, .. }),
..
})) => Some((impl_item.ident, self_ty)),
_ => None,
Some((impl_item.ident, self_ty))
} else {
None
}
}
Some(Node::TraitItem(trait_item)) => {
let trait_did = tcx.hir().get_parent_item(trait_item.hir_id());
match tcx.hir().find_by_def_id(trait_did.def_id) {
Some(Node::Item(Item { kind: ItemKind::Trait(..), .. })) => {
// The method being called is defined in the `trait`, but the `'static`
// obligation comes from the `impl`. Find that `impl` so that we can point
// at it in the suggestion.
let trait_did = trait_did.to_def_id();
match tcx
.hir()
.trait_impls(trait_did)
.iter()
.filter_map(|&impl_did| {
match tcx.hir().get_if_local(impl_did.to_def_id()) {
Some(Node::Item(Item {
kind: ItemKind::Impl(hir::Impl { self_ty, .. }),
..
})) if trait_objects.iter().all(|did| {
// FIXME: we should check `self_ty` against the receiver
// type in the `UnifyReceiver` context, but for now, use
// this imperfect proxy. This will fail if there are
// multiple `impl`s for the same trait like
// `impl Foo for Box<dyn Bar>` and `impl Foo for dyn Bar`.
// In that case, only the first one will get suggestions.
let mut traits = vec![];
let mut hir_v = HirTraitObjectVisitor(&mut traits, *did);
hir_v.visit_ty(self_ty);
!traits.is_empty()
}) =>
{
Some(self_ty)
}
_ => None,
}
})
.next()
{
Some(self_ty) => Some((trait_item.ident, self_ty)),
_ => None,
}
Node::TraitItem(trait_item) => {
let trait_id = tcx.hir().get_parent_item(trait_item.hir_id());
debug_assert_eq!(tcx.def_kind(trait_id.def_id), hir::def::DefKind::Trait);
// The method being called is defined in the `trait`, but the `'static`
// obligation comes from the `impl`. Find that `impl` so that we can point
// at it in the suggestion.
let trait_did = trait_id.to_def_id();
tcx.hir().trait_impls(trait_did).iter().find_map(|&impl_did| {
if let Node::Item(Item {
kind: ItemKind::Impl(hir::Impl { self_ty, .. }),
..
}) = tcx.hir().find_by_def_id(impl_did)?
&& trait_objects.iter().all(|did| {
// FIXME: we should check `self_ty` against the receiver
// type in the `UnifyReceiver` context, but for now, use
// this imperfect proxy. This will fail if there are
// multiple `impl`s for the same trait like
// `impl Foo for Box<dyn Bar>` and `impl Foo for dyn Bar`.
// In that case, only the first one will get suggestions.
let mut traits = vec![];
let mut hir_v = HirTraitObjectVisitor(&mut traits, *did);
hir_v.visit_ty(self_ty);
!traits.is_empty()
})
{
Some((trait_item.ident, *self_ty))
} else {
None
}
_ => None,
}
})
}
_ => None,
}
Expand Down Expand Up @@ -493,7 +468,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {

// Get the `Ident` of the method being called and the corresponding `impl` (to point at
// `Bar` in `impl Foo for dyn Bar {}` and the definition of the method being called).
let Some((ident, self_ty)) = self.get_impl_ident_and_self_ty_from_trait(instance.def_id(), &v.0) else {
let Some((ident, self_ty)) = NiceRegionError::get_impl_ident_and_self_ty_from_trait(tcx, instance.def_id(), &v.0) else {
return false;
};

Expand Down
Loading