diff --git a/Cargo.lock b/Cargo.lock index ea0087de839af..e9c4d6b3bad64 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2703,7 +2703,6 @@ dependencies = [ "rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_data_structures 0.0.0", "rustc_metadata 0.0.0", - "rustc_mir 0.0.0", "rustc_target 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index e5bf9a27ab050..a364a6da2e497 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -49,6 +49,7 @@ //! user of the `DepNode` API of having to know how to compute the expected //! fingerprint for a given set of node parameters. +use crate::mir; use crate::mir::interpret::GlobalId; use crate::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX}; use crate::hir::map::DefPathHash; diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 18308f5444221..00856041edf46 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -4,6 +4,7 @@ use crate::ty::{self, ParamEnvAnd, Ty, TyCtxt}; use crate::ty::subst::SubstsRef; use crate::dep_graph::SerializedDepNodeIndex; use crate::hir::def_id::{CrateNum, DefId, DefIndex}; +use crate::mir; use crate::mir::interpret::GlobalId; use crate::traits; use crate::traits::query::{ @@ -431,6 +432,15 @@ rustc_queries! { tcx.queries.on_disk_cache.try_load_query_result(tcx, id).map(Ok) } } + + /// Extracts a field of a (variant of a) const. + query const_field( + key: ty::ParamEnvAnd<'tcx, (&'tcx ty::Const<'tcx>, mir::Field)> + ) -> &'tcx ty::Const<'tcx> { + eval_always + no_force + desc { "extract field of const" } + } } TypeChecking { diff --git a/src/librustc/ty/print/mod.rs b/src/librustc/ty/print/mod.rs index a3986f7c055e6..a7cb7bd3956f0 100644 --- a/src/librustc/ty/print/mod.rs +++ b/src/librustc/ty/print/mod.rs @@ -7,9 +7,10 @@ use rustc_data_structures::fx::FxHashSet; // `pretty` is a separate module only for organization. mod pretty; -pub mod obsolete; pub use self::pretty::*; +pub mod obsolete; + pub trait Print<'gcx, 'tcx, P> { type Output; type Error; diff --git a/src/librustc/ty/query/keys.rs b/src/librustc/ty/query/keys.rs index d353da801778d..27b0e8e881df9 100644 --- a/src/librustc/ty/query/keys.rs +++ b/src/librustc/ty/query/keys.rs @@ -127,6 +127,15 @@ impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) { } } +impl<'tcx> Key for (&'tcx ty::Const<'tcx>, mir::Field) { + fn query_crate(&self) -> CrateNum { + LOCAL_CRATE + } + fn default_span(&self, _: TyCtxt<'_, '_, '_>) -> Span { + DUMMY_SP + } +} + impl<'tcx> Key for ty::PolyTraitRef<'tcx>{ fn query_crate(&self) -> CrateNum { self.def_id().krate diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/src/librustc_codegen_ssa/mir/constant.rs index eaa1dd186a536..78c22206ab7a5 100644 --- a/src/librustc_codegen_ssa/mir/constant.rs +++ b/src/librustc_codegen_ssa/mir/constant.rs @@ -1,5 +1,4 @@ use rustc::mir::interpret::ErrorHandled; -use rustc_mir::const_eval::const_field; use rustc::mir; use rustc_data_structures::indexed_vec::Idx; use rustc::ty::{self, Ty}; @@ -46,12 +45,8 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { _ => bug!("invalid simd shuffle type: {}", c.ty), }; let values: Vec<_> = (0..fields).map(|field| { - let field = const_field( - bx.tcx(), - ty::ParamEnv::reveal_all(), - None, - mir::Field::new(field as usize), - c, + let field = bx.tcx().const_field( + ty::ParamEnv::reveal_all().and((&c, mir::Field::new(field as usize))) ); if let Some(prim) = field.val.try_to_scalar() { let layout = bx.layout_of(field_ty); diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index dc7aa0f17e88c..d118a61bcc6ce 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -470,7 +470,7 @@ impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx> } } -/// Projects to a field of a (variant of a) const. +/// Extracts a field of a (variant of a) const. // this function uses `unwrap` copiously, because an already validated constant must have valid // fields and can thus never fail outside of compiler bugs pub fn const_field<'a, 'tcx>( diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index d5cee871810f5..716838b4fc597 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -5,7 +5,7 @@ mod check_match; pub(crate) use self::check_match::check_match; -use crate::const_eval::{const_field, const_variant_index}; +use crate::const_eval::const_variant_index; use crate::hair::util::UserAnnotatedTyHelpers; use crate::hair::constant::*; @@ -949,7 +949,9 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { debug!("const_to_pat: cv={:#?} id={:?}", cv, id); let adt_subpattern = |i, variant_opt| { let field = Field::new(i); - let val = const_field(self.tcx, self.param_env, variant_opt, field, cv); + let val = crate::const_eval::const_field( + self.tcx, self.param_env, variant_opt, field, cv + ); self.const_to_pat(instance, val, id, span) }; let adt_subpatterns = |n, variant_opt| { diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 6dc2b00740706..46bda28c13c5c 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -63,6 +63,10 @@ pub fn provide(providers: &mut Providers<'_>) { providers.const_eval = const_eval::const_eval_provider; providers.const_eval_raw = const_eval::const_eval_raw_provider; providers.check_match = hair::pattern::check_match; + providers.const_field = |tcx, param_env_and_value| { + let (param_env, (value, field)) = param_env_and_value.into_parts(); + const_eval::const_field(tcx, param_env, None, field, value) + }; } __build_diagnostic_array! { librustc_mir, DIAGNOSTICS }