Skip to content

Commit

Permalink
Deduce closure signature from supertrait projection bounds
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Nov 29, 2024
1 parent 6345cb0 commit 0320ee1
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 11 deletions.
24 changes: 13 additions & 11 deletions compiler/rustc_hir_typeck/src/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use rustc_span::def_id::LocalDefId;
use rustc_span::{DUMMY_SP, Span};
use rustc_trait_selection::error_reporting::traits::ArgKind;
use rustc_trait_selection::traits;
use rustc_type_ir::ClosureKind;
use rustc_type_ir::{ClosureKind, Upcast as _};
use tracing::{debug, instrument, trace};

use super::{CoroutineTypes, Expectation, FnCtxt, check_fn};
Expand Down Expand Up @@ -312,16 +312,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.iter_instantiated_copied(self.tcx, args)
.map(|(c, s)| (c.as_predicate(), s)),
),
ty::Dynamic(object_type, ..) => {
let sig = object_type.projection_bounds().find_map(|pb| {
let pb = pb.with_self_ty(self.tcx, self.tcx.types.trait_object_dummy_self);
self.deduce_sig_from_projection(None, closure_kind, pb)
});
let kind = object_type
.principal_def_id()
.and_then(|did| self.tcx.fn_trait_kind_from_def_id(did));
(sig, kind)
}
ty::Dynamic(data, ..) => self.deduce_closure_signature_from_predicates(
expected_ty,
closure_kind,
data.iter().map(|bound| {
(
bound
.with_self_ty(self.tcx, self.tcx.types.trait_object_dummy_self)
.upcast(self.tcx),
DUMMY_SP,
)
}),
),
ty::Infer(ty::TyVar(vid)) => self.deduce_closure_signature_from_predicates(
Ty::new_var(self.tcx, self.root_var(vid)),
closure_kind,
Expand Down
15 changes: 15 additions & 0 deletions tests/ui/closures/deduce-from-object-supertrait.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//@ check-pass

trait Foo: Fn(Bar) {}
impl<T> Foo for T where T: Fn(Bar) {}

struct Bar;
impl Bar {
fn bar(&self) {}
}

fn main() {
let x: &dyn Foo = &|x| {
x.bar();
};
}

0 comments on commit 0320ee1

Please sign in to comment.