Skip to content

Commit ec8e229

Browse files
Assemble inherent pick for trait blanket impl
1 parent 5367673 commit ec8e229

File tree

1 file changed

+36
-1
lines changed
  • compiler/rustc_hir_typeck/src/method

1 file changed

+36
-1
lines changed

compiler/rustc_hir_typeck/src/method/probe.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ pub(crate) enum CandidateKind<'tcx> {
111111
InherentImplCandidate(DefId),
112112
ObjectCandidate(ty::PolyTraitRef<'tcx>),
113113
TraitCandidate(ty::PolyTraitRef<'tcx>),
114+
TraitImplSelfCandidate(ty::TraitRef<'tcx>),
114115
WhereClauseCandidate(ty::PolyTraitRef<'tcx>),
115116
}
116117

@@ -648,6 +649,24 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
648649
for step in self.steps.iter() {
649650
self.assemble_probe(&step.self_ty);
650651
}
652+
653+
// HACK:
654+
// Assemble an "inherent" candidate for the self type of the impl we're inside of.
655+
if let Some(own_item) =
656+
self.tcx.opt_associated_item(self.tcx.typeck_root_def_id(self.body_id.to_def_id()))
657+
&& let ty::AssocItemContainer::ImplContainer = own_item.container
658+
&& let Some(trait_ref) = self.tcx.impl_trait_ref(own_item.container_id(self.tcx))
659+
&& let trait_ref = trait_ref.instantiate_identity()
660+
&& matches!(trait_ref.self_ty().kind(), ty::Param(_))
661+
{
662+
for item in self.impl_or_trait_item(trait_ref.def_id) {
663+
self.inherent_candidates.push(Candidate {
664+
item,
665+
import_ids: smallvec![],
666+
kind: TraitImplSelfCandidate(trait_ref),
667+
})
668+
}
669+
}
651670
}
652671

653672
#[instrument(level = "debug", skip(self))]
@@ -1381,7 +1400,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
13811400
InherentImplCandidate(_) => {
13821401
CandidateSource::Impl(candidate.item.container_id(self.tcx))
13831402
}
1384-
ObjectCandidate(_) | WhereClauseCandidate(_) => {
1403+
ObjectCandidate(_) | WhereClauseCandidate(_) | TraitImplSelfCandidate(_) => {
13851404
CandidateSource::Trait(candidate.item.container_id(self.tcx))
13861405
}
13871406
TraitCandidate(trait_ref) => self.probe(|_| {
@@ -1467,6 +1486,18 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
14671486
impl_bounds,
14681487
));
14691488
}
1489+
TraitImplSelfCandidate(trait_ref) => {
1490+
(xform_self_ty, xform_ret_ty) =
1491+
self.xform_self_ty(probe.item, trait_ref.self_ty(), trait_ref.args);
1492+
xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty);
1493+
match ocx.sup(cause, self.param_env, xform_self_ty, self_ty) {
1494+
Ok(()) => {}
1495+
Err(err) => {
1496+
debug!("--> cannot relate self-types {:?}", err);
1497+
return ProbeResult::NoMatch;
1498+
}
1499+
}
1500+
}
14701501
TraitCandidate(poly_trait_ref) => {
14711502
// Some trait methods are excluded for arrays before 2021.
14721503
// (`array.into_iter()` wants a slice iterator for compatibility.)
@@ -1946,6 +1977,10 @@ impl<'tcx> Candidate<'tcx> {
19461977
InherentImplCandidate(_) => InherentImplPick,
19471978
ObjectCandidate(_) => ObjectPick,
19481979
TraitCandidate(_) => TraitPick,
1980+
1981+
// HACK:
1982+
TraitImplSelfCandidate(w) => WhereClausePick(ty::Binder::dummy(w)),
1983+
19491984
WhereClauseCandidate(trait_ref) => {
19501985
// Only trait derived from where-clauses should
19511986
// appear here, so they should not contain any

0 commit comments

Comments
 (0)