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,

`