Skip to content

Commit 64932fb

Browse files
Auto merge of #125907 - fmease:rustdoc-synth-blanket-ocx-next, r=<try>
rustdoc: use the next solver for blanket impl synthesis
2 parents 350d0ef + c7ab39a commit 64932fb

File tree

1 file changed

+26
-39
lines changed

1 file changed

+26
-39
lines changed

src/librustdoc/clean/blanket_impl.rs

Lines changed: 26 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use rustc_hir as hir;
2-
use rustc_infer::infer::{DefineOpaqueTypes, InferOk, TyCtxtInferExt};
3-
use rustc_infer::traits;
4-
use rustc_middle::ty::{self, TypingMode, Upcast};
2+
use rustc_infer::infer::TyCtxtInferExt;
3+
use rustc_infer::traits::ObligationCause;
4+
use rustc_middle::ty::{self, TypingMode};
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;
9-
use tracing::{debug, instrument, trace};
9+
use tracing::{debug, instrument};
1010

1111
use crate::clean;
1212
use crate::clean::{
@@ -22,6 +22,9 @@ pub(crate) fn synthesize_blanket_impls(
2222
let tcx = cx.tcx;
2323
let ty = tcx.type_of(item_def_id);
2424

25+
let infcx =
26+
tcx.infer_ctxt().with_next_trait_solver(true).build(TypingMode::non_body_analysis());
27+
2528
let mut blanket_impls = Vec::new();
2629
for trait_def_id in tcx.visible_traits() {
2730
if !cx.cache.effective_visibilities.is_reachable(tcx, trait_def_id)
@@ -31,53 +34,37 @@ pub(crate) fn synthesize_blanket_impls(
3134
}
3235
// NOTE: doesn't use `for_each_relevant_impl` to avoid looking at anything besides blanket impls
3336
let trait_impls = tcx.trait_impls_of(trait_def_id);
34-
'blanket_impls: for &impl_def_id in trait_impls.blanket_impls() {
35-
trace!("considering impl `{impl_def_id:?}` for trait `{trait_def_id:?}`");
36-
37+
for &impl_def_id in trait_impls.blanket_impls() {
3738
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
38-
if !matches!(trait_ref.skip_binder().self_ty().kind(), ty::Param(_)) {
39-
continue;
40-
}
41-
let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
39+
40+
let ty::Param(_) = trait_ref.skip_binder().self_ty().kind() else { continue };
41+
42+
let ocx = traits::ObligationCtxt::new(&infcx);
43+
4244
let args = infcx.fresh_args_for_item(DUMMY_SP, item_def_id);
4345
let impl_ty = ty.instantiate(tcx, args);
4446
let param_env = ty::ParamEnv::empty();
47+
let cause = ObligationCause::dummy();
4548

4649
let impl_args = infcx.fresh_args_for_item(DUMMY_SP, impl_def_id);
4750
let impl_trait_ref = trait_ref.instantiate(tcx, impl_args);
4851

4952
// Require the type the impl is implemented on to match
5053
// 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 {
54+
if ocx.eq(&cause, param_env, impl_trait_ref.self_ty(), impl_ty).is_err() {
5655
continue;
57-
};
58-
let InferOk { value: (), obligations } = eq_result;
59-
// FIXME(eddyb) ignoring `obligations` might cause false positives.
60-
drop(obligations);
56+
}
57+
58+
ocx.register_obligations(traits::predicates_for_generics(
59+
|_, _| cause.clone(),
60+
param_env,
61+
tcx.predicates_of(impl_def_id).instantiate(tcx, impl_args),
62+
));
6163

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-
}
64+
if !ocx.select_where_possible().is_empty() {
65+
continue;
8066
}
67+
8168
debug!("found applicable impl for trait ref {trait_ref:?}");
8269

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

0 commit comments

Comments
 (0)