Skip to content

Commit 4690fbf

Browse files
committed
make Subtype a true query
1 parent aa92f78 commit 4690fbf

File tree

8 files changed

+98
-15
lines changed

8 files changed

+98
-15
lines changed

src/librustc/dep_graph/dep_node.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ use std::fmt;
7171
use std::hash::Hash;
7272
use syntax_pos::symbol::InternedString;
7373
use traits::query::{
74-
CanonicalProjectionGoal, CanonicalTyGoal, CanonicalTypeOpEqGoal, CanonicalPredicateGoal,
74+
CanonicalProjectionGoal, CanonicalTyGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpSubtypeGoal,
75+
CanonicalPredicateGoal,
7576
};
7677
use ty::{TyCtxt, Instance, InstanceDef, ParamEnv, ParamEnvAnd, PolyTraitRef, Ty};
7778
use ty::subst::Substs;
@@ -649,6 +650,7 @@ define_dep_nodes!( <'tcx>
649650
[] DropckOutlives(CanonicalTyGoal<'tcx>),
650651
[] EvaluateObligation(CanonicalPredicateGoal<'tcx>),
651652
[] TypeOpEq(CanonicalTypeOpEqGoal<'tcx>),
653+
[] TypeOpSubtype(CanonicalTypeOpSubtypeGoal<'tcx>),
652654

653655
[] SubstituteNormalizeAndTestPredicates { key: (DefId, &'tcx Substs<'tcx>) },
654656

src/librustc/traits/query/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ pub type CanonicalPredicateGoal<'tcx> =
3535
pub type CanonicalTypeOpEqGoal<'tcx> =
3636
Canonical<'tcx, type_op::eq::Eq<'tcx>>;
3737

38+
pub type CanonicalTypeOpSubtypeGoal<'tcx> =
39+
Canonical<'tcx, type_op::subtype::Subtype<'tcx>>;
40+
3841
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
3942
pub struct NoSolution;
4043

src/librustc/traits/query/type_op/subtype.rs

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,14 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use infer::{InferCtxt, InferResult};
12-
use traits::ObligationCause;
11+
use infer::canonical::{Canonical, CanonicalizedQueryResult};
1312
use ty::{ParamEnv, Ty, TyCtxt};
1413

15-
#[derive(Debug)]
14+
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
1615
pub struct Subtype<'tcx> {
17-
param_env: ParamEnv<'tcx>,
18-
sub: Ty<'tcx>,
19-
sup: Ty<'tcx>,
16+
pub param_env: ParamEnv<'tcx>,
17+
pub sub: Ty<'tcx>,
18+
pub sup: Ty<'tcx>,
2019
}
2120

2221
impl<'tcx> Subtype<'tcx> {
@@ -29,20 +28,46 @@ impl<'tcx> Subtype<'tcx> {
2928
}
3029
}
3130

32-
impl<'gcx, 'tcx> super::TypeOp<'gcx, 'tcx> for Subtype<'tcx> {
33-
type Output = ();
31+
impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for Subtype<'tcx> {
32+
type QueryResult = ();
3433

35-
fn trivial_noop(self, _tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<Self::Output, Self> {
34+
fn trivial_noop(self, _tcx: TyCtxt<'_, 'gcx, 'tcx>) -> Result<(), Self> {
3635
if self.sub == self.sup {
3736
Ok(())
3837
} else {
3938
Err(self)
4039
}
4140
}
4241

43-
fn perform(self, infcx: &InferCtxt<'_, 'gcx, 'tcx>) -> InferResult<'tcx, Self::Output> {
44-
infcx
45-
.at(&ObligationCause::dummy(), self.param_env)
46-
.sup(self.sup, self.sub)
42+
fn param_env(&self) -> ParamEnv<'tcx> {
43+
self.param_env
4744
}
45+
46+
fn perform_query(
47+
tcx: TyCtxt<'_, 'gcx, 'tcx>,
48+
canonicalized: Canonical<'gcx, Subtype<'gcx>>,
49+
) -> CanonicalizedQueryResult<'gcx, ()> {
50+
tcx.type_op_subtype(canonicalized).unwrap()
51+
}
52+
}
53+
54+
BraceStructTypeFoldableImpl! {
55+
impl<'tcx> TypeFoldable<'tcx> for Subtype<'tcx> {
56+
param_env,
57+
sub,
58+
sup,
59+
}
60+
}
61+
62+
BraceStructLiftImpl! {
63+
impl<'a, 'tcx> Lift<'tcx> for Subtype<'a> {
64+
type Lifted = Subtype<'tcx>;
65+
param_env,
66+
sub,
67+
sup,
68+
}
69+
}
70+
71+
impl_stable_hash_for! {
72+
struct Subtype<'tcx> { param_env, sub, sup }
4873
}

src/librustc/ty/query/config.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use hir::def_id::{CrateNum, DefId, DefIndex};
1414
use mir::interpret::{GlobalId, ConstValue};
1515
use traits::query::{
1616
CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal, CanonicalTypeOpEqGoal,
17+
CanonicalTypeOpSubtypeGoal,
1718
};
1819
use ty::{self, ParamEnvAnd, Ty, TyCtxt};
1920
use ty::subst::Substs;
@@ -110,6 +111,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::type_op_eq<'tcx> {
110111
}
111112
}
112113

114+
impl<'tcx> QueryDescription<'tcx> for queries::type_op_subtype<'tcx> {
115+
fn describe(_tcx: TyCtxt, goal: CanonicalTypeOpSubtypeGoal<'tcx>) -> String {
116+
format!("evaluating `type_op_eq` `{:?}`", goal)
117+
}
118+
}
119+
113120
impl<'tcx> QueryDescription<'tcx> for queries::is_copy_raw<'tcx> {
114121
fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
115122
format!("computing whether `{}` is `Copy`", env.value)

src/librustc/ty/query/mod.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use session::{CompileResult, CrateDisambiguator};
3434
use session::config::OutputFilenames;
3535
use traits::{self, Vtable};
3636
use traits::query::{CanonicalPredicateGoal, CanonicalProjectionGoal,
37-
CanonicalTyGoal, CanonicalTypeOpEqGoal, NoSolution};
37+
CanonicalTyGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpSubtypeGoal, NoSolution};
3838
use traits::query::dropck_outlives::{DtorckConstraint, DropckOutlivesResult};
3939
use traits::query::normalize::NormalizationResult;
4040
use traits::specialization_graph;
@@ -454,6 +454,14 @@ define_queries! { <'tcx>
454454
NoSolution,
455455
>,
456456

457+
/// Do not call this query directly: invoke `infcx.at().subtype()` instead.
458+
[] fn type_op_subtype: TypeOpSubtype(
459+
CanonicalTypeOpSubtypeGoal<'tcx>
460+
) -> Result<
461+
Lrc<Canonical<'tcx, canonical::QueryResult<'tcx, ()>>>,
462+
NoSolution,
463+
>,
464+
457465
[] fn substitute_normalize_and_test_predicates:
458466
substitute_normalize_and_test_predicates_node((DefId, &'tcx Substs<'tcx>)) -> bool,
459467

src/librustc/ty/query/plumbing.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,6 +1029,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
10291029
DepKind::DropckOutlives |
10301030
DepKind::EvaluateObligation |
10311031
DepKind::TypeOpEq |
1032+
DepKind::TypeOpSubtype |
10321033
DepKind::SubstituteNormalizeAndTestPredicates |
10331034
DepKind::InstanceDefSizeEstimate |
10341035
DepKind::ProgramClausesForEnv |

src/librustc_traits/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ mod normalize_projection_ty;
3535
mod normalize_erasing_regions;
3636
pub mod lowering;
3737
mod type_op_eq;
38+
mod type_op_subtype;
3839

3940
use rustc::ty::query::Providers;
4041

@@ -49,6 +50,7 @@ pub fn provide(p: &mut Providers) {
4950
program_clauses_for_env: lowering::program_clauses_for_env,
5051
evaluate_obligation: evaluate_obligation::evaluate_obligation,
5152
type_op_eq: type_op_eq::type_op_eq,
53+
type_op_subtype: type_op_subtype::type_op_subtype,
5254
..*p
5355
};
5456
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use rustc::infer::canonical::{Canonical, QueryResult};
12+
use rustc::traits::query::type_op::subtype::Subtype;
13+
use rustc::traits::query::NoSolution;
14+
use rustc::traits::{FulfillmentContext, ObligationCause};
15+
use rustc::ty::TyCtxt;
16+
use rustc_data_structures::sync::Lrc;
17+
use syntax::codemap::DUMMY_SP;
18+
19+
crate fn type_op_subtype<'tcx>(
20+
tcx: TyCtxt<'_, 'tcx, 'tcx>,
21+
canonicalized: Canonical<'tcx, Subtype<'tcx>>,
22+
) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, ()>>>, NoSolution> {
23+
let tcx = tcx.global_tcx();
24+
tcx.infer_ctxt().enter(|ref infcx| {
25+
let (Subtype { param_env, sub, sup }, canonical_inference_vars) =
26+
infcx.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &canonicalized);
27+
let fulfill_cx = &mut FulfillmentContext::new();
28+
let obligations = match infcx.at(&ObligationCause::dummy(), param_env).sup(sup, sub) {
29+
Ok(v) => v.into_obligations(),
30+
Err(_) => return Err(NoSolution),
31+
};
32+
fulfill_cx.register_predicate_obligations(infcx, obligations);
33+
infcx.make_canonicalized_query_result(canonical_inference_vars, (), fulfill_cx)
34+
})
35+
}

0 commit comments

Comments
 (0)