Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 10 pull requests #122039

Closed
wants to merge 25 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
d74d67c
Implement async closure signature deduction
compiler-errors Mar 1, 2024
e71f207
Add new Tier-3 target: `loongarch64-unknown-linux-musl`
heiher Jun 5, 2023
aa1ab01
tests: Add loongarch64-unknown-linux-musl target
heiher Mar 1, 2024
374607d
const_eval_select: make it safe but be careful with what we expose on…
RalfJung Mar 2, 2024
d858809
typo
RalfJung Mar 2, 2024
4dbd256
Explain use of display adapters
CAD97 Feb 14, 2024
215a4b6
doc wording improvements
CAD97 Mar 5, 2024
b5d7da8
Decouple `DummyAstNode` and `DummyResult`.
nnethercote Mar 1, 2024
a9dff2d
Remove unused `impl DummyAstNode for Block`.
nnethercote Mar 1, 2024
c98be32
Stop using Bubble in coherence and instead emulate it with an intercr…
oli-obk Feb 28, 2024
960dd38
will_wake tests fail on Miri and that is expected
RalfJung Mar 5, 2024
8dd126d
Change some attributes to only_local.
surechen Mar 5, 2024
f391c07
only set noalias on Box with the global allocator
RalfJung Mar 5, 2024
8255618
Update src/doc/rustc/src/platform-support.md
wesleywiser Mar 5, 2024
5a16aeb
Remove some dead code
oli-obk Mar 5, 2024
4d0a71b
Rollup merge of #121065 - CAD97:display-i18n, r=cuviper
matthiaskrgr Mar 5, 2024
74b281f
Rollup merge of #121744 - oli-obk:eager_opaque_checks2, r=lcnr
matthiaskrgr Mar 5, 2024
a73b7e6
Rollup merge of #121829 - nnethercote:dummy-tweaks-2, r=petrochenkov
matthiaskrgr Mar 5, 2024
d2a2350
Rollup merge of #121832 - heiher:loongarch64-musl, r=wesleywiser
matthiaskrgr Mar 5, 2024
d54254e
Rollup merge of #121857 - compiler-errors:async-closure-signature-ded…
matthiaskrgr Mar 5, 2024
dcdb2c3
Rollup merge of #121894 - RalfJung:const_eval_select, r=oli-obk
matthiaskrgr Mar 5, 2024
59ada09
Rollup merge of #122014 - surechen:change_attributes_to_local_2024030…
matthiaskrgr Mar 5, 2024
2af5b05
Rollup merge of #122016 - RalfJung:will_wake, r=dtolnay
matthiaskrgr Mar 5, 2024
8f0b1e4
Rollup merge of #122018 - RalfJung:box-custom-alloc, r=oli-obk
matthiaskrgr Mar 5, 2024
776afd3
Rollup merge of #122028 - oli-obk:drop_in_place_leftovers, r=compiler…
matthiaskrgr Mar 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Implement async closure signature deduction
  • Loading branch information
compiler-errors committed Mar 1, 2024
commit d74d67c8369fd759d860d215aaa576a03d99b692
74 changes: 47 additions & 27 deletions compiler/rustc_hir_typeck/src/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// It's always helpful for inference if we know the kind of
// closure sooner rather than later, so first examine the expected
// type, and see if can glean a closure kind from there.
let (expected_sig, expected_kind) = match closure.kind {
hir::ClosureKind::Closure => match expected.to_option(self) {
Some(ty) => {
self.deduce_closure_signature(self.try_structurally_resolve_type(expr_span, ty))
}
None => (None, None),
},
// We don't want to deduce a signature from `Fn` bounds for coroutines
// or coroutine-closures, because the former does not implement `Fn`
// ever, and the latter's signature doesn't correspond to the coroutine
// type that it returns.
hir::ClosureKind::Coroutine(_) | hir::ClosureKind::CoroutineClosure(_) => (None, None),
let (expected_sig, expected_kind) = match expected.to_option(self) {
Some(ty) => self.deduce_closure_signature(
self.try_structurally_resolve_type(expr_span, ty),
closure.kind,
),
None => (None, None),
};

let ClosureSignatures { bound_sig, mut liberated_sig } =
Expand Down Expand Up @@ -323,11 +317,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn deduce_closure_signature(
&self,
expected_ty: Ty<'tcx>,
closure_kind: hir::ClosureKind,
) -> (Option<ExpectedSig<'tcx>>, Option<ty::ClosureKind>) {
match *expected_ty.kind() {
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => self
.deduce_closure_signature_from_predicates(
expected_ty,
closure_kind,
self.tcx
.explicit_item_bounds(def_id)
.iter_instantiated_copied(self.tcx, args)
Expand All @@ -336,7 +332,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
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, pb)
self.deduce_sig_from_projection(None, closure_kind, pb)
});
let kind = object_type
.principal_def_id()
Expand All @@ -345,19 +341,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
ty::Infer(ty::TyVar(vid)) => self.deduce_closure_signature_from_predicates(
Ty::new_var(self.tcx, self.root_var(vid)),
closure_kind,
self.obligations_for_self_ty(vid).map(|obl| (obl.predicate, obl.cause.span)),
),
ty::FnPtr(sig) => {
let expected_sig = ExpectedSig { cause_span: None, sig };
(Some(expected_sig), Some(ty::ClosureKind::Fn))
}
ty::FnPtr(sig) => match closure_kind {
hir::ClosureKind::Closure => {
let expected_sig = ExpectedSig { cause_span: None, sig };
(Some(expected_sig), Some(ty::ClosureKind::Fn))
}
hir::ClosureKind::Coroutine(_) | hir::ClosureKind::CoroutineClosure(_) => {
(None, None)
}
},
_ => (None, None),
}
}

fn deduce_closure_signature_from_predicates(
&self,
expected_ty: Ty<'tcx>,
closure_kind: hir::ClosureKind,
predicates: impl DoubleEndedIterator<Item = (ty::Predicate<'tcx>, Span)>,
) -> (Option<ExpectedSig<'tcx>>, Option<ty::ClosureKind>) {
let mut expected_sig = None;
Expand Down Expand Up @@ -386,6 +389,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span,
self.deduce_sig_from_projection(
Some(span),
closure_kind,
bound_predicate.rebind(proj_predicate),
),
);
Expand Down Expand Up @@ -422,13 +426,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => Some(data.def_id()),
_ => None,
};
if let Some(closure_kind) =
trait_def_id.and_then(|def_id| self.tcx.fn_trait_kind_from_def_id(def_id))
{
expected_kind = Some(
expected_kind
.map_or_else(|| closure_kind, |current| cmp::min(current, closure_kind)),
);

if let Some(trait_def_id) = trait_def_id {
let found_kind = match closure_kind {
hir::ClosureKind::Closure => self.tcx.fn_trait_kind_from_def_id(trait_def_id),
hir::ClosureKind::CoroutineClosure(hir::CoroutineDesugaring::Async) => {
self.tcx.async_fn_trait_kind_from_def_id(trait_def_id)
}
_ => None,
};

if let Some(found_kind) = found_kind {
expected_kind = Some(
expected_kind
.map_or_else(|| found_kind, |current| cmp::min(current, found_kind)),
);
}
}
}

Expand All @@ -445,14 +458,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn deduce_sig_from_projection(
&self,
cause_span: Option<Span>,
closure_kind: hir::ClosureKind,
projection: ty::PolyProjectionPredicate<'tcx>,
) -> Option<ExpectedSig<'tcx>> {
let tcx = self.tcx;

let trait_def_id = projection.trait_def_id(tcx);
// For now, we only do signature deduction based off of the `Fn` traits.
if !tcx.is_fn_trait(trait_def_id) {
return None;

// For now, we only do signature deduction based off of the `Fn` and `AsyncFn` traits,
// for closures and async closures, respectively.
match closure_kind {
hir::ClosureKind::Closure
if self.tcx.fn_trait_kind_from_def_id(trait_def_id).is_some() => {}
hir::ClosureKind::CoroutineClosure(hir::CoroutineDesugaring::Async)
if self.tcx.async_fn_trait_kind_from_def_id(trait_def_id).is_some() => {}
_ => return None,
}

let arg_param_ty = projection.skip_binder().projection_ty.args.type_at(1);
Expand Down
10 changes: 10 additions & 0 deletions tests/ui/async-await/async-closures/signature-deduction.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//@ check-pass
//@ edition: 2021

#![feature(async_closure)]

async fn foo(x: impl async Fn(&str) -> &str) {}

fn main() {
foo(async |x| x);
}
Loading