about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_const_eval/src/const_eval/fn_queries.rs1
-rw-r--r--compiler/rustc_const_eval/src/lib.rs1
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs14
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs2
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs2
-rw-r--r--compiler/rustc_middle/src/traits/select.rs4
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs11
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs27
10 files changed, 50 insertions, 20 deletions
diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
index f1674d04f8d..351c701305a 100644
--- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
@@ -41,6 +41,7 @@ fn constness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Constness {
             };
             if is_const { hir::Constness::Const } else { hir::Constness::NotConst }
         }
+        hir::Node::Expr(e) if let hir::ExprKind::Closure(c) = e.kind => c.constness,
         _ => {
             if let Some(fn_kind) = node.fn_kind() {
                 if fn_kind.constness() == hir::Constness::Const {
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index 443c01fdb90..46e7b09a55e 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -20,6 +20,7 @@ Rust MIR: a lowered representation of Rust.
 #![feature(trusted_step)]
 #![feature(try_blocks)]
 #![feature(yeet_expr)]
+#![feature(if_let_guard)]
 #![feature(is_some_and)]
 #![recursion_limit = "256"]
 
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index fd166e3c938..38212496ec8 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -783,6 +783,20 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                             );
                             return;
                         }
+                        Ok(Some(ImplSource::Closure(data))) => {
+                            if !tcx.is_const_fn_raw(data.closure_def_id) {
+                                self.check_op(ops::FnCallNonConst {
+                                    caller,
+                                    callee,
+                                    substs,
+                                    span: *fn_span,
+                                    from_hir_call: *from_hir_call,
+                                    feature: None,
+                                });
+
+                                return;
+                            }
+                        }
                         Ok(Some(ImplSource::UserDefined(data))) => {
                             let callee_name = tcx.item_name(callee);
                             if let Some(&did) = tcx
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index bdc4ae391f0..030328d1e26 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1686,6 +1686,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             }
 
             ty::Closure(_, substs) => {
+                let constness = self.tcx.constness(def_id.to_def_id());
+                self.tables.constness.set(def_id.to_def_id().index, constness);
                 record!(self.tables.fn_sig[def_id.to_def_id()] <- substs.as_closure().sig());
             }
 
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 883554f959c..4b09a9b6939 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -485,7 +485,7 @@ impl<'hir> Map<'hir> {
             BodyOwnerKind::Static(mt) => ConstContext::Static(mt),
 
             BodyOwnerKind::Fn if self.tcx.is_constructor(def_id.to_def_id()) => return None,
-            BodyOwnerKind::Fn if self.tcx.is_const_fn_raw(def_id.to_def_id()) => {
+            BodyOwnerKind::Fn | BodyOwnerKind::Closure if self.tcx.is_const_fn_raw(def_id.to_def_id()) => {
                 ConstContext::ConstFn
             }
             BodyOwnerKind::Fn if self.tcx.is_const_default_method(def_id.to_def_id()) => {
diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs
index ec69864c951..1cc9fd526b4 100644
--- a/compiler/rustc_middle/src/traits/select.rs
+++ b/compiler/rustc_middle/src/traits/select.rs
@@ -131,7 +131,9 @@ pub enum SelectionCandidate<'tcx> {
 
     /// Implementation of a `Fn`-family trait by one of the anonymous types
     /// generated for an `||` expression.
-    ClosureCandidate,
+    ClosureCandidate {
+        is_const: bool,
+    },
 
     /// Implementation of a `Generator` trait by one of the anonymous types
     /// generated for a generator.
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index fa571d480b6..993e95b3514 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -2465,8 +2465,10 @@ impl<'tcx> TyCtxt<'tcx> {
 
     #[inline]
     pub fn is_const_fn_raw(self, def_id: DefId) -> bool {
-        matches!(self.def_kind(def_id), DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(..))
-            && self.constness(def_id) == hir::Constness::Const
+        matches!(
+            self.def_kind(def_id),
+            DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(..) | DefKind::Closure
+        ) && self.constness(def_id) == hir::Constness::Const
     }
 
     #[inline]
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index c54d901e9b1..a5635ccfec4 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -254,18 +254,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         // touch bound regions, they just capture the in-scope
         // type/region parameters
         match *obligation.self_ty().skip_binder().kind() {
-            ty::Closure(_, closure_substs) => {
+            ty::Closure(def_id, closure_substs) => {
+                let is_const = self.tcx().is_const_fn_raw(def_id);
                 debug!(?kind, ?obligation, "assemble_unboxed_candidates");
                 match self.infcx.closure_kind(closure_substs) {
                     Some(closure_kind) => {
                         debug!(?closure_kind, "assemble_unboxed_candidates");
                         if closure_kind.extends(kind) {
-                            candidates.vec.push(ClosureCandidate);
+                            candidates.vec.push(ClosureCandidate {
+                                is_const,
+                            });
                         }
                     }
                     None => {
                         debug!("assemble_unboxed_candidates: closure_kind not yet known");
-                        candidates.vec.push(ClosureCandidate);
+                        candidates.vec.push(ClosureCandidate {
+                            is_const,
+                        });
                     }
                 }
             }
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 15526b34ed2..a41d10f1043 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -84,7 +84,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 ImplSource::Object(data)
             }
 
-            ClosureCandidate => {
+            ClosureCandidate { .. } => {
                 let vtable_closure = self.confirm_closure_candidate(obligation)?;
                 ImplSource::Closure(vtable_closure)
             }
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 3f14491f803..25a294b5401 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -1365,15 +1365,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     // const param
                     ParamCandidate(trait_pred) if trait_pred.is_const_if_const() => {}
                     // const projection
-                    ProjectionCandidate(_, ty::BoundConstness::ConstIfConst) => {}
+                    ProjectionCandidate(_, ty::BoundConstness::ConstIfConst)
                     // auto trait impl
-                    AutoImplCandidate => {}
+                    | AutoImplCandidate
                     // generator / future, this will raise error in other places
                     // or ignore error with const_async_blocks feature
-                    GeneratorCandidate => {}
-                    FutureCandidate => {}
+                    | GeneratorCandidate
+                    | FutureCandidate
                     // FnDef where the function is const
-                    FnPointerCandidate { is_const: true } => {}
+                    | FnPointerCandidate { is_const: true }
+                    | ConstDestructCandidate(_)
+                    | ClosureCandidate { is_const: true } => {}
+
                     FnPointerCandidate { is_const: false } => {
                         if let ty::FnDef(def_id, _) = obligation.self_ty().skip_binder().kind() && tcx.trait_of_item(*def_id).is_some() {
                             // Trait methods are not seen as const unless the trait is implemented as const.
@@ -1382,7 +1385,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                             continue
                         }
                     }
-                    ConstDestructCandidate(_) => {}
+
                     _ => {
                         // reject all other types of candidates
                         continue;
@@ -1844,7 +1847,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             (
                 ParamCandidate(ref cand),
                 ImplCandidate(..)
-                | ClosureCandidate
+                | ClosureCandidate { .. }
                 | GeneratorCandidate
                 | FutureCandidate
                 | FnPointerCandidate { .. }
@@ -1863,7 +1866,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             }
             (
                 ImplCandidate(_)
-                | ClosureCandidate
+                | ClosureCandidate { .. }
                 | GeneratorCandidate
                 | FutureCandidate
                 | FnPointerCandidate { .. }
@@ -1894,7 +1897,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             (
                 ObjectCandidate(_) | ProjectionCandidate(..),
                 ImplCandidate(..)
-                | ClosureCandidate
+                | ClosureCandidate { .. }
                 | GeneratorCandidate
                 | FutureCandidate
                 | FnPointerCandidate { .. }
@@ -1907,7 +1910,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
             (
                 ImplCandidate(..)
-                | ClosureCandidate
+                | ClosureCandidate { .. }
                 | GeneratorCandidate
                 | FutureCandidate
                 | FnPointerCandidate { .. }
@@ -1989,7 +1992,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             // Everything else is ambiguous
             (
                 ImplCandidate(_)
-                | ClosureCandidate
+                | ClosureCandidate { .. }
                 | GeneratorCandidate
                 | FutureCandidate
                 | FnPointerCandidate { .. }
@@ -1999,7 +2002,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 | BuiltinCandidate { has_nested: true }
                 | TraitAliasCandidate,
                 ImplCandidate(_)
-                | ClosureCandidate
+                | ClosureCandidate { .. }
                 | GeneratorCandidate
                 | FutureCandidate
                 | FnPointerCandidate { .. }