Skip to content

Commit

Permalink
Unrolled build for rust-lang#130252
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
rust-timer authored Sep 12, 2024
2 parents f753bc7 + 8dc2278 commit 69e95e2
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 28 deletions.
12 changes: 6 additions & 6 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2602,12 +2602,12 @@ impl CoroutineKind {
}
}

pub fn is_async(self) -> bool {
matches!(self, CoroutineKind::Async { .. })
}

pub fn is_gen(self) -> bool {
matches!(self, CoroutineKind::Gen { .. })
pub fn as_str(self) -> &'static str {
match self {
CoroutineKind::Async { .. } => "async",
CoroutineKind::Gen { .. } => "gen",
CoroutineKind::AsyncGen { .. } => "async gen",
}
}

pub fn closure_id(self) -> NodeId {
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_ast_passes/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -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_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
.const = `const` 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_without_body =
Expand Down
17 changes: 6 additions & 11 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1418,21 +1418,16 @@ impl<'a> Visitor<'a> for AstValidator<'a> {

// Functions cannot both be `const async` or `const gen`
if let Some(&FnHeader {
constness: Const::Yes(cspan),
constness: Const::Yes(const_span),
coroutine_kind: Some(coroutine_kind),
..
}) = fk.header()
{
let aspan = match coroutine_kind {
CoroutineKind::Async { span: aspan, .. }
| CoroutineKind::Gen { span: aspan, .. }
| CoroutineKind::AsyncGen { span: aspan, .. } => aspan,
};
// FIXME(gen_blocks): Report a different error for `const gen`
self.dcx().emit_err(errors::ConstAndAsync {
spans: vec![cspan, aspan],
cspan,
aspan,
self.dcx().emit_err(errors::ConstAndCoroutine {
spans: vec![coroutine_kind.span(), const_span],
const_span,
coroutine_span: coroutine_kind.span(),
coroutine_kind: coroutine_kind.as_str(),
span,
});
}
Expand Down
11 changes: 6 additions & 5 deletions compiler/rustc_ast_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -657,16 +657,17 @@ pub(crate) enum TildeConstReason {
}

#[derive(Diagnostic)]
#[diag(ast_passes_const_and_async)]
pub(crate) struct ConstAndAsync {
#[diag(ast_passes_const_and_coroutine)]
pub(crate) struct ConstAndCoroutine {
#[primary_span]
pub spans: Vec<Span>,
#[label(ast_passes_const)]
pub cspan: Span,
#[label(ast_passes_async)]
pub aspan: Span,
pub const_span: Span,
#[label(ast_passes_coroutine)]
pub coroutine_span: Span,
#[label]
pub span: Span,
pub coroutine_kind: &'static str,
}

#[derive(Diagnostic)]
Expand Down
12 changes: 11 additions & 1 deletion src/tools/clippy/clippy_utils/src/ast_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
) => {
eq_closure_binder(lb, rb)
&& lc == rc
&& la.map_or(false, CoroutineKind::is_async) == ra.map_or(false, CoroutineKind::is_async)
&& eq_coroutine_kind(*la, *ra)
&& lm == rm
&& eq_fn_decl(lf, rf)
&& eq_expr(le, re)
Expand All @@ -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 {
l.is_placeholder == r.is_placeholder
&& eq_id(l.ident, r.ident)
Expand Down
12 changes: 12 additions & 0 deletions tests/ui/coroutine/const_gen_fn.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 20 additions & 0 deletions tests/ui/coroutine/const_gen_fn.stderr
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 69e95e2

Please sign in to comment.