Auto merge of #55067 - ljedrz:generic_iterator_related_improvements, r=petrochenkov
A few iterator-related improvements - typeck: don't collect into a vector when unnecessary - create only one vector when winnowing candidates - change a cloning map to `into_iter`
This commit is contained in:
commit
5ea8eb55cd
6 changed files with 16 additions and 18 deletions
|
@ -71,6 +71,7 @@
|
|||
#![feature(in_band_lifetimes)]
|
||||
#![feature(macro_at_most_once_rep)]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(transpose_result)]
|
||||
|
||||
#![recursion_limit="512"]
|
||||
|
||||
|
|
|
@ -1368,8 +1368,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
|
||||
// Winnow, but record the exact outcome of evaluation, which
|
||||
// is needed for specialization. Propagate overflow if it occurs.
|
||||
let candidates: Result<Vec<Option<EvaluatedCandidate<'_>>>, _> = candidates
|
||||
.into_iter()
|
||||
let mut candidates = candidates.into_iter()
|
||||
.map(|c| match self.evaluate_candidate(stack, &c) {
|
||||
Ok(eval) if eval.may_apply() => Ok(Some(EvaluatedCandidate {
|
||||
candidate: c,
|
||||
|
@ -1378,10 +1377,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
Ok(_) => Ok(None),
|
||||
Err(OverflowError) => Err(Overflow),
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut candidates: Vec<EvaluatedCandidate<'_>> =
|
||||
candidates?.into_iter().filter_map(|c| c).collect();
|
||||
.flat_map(Result::transpose)
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
debug!(
|
||||
"winnowed to {} candidates for {:?}: {:?}",
|
||||
|
@ -1390,7 +1387,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
candidates
|
||||
);
|
||||
|
||||
// If there are STILL multiple candidate, we can further
|
||||
// If there are STILL multiple candidates, we can further
|
||||
// reduce the list by dropping duplicates -- including
|
||||
// resolving specializations.
|
||||
if candidates.len() > 1 {
|
||||
|
|
|
@ -681,7 +681,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
|
|||
match (r1, r2) {
|
||||
(Representability::SelfRecursive(v1),
|
||||
Representability::SelfRecursive(v2)) => {
|
||||
Representability::SelfRecursive(v1.iter().map(|s| *s).chain(v2).collect())
|
||||
Representability::SelfRecursive(v1.into_iter().chain(v2).collect())
|
||||
}
|
||||
(r1, r2) => cmp::max(r1, r2)
|
||||
}
|
||||
|
|
|
@ -1592,8 +1592,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
|
|||
debug!("ty_of_fn");
|
||||
|
||||
let tcx = self.tcx();
|
||||
let input_tys: Vec<Ty> =
|
||||
decl.inputs.iter().map(|a| self.ty_of_arg(a, None)).collect();
|
||||
let input_tys =
|
||||
decl.inputs.iter().map(|a| self.ty_of_arg(a, None));
|
||||
|
||||
let output_ty = match decl.output {
|
||||
hir::Return(ref output) => self.ast_ty_to_ty(output),
|
||||
|
@ -1603,7 +1603,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
|
|||
debug!("ty_of_fn: output_ty={:?}", output_ty);
|
||||
|
||||
let bare_fn_ty = ty::Binder::bind(tcx.mk_fn_sig(
|
||||
input_tys.into_iter(),
|
||||
input_tys,
|
||||
output_ty,
|
||||
decl.variadic,
|
||||
unsafety,
|
||||
|
|
|
@ -626,7 +626,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
|
|||
|
||||
// Typecheck the patterns first, so that we get types for all the
|
||||
// bindings.
|
||||
let all_arm_pats_diverge: Vec<_> = arms.iter().map(|arm| {
|
||||
let all_arm_pats_diverge = arms.iter().map(|arm| {
|
||||
let mut all_pats_diverge = Diverges::WarnedAlways;
|
||||
for p in &arm.pats {
|
||||
self.diverges.set(Diverges::Maybe);
|
||||
|
@ -642,7 +642,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
|
|||
Diverges::Maybe => Diverges::Maybe,
|
||||
Diverges::Always | Diverges::WarnedAlways => Diverges::WarnedAlways,
|
||||
}
|
||||
}).collect();
|
||||
});
|
||||
|
||||
// Now typecheck the blocks.
|
||||
//
|
||||
|
|
|
@ -1769,7 +1769,7 @@ fn check_transparent<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: De
|
|||
}
|
||||
|
||||
// For each field, figure out if it's known to be a ZST and align(1)
|
||||
let field_infos: Vec<_> = adt.non_enum_variant().fields.iter().map(|field| {
|
||||
let field_infos = adt.non_enum_variant().fields.iter().map(|field| {
|
||||
let ty = field.ty(tcx, Substs::identity_for_item(tcx, field.did));
|
||||
let param_env = tcx.param_env(field.did);
|
||||
let layout = tcx.layout_of(param_env.and(ty));
|
||||
|
@ -1778,19 +1778,19 @@ fn check_transparent<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: De
|
|||
let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
|
||||
let align1 = layout.map(|layout| layout.align.abi() == 1).unwrap_or(false);
|
||||
(span, zst, align1)
|
||||
}).collect();
|
||||
});
|
||||
|
||||
let non_zst_fields = field_infos.iter().filter(|(_span, zst, _align1)| !*zst);
|
||||
let non_zst_fields = field_infos.clone().filter(|(_span, zst, _align1)| !*zst);
|
||||
let non_zst_count = non_zst_fields.clone().count();
|
||||
if non_zst_count != 1 {
|
||||
let field_spans: Vec<_> = non_zst_fields.map(|(span, _zst, _align1)| *span).collect();
|
||||
let field_spans: Vec<_> = non_zst_fields.map(|(span, _zst, _align1)| span).collect();
|
||||
struct_span_err!(tcx.sess, sp, E0690,
|
||||
"transparent struct needs exactly one non-zero-sized field, but has {}",
|
||||
non_zst_count)
|
||||
.span_note(field_spans, "non-zero-sized field")
|
||||
.emit();
|
||||
}
|
||||
for &(span, zst, align1) in &field_infos {
|
||||
for (span, zst, align1) in field_infos {
|
||||
if zst && !align1 {
|
||||
span_err!(tcx.sess, span, E0691,
|
||||
"zero-sized field in transparent struct has alignment larger than 1");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue