Skip to content

Commit c8ebde4

Browse files
Filter out non-Self supertrait predicates in deduce_signature_from_predicates
1 parent 213be32 commit c8ebde4

File tree

3 files changed

+39
-6
lines changed

3 files changed

+39
-6
lines changed

compiler/rustc_hir_typeck/src/closure.rs

+20-5
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
169169
) -> (Option<ExpectedSig<'tcx>>, Option<ty::ClosureKind>) {
170170
match *expected_ty.kind() {
171171
ty::Opaque(def_id, substs) => self.deduce_signature_from_predicates(
172+
// Elaborating expectations from explicit_item_bounds shouldn't include any variable shenanigans
173+
|ty| ty == expected_ty,
172174
self.tcx.bound_explicit_item_bounds(def_id).subst_iter_copied(self.tcx, substs),
173175
),
174176
ty::Dynamic(ref object_type, ..) => {
@@ -181,9 +183,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
181183
.and_then(|did| self.tcx.fn_trait_kind_from_lang_item(did));
182184
(sig, kind)
183185
}
184-
ty::Infer(ty::TyVar(vid)) => self.deduce_signature_from_predicates(
185-
self.obligations_for_self_ty(vid).map(|obl| (obl.predicate, obl.cause.span)),
186-
),
186+
ty::Infer(ty::TyVar(vid)) => {
187+
let root_vid = self.root_var(vid);
188+
self.deduce_signature_from_predicates(
189+
// We need to do equality "modulo root vids" here, since that's
190+
// how `obligations_for_self_ty` filters its predicates.
191+
|ty| self.self_type_matches_expected_vid(ty, root_vid),
192+
self.obligations_for_self_ty(root_vid)
193+
.map(|obl| (obl.predicate, obl.cause.span)),
194+
)
195+
}
187196
ty::FnPtr(sig) => {
188197
let expected_sig = ExpectedSig { cause_span: None, sig };
189198
(Some(expected_sig), Some(ty::ClosureKind::Fn))
@@ -194,6 +203,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
194203

195204
fn deduce_signature_from_predicates(
196205
&self,
206+
eq_expected_ty: impl Fn(Ty<'tcx>) -> bool,
197207
predicates: impl DoubleEndedIterator<Item = (ty::Predicate<'tcx>, Span)>,
198208
) -> (Option<ExpectedSig<'tcx>>, Option<ty::ClosureKind>) {
199209
let mut expected_sig = None;
@@ -213,6 +223,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
213223
// the complete signature.
214224
if expected_sig.is_none()
215225
&& let ty::PredicateKind::Projection(proj_predicate) = bound_predicate.skip_binder()
226+
&& eq_expected_ty(proj_predicate.projection_ty.self_ty())
216227
{
217228
expected_sig = self.normalize_associated_types_in(
218229
obligation.cause.span,
@@ -228,10 +239,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
228239
// like `F : Fn<A>`. Note that due to subtyping we could encounter
229240
// many viable options, so pick the most restrictive.
230241
let trait_def_id = match bound_predicate.skip_binder() {
231-
ty::PredicateKind::Projection(data) => {
242+
ty::PredicateKind::Projection(data)
243+
if eq_expected_ty(data.projection_ty.self_ty()) =>
244+
{
232245
Some(data.projection_ty.trait_def_id(self.tcx))
233246
}
234-
ty::PredicateKind::Trait(data) => Some(data.def_id()),
247+
ty::PredicateKind::Trait(data) if eq_expected_ty(data.self_ty()) => {
248+
Some(data.def_id())
249+
}
235250
_ => None,
236251
};
237252
if let Some(closure_kind) =

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
640640
}
641641

642642
#[instrument(skip(self), level = "debug")]
643-
fn self_type_matches_expected_vid(&self, self_ty: Ty<'tcx>, expected_vid: ty::TyVid) -> bool {
643+
pub(in super::super) fn self_type_matches_expected_vid(
644+
&self,
645+
self_ty: Ty<'tcx>,
646+
expected_vid: ty::TyVid,
647+
) -> bool {
644648
let self_ty = self.shallow_resolve(self_ty);
645649
debug!(?self_ty);
646650

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// check-pass
2+
3+
// Makes sure that we only consider `Self` supertrait predicates while
4+
// elaborating during closure signature deduction.
5+
6+
#![feature(trait_alias)]
7+
8+
trait Confusing<F> = Fn(i32) where F: Fn(u32);
9+
10+
fn alias<T: Confusing<F>, F>(_: T, _: F) {}
11+
12+
fn main() {
13+
alias(|_| {}, |_| {});
14+
}

0 commit comments

Comments
 (0)