提交 71ce2e7e 编写于 作者: N Niko Matsakis

make `Eq` a true query

上级 1acffada
......@@ -70,8 +70,9 @@
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 @@ pub fn fingerprint_needed_for_crate_hash(self) -> bool {
[] NormalizeTyAfterErasingRegions(ParamEnvAnd<'tcx, Ty<'tcx>>),
[] DropckOutlives(CanonicalTyGoal<'tcx>),
[] EvaluateObligation(CanonicalPredicateGoal<'tcx>),
[] TypeOpEq(CanonicalTypeOpEqGoal<'tcx>),
[] SubstituteNormalizeAndTestPredicates { key: (DefId, &'tcx Substs<'tcx>) },
......
......@@ -32,6 +32,9 @@
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;
......
......@@ -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 @@ fn perform_query(
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 @@ impl<'a, 'tcx> Lift<'tcx> for Eq<'a> {
b,
}
}
impl_stable_hash_for! {
struct Eq<'tcx> { param_env, a, b }
}
......@@ -12,7 +12,9 @@
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 @@ fn describe(_tcx: TyCtxt, goal: CanonicalPredicateGoal<'tcx>) -> String {
}
}
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)
......
......@@ -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 @@ fn default_span(&self, _tcx: TyCtxt) -> Span {
}
}
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
}
......
......@@ -34,7 +34,7 @@
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 @@
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,
......
......@@ -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 |
......
......@@ -34,6 +34,7 @@
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
};
}
// 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)
})
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册