From 54b935b9b99a8cf276bc55906b9817f8cf44bfbb Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 20 Feb 2019 01:20:06 +0000 Subject: [PATCH] Handle const generics elsewhere Co-Authored-By: Gabriel Smith --- src/librustc/middle/resolve_lifetime.rs | 2 +- src/librustc/traits/error_reporting.rs | 3 ++- src/librustc/traits/mod.rs | 3 ++- src/librustc/traits/object_safety.rs | 3 ++- src/librustc/traits/on_unimplemented.rs | 3 ++- src/librustc/ty/relate.rs | 3 +++ src/librustc/ty/util.rs | 20 ++++++++++++++++---- src/librustc_privacy/lib.rs | 10 ++++++++-- src/librustc_traits/chalk_context/mod.rs | 13 ++++++++++++- 9 files changed, 48 insertions(+), 12 deletions(-) diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 2618d0874cb..d2bec1070f9 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -1974,7 +1974,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { object_lifetime_default, .. } => Some(object_lifetime_default), - GenericParamDefKind::Lifetime => None, + GenericParamDefKind::Lifetime | GenericParamDefKind::Const => None, }) .collect() }) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 3eb49092fed..322e384e13e 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -389,7 +389,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { for param in generics.params.iter() { let value = match param.kind { - GenericParamDefKind::Type {..} => { + GenericParamDefKind::Type { .. } | + GenericParamDefKind::Const => { trait_ref.substs[param.index as usize].to_string() }, GenericParamDefKind::Lifetime => continue, diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index ee7893a27de..32bb7f18693 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -1010,7 +1010,8 @@ fn vtable_methods<'a, 'tcx>( InternalSubsts::for_item(tcx, def_id, |param, _| match param.kind { GenericParamDefKind::Lifetime => tcx.types.re_erased.into(), - GenericParamDefKind::Type {..} => { + GenericParamDefKind::Type { .. } | + GenericParamDefKind::Const => { trait_ref.substs[param.index as usize] } } diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index b2079c25169..e7a5138e689 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -310,7 +310,8 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { } // We can't monomorphize things like `fn foo(...)`. - if self.generics_of(method.def_id).own_counts().types != 0 { + let own_counts = self.generics_of(method.def_id).own_counts(); + if own_counts.types + own_counts.consts != 0 { return Some(MethodViolationCode::Generic); } diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs index f61c32614cc..c86fd0d52b9 100644 --- a/src/librustc/traits/on_unimplemented.rs +++ b/src/librustc/traits/on_unimplemented.rs @@ -280,7 +280,8 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString { let generics = tcx.generics_of(trait_ref.def_id); let generic_map = generics.params.iter().filter_map(|param| { let value = match param.kind { - GenericParamDefKind::Type {..} => { + GenericParamDefKind::Type { .. } | + GenericParamDefKind::Const => { trait_ref.substs[param.index as usize].to_string() }, GenericParamDefKind::Lifetime => return None diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 2940757fa90..3a31801b3be 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -705,6 +705,9 @@ impl<'tcx> Relate<'tcx> for Kind<'tcx> { (UnpackedKind::Type(unpacked), x) => { bug!("impossible case reached: can't relate: {:?} with {:?}", unpacked, x) } + (UnpackedKind::Const(_), _) => { + unimplemented!() // FIXME(const_generics) + } } } } diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 4ad3ffaa93d..fb0d1e2080b 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -12,6 +12,7 @@ use crate::ty::subst::{Subst, InternalSubsts, SubstsRef, UnpackedKind}; use crate::ty::query::TyCtxtAt; use crate::ty::TyKind::*; use crate::ty::layout::{Integer, IntegerExt}; +use crate::mir::interpret::ConstValue; use crate::util::common::ErrorReported; use crate::middle::lang_items; @@ -495,8 +496,16 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { }) => { !impl_generics.type_param(pt, self).pure_wrt_drop } - UnpackedKind::Lifetime(_) | UnpackedKind::Type(_) => { - // not a type or region param - this should be reported + UnpackedKind::Const(&ty::LazyConst::Evaluated(ty::Const { + val: ConstValue::Param(ref pc), + .. + })) => { + !impl_generics.const_param(pc, self).pure_wrt_drop + } + UnpackedKind::Lifetime(_) | + UnpackedKind::Type(_) | + UnpackedKind::Const(_) => { + // Not a type, const or region param: this should be reported // as an error. false } @@ -587,15 +596,18 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { Some(ty::Binder::bind(env_ty)) } - /// Given the `DefId` of some item that has no type parameters, make + /// Given the `DefId` of some item that has no type or const parameters, make /// a suitable "empty substs" for it. pub fn empty_substs_for_def_id(self, item_def_id: DefId) -> SubstsRef<'tcx> { InternalSubsts::for_item(self, item_def_id, |param, _| { match param.kind { GenericParamDefKind::Lifetime => self.types.re_erased.into(), - GenericParamDefKind::Type {..} => { + GenericParamDefKind::Type { .. } => { bug!("empty_substs_for_def_id: {:?} has type parameters", item_def_id) } + GenericParamDefKind::Const { .. } => { + bug!("empty_substs_for_def_id: {:?} has const parameters", item_def_id) + } } }) } diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 550b333700b..a9f05eb60db 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -748,12 +748,15 @@ impl<'a, 'tcx> ReachEverythingInTheInterfaceVisitor<'_, 'a, 'tcx> { fn generics(&mut self) -> &mut Self { for param in &self.ev.tcx.generics_of(self.item_def_id).params { match param.kind { + GenericParamDefKind::Lifetime => {} GenericParamDefKind::Type { has_default, .. } => { if has_default { self.visit(self.ev.tcx.type_of(param.def_id)); } } - GenericParamDefKind::Lifetime => {} + GenericParamDefKind::Const => { + self.visit(self.ev.tcx.type_of(param.def_id)); + } } } self @@ -1517,12 +1520,15 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { fn generics(&mut self) -> &mut Self { for param in &self.tcx.generics_of(self.item_def_id).params { match param.kind { + GenericParamDefKind::Lifetime => {} GenericParamDefKind::Type { has_default, .. } => { if has_default { self.visit(self.tcx.type_of(param.def_id)); } } - GenericParamDefKind::Lifetime => {} + GenericParamDefKind::Const => { + self.visit(self.tcx.type_of(param.def_id)); + } } } self diff --git a/src/librustc_traits/chalk_context/mod.rs b/src/librustc_traits/chalk_context/mod.rs index a326d84725a..6420f20a3ea 100644 --- a/src/librustc_traits/chalk_context/mod.rs +++ b/src/librustc_traits/chalk_context/mod.rs @@ -32,11 +32,12 @@ use rustc::traits::{ InEnvironment, ChalkCanonicalGoal, }; -use rustc::ty::{self, TyCtxt}; +use rustc::ty::{self, TyCtxt, InferConst}; use rustc::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use rustc::ty::query::Providers; use rustc::ty::subst::{Kind, UnpackedKind}; use rustc_data_structures::sync::Lrc; +use rustc::mir::interpret::ConstValue; use syntax_pos::DUMMY_SP; use std::fmt::{self, Debug}; @@ -287,6 +288,16 @@ impl context::ContextOps> for ChalkContext<'cx, 'gcx> { } _ => false, }, + UnpackedKind::Const(ct) => match ct { + ty::LazyConst::Evaluated(ty::Const { + val: ConstValue::Infer(InferConst::Canonical(debruijn, bound_ct)), + .. + }) => { + debug_assert_eq!(*debruijn, ty::INNERMOST); + cvar == *bound_ct + } + _ => false, + } }) }