Skip to content

Commit 180a69b

Browse files
committed
Make diagnostics know about more coro closures than async closures
1 parent 4d818d0 commit 180a69b

File tree

5 files changed

+18
-12
lines changed

5 files changed

+18
-12
lines changed

compiler/rustc_hir/src/hir.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1893,9 +1893,7 @@ impl CoroutineKind {
18931893
CoroutineKind::Coroutine(mov) => mov,
18941894
}
18951895
}
1896-
}
18971896

1898-
impl CoroutineKind {
18991897
pub fn is_fn_like(self) -> bool {
19001898
matches!(self, CoroutineKind::Desugared(_, CoroutineSource::Fn))
19011899
}

compiler/rustc_trait_selection/messages.ftl

+2-2
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,6 @@ trait_selection_adjust_signature_remove_borrow = consider adjusting the signatur
7272
7373
trait_selection_ascribe_user_type_prove_predicate = ...so that the where clause holds
7474
75-
trait_selection_async_closure_not_fn = async closure does not implement `{$kind}` because it captures state from its environment
76-
7775
trait_selection_await_both_futures = consider `await`ing on both `Future`s
7876
trait_selection_await_future = consider `await`ing on the `Future`
7977
trait_selection_await_note = calling an async function returns a future
@@ -123,6 +121,8 @@ trait_selection_closure_kind_requirement = the requirement to implement `{$trait
123121
124122
trait_selection_compare_impl_item_obligation = ...so that the definition in impl matches the definition from the trait
125123
trait_selection_consider_specifying_length = consider specifying the actual array length
124+
trait_selection_coro_closure_not_fn = {$coro_kind}closure does not implement `{$kind}` because it captures state from its environment
125+
126126
trait_selection_data_flows = ...but data{$label_var1_exists ->
127127
[true] {" "}from `{$label_var1}`
128128
*[false] {""}

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

+12-5
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,7 @@ use super::{
3737
use crate::error_reporting::TypeErrCtxt;
3838
use crate::error_reporting::infer::TyCategory;
3939
use crate::error_reporting::traits::report_dyn_incompatibility;
40-
use crate::errors::{
41-
AsyncClosureNotFn, ClosureFnMutLabel, ClosureFnOnceLabel, ClosureKindMismatch,
42-
};
40+
use crate::errors::{ClosureFnMutLabel, ClosureFnOnceLabel, ClosureKindMismatch, CoroClosureNotFn};
4341
use crate::infer::{self, InferCtxt, InferCtxtExt as _};
4442
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
4543
use crate::traits::{
@@ -887,15 +885,24 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
887885
}
888886

889887
// If the closure has captures, then perhaps the reason that the trait
890-
// is unimplemented is because async closures don't implement `Fn`/`FnMut`
888+
// is unimplemented is because coro closures don't implement `Fn`/`FnMut`
891889
// if they have captures.
892890
if let Some(by_ref_captures) = by_ref_captures
893891
&& let ty::FnPtr(sig_tys, _) = by_ref_captures.kind()
894892
&& !sig_tys.skip_binder().output().is_unit()
895893
{
896-
let mut err = self.dcx().create_err(AsyncClosureNotFn {
894+
let coro_kind = match self
895+
.tcx
896+
.coroutine_kind(self.tcx.coroutine_for_closure(closure_def_id))
897+
.unwrap()
898+
{
899+
rustc_hir::CoroutineKind::Desugared(desugaring, _) => desugaring.to_string(),
900+
coro => coro.to_string(),
901+
};
902+
let mut err = self.dcx().create_err(CoroClosureNotFn {
897903
span: self.tcx.def_span(closure_def_id),
898904
kind: expected_kind.as_str(),
905+
coro_kind,
899906
});
900907
self.note_obligation_cause(&mut err, &obligation);
901908
return Some(err.emit());

compiler/rustc_trait_selection/src/errors.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -170,11 +170,12 @@ pub struct ClosureFnMutLabel {
170170
}
171171

172172
#[derive(Diagnostic)]
173-
#[diag(trait_selection_async_closure_not_fn)]
174-
pub(crate) struct AsyncClosureNotFn {
173+
#[diag(trait_selection_coro_closure_not_fn)]
174+
pub(crate) struct CoroClosureNotFn {
175175
#[primary_span]
176176
pub span: Span,
177177
pub kind: &'static str,
178+
pub coro_kind: String,
178179
}
179180

180181
#[derive(Diagnostic)]

tests/ui/iterators/generator_returned_from_fn.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ LL | | }
1010
LL | | } }
1111
| |_____^ returns a reference to data owned by the current function
1212

13-
error: async closure does not implement `Fn` because it captures state from its environment
13+
error: `gen` closure does not implement `Fn` because it captures state from its environment
1414
--> $DIR/generator_returned_from_fn.rs:35:13
1515
|
1616
LL | iter! { move || {

0 commit comments

Comments
 (0)