Skip to content

Commit 342a19d

Browse files
committed
rustdoc: use the next solver for blanket impl synthesis
1 parent 79a272c commit 342a19d

File tree

1 file changed

+29
-32
lines changed

1 file changed

+29
-32
lines changed

src/librustdoc/clean/blanket_impl.rs

+29-32
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use rustc_hir as hir;
2-
use rustc_infer::infer::{DefineOpaqueTypes, InferOk, TyCtxtInferExt};
3-
use rustc_infer::traits;
2+
use rustc_infer::infer::TyCtxtInferExt;
3+
use rustc_infer::traits::ObligationCause;
44
use rustc_middle::ty::{self, TypingMode, Upcast};
55
use rustc_span::DUMMY_SP;
66
use rustc_span::def_id::DefId;
7-
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
7+
use rustc_trait_selection::traits;
88
use thin_vec::ThinVec;
99
use tracing::{debug, instrument, trace};
1010

@@ -31,53 +31,50 @@ pub(crate) fn synthesize_blanket_impls(
3131
}
3232
// NOTE: doesn't use `for_each_relevant_impl` to avoid looking at anything besides blanket impls
3333
let trait_impls = tcx.trait_impls_of(trait_def_id);
34-
'blanket_impls: for &impl_def_id in trait_impls.blanket_impls() {
34+
for &impl_def_id in trait_impls.blanket_impls() {
3535
trace!("considering impl `{impl_def_id:?}` for trait `{trait_def_id:?}`");
3636

3737
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
3838
if !matches!(trait_ref.skip_binder().self_ty().kind(), ty::Param(_)) {
3939
continue;
4040
}
41-
let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
41+
let infcx = tcx
42+
.infer_ctxt()
43+
.with_next_trait_solver(true)
44+
.build(TypingMode::non_body_analysis());
45+
let ocx = traits::ObligationCtxt::new(&infcx);
46+
4247
let args = infcx.fresh_args_for_item(DUMMY_SP, item_def_id);
4348
let impl_ty = ty.instantiate(tcx, args);
4449
let param_env = ty::ParamEnv::empty();
50+
let cause = ObligationCause::dummy();
4551

4652
let impl_args = infcx.fresh_args_for_item(DUMMY_SP, impl_def_id);
4753
let impl_trait_ref = trait_ref.instantiate(tcx, impl_args);
4854

4955
// Require the type the impl is implemented on to match
5056
// our type, and ignore the impl if there was a mismatch.
51-
let Ok(eq_result) = infcx.at(&traits::ObligationCause::dummy(), param_env).eq(
52-
DefineOpaqueTypes::Yes,
53-
impl_trait_ref.self_ty(),
54-
impl_ty,
55-
) else {
57+
if ocx.eq(&cause, param_env, impl_trait_ref.self_ty(), impl_ty).is_err() {
5658
continue;
57-
};
58-
let InferOk { value: (), obligations } = eq_result;
59-
// FIXME(eddyb) ignoring `obligations` might cause false positives.
60-
drop(obligations);
59+
}
6160

62-
let predicates = tcx
63-
.predicates_of(impl_def_id)
64-
.instantiate(tcx, impl_args)
65-
.predicates
66-
.into_iter()
67-
.chain(Some(impl_trait_ref.upcast(tcx)));
68-
for predicate in predicates {
69-
let obligation = traits::Obligation::new(
70-
tcx,
71-
traits::ObligationCause::dummy(),
72-
param_env,
73-
predicate,
74-
);
75-
match infcx.evaluate_obligation(&obligation) {
76-
Ok(eval_result) if eval_result.may_apply() => {}
77-
Err(traits::OverflowError::Canonical) => {}
78-
_ => continue 'blanket_impls,
79-
}
61+
ocx.register_obligations(traits::predicates_for_generics(
62+
|_, _| cause.clone(),
63+
param_env,
64+
tcx.predicates_of(impl_def_id).instantiate(tcx, impl_args),
65+
));
66+
67+
ocx.register_obligation(traits::Obligation {
68+
cause,
69+
recursion_depth: 0,
70+
param_env,
71+
predicate: impl_trait_ref.upcast(tcx),
72+
});
73+
74+
if !ocx.select_where_possible().is_empty() {
75+
continue;
8076
}
77+
8178
debug!("found applicable impl for trait ref {trait_ref:?}");
8279

8380
cx.generated_synthetics.insert((ty.skip_binder(), trait_def_id));

0 commit comments

Comments
 (0)