about summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src/transform
diff options
context:
space:
mode:
authorDeadbeef <ent3rm4n@gmail.com>2021-12-29 17:05:54 +0800
committerDeadbeef <ent3rm4n@gmail.com>2022-02-12 19:24:43 +1100
commitd3acb9d00e64d68d8c91c9d9925b92cd79b33379 (patch)
tree44891fbd41e701febd1ffab7efb41a9a3891d870 /compiler/rustc_const_eval/src/transform
parent6d6314f878bf489e15293498ecb4af082c8d53d8 (diff)
downloadrust-d3acb9d00e64d68d8c91c9d9925b92cd79b33379.tar.gz
rust-d3acb9d00e64d68d8c91c9d9925b92cd79b33379.zip
Handle Fn family trait call errror
Diffstat (limited to 'compiler/rustc_const_eval/src/transform')
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/ops.rs41
1 files changed, 39 insertions, 2 deletions
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
index 237201c5478..519b4c02b61 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
@@ -8,7 +8,9 @@ use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
 use rustc_middle::mir;
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
-use rustc_middle::ty::{suggest_constraining_type_param, Adt, Param, TraitPredicate, Ty};
+use rustc_middle::ty::{
+    suggest_constraining_type_param, Adt, Closure, FnDef, FnPtr, Param, TraitPredicate, Ty,
+};
 use rustc_middle::ty::{Binder, BoundConstness, ImplPolarity, TraitRef};
 use rustc_session::parse::feature_err;
 use rustc_span::symbol::sym;
@@ -155,7 +157,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
             CallKind::Normal { desugaring: Some((kind, self_ty)), .. } => {
                 macro_rules! error {
                     ($fmt:literal) => {
-                        struct_span_err!(tcx.sess, span, E0015, $fmt, self_ty, ccx.const_kind(),)
+                        struct_span_err!(tcx.sess, span, E0015, $fmt, self_ty, ccx.const_kind())
                     };
                 }
 
@@ -176,6 +178,41 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
 
                 diag_trait(err, self_ty, kind.trait_def_id(tcx))
             }
+            CallKind::FnCall { fn_trait_id, self_ty } => {
+                let mut err = struct_span_err!(
+                    tcx.sess,
+                    span,
+                    E0015,
+                    "cannot call non-const closure in {}s",
+                    ccx.const_kind(),
+                );
+
+                match self_ty.kind() {
+                    FnDef(def_id, ..) => {
+                        let span = tcx.sess.source_map().guess_head_span(tcx.def_span(*def_id));
+                        if ccx.tcx.is_const_fn_raw(*def_id) {
+                            span_bug!(span, "calling const FnDef errored when it shouldn't");
+                        }
+
+                        err.span_note(span, "function defined here, but it is not `const`");
+                    }
+                    FnPtr(..) => {
+                        err.note(&format!(
+                            "function pointers need an RFC before allowed to be called in {}s",
+                            ccx.const_kind()
+                        ));
+                    }
+                    Closure(..) => {
+                        err.note(&format!(
+                            "closures need an RFC before allowed to be called in {}s",
+                            ccx.const_kind()
+                        ));
+                    }
+                    _ => {}
+                }
+
+                diag_trait(err, self_ty, fn_trait_id)
+            }
             CallKind::Operator { trait_id, self_ty, .. } => {
                 let mut err = struct_span_err!(
                     tcx.sess,