about summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_const_eval/src')
-rw-r--r--compiler/rustc_const_eval/src/check_consts/check.rs29
-rw-r--r--compiler/rustc_const_eval/src/check_consts/ops.rs11
2 files changed, 22 insertions, 18 deletions
diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs
index 779de61edc3..303c490d827 100644
--- a/compiler/rustc_const_eval/src/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/check_consts/check.rs
@@ -363,7 +363,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
     }
 
     fn revalidate_conditional_constness(
-        &self,
+        &mut self,
         callee: DefId,
         callee_args: ty::GenericArgsRef<'tcx>,
         call_source: CallSource,
@@ -374,11 +374,24 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
             return;
         }
 
+        let const_conditions = tcx.const_conditions(callee).instantiate(tcx, callee_args);
+        // If there are any const conditions on this fn and `const_trait_impl`
+        // is not enabled, simply bail. We shouldn't be able to call conditionally
+        // const functions on stable.
+        if !const_conditions.is_empty() && !tcx.features().const_trait_impl() {
+            self.check_op(ops::FnCallNonConst {
+                callee,
+                args: callee_args,
+                span: call_span,
+                call_source,
+                feature: Some(sym::const_trait_impl),
+            });
+            return;
+        }
+
         let infcx = tcx.infer_ctxt().build(self.body.typing_mode(tcx));
         let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
 
-        let const_conditions = tcx.const_conditions(callee).instantiate(tcx, callee_args);
-
         let body_id = self.body.source.def_id().expect_local();
         let host_polarity = match self.const_kind() {
             hir::ConstContext::ConstFn => ty::BoundConstness::Maybe,
@@ -621,7 +634,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                 };
 
                 let ConstCx { tcx, body, param_env, .. } = *self.ccx;
-                let caller = self.def_id();
 
                 let fn_ty = func.ty(body, tcx);
 
@@ -639,12 +651,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                     }
                 };
 
-                self.revalidate_conditional_constness(
-                    callee,
-                    fn_args,
-                    call_source,
-                    terminator.source_info.span,
-                );
+                self.revalidate_conditional_constness(callee, fn_args, call_source, *fn_span);
 
                 let mut is_trait = false;
                 // Attempting to call a trait method?
@@ -684,7 +691,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                             None
                         };
                         self.check_op(ops::FnCallNonConst {
-                            caller,
                             callee,
                             args: fn_args,
                             span: *fn_span,
@@ -774,7 +780,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                 // Trait functions are not `const fn` so we have to skip them here.
                 if !tcx.is_const_fn(callee) && !is_trait {
                     self.check_op(ops::FnCallNonConst {
-                        caller,
                         callee,
                         args: fn_args,
                         span: *fn_span,
diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs
index 961a27ae9ba..ce36701a942 100644
--- a/compiler/rustc_const_eval/src/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/check_consts/ops.rs
@@ -1,6 +1,5 @@
 //! Concrete error types for all operations which may be invalid in a certain const context.
 
-use hir::def_id::LocalDefId;
 use hir::{ConstContext, LangItem};
 use rustc_errors::Diag;
 use rustc_errors::codes::*;
@@ -74,7 +73,6 @@ impl<'tcx> NonConstOp<'tcx> for FnCallIndirect {
 /// A function call where the callee is not marked as `const`.
 #[derive(Debug, Clone, Copy)]
 pub(crate) struct FnCallNonConst<'tcx> {
-    pub caller: LocalDefId,
     pub callee: DefId,
     pub args: GenericArgsRef<'tcx>,
     pub span: Span,
@@ -87,8 +85,9 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
     #[allow(rustc::diagnostic_outside_of_impl)]
     #[allow(rustc::untranslatable_diagnostic)]
     fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, _: Span) -> Diag<'tcx> {
-        let FnCallNonConst { caller, callee, args, span, call_source, feature } = *self;
-        let ConstCx { tcx, param_env, body, .. } = *ccx;
+        let FnCallNonConst { callee, args, span, call_source, feature } = *self;
+        let ConstCx { tcx, param_env, .. } = *ccx;
+        let caller = ccx.def_id();
 
         let diag_trait = |err, self_ty: Ty<'_>, trait_id| {
             let trait_ref = TraitRef::from_method(tcx, trait_id, args);
@@ -116,7 +115,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
                     let obligation =
                         Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref);
 
-                    let infcx = tcx.infer_ctxt().build(body.typing_mode(tcx));
+                    let infcx = tcx.infer_ctxt().build(ccx.body.typing_mode(tcx));
                     let mut selcx = SelectionContext::new(&infcx);
                     let implsrc = selcx.select(&obligation);
 
@@ -289,7 +288,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
         if let Some(feature) = feature {
             ccx.tcx.disabled_nightly_features(
                 &mut err,
-                body.source.def_id().as_local().map(|local| ccx.tcx.local_def_id_to_hir_id(local)),
+                Some(ccx.tcx.local_def_id_to_hir_id(caller)),
                 [(String::new(), feature)],
             );
         }