about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan MacKenzie <ecstaticmorse@gmail.com>2020-02-04 14:03:16 -0800
committerDylan MacKenzie <ecstaticmorse@gmail.com>2020-02-18 21:03:28 -0800
commit7a019b1bd2b13993bb2039053d815df02504083e (patch)
treebb20db102cd26a03ecac2c7e16c39f59756c1b33
parent5e422efba1be879633c7be7ad178915f2ace7f04 (diff)
downloadrust-7a019b1bd2b13993bb2039053d815df02504083e.tar.gz
rust-7a019b1bd2b13993bb2039053d815df02504083e.zip
Check for trait methods on concrete types in const checking
-rw-r--r--src/librustc_mir/transform/check_consts/validation.rs20
1 files changed, 17 insertions, 3 deletions
diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs
index 167d8145c03..1a1c34e1c67 100644
--- a/src/librustc_mir/transform/check_consts/validation.rs
+++ b/src/librustc_mir/transform/check_consts/validation.rs
@@ -4,7 +4,7 @@ use rustc::middle::lang_items;
 use rustc::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
 use rustc::mir::*;
 use rustc::ty::cast::CastTy;
-use rustc::ty::{self, TyCtxt};
+use rustc::ty::{self, Instance, InstanceDef, TyCtxt};
 use rustc_errors::struct_span_err;
 use rustc_hir::{def_id::DefId, HirId};
 use rustc_index::bit_set::BitSet;
@@ -501,8 +501,8 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
             TerminatorKind::Call { func, .. } => {
                 let fn_ty = func.ty(*self.body, self.tcx);
 
-                let def_id = match fn_ty.kind {
-                    ty::FnDef(def_id, _) => def_id,
+                let (def_id, substs) = match fn_ty.kind {
+                    ty::FnDef(def_id, substs) => (def_id, substs),
 
                     ty::FnPtr(_) => {
                         self.check_op(ops::FnCallIndirect);
@@ -519,6 +519,20 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
                     return;
                 }
 
+                // See if this is a trait method for a concrete type whose impl of that trait is
+                // `const`.
+                if self.tcx.features().const_trait_impl {
+                    let instance = Instance::resolve(self.tcx, self.param_env, def_id, substs);
+                    debug!("Resolving ({:?}) -> {:?}", def_id, instance);
+                    if let Some(func) = instance {
+                        if let InstanceDef::Item(def_id) = func.def {
+                            if is_const_fn(self.tcx, def_id) {
+                                return;
+                            }
+                        }
+                    }
+                }
+
                 if is_lang_panic_fn(self.tcx, def_id) {
                     self.check_op(ops::Panic);
                 } else if let Some(feature) = is_unstable_const_fn(self.tcx, def_id) {