From 58031c7cb2352fb17f2c720a84f541c532ffdf09 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Thu, 2 Jul 2020 23:13:32 +0200 Subject: [PATCH] ConstKind::Unevaluated --- src/librustc_codegen_ssa/mir/constant.rs | 4 ++-- src/librustc_middle/ty/mod.rs | 12 ++++++++++++ src/librustc_middle/ty/print/pretty.rs | 12 ++++++------ src/librustc_middle/ty/sty.rs | 10 +++++----- src/librustc_mir/borrow_check/type_check/mod.rs | 4 ++-- src/librustc_mir/interpret/operand.rs | 4 ++-- src/librustc_mir/monomorphize/collector.rs | 6 +++--- src/librustc_mir/transform/check_consts/qualifs.rs | 6 +++--- src/librustc_mir/transform/promote_consts.rs | 2 +- src/librustc_mir_build/hair/cx/expr.rs | 8 ++++++-- src/librustc_trait_selection/traits/fulfill.rs | 4 ++-- src/librustc_trait_selection/traits/select/mod.rs | 4 ++-- src/librustc_trait_selection/traits/wf.rs | 6 +++--- src/librustdoc/clean/utils.rs | 8 ++++---- 14 files changed, 53 insertions(+), 37 deletions(-) diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/src/librustc_codegen_ssa/mir/constant.rs index 11ec62f96ed3..007be7a62ae3 100644 --- a/src/librustc_codegen_ssa/mir/constant.rs +++ b/src/librustc_codegen_ssa/mir/constant.rs @@ -25,10 +25,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { constant: &mir::Constant<'tcx>, ) -> Result, ErrorHandled> { match self.monomorphize(&constant.literal).val { - ty::ConstKind::Unevaluated(def_id, substs, promoted) => self + ty::ConstKind::Unevaluated(def, substs, promoted) => self .cx .tcx() - .const_eval_resolve(ty::ParamEnv::reveal_all(), def_id, substs, promoted, None) + .const_eval_resolve(ty::ParamEnv::reveal_all(), def.did, substs, promoted, None) .map_err(|err| { if promoted.is_none() { self.cx diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs index f8a205084de8..539dfa6e892b 100644 --- a/src/librustc_middle/ty/mod.rs +++ b/src/librustc_middle/ty/mod.rs @@ -1586,12 +1586,24 @@ impl WithOptParam { } impl WithOptParam { + pub fn to_global(self) -> WithOptParam { + WithOptParam { did: self.did.to_def_id(), param_did: self.param_did } + } + pub fn ty_def_id(self) -> DefId { if let Some(did) = self.param_did { did } else { self.did.to_def_id() } } } impl WithOptParam { + pub fn as_local(self) -> Option> { + self.did.as_local().map(|did| WithOptParam { did, param_did: self.param_did }) + } + + pub fn is_local(self) -> bool { + self.did.is_local() + } + pub fn ty_def_id(self) -> DefId { self.param_did.unwrap_or(self.did) } diff --git a/src/librustc_middle/ty/print/pretty.rs b/src/librustc_middle/ty/print/pretty.rs index 3809c8d245bb..1cba593879aa 100644 --- a/src/librustc_middle/ty/print/pretty.rs +++ b/src/librustc_middle/ty/print/pretty.rs @@ -883,18 +883,18 @@ pub trait PrettyPrinter<'tcx>: } match ct.val { - ty::ConstKind::Unevaluated(did, substs, promoted) => { + ty::ConstKind::Unevaluated(def, substs, promoted) => { if let Some(promoted) = promoted { - p!(print_value_path(did, substs)); + p!(print_value_path(def.did, substs)); p!(write("::{:?}", promoted)); } else { - match self.tcx().def_kind(did) { + match self.tcx().def_kind(def.did) { DefKind::Static | DefKind::Const | DefKind::AssocConst => { - p!(print_value_path(did, substs)) + p!(print_value_path(def.did, substs)) } _ => { - if did.is_local() { - let span = self.tcx().def_span(did); + if def.is_local() { + let span = self.tcx().def_span(def.did); if let Ok(snip) = self.tcx().sess.source_map().span_to_snippet(span) { p!(write("{}", snip)) diff --git a/src/librustc_middle/ty/sty.rs b/src/librustc_middle/ty/sty.rs index 6326068905d3..1e7171ea06c5 100644 --- a/src/librustc_middle/ty/sty.rs +++ b/src/librustc_middle/ty/sty.rs @@ -2278,7 +2278,7 @@ impl<'tcx> Const<'tcx> { ty::ConstKind::Param(ty::ParamConst::new(index, name)) } _ => ty::ConstKind::Unevaluated( - def.did.to_def_id(), + def.to_global(), InternalSubsts::identity_for_item(tcx, def.did.to_def_id()), None, ), @@ -2347,7 +2347,7 @@ impl<'tcx> Const<'tcx> { /// Tries to evaluate the constant if it is `Unevaluated`. If that doesn't succeed, return the /// unevaluated constant. pub fn eval(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> &Const<'tcx> { - if let ConstKind::Unevaluated(did, substs, promoted) = self.val { + if let ConstKind::Unevaluated(def, substs, promoted) = self.val { use crate::mir::interpret::ErrorHandled; let param_env_and_substs = param_env.with_reveal_all().and(substs); @@ -2363,7 +2363,7 @@ impl<'tcx> Const<'tcx> { // FIXME(eddyb, skinny121) pass `InferCtxt` into here when it's available, so that // we can call `infcx.const_eval_resolve` which handles inference variables. let param_env_and_substs = if param_env_and_substs.needs_infer() { - tcx.param_env(did).and(InternalSubsts::identity_for_item(tcx, did)) + tcx.param_env(def.did).and(InternalSubsts::identity_for_item(tcx, def.did)) } else { param_env_and_substs }; @@ -2373,7 +2373,7 @@ impl<'tcx> Const<'tcx> { let (param_env, substs) = param_env_and_substs.into_parts(); // try to resolve e.g. associated constants to their definition on an impl, and then // evaluate the const. - match tcx.const_eval_resolve(param_env, did, substs, promoted, None) { + match tcx.const_eval_resolve(param_env, def.did, substs, promoted, None) { // NOTE(eddyb) `val` contains no lifetimes/types/consts, // and we use the original type, so nothing from `substs` // (which may be identity substs, see above), @@ -2433,7 +2433,7 @@ pub enum ConstKind<'tcx> { /// Used in the HIR by using `Unevaluated` everywhere and later normalizing to one of the other /// variants when the code is monomorphic enough for that. - Unevaluated(DefId, SubstsRef<'tcx>, Option), + Unevaluated(ty::WithOptParam, SubstsRef<'tcx>, Option), /// Used to hold computed value. Value(ConstValue<'tcx>), diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/src/librustc_mir/borrow_check/type_check/mod.rs index 3532b6de003b..7b84737fa77a 100644 --- a/src/librustc_mir/borrow_check/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/type_check/mod.rs @@ -321,7 +321,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { } } else { let tcx = self.tcx(); - if let ty::ConstKind::Unevaluated(def_id, substs, promoted) = constant.literal.val { + if let ty::ConstKind::Unevaluated(def, substs, promoted) = constant.literal.val { if let Some(promoted) = promoted { let check_err = |verifier: &mut TypeVerifier<'a, 'b, 'tcx>, promoted: &Body<'tcx>, @@ -357,7 +357,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { ConstraintCategory::Boring, self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new( constant.literal.ty, - def_id, + def.did, UserSubsts { substs, user_self_ty: None }, )), ) { diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index b02b5219ba1a..face72d70cea 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -549,8 +549,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let val_val = match val.val { ty::ConstKind::Param(_) => throw_inval!(TooGeneric), ty::ConstKind::Error(_) => throw_inval!(TypeckError(ErrorReported)), - ty::ConstKind::Unevaluated(def_id, substs, promoted) => { - let instance = self.resolve(def_id, substs)?; + ty::ConstKind::Unevaluated(def, substs, promoted) => { + let instance = self.resolve(def.did, substs)?; // We use `const_eval` here and `const_eval_raw` elsewhere in mir interpretation. // The reason we use `const_eval_raw` everywhere else is to prevent cycles during // validation, because validation automatically reads through any references, thus diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index f9b3c319c1f6..7a649649a42f 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -622,12 +622,12 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { match substituted_constant.val { ty::ConstKind::Value(val) => collect_const_value(self.tcx, val, self.output), - ty::ConstKind::Unevaluated(def_id, substs, promoted) => { - match self.tcx.const_eval_resolve(param_env, def_id, substs, promoted, None) { + ty::ConstKind::Unevaluated(def, substs, promoted) => { + match self.tcx.const_eval_resolve(param_env, def.did, substs, promoted, None) { Ok(val) => collect_const_value(self.tcx, val, self.output), Err(ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted) => {} Err(ErrorHandled::TooGeneric) => span_bug!( - self.tcx.def_span(def_id), + self.tcx.def_span(def.did), "collection encountered polymorphic constant", ), } diff --git a/src/librustc_mir/transform/check_consts/qualifs.rs b/src/librustc_mir/transform/check_consts/qualifs.rs index 3dddd9c1c176..705eb5d73233 100644 --- a/src/librustc_mir/transform/check_consts/qualifs.rs +++ b/src/librustc_mir/transform/check_consts/qualifs.rs @@ -244,11 +244,11 @@ where }; // Check the qualifs of the value of `const` items. - if let ty::ConstKind::Unevaluated(def_id, _, promoted) = constant.literal.val { + if let ty::ConstKind::Unevaluated(def, _, promoted) = constant.literal.val { assert!(promoted.is_none()); // Don't peek inside trait associated constants. - if cx.tcx.trait_of_item(def_id).is_none() { - let qualifs = cx.tcx.at(constant.span).mir_const_qualif(def_id); + if cx.tcx.trait_of_item(def.did).is_none() { + let qualifs = cx.tcx.at(constant.span).mir_const_qualif(def.did); if !Q::in_qualifs(&qualifs) { return false; } diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 5aa67227994d..a96ba715835f 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -955,7 +955,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { literal: tcx.mk_const(ty::Const { ty, val: ty::ConstKind::Unevaluated( - def_id, + ty::WithOptParam::dummy(def_id), InternalSubsts::for_item(tcx, def_id, |param, _| { if let ty::GenericParamDefKind::Lifetime = param.kind { tcx.lifetimes.re_erased.into() diff --git a/src/librustc_mir_build/hair/cx/expr.rs b/src/librustc_mir_build/hair/cx/expr.rs index d36990684e03..025ef1ece460 100644 --- a/src/librustc_mir_build/hair/cx/expr.rs +++ b/src/librustc_mir_build/hair/cx/expr.rs @@ -600,7 +600,11 @@ fn make_mirror_unadjusted<'a, 'tcx>( // and not the beginning of discriminants (which is always `0`) let substs = InternalSubsts::identity_for_item(cx.tcx(), did); let lhs = mk_const(cx.tcx().mk_const(ty::Const { - val: ty::ConstKind::Unevaluated(did, substs, None), + val: ty::ConstKind::Unevaluated( + ty::WithOptParam::dummy(did), + substs, + None, + ), ty: var_ty, })); let bin = ExprKind::Binary { op: BinOp::Add, lhs, rhs: offset }; @@ -796,7 +800,7 @@ fn convert_path_expr<'a, 'tcx>( debug!("convert_path_expr: (const) user_ty={:?}", user_ty); ExprKind::Literal { literal: cx.tcx.mk_const(ty::Const { - val: ty::ConstKind::Unevaluated(def_id, substs, None), + val: ty::ConstKind::Unevaluated(ty::WithOptParam::dummy(def_id), substs, None), ty: cx.tables().node_type(expr.hir_id), }), user_ty, diff --git a/src/librustc_trait_selection/traits/fulfill.rs b/src/librustc_trait_selection/traits/fulfill.rs index 800aef7284f9..702dcc2f9e1f 100644 --- a/src/librustc_trait_selection/traits/fulfill.rs +++ b/src/librustc_trait_selection/traits/fulfill.rs @@ -524,10 +524,10 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { let stalled_on = &mut pending_obligation.stalled_on; let mut evaluate = |c: &'tcx Const<'tcx>| { - if let ty::ConstKind::Unevaluated(def_id, substs, promoted) = c.val { + if let ty::ConstKind::Unevaluated(def, substs, promoted) = c.val { match self.selcx.infcx().const_eval_resolve( obligation.param_env, - def_id, + def.did, substs, promoted, Some(obligation.cause.span), diff --git a/src/librustc_trait_selection/traits/select/mod.rs b/src/librustc_trait_selection/traits/select/mod.rs index ba5e60012da1..77c50973b914 100644 --- a/src/librustc_trait_selection/traits/select/mod.rs +++ b/src/librustc_trait_selection/traits/select/mod.rs @@ -507,11 +507,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug!("evaluate_predicate_recursively: equating consts c1={:?} c2={:?}", c1, c2); let evaluate = |c: &'tcx ty::Const<'tcx>| { - if let ty::ConstKind::Unevaluated(def_id, substs, promoted) = c.val { + if let ty::ConstKind::Unevaluated(def, substs, promoted) = c.val { self.infcx .const_eval_resolve( obligation.param_env, - def_id, + def.did, substs, promoted, Some(obligation.cause.span), diff --git a/src/librustc_trait_selection/traits/wf.rs b/src/librustc_trait_selection/traits/wf.rs index ebff2dd9b23c..30ba49ed2d8f 100644 --- a/src/librustc_trait_selection/traits/wf.rs +++ b/src/librustc_trait_selection/traits/wf.rs @@ -359,13 +359,13 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { GenericArgKind::Const(constant) => { match constant.val { - ty::ConstKind::Unevaluated(def_id, substs, promoted) => { + ty::ConstKind::Unevaluated(def, substs, promoted) => { assert!(promoted.is_none()); - let obligations = self.nominal_obligations(def_id, substs); + let obligations = self.nominal_obligations(def.did, substs); self.out.extend(obligations); - let predicate = ty::PredicateKind::ConstEvaluatable(def_id, substs) + let predicate = ty::PredicateKind::ConstEvaluatable(def.did, substs) .to_predicate(self.tcx()); let cause = self.cause(traits::MiscObligation); self.out.push(traits::Obligation::new( diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 832b2420c238..52c306688268 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -466,12 +466,12 @@ pub fn name_from_pat(p: &hir::Pat<'_>) -> String { pub fn print_const(cx: &DocContext<'_>, n: &'tcx ty::Const<'_>) -> String { match n.val { - ty::ConstKind::Unevaluated(def_id, _, promoted) => { - let mut s = if let Some(def_id) = def_id.as_local() { - let hir_id = cx.tcx.hir().as_local_hir_id(def_id); + ty::ConstKind::Unevaluated(def, _, promoted) => { + let mut s = if let Some(def) = def.as_local() { + let hir_id = cx.tcx.hir().as_local_hir_id(def.did); print_const_expr(cx, cx.tcx.hir().body_owned_by(hir_id)) } else { - inline::print_inlined_const(cx, def_id) + inline::print_inlined_const(cx, def.did) }; if let Some(promoted) = promoted { s.push_str(&format!("::{:?}", promoted))