Rollup merge of #130252 - compiler-errors:const-gen, r=chenyukang
Properly report error on `const gen fn` Fixes #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.
This commit is contained in:
commit
a3d9d13d7a
7 changed files with 66 additions and 28 deletions
|
@ -2602,12 +2602,12 @@ impl CoroutineKind {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_async(self) -> bool {
|
pub fn as_str(self) -> &'static str {
|
||||||
matches!(self, CoroutineKind::Async { .. })
|
match self {
|
||||||
}
|
CoroutineKind::Async { .. } => "async",
|
||||||
|
CoroutineKind::Gen { .. } => "gen",
|
||||||
pub fn is_gen(self) -> bool {
|
CoroutineKind::AsyncGen { .. } => "async gen",
|
||||||
matches!(self, CoroutineKind::Gen { .. })
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn closure_id(self) -> NodeId {
|
pub fn closure_id(self) -> NodeId {
|
||||||
|
|
|
@ -40,15 +40,15 @@ ast_passes_body_in_extern = incorrect `{$kind}` inside `extern` block
|
||||||
|
|
||||||
ast_passes_bound_in_context = bounds on `type`s in {$ctx} have no effect
|
ast_passes_bound_in_context = bounds on `type`s in {$ctx} have no effect
|
||||||
|
|
||||||
ast_passes_const_and_async = functions cannot be both `const` and `async`
|
|
||||||
.const = `const` because of this
|
|
||||||
.async = `async` because of this
|
|
||||||
.label = {""}
|
|
||||||
|
|
||||||
ast_passes_const_and_c_variadic = functions cannot be both `const` and C-variadic
|
ast_passes_const_and_c_variadic = functions cannot be both `const` and C-variadic
|
||||||
.const = `const` because of this
|
.const = `const` because of this
|
||||||
.variadic = C-variadic because of this
|
.variadic = C-variadic because of this
|
||||||
|
|
||||||
|
ast_passes_const_and_coroutine = functions cannot be both `const` and `{$coroutine_kind}`
|
||||||
|
.const = `const` because of this
|
||||||
|
.coroutine = `{$coroutine_kind}` because of this
|
||||||
|
.label = {""}
|
||||||
|
|
||||||
ast_passes_const_bound_trait_object = const trait bounds are not allowed in trait object types
|
ast_passes_const_bound_trait_object = const trait bounds are not allowed in trait object types
|
||||||
|
|
||||||
ast_passes_const_without_body =
|
ast_passes_const_without_body =
|
||||||
|
|
|
@ -1418,21 +1418,16 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
|
|
||||||
// Functions cannot both be `const async` or `const gen`
|
// Functions cannot both be `const async` or `const gen`
|
||||||
if let Some(&FnHeader {
|
if let Some(&FnHeader {
|
||||||
constness: Const::Yes(cspan),
|
constness: Const::Yes(const_span),
|
||||||
coroutine_kind: Some(coroutine_kind),
|
coroutine_kind: Some(coroutine_kind),
|
||||||
..
|
..
|
||||||
}) = fk.header()
|
}) = fk.header()
|
||||||
{
|
{
|
||||||
let aspan = match coroutine_kind {
|
self.dcx().emit_err(errors::ConstAndCoroutine {
|
||||||
CoroutineKind::Async { span: aspan, .. }
|
spans: vec![coroutine_kind.span(), const_span],
|
||||||
| CoroutineKind::Gen { span: aspan, .. }
|
const_span,
|
||||||
| CoroutineKind::AsyncGen { span: aspan, .. } => aspan,
|
coroutine_span: coroutine_kind.span(),
|
||||||
};
|
coroutine_kind: coroutine_kind.as_str(),
|
||||||
// FIXME(gen_blocks): Report a different error for `const gen`
|
|
||||||
self.dcx().emit_err(errors::ConstAndAsync {
|
|
||||||
spans: vec![cspan, aspan],
|
|
||||||
cspan,
|
|
||||||
aspan,
|
|
||||||
span,
|
span,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -657,16 +657,17 @@ pub(crate) enum TildeConstReason {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_const_and_async)]
|
#[diag(ast_passes_const_and_coroutine)]
|
||||||
pub(crate) struct ConstAndAsync {
|
pub(crate) struct ConstAndCoroutine {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub spans: Vec<Span>,
|
pub spans: Vec<Span>,
|
||||||
#[label(ast_passes_const)]
|
#[label(ast_passes_const)]
|
||||||
pub cspan: Span,
|
pub const_span: Span,
|
||||||
#[label(ast_passes_async)]
|
#[label(ast_passes_coroutine)]
|
||||||
pub aspan: Span,
|
pub coroutine_span: Span,
|
||||||
#[label]
|
#[label]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
pub coroutine_kind: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
|
|
|
@ -221,7 +221,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
|
||||||
) => {
|
) => {
|
||||||
eq_closure_binder(lb, rb)
|
eq_closure_binder(lb, rb)
|
||||||
&& lc == rc
|
&& lc == rc
|
||||||
&& la.map_or(false, CoroutineKind::is_async) == ra.map_or(false, CoroutineKind::is_async)
|
&& eq_coroutine_kind(*la, *ra)
|
||||||
&& lm == rm
|
&& lm == rm
|
||||||
&& eq_fn_decl(lf, rf)
|
&& eq_fn_decl(lf, rf)
|
||||||
&& eq_expr(le, re)
|
&& eq_expr(le, re)
|
||||||
|
@ -241,6 +241,16 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn eq_coroutine_kind(a: Option<CoroutineKind>, b: Option<CoroutineKind>) -> bool {
|
||||||
|
match (a, b) {
|
||||||
|
(Some(CoroutineKind::Async { .. }), Some(CoroutineKind::Async { .. }))
|
||||||
|
| (Some(CoroutineKind::Gen { .. }), Some(CoroutineKind::Gen { .. }))
|
||||||
|
| (Some(CoroutineKind::AsyncGen { .. }), Some(CoroutineKind::AsyncGen { .. }))
|
||||||
|
| (None, None) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn eq_field(l: &ExprField, r: &ExprField) -> bool {
|
pub fn eq_field(l: &ExprField, r: &ExprField) -> bool {
|
||||||
l.is_placeholder == r.is_placeholder
|
l.is_placeholder == r.is_placeholder
|
||||||
&& eq_id(l.ident, r.ident)
|
&& eq_id(l.ident, r.ident)
|
||||||
|
|
12
tests/ui/coroutine/const_gen_fn.rs
Normal file
12
tests/ui/coroutine/const_gen_fn.rs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
//@ edition:2024
|
||||||
|
//@ compile-flags: -Zunstable-options
|
||||||
|
|
||||||
|
#![feature(gen_blocks)]
|
||||||
|
|
||||||
|
const gen fn a() {}
|
||||||
|
//~^ ERROR functions cannot be both `const` and `gen`
|
||||||
|
|
||||||
|
const async gen fn b() {}
|
||||||
|
//~^ ERROR functions cannot be both `const` and `async gen`
|
||||||
|
|
||||||
|
fn main() {}
|
20
tests/ui/coroutine/const_gen_fn.stderr
Normal file
20
tests/ui/coroutine/const_gen_fn.stderr
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
error: functions cannot be both `const` and `gen`
|
||||||
|
--> $DIR/const_gen_fn.rs:6:1
|
||||||
|
|
|
||||||
|
LL | const gen fn a() {}
|
||||||
|
| ^^^^^-^^^----------
|
||||||
|
| | |
|
||||||
|
| | `gen` because of this
|
||||||
|
| `const` because of this
|
||||||
|
|
||||||
|
error: functions cannot be both `const` and `async gen`
|
||||||
|
--> $DIR/const_gen_fn.rs:9:1
|
||||||
|
|
|
||||||
|
LL | const async gen fn b() {}
|
||||||
|
| ^^^^^-^^^^^^^^^----------
|
||||||
|
| | |
|
||||||
|
| | `async gen` because of this
|
||||||
|
| `const` because of this
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue