Last nits · rust-lang/rust@9a75603 (original) (raw)
`@@ -13,6 +13,7 @@ use rustc_span::{ErrorGuaranteed, Span};
`
13
13
``
14
14
`use std::collections::VecDeque;
`
15
15
`use std::fmt::Write;
`
``
16
`+
use std::ops::ControlFlow;
`
16
17
``
17
18
`impl<'tcx> Value<TyCtxt<'tcx>> for Ty<'_> {
`
18
19
`fn from_cycle_error(tcx: TyCtxt<'tcx>, _: &CycleError, guar: ErrorGuaranteed) -> Self {
`
`@@ -130,16 +131,34 @@ impl<'tcx> Value<TyCtxt<'tcx>> for ty::EarlyBinder<ty::Binder<'_, ty::FnSig<'_>>
`
130
131
`}
`
131
132
`}
`
132
133
``
``
134
`` +
// Take a cycle of Q
and try try_cycle
on every permutation, falling back to otherwise
.
``
``
135
`+
fn search_for_cycle_permutation<Q, T>(
`
``
136
`+
cycle: &[Q],
`
``
137
`+
try_cycle: impl Fn(&mut VecDeque<&Q>) -> ControlFlow<T, ()>,
`
``
138
`+
otherwise: impl FnOnce() -> T,
`
``
139
`+
) -> T {
`
``
140
`+
let mut cycle: VecDeque<_> = cycle.iter().collect();
`
``
141
`+
for _ in 0..cycle.len() {
`
``
142
`+
match try_cycle(&mut cycle) {
`
``
143
`+
ControlFlow::Continue(_) => {
`
``
144
`+
cycle.rotate_left(1);
`
``
145
`+
}
`
``
146
`+
ControlFlow::Break(t) => return t,
`
``
147
`+
}
`
``
148
`+
}
`
``
149
+
``
150
`+
otherwise()
`
``
151
`+
}
`
``
152
+
133
153
`impl<'tcx, T> Value<TyCtxt<'tcx>> for Result<T, &'_ ty::layout::LayoutError<'_>> {
`
134
154
`fn from_cycle_error(
`
135
155
`tcx: TyCtxt<'tcx>,
`
136
156
`cycle_error: &CycleError,
`
137
157
`_guar: ErrorGuaranteed,
`
138
158
`) -> Self {
`
139
``
`-
let mut cycle: VecDeque<_> = cycle_error.cycle.iter().collect();
`
140
``
-
141
``
`-
let guar = 'search: {
`
142
``
`-
for _ in 0..cycle.len() {
`
``
159
`+
let diag = search_for_cycle_permutation(
`
``
160
`+
&cycle_error.cycle,
`
``
161
`+
|cycle| {
`
143
162
`if cycle[0].query.dep_kind == dep_kinds::layout_of
`
144
163
` && let Some(def_id) = cycle[0].query.ty_def_id
`
145
164
` && let Some(def_id) = def_id.as_local()
`
`@@ -204,13 +223,16 @@ impl<'tcx, T> Value<TyCtxt<'tcx>> for Result<T, &'_ ty::layout::LayoutError<'_>>
`
204
223
`) {
`
205
224
`` diag.note("a recursive async fn
call must introduce indirection such as Box::pin
to avoid an infinitely sized future");
``
206
225
`}
`
207
``
`-
break 'search diag.emit();
`
``
226
+
``
227
`+
ControlFlow::Break(diag)
`
208
228
`} else {
`
209
``
`-
cycle.rotate_left(1);
`
``
229
`+
ControlFlow::Continue(())
`
210
230
`}
`
211
``
`-
}
`
212
``
`-
report_cycle(tcx.sess, cycle_error).emit()
`
213
``
`-
};
`
``
231
`+
},
`
``
232
`+
|| report_cycle(tcx.sess, cycle_error),
`
``
233
`+
);
`
``
234
+
``
235
`+
let guar = diag.emit();
`
214
236
``
215
237
`// tcx.arena.alloc cannot be used because we are not allowed to use &'tcx LayoutError under
`
216
238
`// min_specialization. Since this is an error path anyways, leaking doesn't matter (and really,
`