diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2018-06-11 10:33:37 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2018-06-26 10:59:40 -0400 |
| commit | 71ce2e7eb6d941def725e85b8e9a23c75472ec62 (patch) | |
| tree | 388a86b22734c8a3088f86a63ac7aa06c8138fb0 | |
| parent | 1acffada44df88112d23941cd96ea120ea4b8daf (diff) | |
| download | rust-71ce2e7eb6d941def725e85b8e9a23c75472ec62.tar.gz rust-71ce2e7eb6d941def725e85b8e9a23c75472ec62.zip | |
make `Eq` a true query
| -rw-r--r-- | src/librustc/dep_graph/dep_node.rs | 6 | ||||
| -rw-r--r-- | src/librustc/traits/query/mod.rs | 3 | ||||
| -rw-r--r-- | src/librustc/traits/query/type_op/eq.rs | 32 | ||||
| -rw-r--r-- | src/librustc/ty/query/config.rs | 10 | ||||
| -rw-r--r-- | src/librustc/ty/query/keys.rs | 29 | ||||
| -rw-r--r-- | src/librustc/ty/query/mod.rs | 10 | ||||
| -rw-r--r-- | src/librustc/ty/query/plumbing.rs | 1 | ||||
| -rw-r--r-- | src/librustc_traits/lib.rs | 2 | ||||
| -rw-r--r-- | src/librustc_traits/type_op_eq.rs | 35 |
9 files changed, 80 insertions, 48 deletions
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 3a152ccd0c9..efaebfd0610 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -70,8 +70,9 @@ use rustc_data_structures::stable_hasher::{StableHasher, HashStable}; use std::fmt; use std::hash::Hash; use syntax_pos::symbol::InternedString; -use traits::query::{CanonicalProjectionGoal, - CanonicalTyGoal, CanonicalPredicateGoal}; +use traits::query::{ + CanonicalProjectionGoal, CanonicalTyGoal, CanonicalTypeOpEqGoal, CanonicalPredicateGoal, +}; use ty::{TyCtxt, Instance, InstanceDef, ParamEnv, ParamEnvAnd, PolyTraitRef, Ty}; use ty::subst::Substs; @@ -647,6 +648,7 @@ define_dep_nodes!( <'tcx> [] NormalizeTyAfterErasingRegions(ParamEnvAnd<'tcx, Ty<'tcx>>), [] DropckOutlives(CanonicalTyGoal<'tcx>), [] EvaluateObligation(CanonicalPredicateGoal<'tcx>), + [] TypeOpEq(CanonicalTypeOpEqGoal<'tcx>), [] SubstituteNormalizeAndTestPredicates { key: (DefId, &'tcx Substs<'tcx>) }, diff --git a/src/librustc/traits/query/mod.rs b/src/librustc/traits/query/mod.rs index 7181a94acff..3ee0c0cdd0b 100644 --- a/src/librustc/traits/query/mod.rs +++ b/src/librustc/traits/query/mod.rs @@ -32,6 +32,9 @@ pub type CanonicalTyGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, Ty<'tcx>> pub type CanonicalPredicateGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::Predicate<'tcx>>>; +pub type CanonicalTypeOpEqGoal<'tcx> = + Canonical<'tcx, type_op::eq::Eq<'tcx>>; + #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub struct NoSolution; diff --git a/src/librustc/traits/query/type_op/eq.rs b/src/librustc/traits/query/type_op/eq.rs index 9dad9fa4e0a..8925fa12f03 100644 --- a/src/librustc/traits/query/type_op/eq.rs +++ b/src/librustc/traits/query/type_op/eq.rs @@ -8,17 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use infer::canonical::{CanonicalizedQueryResult, Canonical}; -use traits::query::NoSolution; -use traits::{FulfillmentContext, ObligationCause}; +use infer::canonical::{Canonical, CanonicalizedQueryResult}; use ty::{self, ParamEnv, Ty, TyCtxt}; -use syntax::codemap::DUMMY_SP; -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct Eq<'tcx> { - param_env: ParamEnv<'tcx>, - a: Ty<'tcx>, - b: Ty<'tcx>, + pub param_env: ParamEnv<'tcx>, + pub a: Ty<'tcx>, + pub b: Ty<'tcx>, } impl<'tcx> Eq<'tcx> { @@ -46,20 +43,7 @@ impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for Eq<'tcx> { tcx: TyCtxt<'_, 'gcx, 'tcx>, canonicalized: Canonical<'gcx, Eq<'gcx>>, ) -> CanonicalizedQueryResult<'gcx, ()> { - let tcx = tcx.global_tcx(); - tcx.infer_ctxt() - .enter(|ref infcx| { - let (Eq { param_env, a, b }, canonical_inference_vars) = - infcx.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &canonicalized); - let fulfill_cx = &mut FulfillmentContext::new(); - let obligations = match infcx.at(&ObligationCause::dummy(), param_env).eq(a, b) { - Ok(v) => v.into_obligations(), - Err(_) => return Err(NoSolution), - }; - fulfill_cx.register_predicate_obligations(infcx, obligations); - infcx.make_canonicalized_query_result(canonical_inference_vars, (), fulfill_cx) - }) - .unwrap() + tcx.type_op_eq(canonicalized).unwrap() } } @@ -79,3 +63,7 @@ BraceStructLiftImpl! { b, } } + +impl_stable_hash_for! { + struct Eq<'tcx> { param_env, a, b } +} diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index cc00e9a00ab..d02eac6f212 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -12,7 +12,9 @@ use dep_graph::SerializedDepNodeIndex; use dep_graph::DepNode; use hir::def_id::{CrateNum, DefId, DefIndex}; use mir::interpret::{GlobalId, ConstValue}; -use traits::query::{CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal}; +use traits::query::{ + CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal, CanonicalTypeOpEqGoal, +}; use ty::{self, ParamEnvAnd, Ty, TyCtxt}; use ty::subst::Substs; use ty::query::queries; @@ -102,6 +104,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::evaluate_obligation<'tcx> { } } +impl<'tcx> QueryDescription<'tcx> for queries::type_op_eq<'tcx> { + fn describe(_tcx: TyCtxt, goal: CanonicalTypeOpEqGoal<'tcx>) -> String { + format!("evaluating `type_op_eq` `{:?}`", goal) + } +} + impl<'tcx> QueryDescription<'tcx> for queries::is_copy_raw<'tcx> { fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String { format!("computing whether `{}` is `Copy`", env.value) diff --git a/src/librustc/ty/query/keys.rs b/src/librustc/ty/query/keys.rs index 279d5ebb990..cad3a658682 100644 --- a/src/librustc/ty/query/keys.rs +++ b/src/librustc/ty/query/keys.rs @@ -10,8 +10,8 @@ //! Defines the set of legal keys that can be used in queries. +use infer::canonical::Canonical; use hir::def_id::{CrateNum, DefId, LOCAL_CRATE, DefIndex}; -use traits::query::{CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal}; use ty::{self, Ty, TyCtxt}; use ty::subst::Substs; use ty::fast_reject::SimplifiedType; @@ -190,27 +190,12 @@ impl Key for InternedString { } } -impl<'tcx> Key for CanonicalProjectionGoal<'tcx> { - fn query_crate(&self) -> CrateNum { - LOCAL_CRATE - } - - fn default_span(&self, _tcx: TyCtxt) -> Span { - DUMMY_SP - } -} - -impl<'tcx> Key for CanonicalTyGoal<'tcx> { - fn query_crate(&self) -> CrateNum { - LOCAL_CRATE - } - - fn default_span(&self, _tcx: TyCtxt) -> Span { - DUMMY_SP - } -} - -impl<'tcx> Key for CanonicalPredicateGoal<'tcx> { +/// Canonical query goals correspond to abstract trait operations that +/// are not tied to any crate in particular. +impl<'tcx, T> Key for Canonical<'tcx, T> +where + T: Debug + Hash + Clone + Eq, +{ fn query_crate(&self) -> CrateNum { LOCAL_CRATE } diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index f19bc01e198..d5cd37fd98a 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -34,7 +34,7 @@ use session::{CompileResult, CrateDisambiguator}; use session::config::OutputFilenames; use traits::{self, Vtable}; use traits::query::{CanonicalPredicateGoal, CanonicalProjectionGoal, - CanonicalTyGoal, NoSolution}; + CanonicalTyGoal, CanonicalTypeOpEqGoal, NoSolution}; use traits::query::dropck_outlives::{DtorckConstraint, DropckOutlivesResult}; use traits::query::normalize::NormalizationResult; use traits::specialization_graph; @@ -446,6 +446,14 @@ define_queries! { <'tcx> CanonicalPredicateGoal<'tcx> ) -> Result<traits::EvaluationResult, traits::OverflowError>, + /// Do not call this query directly: invoke `infcx.eq()` instead. + [] fn type_op_eq: TypeOpEq( + CanonicalTypeOpEqGoal<'tcx> + ) -> Result< + Lrc<Canonical<'tcx, canonical::QueryResult<'tcx, ()>>>, + NoSolution, + >, + [] fn substitute_normalize_and_test_predicates: substitute_normalize_and_test_predicates_node((DefId, &'tcx Substs<'tcx>)) -> bool, diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 4679c265d58..51695b113d5 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -1028,6 +1028,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::NormalizeTyAfterErasingRegions | DepKind::DropckOutlives | DepKind::EvaluateObligation | + DepKind::TypeOpEq | DepKind::SubstituteNormalizeAndTestPredicates | DepKind::InstanceDefSizeEstimate | DepKind::ProgramClausesForEnv | diff --git a/src/librustc_traits/lib.rs b/src/librustc_traits/lib.rs index 830aa93c3c3..dae960c9aa3 100644 --- a/src/librustc_traits/lib.rs +++ b/src/librustc_traits/lib.rs @@ -34,6 +34,7 @@ mod evaluate_obligation; mod normalize_projection_ty; mod normalize_erasing_regions; pub mod lowering; +mod type_op_eq; use rustc::ty::query::Providers; @@ -47,6 +48,7 @@ pub fn provide(p: &mut Providers) { program_clauses_for: lowering::program_clauses_for, program_clauses_for_env: lowering::program_clauses_for_env, evaluate_obligation: evaluate_obligation::evaluate_obligation, + type_op_eq: type_op_eq::type_op_eq, ..*p }; } diff --git a/src/librustc_traits/type_op_eq.rs b/src/librustc_traits/type_op_eq.rs new file mode 100644 index 00000000000..b73bee46486 --- /dev/null +++ b/src/librustc_traits/type_op_eq.rs @@ -0,0 +1,35 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use rustc::infer::canonical::{Canonical, QueryResult}; +use rustc::traits::query::type_op::eq::Eq; +use rustc::traits::query::NoSolution; +use rustc::traits::{FulfillmentContext, ObligationCause}; +use rustc::ty::TyCtxt; +use rustc_data_structures::sync::Lrc; +use syntax::codemap::DUMMY_SP; + +crate fn type_op_eq<'tcx>( + tcx: TyCtxt<'_, 'tcx, 'tcx>, + canonicalized: Canonical<'tcx, Eq<'tcx>>, +) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, ()>>>, NoSolution> { + let tcx = tcx.global_tcx(); + tcx.infer_ctxt().enter(|ref infcx| { + let (Eq { param_env, a, b }, canonical_inference_vars) = + infcx.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &canonicalized); + let fulfill_cx = &mut FulfillmentContext::new(); + let obligations = match infcx.at(&ObligationCause::dummy(), param_env).eq(a, b) { + Ok(v) => v.into_obligations(), + Err(_) => return Err(NoSolution), + }; + fulfill_cx.register_predicate_obligations(infcx, obligations); + infcx.make_canonicalized_query_result(canonical_inference_vars, (), fulfill_cx) + }) +} |
