Skip to content

Commit caa701e

Browse files
Elaborate supertrait obligations when deducing closure signature
1 parent 060d439 commit caa701e

File tree

4 files changed

+41
-35
lines changed

4 files changed

+41
-35
lines changed

compiler/rustc_hir_typeck/src/closure.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use rustc_middle::ty::visit::TypeVisitable;
1515
use rustc_middle::ty::{self, Ty};
1616
use rustc_span::source_map::Span;
1717
use rustc_target::spec::abi::Abi;
18+
use rustc_trait_selection::traits;
1819
use rustc_trait_selection::traits::error_reporting::ArgKind;
1920
use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
2021
use std::cmp;
@@ -226,27 +227,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
226227
expected_vid: ty::TyVid,
227228
) -> (Option<ExpectedSig<'tcx>>, Option<ty::ClosureKind>) {
228229
let mut expected_sig = None;
229-
// Even if we can't infer the full signature, we may be able to
230-
// infer the kind. This can occur when we elaborate a predicate
231-
// like `F : Fn<A>`. Note that due to subtyping we could encounter
232-
// many viable options, so pick the most restrictive.
233230
let mut expected_kind = None;
234231

235-
for obligation in self.obligations_for_self_ty(expected_vid) {
232+
for obligation in traits::elaborate_obligations(
233+
self.tcx,
234+
self.obligations_for_self_ty(expected_vid).collect(),
235+
) {
236236
debug!(?obligation.predicate);
237237
let bound_predicate = obligation.predicate.kind();
238238

239+
// Given a Projection predicate, we can potentially infer
240+
// the complete signature.
239241
if expected_sig.is_none()
240242
&& let ty::PredicateKind::Projection(proj_predicate) = bound_predicate.skip_binder()
241243
{
242-
// Given a Projection predicate, we can potentially infer
243-
// the complete signature.
244244
expected_sig = self.deduce_sig_from_projection(
245245
Some(obligation.cause.span),
246246
bound_predicate.rebind(proj_predicate),
247247
);
248248
}
249249

250+
// Even if we can't infer the full signature, we may be able to
251+
// infer the kind. This can occur when we elaborate a predicate
252+
// like `F : Fn<A>`. Note that due to subtyping we could encounter
253+
// many viable options, so pick the most restrictive.
250254
let trait_def_id = match bound_predicate.skip_binder() {
251255
ty::PredicateKind::Projection(data) => {
252256
Some(data.projection_ty.trait_def_id(self.tcx))
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// check-pass
2+
// Checks that we can infer a closure signature even if the `FnOnce` bound is
3+
// a supertrait of the obligations we have currently registered for the Ty var.
4+
5+
pub trait Receive<T, E>: FnOnce(Result<T, E>) {
6+
fn receive(self, res: Result<T, E>);
7+
}
8+
9+
impl<T, E, F: FnOnce(Result<T, E>)> Receive<T, E> for F {
10+
fn receive(self, res: Result<T, E>) {
11+
self(res)
12+
}
13+
}
14+
15+
pub trait Async<T, E> {
16+
fn receive<F: Receive<T, E>>(self, f: F);
17+
}
18+
19+
impl<T, E> Async<T, E> for Result<T, E> {
20+
fn receive<F: Receive<T, E>>(self, f: F) {
21+
f(self)
22+
}
23+
}
24+
25+
pub fn main() {
26+
Ok::<u32, ()>(123).receive(|res| {
27+
res.unwrap();
28+
});
29+
}

src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1+
// check-pass
12
// Regression test for issue #57611
23
// Ensures that we don't ICE
3-
// FIXME: This should compile, but it currently doesn't
4-
// known-bug: unknown
54

65
#![feature(trait_alias)]
76
#![feature(type_alias_impl_trait)]

src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.stderr

Lines changed: 0 additions & 26 deletions
This file was deleted.

0 commit comments

Comments
 (0)