about summary refs log tree commit diff
path: root/compiler/rustc_middle/src
diff options
context:
space:
mode:
authorlcnr <rust@lcnr.de>2022-10-18 16:31:56 +0200
committerlcnr <rust@lcnr.de>2022-10-18 16:31:56 +0200
commit116d35d401b52add75bcef8edd698f72855ed3c3 (patch)
treedfdfb61cd71fe7cbfbc6fbf2efa6692b8a53fa9b /compiler/rustc_middle/src
parent660ca4804175e6220a2284b8e7441aacf10367dd (diff)
downloadrust-116d35d401b52add75bcef8edd698f72855ed3c3.tar.gz
rust-116d35d401b52add75bcef8edd698f72855ed3c3.zip
`const_evaluatable_unchecked` to const eval
Diffstat (limited to 'compiler/rustc_middle/src')
-rw-r--r--compiler/rustc_middle/src/lib.rs1
-rw-r--r--compiler/rustc_middle/src/mir/interpret/queries.rs26
2 files changed, 26 insertions, 1 deletions
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index 45c84680ad2..a58cbc3767e 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -55,6 +55,7 @@
 #![feature(drain_filter)]
 #![feature(intra_doc_pointers)]
 #![feature(yeet_expr)]
+#![feature(result_option_inspect)]
 #![feature(const_option)]
 #![recursion_limit = "512"]
 #![allow(rustc::potential_query_instability)]
diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs
index 8f67161420d..1358425b259 100644
--- a/compiler/rustc_middle/src/mir/interpret/queries.rs
+++ b/compiler/rustc_middle/src/mir/interpret/queries.rs
@@ -4,7 +4,9 @@ use crate::mir;
 use crate::ty::subst::InternalSubsts;
 use crate::ty::visit::TypeVisitable;
 use crate::ty::{self, query::TyCtxtAt, query::TyCtxtEnsure, TyCtxt};
+use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
+use rustc_session::lint;
 use rustc_span::{Span, DUMMY_SP};
 
 impl<'tcx> TyCtxt<'tcx> {
@@ -83,7 +85,29 @@ impl<'tcx> TyCtxt<'tcx> {
         match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs) {
             Ok(Some(instance)) => {
                 let cid = GlobalId { instance, promoted: None };
-                self.const_eval_global_id_for_typeck(param_env, cid, span)
+                self.const_eval_global_id_for_typeck(param_env, cid, span).inspect(|_| {
+                    // We are emitting the lint here instead of in `is_const_evaluatable`
+                    // as we normalize obligations before checking them, and normalization
+                    // uses this function to evaluate this constant.
+                    //
+                    // @lcnr believes that successfully evaluating even though there are
+                    // used generic parameters is a bug of evaluation, so checking for it
+                    // here does feel somewhat sensible.
+                    if !self.features().generic_const_exprs && ct.substs.has_non_region_param() {
+                        assert!(matches!(self.def_kind(ct.def.did), DefKind::AnonConst));
+                        let mir_body = self.mir_for_ctfe_opt_const_arg(ct.def);
+                        if mir_body.is_polymorphic {
+                            let Some(local_def_id) = ct.def.did.as_local() else { return };
+                            self.struct_span_lint_hir(
+                                lint::builtin::CONST_EVALUATABLE_UNCHECKED,
+                                self.hir().local_def_id_to_hir_id(local_def_id),
+                                self.def_span(ct.def.did),
+                                "cannot use constants which depend on generic parameters in types",
+                                |err| err,
+                            )
+                        }
+                    }
+                })
             }
             Ok(None) => Err(ErrorHandled::TooGeneric),
             Err(error_reported) => Err(ErrorHandled::Reported(error_reported)),