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(in_band_lifetimes)]
|
||||||
#![feature(macro_at_most_once_rep)]
|
#![feature(macro_at_most_once_rep)]
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
|
#![feature(transpose_result)]
|
||||||
|
|
||||||
#![recursion_limit="512"]
|
#![recursion_limit="512"]
|
||||||
|
|
||||||
|
|
|
@ -1368,8 +1368,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||||
|
|
||||||
// Winnow, but record the exact outcome of evaluation, which
|
// Winnow, but record the exact outcome of evaluation, which
|
||||||
// is needed for specialization. Propagate overflow if it occurs.
|
// is needed for specialization. Propagate overflow if it occurs.
|
||||||
let candidates: Result<Vec<Option<EvaluatedCandidate<'_>>>, _> = candidates
|
let mut candidates = candidates.into_iter()
|
||||||
.into_iter()
|
|
||||||
.map(|c| match self.evaluate_candidate(stack, &c) {
|
.map(|c| match self.evaluate_candidate(stack, &c) {
|
||||||
Ok(eval) if eval.may_apply() => Ok(Some(EvaluatedCandidate {
|
Ok(eval) if eval.may_apply() => Ok(Some(EvaluatedCandidate {
|
||||||
candidate: c,
|
candidate: c,
|
||||||
|
@ -1378,10 +1377,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||||
Ok(_) => Ok(None),
|
Ok(_) => Ok(None),
|
||||||
Err(OverflowError) => Err(Overflow),
|
Err(OverflowError) => Err(Overflow),
|
||||||
})
|
})
|
||||||
.collect();
|
.flat_map(Result::transpose)
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
let mut candidates: Vec<EvaluatedCandidate<'_>> =
|
|
||||||
candidates?.into_iter().filter_map(|c| c).collect();
|
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"winnowed to {} candidates for {:?}: {:?}",
|
"winnowed to {} candidates for {:?}: {:?}",
|
||||||
|
@ -1390,7 +1387,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||||
candidates
|
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
|
// reduce the list by dropping duplicates -- including
|
||||||
// resolving specializations.
|
// resolving specializations.
|
||||||
if candidates.len() > 1 {
|
if candidates.len() > 1 {
|
||||||
|
|
|
@ -681,7 +681,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
|
||||||
match (r1, r2) {
|
match (r1, r2) {
|
||||||
(Representability::SelfRecursive(v1),
|
(Representability::SelfRecursive(v1),
|
||||||
Representability::SelfRecursive(v2)) => {
|
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)
|
(r1, r2) => cmp::max(r1, r2)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1592,8 +1592,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
|
||||||
debug!("ty_of_fn");
|
debug!("ty_of_fn");
|
||||||
|
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
let input_tys: Vec<Ty> =
|
let input_tys =
|
||||||
decl.inputs.iter().map(|a| self.ty_of_arg(a, None)).collect();
|
decl.inputs.iter().map(|a| self.ty_of_arg(a, None));
|
||||||
|
|
||||||
let output_ty = match decl.output {
|
let output_ty = match decl.output {
|
||||||
hir::Return(ref output) => self.ast_ty_to_ty(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);
|
debug!("ty_of_fn: output_ty={:?}", output_ty);
|
||||||
|
|
||||||
let bare_fn_ty = ty::Binder::bind(tcx.mk_fn_sig(
|
let bare_fn_ty = ty::Binder::bind(tcx.mk_fn_sig(
|
||||||
input_tys.into_iter(),
|
input_tys,
|
||||||
output_ty,
|
output_ty,
|
||||||
decl.variadic,
|
decl.variadic,
|
||||||
unsafety,
|
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
|
// Typecheck the patterns first, so that we get types for all the
|
||||||
// bindings.
|
// 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;
|
let mut all_pats_diverge = Diverges::WarnedAlways;
|
||||||
for p in &arm.pats {
|
for p in &arm.pats {
|
||||||
self.diverges.set(Diverges::Maybe);
|
self.diverges.set(Diverges::Maybe);
|
||||||
|
@ -642,7 +642,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
|
||||||
Diverges::Maybe => Diverges::Maybe,
|
Diverges::Maybe => Diverges::Maybe,
|
||||||
Diverges::Always | Diverges::WarnedAlways => Diverges::WarnedAlways,
|
Diverges::Always | Diverges::WarnedAlways => Diverges::WarnedAlways,
|
||||||
}
|
}
|
||||||
}).collect();
|
});
|
||||||
|
|
||||||
// Now typecheck the blocks.
|
// 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)
|
// 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 ty = field.ty(tcx, Substs::identity_for_item(tcx, field.did));
|
||||||
let param_env = tcx.param_env(field.did);
|
let param_env = tcx.param_env(field.did);
|
||||||
let layout = tcx.layout_of(param_env.and(ty));
|
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 zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
|
||||||
let align1 = layout.map(|layout| layout.align.abi() == 1).unwrap_or(false);
|
let align1 = layout.map(|layout| layout.align.abi() == 1).unwrap_or(false);
|
||||||
(span, zst, align1)
|
(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();
|
let non_zst_count = non_zst_fields.clone().count();
|
||||||
if non_zst_count != 1 {
|
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,
|
struct_span_err!(tcx.sess, sp, E0690,
|
||||||
"transparent struct needs exactly one non-zero-sized field, but has {}",
|
"transparent struct needs exactly one non-zero-sized field, but has {}",
|
||||||
non_zst_count)
|
non_zst_count)
|
||||||
.span_note(field_spans, "non-zero-sized field")
|
.span_note(field_spans, "non-zero-sized field")
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
for &(span, zst, align1) in &field_infos {
|
for (span, zst, align1) in field_infos {
|
||||||
if zst && !align1 {
|
if zst && !align1 {
|
||||||
span_err!(tcx.sess, span, E0691,
|
span_err!(tcx.sess, span, E0691,
|
||||||
"zero-sized field in transparent struct has alignment larger than 1");
|
"zero-sized field in transparent struct has alignment larger than 1");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue