Skip to content

Commit a3d9d13

Browse files
authored
Rollup merge of rust-lang#130252 - compiler-errors:const-gen, r=chenyukang
Properly report error on `const gen fn` Fixes rust-lang#130232 Also removes some (what I thought were unused) functions, and fixes a bug in clippy where we considered `gen fn` to be the same as `fn` because it was only built to consider asyncness.
2 parents 57020e0 + 8dc2278 commit a3d9d13

File tree

7 files changed

+66
-28
lines changed

7 files changed

+66
-28
lines changed

Diff for: compiler/rustc_ast/src/ast.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -2602,12 +2602,12 @@ impl CoroutineKind {
26022602
}
26032603
}
26042604

2605-
pub fn is_async(self) -> bool {
2606-
matches!(self, CoroutineKind::Async { .. })
2607-
}
2608-
2609-
pub fn is_gen(self) -> bool {
2610-
matches!(self, CoroutineKind::Gen { .. })
2605+
pub fn as_str(self) -> &'static str {
2606+
match self {
2607+
CoroutineKind::Async { .. } => "async",
2608+
CoroutineKind::Gen { .. } => "gen",
2609+
CoroutineKind::AsyncGen { .. } => "async gen",
2610+
}
26112611
}
26122612

26132613
pub fn closure_id(self) -> NodeId {

Diff for: compiler/rustc_ast_passes/messages.ftl

+5-5
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,15 @@ ast_passes_body_in_extern = incorrect `{$kind}` inside `extern` block
4040
4141
ast_passes_bound_in_context = bounds on `type`s in {$ctx} have no effect
4242
43-
ast_passes_const_and_async = functions cannot be both `const` and `async`
44-
.const = `const` because of this
45-
.async = `async` because of this
46-
.label = {""}
47-
4843
ast_passes_const_and_c_variadic = functions cannot be both `const` and C-variadic
4944
.const = `const` because of this
5045
.variadic = C-variadic because of this
5146
47+
ast_passes_const_and_coroutine = functions cannot be both `const` and `{$coroutine_kind}`
48+
.const = `const` because of this
49+
.coroutine = `{$coroutine_kind}` because of this
50+
.label = {""}
51+
5252
ast_passes_const_bound_trait_object = const trait bounds are not allowed in trait object types
5353
5454
ast_passes_const_without_body =

Diff for: compiler/rustc_ast_passes/src/ast_validation.rs

+6-11
Original file line numberDiff line numberDiff line change
@@ -1418,21 +1418,16 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
14181418

14191419
// Functions cannot both be `const async` or `const gen`
14201420
if let Some(&FnHeader {
1421-
constness: Const::Yes(cspan),
1421+
constness: Const::Yes(const_span),
14221422
coroutine_kind: Some(coroutine_kind),
14231423
..
14241424
}) = fk.header()
14251425
{
1426-
let aspan = match coroutine_kind {
1427-
CoroutineKind::Async { span: aspan, .. }
1428-
| CoroutineKind::Gen { span: aspan, .. }
1429-
| CoroutineKind::AsyncGen { span: aspan, .. } => aspan,
1430-
};
1431-
// FIXME(gen_blocks): Report a different error for `const gen`
1432-
self.dcx().emit_err(errors::ConstAndAsync {
1433-
spans: vec![cspan, aspan],
1434-
cspan,
1435-
aspan,
1426+
self.dcx().emit_err(errors::ConstAndCoroutine {
1427+
spans: vec![coroutine_kind.span(), const_span],
1428+
const_span,
1429+
coroutine_span: coroutine_kind.span(),
1430+
coroutine_kind: coroutine_kind.as_str(),
14361431
span,
14371432
});
14381433
}

Diff for: compiler/rustc_ast_passes/src/errors.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -657,16 +657,17 @@ pub(crate) enum TildeConstReason {
657657
}
658658

659659
#[derive(Diagnostic)]
660-
#[diag(ast_passes_const_and_async)]
661-
pub(crate) struct ConstAndAsync {
660+
#[diag(ast_passes_const_and_coroutine)]
661+
pub(crate) struct ConstAndCoroutine {
662662
#[primary_span]
663663
pub spans: Vec<Span>,
664664
#[label(ast_passes_const)]
665-
pub cspan: Span,
666-
#[label(ast_passes_async)]
667-
pub aspan: Span,
665+
pub const_span: Span,
666+
#[label(ast_passes_coroutine)]
667+
pub coroutine_span: Span,
668668
#[label]
669669
pub span: Span,
670+
pub coroutine_kind: &'static str,
670671
}
671672

672673
#[derive(Diagnostic)]

Diff for: src/tools/clippy/clippy_utils/src/ast_utils.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
221221
) => {
222222
eq_closure_binder(lb, rb)
223223
&& lc == rc
224-
&& la.map_or(false, CoroutineKind::is_async) == ra.map_or(false, CoroutineKind::is_async)
224+
&& eq_coroutine_kind(*la, *ra)
225225
&& lm == rm
226226
&& eq_fn_decl(lf, rf)
227227
&& eq_expr(le, re)
@@ -241,6 +241,16 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
241241
}
242242
}
243243

244+
fn eq_coroutine_kind(a: Option<CoroutineKind>, b: Option<CoroutineKind>) -> bool {
245+
match (a, b) {
246+
(Some(CoroutineKind::Async { .. }), Some(CoroutineKind::Async { .. }))
247+
| (Some(CoroutineKind::Gen { .. }), Some(CoroutineKind::Gen { .. }))
248+
| (Some(CoroutineKind::AsyncGen { .. }), Some(CoroutineKind::AsyncGen { .. }))
249+
| (None, None) => true,
250+
_ => false,
251+
}
252+
}
253+
244254
pub fn eq_field(l: &ExprField, r: &ExprField) -> bool {
245255
l.is_placeholder == r.is_placeholder
246256
&& eq_id(l.ident, r.ident)

Diff for: tests/ui/coroutine/const_gen_fn.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//@ edition:2024
2+
//@ compile-flags: -Zunstable-options
3+
4+
#![feature(gen_blocks)]
5+
6+
const gen fn a() {}
7+
//~^ ERROR functions cannot be both `const` and `gen`
8+
9+
const async gen fn b() {}
10+
//~^ ERROR functions cannot be both `const` and `async gen`
11+
12+
fn main() {}

Diff for: tests/ui/coroutine/const_gen_fn.stderr

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error: functions cannot be both `const` and `gen`
2+
--> $DIR/const_gen_fn.rs:6:1
3+
|
4+
LL | const gen fn a() {}
5+
| ^^^^^-^^^----------
6+
| | |
7+
| | `gen` because of this
8+
| `const` because of this
9+
10+
error: functions cannot be both `const` and `async gen`
11+
--> $DIR/const_gen_fn.rs:9:1
12+
|
13+
LL | const async gen fn b() {}
14+
| ^^^^^-^^^^^^^^^----------
15+
| | |
16+
| | `async gen` because of this
17+
| `const` because of this
18+
19+
error: aborting due to 2 previous errors
20+

0 commit comments

Comments
 (0)