Skip to content

Commit d780ac6

Browse files
committed
Forbid const fn within const impls
1 parent 3596a25 commit d780ac6

File tree

8 files changed

+99
-8
lines changed

8 files changed

+99
-8
lines changed

compiler/rustc_ast_passes/messages.ftl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,11 @@ ast_passes_generic_before_constraints = generic arguments must come before the f
200200
201201
ast_passes_generic_default_trailing = generic parameters with a default must be trailing
202202
203+
ast_passes_impl_fn_const =
204+
redundant `const` fn marker in const impl
205+
.parent_constness = this declares all associated functions implicitly const
206+
.label = remove the `const`
207+
203208
ast_passes_incompatible_features = `{$f1}` and `{$f2}` are incompatible, using them at the same time is not allowed
204209
.help = remove one of these features
205210

compiler/rustc_ast_passes/src/ast_validation.rs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,18 @@ impl<'a> AstValidator<'a> {
232232
}
233233
}
234234

235+
fn check_impl_fn_not_const(&self, constness: Const, parent_constness: Const) {
236+
let Const::Yes(span) = constness else {
237+
return;
238+
};
239+
240+
let Const::Yes(parent_constness) = parent_constness else {
241+
return;
242+
};
243+
244+
self.dcx().emit_err(errors::ImplFnConst { span, parent_constness });
245+
}
246+
235247
fn check_trait_fn_not_const(&self, constness: Const, parent: &TraitOrImpl) {
236248
let Const::Yes(span) = constness else {
237249
return;
@@ -1631,14 +1643,23 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
16311643
);
16321644
}
16331645

1634-
if let Some(parent @ (TraitOrImpl::Trait { .. } | TraitOrImpl::TraitImpl { .. })) =
1635-
&self.outer_trait_or_trait_impl
1636-
{
1637-
self.visibility_not_permitted(&item.vis, errors::VisibilityNotPermittedNote::TraitImpl);
1638-
if let AssocItemKind::Fn(box Fn { sig, .. }) = &item.kind {
1639-
self.check_trait_fn_not_const(sig.header.constness, parent);
1640-
self.check_async_fn_in_const_trait_or_impl(sig, parent);
1646+
match &self.outer_trait_or_trait_impl {
1647+
Some(parent @ (TraitOrImpl::Trait { .. } | TraitOrImpl::TraitImpl { .. })) => {
1648+
self.visibility_not_permitted(
1649+
&item.vis,
1650+
errors::VisibilityNotPermittedNote::TraitImpl,
1651+
);
1652+
if let AssocItemKind::Fn(box Fn { sig, .. }) = &item.kind {
1653+
self.check_trait_fn_not_const(sig.header.constness, parent);
1654+
self.check_async_fn_in_const_trait_or_impl(sig, parent);
1655+
}
1656+
}
1657+
Some(TraitOrImpl::Impl { constness }) => {
1658+
if let AssocItemKind::Fn(box Fn { sig, .. }) = &item.kind {
1659+
self.check_impl_fn_not_const(sig.header.constness, *constness);
1660+
}
16411661
}
1662+
None => {}
16421663
}
16431664

16441665
if let AssocItemKind::Const(ci) = &item.kind {

compiler/rustc_ast_passes/src/errors.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,15 @@ pub(crate) enum VisibilityNotPermittedNote {
3535
#[note(ast_passes_individual_foreign_items)]
3636
IndividualForeignItems,
3737
}
38+
#[derive(Diagnostic)]
39+
#[diag(ast_passes_impl_fn_const)]
40+
pub(crate) struct ImplFnConst {
41+
#[primary_span]
42+
#[suggestion(ast_passes_label, code = "", applicability = "machine-applicable")]
43+
pub span: Span,
44+
#[label(ast_passes_parent_constness)]
45+
pub parent_constness: Span,
46+
}
3847

3948
#[derive(Diagnostic)]
4049
#[diag(ast_passes_trait_fn_const, code = E0379)]
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//@run-rustfix
2+
3+
#![feature(const_trait_impl)]
4+
struct Foo;
5+
6+
const impl Foo {
7+
fn bar() {}
8+
fn baz() {}
9+
//~^ ERROR: redundant `const`
10+
}
11+
12+
const _: () = {
13+
Foo::bar();
14+
Foo::baz();
15+
};
16+
17+
fn main() {
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//@run-rustfix
2+
3+
#![feature(const_trait_impl)]
4+
struct Foo;
5+
6+
const impl Foo {
7+
fn bar() {}
8+
const fn baz() {}
9+
//~^ ERROR: redundant `const`
10+
}
11+
12+
const _: () = {
13+
Foo::bar();
14+
Foo::baz();
15+
};
16+
17+
fn main() {
18+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error: redundant `const` fn marker in const impl
2+
--> $DIR/const-impl-inherent-double-const.rs:8:5
3+
|
4+
LL | const impl Foo {
5+
| ----- this declares all associated functions implicitly const
6+
LL | fn bar() {}
7+
LL | const fn baz() {}
8+
| ^^^^^ help: remove the `const`
9+
10+
error: aborting due to 1 previous error
11+

tests/ui/traits/const-traits/span-bug-issue-121418.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ impl const dyn T {
77
pub const fn new() -> std::sync::Mutex<dyn T> {}
88
//~^ ERROR mismatched types
99
//~| ERROR cannot be known at compilation time
10+
//~| ERROR redundant `const` fn marker in const impl
1011
}
1112

1213
fn main() {}

tests/ui/traits/const-traits/span-bug-issue-121418.stderr

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
error: redundant `const` fn marker in const impl
2+
--> $DIR/span-bug-issue-121418.rs:7:9
3+
|
4+
LL | impl const dyn T {
5+
| ----- this declares all associated functions implicitly const
6+
LL | pub const fn new() -> std::sync::Mutex<dyn T> {}
7+
| ^^^^^ help: remove the `const`
8+
19
error[E0277]: the size for values of type `(dyn T + 'static)` cannot be known at compilation time
210
--> $DIR/span-bug-issue-121418.rs:7:27
311
|
@@ -20,7 +28,7 @@ LL | pub const fn new() -> std::sync::Mutex<dyn T> {}
2028
= note: expected struct `std::sync::Mutex<(dyn T + 'static)>`
2129
found unit type `()`
2230

23-
error: aborting due to 2 previous errors
31+
error: aborting due to 3 previous errors
2432

2533
Some errors have detailed explanations: E0277, E0308.
2634
For more information about an error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)