Skip to content

Commit 2ed5f25

Browse files
committed
Move code that finds missing bounds into a function
1 parent 3153584 commit 2ed5f25

File tree

1 file changed

+50
-38
lines changed

1 file changed

+50
-38
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 50 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -292,44 +292,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
292292
.as_local()
293293
.and_then(|def_id| tcx.hir().get_generics(def_id))
294294
{
295-
let predicates: Result<Vec<_>, _> = tcx.infer_ctxt().enter(|infcx| {
296-
let mut fulfill_cx =
297-
<dyn rustc_infer::traits::TraitEngine<'_>>::new(infcx.tcx);
298-
299-
let copy_did = infcx.tcx.lang_items().copy_trait().unwrap();
300-
let cause = ObligationCause::new(
301-
span,
302-
self.mir_hir_id(),
303-
rustc_infer::traits::ObligationCauseCode::MiscObligation,
304-
);
305-
fulfill_cx.register_bound(
306-
&infcx,
307-
self.param_env,
308-
// Erase any region vids from the type, which may not be resolved
309-
infcx.tcx.erase_regions(ty),
310-
copy_did,
311-
cause,
312-
);
313-
// Select all, including ambiguous predicates
314-
let errors = fulfill_cx.select_all_or_error(&infcx);
315-
316-
// Only emit suggestion if all required predicates are on generic
317-
errors
318-
.into_iter()
319-
.map(|err| match err.obligation.predicate.kind().skip_binder() {
320-
PredicateKind::Trait(predicate) => {
321-
match predicate.self_ty().kind() {
322-
ty::Param(param_ty) => Ok((
323-
generics.type_param(param_ty, tcx),
324-
predicate.trait_ref.print_only_trait_path().to_string(),
325-
)),
326-
_ => Err(()),
327-
}
328-
}
329-
_ => Err(()),
330-
})
331-
.collect()
332-
});
295+
let copy_did = tcx.lang_items().copy_trait().unwrap();
296+
let predicates =
297+
self.try_find_missing_generic_bounds(ty, copy_did, generics, span);
333298

334299
if let Ok(predicates) = predicates {
335300
suggest_constraining_type_params(
@@ -2256,6 +2221,53 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
22562221
}
22572222
}
22582223
}
2224+
2225+
/// Tries to find bounds on `generics` that satisfy `ty: required_trait_did` bound.
2226+
fn try_find_missing_generic_bounds(
2227+
&self,
2228+
ty: Ty<'tcx>,
2229+
required_trait_did: DefId,
2230+
generics: &'tcx ty::Generics,
2231+
obligation_cause_span: Span,
2232+
) -> Result<Vec<(&'tcx ty::GenericParamDef, String)>, ()> {
2233+
let tcx = self.infcx.tcx;
2234+
let predicates: Result<Vec<_>, _> = tcx.infer_ctxt().enter(|infcx| {
2235+
let mut fulfill_cx = <dyn rustc_infer::traits::TraitEngine<'_>>::new(infcx.tcx);
2236+
2237+
let cause = ObligationCause::new(
2238+
obligation_cause_span,
2239+
self.mir_hir_id(),
2240+
rustc_infer::traits::ObligationCauseCode::MiscObligation,
2241+
);
2242+
fulfill_cx.register_bound(
2243+
&infcx,
2244+
self.param_env,
2245+
// Erase any region vids from the type, which may not be resolved
2246+
infcx.tcx.erase_regions(ty),
2247+
required_trait_did,
2248+
cause,
2249+
);
2250+
// Select all, including ambiguous predicates
2251+
let errors = fulfill_cx.select_all_or_error(&infcx);
2252+
2253+
// Only emit suggestion if all required predicates are on generic
2254+
errors
2255+
.into_iter()
2256+
.map(|err| match err.obligation.predicate.kind().skip_binder() {
2257+
PredicateKind::Trait(predicate) => match predicate.self_ty().kind() {
2258+
ty::Param(param_ty) => Ok((
2259+
generics.type_param(param_ty, tcx),
2260+
predicate.trait_ref.print_only_trait_path().to_string(),
2261+
)),
2262+
_ => Err(()),
2263+
},
2264+
_ => Err(()),
2265+
})
2266+
.collect()
2267+
});
2268+
2269+
predicates
2270+
}
22592271
}
22602272

22612273
#[derive(Debug)]

0 commit comments

Comments
 (0)