Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit cfe9972

Browse files
authored
Unrolled build for rust-lang#141359
Rollup merge of rust-lang#141359 - compiler-errors:async-fn-once, r=lcnr Fix `FnOnce` impl for `AsyncFn`/`AsyncFnMut` self-borrowing closures in new solver This only affects closures that are "`AsyncFn`/`AsyncFnMut`" in their calling capability that are being called with the `FnOnce` trait. fixes rust-lang/trait-system-refactor-initiative#217 r? lcnr
2 parents d423c81 + e0f8055 commit cfe9972

File tree

3 files changed

+21
-8
lines changed

3 files changed

+21
-8
lines changed

compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<I: Intern
327327
// always be called once. It additionally implements `Fn`/`FnMut`
328328
// only if it has no upvars referencing the closure-env lifetime,
329329
// and if the closure kind permits it.
330-
if closure_kind != ty::ClosureKind::FnOnce && args.has_self_borrows() {
330+
if goal_kind != ty::ClosureKind::FnOnce && args.has_self_borrows() {
331331
return Err(NoSolution);
332332
}
333333

compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -841,16 +841,17 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
841841
return None;
842842
};
843843

844-
let (closure_def_id, found_args, by_ref_captures) = match *self_ty.kind() {
844+
let (closure_def_id, found_args, has_self_borrows) = match *self_ty.kind() {
845845
ty::Closure(def_id, args) => {
846-
(def_id, args.as_closure().sig().map_bound(|sig| sig.inputs()[0]), None)
846+
(def_id, args.as_closure().sig().map_bound(|sig| sig.inputs()[0]), false)
847847
}
848848
ty::CoroutineClosure(def_id, args) => (
849849
def_id,
850850
args.as_coroutine_closure()
851851
.coroutine_closure_sig()
852852
.map_bound(|sig| sig.tupled_inputs_ty),
853-
Some(args.as_coroutine_closure().coroutine_captures_by_ref_ty()),
853+
!args.as_coroutine_closure().tupled_upvars_ty().is_ty_var()
854+
&& args.as_coroutine_closure().has_self_borrows(),
854855
),
855856
_ => return None,
856857
};
@@ -884,10 +885,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
884885
// If the closure has captures, then perhaps the reason that the trait
885886
// is unimplemented is because async closures don't implement `Fn`/`FnMut`
886887
// if they have captures.
887-
if let Some(by_ref_captures) = by_ref_captures
888-
&& let ty::FnPtr(sig_tys, _) = by_ref_captures.kind()
889-
&& !sig_tys.skip_binder().output().is_unit()
890-
{
888+
if has_self_borrows && expected_kind != ty::ClosureKind::FnOnce {
891889
let mut err = self.dcx().create_err(AsyncClosureNotFn {
892890
span: self.tcx.def_span(closure_def_id),
893891
kind: expected_kind.as_str(),
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//@ edition:2021
2+
//@ check-pass
3+
//@ revisions: current next
4+
//@ ignore-compare-mode-next-solver (explicit revisions)
5+
//@[next] compile-flags: -Znext-solver
6+
7+
fn call_once<F>(_: impl FnOnce() -> F) {}
8+
9+
fn main() {
10+
let mut i = 0;
11+
let c = async || {
12+
i += 1;
13+
};
14+
call_once(c);
15+
}

0 commit comments

Comments
 (0)