Rollup merge of #82917 - cuviper:iter-zip, r=m-ou-se
Add function core::iter::zip This makes it a little easier to `zip` iterators: ```rust for (x, y) in zip(xs, ys) {} // vs. for (x, y) in xs.into_iter().zip(ys) {} ``` You can `zip(&mut xs, &ys)` for the conventional `iter_mut()` and `iter()`, respectively. This can also support arbitrary nesting, where it's easier to see the item layout than with arbitrary `zip` chains: ```rust for ((x, y), z) in zip(zip(xs, ys), zs) {} for (x, (y, z)) in zip(xs, zip(ys, zs)) {} // vs. for ((x, y), z) in xs.into_iter().zip(ys).zip(xz) {} for (x, (y, z)) in xs.into_iter().zip((ys.into_iter().zip(xz)) {} ``` It may also format more nicely, especially when the first iterator is a longer chain of methods -- for example: ```rust iter::zip( trait_ref.substs.types().skip(1), impl_trait_ref.substs.types().skip(1), ) // vs. trait_ref .substs .types() .skip(1) .zip(impl_trait_ref.substs.types().skip(1)) ``` This replaces the tuple-pair `IntoIterator` in #78204. There is prior art for the utility of this in [`itertools::zip`]. [`itertools::zip`]: https://docs.rs/itertools/0.10.0/itertools/fn.zip.html
This commit is contained in:
commit
b2e254318d
111 changed files with 310 additions and 256 deletions
|
@ -27,6 +27,7 @@ use rustc_middle::ty::relate::TypeRelation;
|
|||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
|
||||
use rustc_middle::ty::{self, BoundVar, Const, ToPredicate, Ty, TyCtxt};
|
||||
use std::fmt::Debug;
|
||||
use std::iter;
|
||||
|
||||
impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
|
||||
/// This method is meant to be invoked as the final step of a canonical query
|
||||
|
@ -418,7 +419,8 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
|
|||
|
||||
// In terms of our example above, we are iterating over pairs like:
|
||||
// [(?A, Vec<?0>), ('static, '?1), (?B, ?0)]
|
||||
for (original_value, result_value) in original_values.var_values.iter().zip(result_values) {
|
||||
for (original_value, result_value) in iter::zip(&original_values.var_values, result_values)
|
||||
{
|
||||
match result_value.unpack() {
|
||||
GenericArgKind::Type(result_value) => {
|
||||
// e.g., here `result_value` might be `?0` in the example above...
|
||||
|
|
|
@ -73,7 +73,7 @@ use rustc_middle::ty::{
|
|||
use rustc_span::{sym, BytePos, DesugaringKind, Pos, Span};
|
||||
use rustc_target::spec::abi;
|
||||
use std::ops::ControlFlow;
|
||||
use std::{cmp, fmt};
|
||||
use std::{cmp, fmt, iter};
|
||||
|
||||
mod note;
|
||||
|
||||
|
@ -963,7 +963,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
ty::GenericParamDefKind::Const { has_default: true } => Some(param.def_id),
|
||||
_ => None,
|
||||
});
|
||||
for (def_id, actual) in default_params.zip(substs.iter().rev()) {
|
||||
for (def_id, actual) in iter::zip(default_params, substs.iter().rev()) {
|
||||
match actual.unpack() {
|
||||
GenericArgKind::Const(c) => {
|
||||
if self.tcx.const_param_default(def_id).subst(self.tcx, substs) != c {
|
||||
|
@ -1040,7 +1040,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
let len1 = sig1.inputs().len();
|
||||
let len2 = sig2.inputs().len();
|
||||
if len1 == len2 {
|
||||
for (i, (l, r)) in sig1.inputs().iter().zip(sig2.inputs().iter()).enumerate() {
|
||||
for (i, (l, r)) in iter::zip(sig1.inputs(), sig2.inputs()).enumerate() {
|
||||
let (x1, x2) = self.cmp(l, r);
|
||||
(values.0).0.extend(x1.0);
|
||||
(values.1).0.extend(x2.0);
|
||||
|
@ -1161,12 +1161,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
let common_len = cmp::min(len1, len2);
|
||||
let remainder1: Vec<_> = sub1.types().skip(common_len).collect();
|
||||
let remainder2: Vec<_> = sub2.types().skip(common_len).collect();
|
||||
let common_default_params = remainder1
|
||||
.iter()
|
||||
.rev()
|
||||
.zip(remainder2.iter().rev())
|
||||
.filter(|(a, b)| a == b)
|
||||
.count();
|
||||
let common_default_params =
|
||||
iter::zip(remainder1.iter().rev(), remainder2.iter().rev())
|
||||
.filter(|(a, b)| a == b)
|
||||
.count();
|
||||
let len = sub1.len() - common_default_params;
|
||||
let consts_offset = len - sub1.consts().count();
|
||||
|
||||
|
@ -1297,12 +1295,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
|
||||
const SEPARATOR: &str = "::";
|
||||
let separator_len = SEPARATOR.len();
|
||||
let split_idx: usize = t1_str
|
||||
.split(SEPARATOR)
|
||||
.zip(t2_str.split(SEPARATOR))
|
||||
.take_while(|(mod1_str, mod2_str)| mod1_str == mod2_str)
|
||||
.map(|(mod_str, _)| mod_str.len() + separator_len)
|
||||
.sum();
|
||||
let split_idx: usize =
|
||||
iter::zip(t1_str.split(SEPARATOR), t2_str.split(SEPARATOR))
|
||||
.take_while(|(mod1_str, mod2_str)| mod1_str == mod2_str)
|
||||
.map(|(mod_str, _)| mod_str.len() + separator_len)
|
||||
.sum();
|
||||
|
||||
debug!(
|
||||
"cmp: separator_len={}, split_idx={}, min_len={}",
|
||||
|
@ -1907,7 +1904,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
.find_map(|(path, msg)| (&path_str == path).then_some(msg))
|
||||
{
|
||||
let mut show_suggestion = true;
|
||||
for (exp_ty, found_ty) in exp_substs.types().zip(found_substs.types()) {
|
||||
for (exp_ty, found_ty) in
|
||||
iter::zip(exp_substs.types(), found_substs.types())
|
||||
{
|
||||
match *exp_ty.kind() {
|
||||
ty::Ref(_, exp_ty, _) => {
|
||||
match (exp_ty.kind(), found_ty.kind()) {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#![feature(const_fn)]
|
||||
#![feature(const_panic)]
|
||||
#![feature(extend_one)]
|
||||
#![feature(iter_zip)]
|
||||
#![feature(never_type)]
|
||||
#![cfg_attr(bootstrap, feature(or_patterns))]
|
||||
#![feature(in_band_lifetimes)]
|
||||
|
|
|
@ -9,6 +9,7 @@ use rustc_middle::ty::TyCtxt;
|
|||
use rustc_span::symbol::Symbol;
|
||||
use rustc_span::{MultiSpan, Span};
|
||||
use std::fmt;
|
||||
use std::iter;
|
||||
|
||||
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
pub fn report_extra_impl_obligation(
|
||||
|
@ -94,7 +95,7 @@ pub fn report_object_safety_error(
|
|||
note_span
|
||||
.push_span_label(trait_span, "this trait cannot be made into an object...".to_string());
|
||||
}
|
||||
for (span, msg) in multi_span.into_iter().zip(messages.into_iter()) {
|
||||
for (span, msg) in iter::zip(multi_span, messages) {
|
||||
note_span.push_span_label(span, msg);
|
||||
}
|
||||
err.span_note(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue