Skip to content

Commit 7c8887c

Browse files
committed
introduce (but do not use) ascribe_user_type goal
Lots of annoying boilerplate.
1 parent f99911a commit 7c8887c

File tree

11 files changed

+133
-8
lines changed

11 files changed

+133
-8
lines changed

src/librustc/dep_graph/dep_node.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,9 @@ use std::hash::Hash;
7272
use syntax_pos::symbol::InternedString;
7373
use traits;
7474
use traits::query::{
75-
CanonicalProjectionGoal, CanonicalTyGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpSubtypeGoal,
76-
CanonicalPredicateGoal, CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpNormalizeGoal,
75+
CanonicalProjectionGoal, CanonicalTyGoal, CanonicalTypeOpAscribeUserTypeGoal,
76+
CanonicalTypeOpEqGoal, CanonicalTypeOpSubtypeGoal, CanonicalPredicateGoal,
77+
CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpNormalizeGoal,
7778
};
7879
use ty::{TyCtxt, FnSig, Instance, InstanceDef,
7980
ParamEnv, ParamEnvAnd, Predicate, PolyFnSig, PolyTraitRef, Ty};
@@ -654,6 +655,7 @@ define_dep_nodes!( <'tcx>
654655
[] ImpliedOutlivesBounds(CanonicalTyGoal<'tcx>),
655656
[] DropckOutlives(CanonicalTyGoal<'tcx>),
656657
[] EvaluateObligation(CanonicalPredicateGoal<'tcx>),
658+
[] TypeOpAscribeUserType(CanonicalTypeOpAscribeUserTypeGoal<'tcx>),
657659
[] TypeOpEq(CanonicalTypeOpEqGoal<'tcx>),
658660
[] TypeOpSubtype(CanonicalTypeOpSubtypeGoal<'tcx>),
659661
[] TypeOpProvePredicate(CanonicalTypeOpProvePredicateGoal<'tcx>),

src/librustc/mir/mod.rs

+8
Original file line numberDiff line numberDiff line change
@@ -2438,6 +2438,14 @@ EnumTypeFoldableImpl! {
24382438
}
24392439
}
24402440

2441+
EnumLiftImpl! {
2442+
impl<'a, 'tcx> Lift<'tcx> for UserTypeAnnotation<'a> {
2443+
type Lifted = UserTypeAnnotation<'tcx>;
2444+
(UserTypeAnnotation::Ty)(ty),
2445+
(UserTypeAnnotation::TypeOf)(def, substs),
2446+
}
2447+
}
2448+
24412449
newtype_index! {
24422450
pub struct Promoted {
24432451
DEBUG_FORMAT = "promoted[{}]"

src/librustc/traits/query/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ pub type CanonicalTyGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, Ty<'tcx>>
3434
pub type CanonicalPredicateGoal<'tcx> =
3535
Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::Predicate<'tcx>>>;
3636

37+
pub type CanonicalTypeOpAscribeUserTypeGoal<'tcx> =
38+
Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::ascribe_user_type::AscribeUserType<'tcx>>>;
39+
3740
pub type CanonicalTypeOpEqGoal<'tcx> =
3841
Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::eq::Eq<'tcx>>>;
3942

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Copyright 2016 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 infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse};
12+
use mir::UserTypeAnnotation;
13+
use traits::query::Fallible;
14+
use ty::{self, ParamEnvAnd, Ty, TyCtxt};
15+
16+
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
17+
pub struct AscribeUserType<'tcx> {
18+
pub mir_ty: Ty<'tcx>,
19+
pub variance: ty::Variance,
20+
pub user_ty: UserTypeAnnotation<'tcx>,
21+
}
22+
23+
impl<'tcx> AscribeUserType<'tcx> {
24+
pub fn new(
25+
mir_ty: Ty<'tcx>,
26+
variance: ty::Variance,
27+
user_ty: UserTypeAnnotation<'tcx>,
28+
) -> Self {
29+
AscribeUserType { mir_ty, variance, user_ty }
30+
}
31+
}
32+
33+
impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for AscribeUserType<'tcx> {
34+
type QueryResponse = ();
35+
36+
fn try_fast_path(
37+
_tcx: TyCtxt<'_, 'gcx, 'tcx>,
38+
_key: &ParamEnvAnd<'tcx, Self>,
39+
) -> Option<Self::QueryResponse> {
40+
None
41+
}
42+
43+
fn perform_query(
44+
tcx: TyCtxt<'_, 'gcx, 'tcx>,
45+
canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Self>>,
46+
) -> Fallible<CanonicalizedQueryResponse<'gcx, ()>> {
47+
tcx.type_op_ascribe_user_type(canonicalized)
48+
}
49+
50+
fn shrink_to_tcx_lifetime(
51+
v: &'a CanonicalizedQueryResponse<'gcx, ()>,
52+
) -> &'a Canonical<'tcx, QueryResponse<'tcx, ()>> {
53+
v
54+
}
55+
}
56+
57+
BraceStructTypeFoldableImpl! {
58+
impl<'tcx> TypeFoldable<'tcx> for AscribeUserType<'tcx> {
59+
mir_ty, variance, user_ty
60+
}
61+
}
62+
63+
BraceStructLiftImpl! {
64+
impl<'a, 'tcx> Lift<'tcx> for AscribeUserType<'a> {
65+
type Lifted = AscribeUserType<'tcx>;
66+
mir_ty, variance, user_ty
67+
}
68+
}
69+
70+
impl_stable_hash_for! {
71+
struct AscribeUserType<'tcx> {
72+
mir_ty, variance, user_ty
73+
}
74+
}

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

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use traits::ObligationCause;
2020
use ty::fold::TypeFoldable;
2121
use ty::{Lift, ParamEnvAnd, TyCtxt};
2222

23+
pub mod ascribe_user_type;
2324
pub mod custom;
2425
pub mod eq;
2526
pub mod implied_outlives_bounds;

src/librustc/ty/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ impl Visibility {
328328
}
329329
}
330330

331-
#[derive(Clone, PartialEq, RustcDecodable, RustcEncodable, Copy)]
331+
#[derive(Copy, Clone, PartialEq, Eq, RustcDecodable, RustcEncodable, Hash)]
332332
pub enum Variance {
333333
Covariant, // T<A> <: T<B> iff A <: B -- e.g., function return type
334334
Invariant, // T<A> <: T<B> iff B == A -- e.g., type of mutable cell

src/librustc/ty/query/config.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ use hir::def_id::{CrateNum, DefId, DefIndex};
1414
use mir::interpret::GlobalId;
1515
use traits;
1616
use traits::query::{
17-
CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal, CanonicalTypeOpEqGoal,
18-
CanonicalTypeOpNormalizeGoal, CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal,
17+
CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,
18+
CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal,
19+
CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal,
1920
};
2021
use ty::{self, ParamEnvAnd, Ty, TyCtxt};
2122
use ty::subst::Substs;
@@ -115,6 +116,15 @@ impl<'tcx> QueryDescription<'tcx> for queries::evaluate_obligation<'tcx> {
115116
}
116117
}
117118

119+
impl<'tcx> QueryDescription<'tcx> for queries::type_op_ascribe_user_type<'tcx> {
120+
fn describe(
121+
_tcx: TyCtxt<'_, '_, '_>,
122+
goal: CanonicalTypeOpAscribeUserTypeGoal<'tcx>,
123+
) -> Cow<'static, str> {
124+
format!("evaluating `type_op_ascribe_user_type` `{:?}`", goal).into()
125+
}
126+
}
127+
118128
impl<'tcx> QueryDescription<'tcx> for queries::type_op_eq<'tcx> {
119129
fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTypeOpEqGoal<'tcx>) -> Cow<'static, str> {
120130
format!("evaluating `type_op_eq` `{:?}`", goal).into()

src/librustc/ty/query/mod.rs

+14-3
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,12 @@ use mir::interpret::GlobalId;
3434
use session::{CompileResult, CrateDisambiguator};
3535
use session::config::OutputFilenames;
3636
use traits::{self, Vtable};
37-
use traits::query::{CanonicalPredicateGoal, CanonicalProjectionGoal,
38-
CanonicalTyGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpSubtypeGoal,
39-
CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpNormalizeGoal, NoSolution};
37+
use traits::query::{
38+
CanonicalPredicateGoal, CanonicalProjectionGoal,
39+
CanonicalTyGoal, CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal,
40+
CanonicalTypeOpSubtypeGoal, CanonicalTypeOpProvePredicateGoal,
41+
CanonicalTypeOpNormalizeGoal, NoSolution,
42+
};
4043
use traits::query::dropck_outlives::{DtorckConstraint, DropckOutlivesResult};
4144
use traits::query::normalize::NormalizationResult;
4245
use traits::query::outlives_bounds::OutlivesBound;
@@ -589,6 +592,14 @@ define_queries! { <'tcx>
589592
CanonicalPredicateGoal<'tcx>
590593
) -> Result<traits::EvaluationResult, traits::OverflowError>,
591594

595+
/// Do not call this query directly: part of the `Eq` type-op
596+
[] fn type_op_ascribe_user_type: TypeOpAscribeUserType(
597+
CanonicalTypeOpAscribeUserTypeGoal<'tcx>
598+
) -> Result<
599+
Lrc<Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>>,
600+
NoSolution,
601+
>,
602+
592603
/// Do not call this query directly: part of the `Eq` type-op
593604
[] fn type_op_eq: TypeOpEq(
594605
CanonicalTypeOpEqGoal<'tcx>

src/librustc/ty/query/plumbing.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1079,6 +1079,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
10791079
DepKind::ImpliedOutlivesBounds |
10801080
DepKind::DropckOutlives |
10811081
DepKind::EvaluateObligation |
1082+
DepKind::TypeOpAscribeUserType |
10821083
DepKind::TypeOpEq |
10831084
DepKind::TypeOpSubtype |
10841085
DepKind::TypeOpProvePredicate |

src/librustc_mir/borrow_check/nll/type_check/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1008,6 +1008,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
10081008

10091009
let ty = self.tcx().type_of(def_id);
10101010
let ty = ty.subst(tcx, substs);
1011+
debug!("relate_type_and_user_type: ty of def-id is {:?}", ty);
10111012
let ty = self.normalize(ty, locations);
10121013

10131014
self.relate_types(ty, v1, a, locations, category)?;

src/librustc_traits/type_op.rs

+14
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
use rustc::infer::canonical::{Canonical, QueryResponse};
1212
use rustc::infer::InferCtxt;
13+
use rustc::traits::query::type_op::ascribe_user_type::AscribeUserType;
1314
use rustc::traits::query::type_op::eq::Eq;
1415
use rustc::traits::query::type_op::normalize::Normalize;
1516
use rustc::traits::query::type_op::prove_predicate::ProvePredicate;
@@ -24,6 +25,7 @@ use std::fmt;
2425

2526
crate fn provide(p: &mut Providers) {
2627
*p = Providers {
28+
type_op_ascribe_user_type,
2729
type_op_eq,
2830
type_op_prove_predicate,
2931
type_op_subtype,
@@ -35,6 +37,18 @@ crate fn provide(p: &mut Providers) {
3537
};
3638
}
3739

40+
fn type_op_ascribe_user_type<'tcx>(
41+
tcx: TyCtxt<'_, 'tcx, 'tcx>,
42+
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, AscribeUserType<'tcx>>>,
43+
) -> Result<Lrc<Canonical<'tcx, QueryResponse<'tcx, ()>>>, NoSolution> {
44+
tcx.infer_ctxt()
45+
.enter_canonical_trait_query(&canonicalized, |infcx, fulfill_cx, key| {
46+
let (param_env, AscribeUserType { mir_ty, variance, user_ty }) = key.into_parts();
47+
drop((infcx, fulfill_cx, param_env, mir_ty, variance, user_ty));
48+
Ok(())
49+
})
50+
}
51+
3852
fn type_op_eq<'tcx>(
3953
tcx: TyCtxt<'_, 'tcx, 'tcx>,
4054
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Eq<'tcx>>>,

0 commit comments

Comments
 (0)