Check for trait methods on concrete types in const checking

This commit is contained in:
Dylan MacKenzie 2020-02-04 14:03:16 -08:00
parent 5e422efba1
commit 7a019b1bd2

View file

@ -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) {