diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index 6a7850999831..4cc0ab630416 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -319,7 +319,17 @@ pub fn hir_body_const_context(self, local_def_id: LocalDefId) -> Option return None, // Const closures use their parent's const context BodyOwnerKind::Closure if self.is_const_fn(def_id) => { - return self.hir_body_const_context(self.local_parent(local_def_id)); + return Some( + self.hir_body_const_context(self.local_parent(local_def_id)).unwrap_or_else( + || { + assert!( + self.dcx().has_errors().is_some(), + "`const` closure with no enclosing const context", + ); + ConstContext::ConstFn + }, + ), + ); } BodyOwnerKind::Fn if self.is_const_fn(def_id) => ConstContext::ConstFn, BodyOwnerKind::Fn | BodyOwnerKind::Closure | BodyOwnerKind::GlobalAsm => return None, diff --git a/tests/ui/traits/const-traits/const-closure-in-non-const-trait-impl-method.rs b/tests/ui/traits/const-traits/const-closure-in-non-const-trait-impl-method.rs new file mode 100644 index 000000000000..b538c4b6a32f --- /dev/null +++ b/tests/ui/traits/const-traits/const-closure-in-non-const-trait-impl-method.rs @@ -0,0 +1,17 @@ +#![feature(const_trait_impl)] +#![feature(const_closures)] + +// Regression test for https://github.com/rust-lang/rust/issues/153891 + +const trait Foo { + fn test() -> impl [const] Fn(); +} + +impl Foo for &mut T { + const fn test() -> impl [const] Fn() { + //~^ ERROR functions in trait impls cannot be declared const + const move || {} + } +} + +fn main() {} diff --git a/tests/ui/traits/const-traits/const-closure-in-non-const-trait-impl-method.stderr b/tests/ui/traits/const-traits/const-closure-in-non-const-trait-impl-method.stderr new file mode 100644 index 000000000000..3ff5578748d2 --- /dev/null +++ b/tests/ui/traits/const-traits/const-closure-in-non-const-trait-impl-method.stderr @@ -0,0 +1,19 @@ +error[E0379]: functions in trait impls cannot be declared const + --> $DIR/const-closure-in-non-const-trait-impl-method.rs:11:5 + | +LL | const fn test() -> impl [const] Fn() { + | ^^^^^ functions in trait impls cannot be const + | +help: remove the `const` ... + | +LL - const fn test() -> impl [const] Fn() { +LL + fn test() -> impl [const] Fn() { + | +help: ... and declare the impl to be const instead + | +LL | impl const Foo for &mut T { + | +++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0379`. diff --git a/tests/ui/traits/const-traits/const-closure-in-non-const-trait-method.rs b/tests/ui/traits/const-traits/const-closure-in-non-const-trait-method.rs new file mode 100644 index 000000000000..dfd079318087 --- /dev/null +++ b/tests/ui/traits/const-traits/const-closure-in-non-const-trait-method.rs @@ -0,0 +1,12 @@ +#![feature(const_closures)] + +// Regression test for https://github.com/rust-lang/rust/issues/153891 + +trait Tr { + const fn test() { + //~^ ERROR functions in traits cannot be declared const + (const || {})() + } +} + +fn main() {} diff --git a/tests/ui/traits/const-traits/const-closure-in-non-const-trait-method.stderr b/tests/ui/traits/const-traits/const-closure-in-non-const-trait-method.stderr new file mode 100644 index 000000000000..79462f620da3 --- /dev/null +++ b/tests/ui/traits/const-traits/const-closure-in-non-const-trait-method.stderr @@ -0,0 +1,12 @@ +error[E0379]: functions in traits cannot be declared const + --> $DIR/const-closure-in-non-const-trait-method.rs:6:5 + | +LL | const fn test() { + | ^^^^^- + | | + | functions in traits cannot be const + | help: remove the `const` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0379`.