about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2018-10-23 20:31:57 -0400
committerNiko Matsakis <niko@alum.mit.edu>2018-10-24 15:12:40 -0400
commit7c8887ccbf7104e98ead7539f3cfbd42332b5e4d (patch)
treee0045abb25811d5fa20190a1fe463dac05ed9deb
parentf99911a4a0bead7dd1f9ef2f90442844434cc391 (diff)
downloadrust-7c8887ccbf7104e98ead7539f3cfbd42332b5e4d.tar.gz
rust-7c8887ccbf7104e98ead7539f3cfbd42332b5e4d.zip
introduce (but do not use) `ascribe_user_type` goal
Lots of annoying boilerplate.
-rw-r--r--src/librustc/dep_graph/dep_node.rs6
-rw-r--r--src/librustc/mir/mod.rs8
-rw-r--r--src/librustc/traits/query/mod.rs3
-rw-r--r--src/librustc/traits/query/type_op/ascribe_user_type.rs74
-rw-r--r--src/librustc/traits/query/type_op/mod.rs1
-rw-r--r--src/librustc/ty/mod.rs2
-rw-r--r--src/librustc/ty/query/config.rs14
-rw-r--r--src/librustc/ty/query/mod.rs17
-rw-r--r--src/librustc/ty/query/plumbing.rs1
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/mod.rs1
-rw-r--r--src/librustc_traits/type_op.rs14
11 files changed, 133 insertions, 8 deletions
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index de03892b994..4d6d3bd56f2 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -72,8 +72,9 @@ use std::hash::Hash;
 use syntax_pos::symbol::InternedString;
 use traits;
 use traits::query::{
-    CanonicalProjectionGoal, CanonicalTyGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpSubtypeGoal,
-    CanonicalPredicateGoal, CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpNormalizeGoal,
+    CanonicalProjectionGoal, CanonicalTyGoal, CanonicalTypeOpAscribeUserTypeGoal,
+    CanonicalTypeOpEqGoal, CanonicalTypeOpSubtypeGoal, CanonicalPredicateGoal,
+    CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpNormalizeGoal,
 };
 use ty::{TyCtxt, FnSig, Instance, InstanceDef,
          ParamEnv, ParamEnvAnd, Predicate, PolyFnSig, PolyTraitRef, Ty};
@@ -654,6 +655,7 @@ define_dep_nodes!( <'tcx>
     [] ImpliedOutlivesBounds(CanonicalTyGoal<'tcx>),
     [] DropckOutlives(CanonicalTyGoal<'tcx>),
     [] EvaluateObligation(CanonicalPredicateGoal<'tcx>),
+    [] TypeOpAscribeUserType(CanonicalTypeOpAscribeUserTypeGoal<'tcx>),
     [] TypeOpEq(CanonicalTypeOpEqGoal<'tcx>),
     [] TypeOpSubtype(CanonicalTypeOpSubtypeGoal<'tcx>),
     [] TypeOpProvePredicate(CanonicalTypeOpProvePredicateGoal<'tcx>),
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 62b5327ae46..571beaae459 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -2438,6 +2438,14 @@ EnumTypeFoldableImpl! {
     }
 }
 
+EnumLiftImpl! {
+    impl<'a, 'tcx> Lift<'tcx> for UserTypeAnnotation<'a> {
+        type Lifted = UserTypeAnnotation<'tcx>;
+        (UserTypeAnnotation::Ty)(ty),
+        (UserTypeAnnotation::TypeOf)(def, substs),
+    }
+}
+
 newtype_index! {
     pub struct Promoted {
         DEBUG_FORMAT = "promoted[{}]"
diff --git a/src/librustc/traits/query/mod.rs b/src/librustc/traits/query/mod.rs
index 35f17aebc04..13683d85444 100644
--- a/src/librustc/traits/query/mod.rs
+++ b/src/librustc/traits/query/mod.rs
@@ -34,6 +34,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 CanonicalTypeOpAscribeUserTypeGoal<'tcx> =
+    Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::ascribe_user_type::AscribeUserType<'tcx>>>;
+
 pub type CanonicalTypeOpEqGoal<'tcx> =
     Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::eq::Eq<'tcx>>>;
 
diff --git a/src/librustc/traits/query/type_op/ascribe_user_type.rs b/src/librustc/traits/query/type_op/ascribe_user_type.rs
new file mode 100644
index 00000000000..607cfa0ec7a
--- /dev/null
+++ b/src/librustc/traits/query/type_op/ascribe_user_type.rs
@@ -0,0 +1,74 @@
+// Copyright 2016 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 infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse};
+use mir::UserTypeAnnotation;
+use traits::query::Fallible;
+use ty::{self, ParamEnvAnd, Ty, TyCtxt};
+
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
+pub struct AscribeUserType<'tcx> {
+    pub mir_ty: Ty<'tcx>,
+    pub variance: ty::Variance,
+    pub user_ty: UserTypeAnnotation<'tcx>,
+}
+
+impl<'tcx> AscribeUserType<'tcx> {
+    pub fn new(
+        mir_ty: Ty<'tcx>,
+        variance: ty::Variance,
+        user_ty: UserTypeAnnotation<'tcx>,
+    ) -> Self {
+        AscribeUserType { mir_ty, variance, user_ty }
+    }
+}
+
+impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for AscribeUserType<'tcx> {
+    type QueryResponse = ();
+
+    fn try_fast_path(
+        _tcx: TyCtxt<'_, 'gcx, 'tcx>,
+        _key: &ParamEnvAnd<'tcx, Self>,
+    ) -> Option<Self::QueryResponse> {
+        None
+    }
+
+    fn perform_query(
+        tcx: TyCtxt<'_, 'gcx, 'tcx>,
+        canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Self>>,
+    ) -> Fallible<CanonicalizedQueryResponse<'gcx, ()>> {
+        tcx.type_op_ascribe_user_type(canonicalized)
+    }
+
+    fn shrink_to_tcx_lifetime(
+        v: &'a CanonicalizedQueryResponse<'gcx, ()>,
+    ) -> &'a Canonical<'tcx, QueryResponse<'tcx, ()>> {
+        v
+    }
+}
+
+BraceStructTypeFoldableImpl! {
+    impl<'tcx> TypeFoldable<'tcx> for AscribeUserType<'tcx> {
+        mir_ty, variance, user_ty
+    }
+}
+
+BraceStructLiftImpl! {
+    impl<'a, 'tcx> Lift<'tcx> for AscribeUserType<'a> {
+        type Lifted = AscribeUserType<'tcx>;
+        mir_ty, variance, user_ty
+    }
+}
+
+impl_stable_hash_for! {
+    struct AscribeUserType<'tcx> {
+        mir_ty, variance, user_ty
+    }
+}
diff --git a/src/librustc/traits/query/type_op/mod.rs b/src/librustc/traits/query/type_op/mod.rs
index b292df758ee..d20d43cf757 100644
--- a/src/librustc/traits/query/type_op/mod.rs
+++ b/src/librustc/traits/query/type_op/mod.rs
@@ -20,6 +20,7 @@ use traits::ObligationCause;
 use ty::fold::TypeFoldable;
 use ty::{Lift, ParamEnvAnd, TyCtxt};
 
+pub mod ascribe_user_type;
 pub mod custom;
 pub mod eq;
 pub mod implied_outlives_bounds;
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index bb9346f2f46..cad90031e97 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -328,7 +328,7 @@ impl Visibility {
     }
 }
 
-#[derive(Clone, PartialEq, RustcDecodable, RustcEncodable, Copy)]
+#[derive(Copy, Clone, PartialEq, Eq, RustcDecodable, RustcEncodable, Hash)]
 pub enum Variance {
     Covariant,      // T<A> <: T<B> iff A <: B -- e.g., function return type
     Invariant,      // T<A> <: T<B> iff B == A -- e.g., type of mutable cell
diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs
index d0c3109da52..0f6ff93c523 100644
--- a/src/librustc/ty/query/config.rs
+++ b/src/librustc/ty/query/config.rs
@@ -14,8 +14,9 @@ use hir::def_id::{CrateNum, DefId, DefIndex};
 use mir::interpret::GlobalId;
 use traits;
 use traits::query::{
-    CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal, CanonicalTypeOpEqGoal,
-    CanonicalTypeOpNormalizeGoal, CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal,
+    CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,
+    CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal,
+    CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal,
 };
 use ty::{self, ParamEnvAnd, Ty, TyCtxt};
 use ty::subst::Substs;
@@ -115,6 +116,15 @@ impl<'tcx> QueryDescription<'tcx> for queries::evaluate_obligation<'tcx> {
     }
 }
 
+impl<'tcx> QueryDescription<'tcx> for queries::type_op_ascribe_user_type<'tcx> {
+    fn describe(
+        _tcx: TyCtxt<'_, '_, '_>,
+        goal: CanonicalTypeOpAscribeUserTypeGoal<'tcx>,
+    ) -> Cow<'static, str> {
+        format!("evaluating `type_op_ascribe_user_type` `{:?}`", goal).into()
+    }
+}
+
 impl<'tcx> QueryDescription<'tcx> for queries::type_op_eq<'tcx> {
     fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTypeOpEqGoal<'tcx>) -> Cow<'static, str> {
         format!("evaluating `type_op_eq` `{:?}`", goal).into()
diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs
index e4fc45f3798..a59a15da08d 100644
--- a/src/librustc/ty/query/mod.rs
+++ b/src/librustc/ty/query/mod.rs
@@ -34,9 +34,12 @@ use mir::interpret::GlobalId;
 use session::{CompileResult, CrateDisambiguator};
 use session::config::OutputFilenames;
 use traits::{self, Vtable};
-use traits::query::{CanonicalPredicateGoal, CanonicalProjectionGoal,
-                    CanonicalTyGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpSubtypeGoal,
-                    CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpNormalizeGoal, NoSolution};
+use traits::query::{
+    CanonicalPredicateGoal, CanonicalProjectionGoal,
+    CanonicalTyGoal, CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal,
+    CanonicalTypeOpSubtypeGoal, CanonicalTypeOpProvePredicateGoal,
+    CanonicalTypeOpNormalizeGoal, NoSolution,
+};
 use traits::query::dropck_outlives::{DtorckConstraint, DropckOutlivesResult};
 use traits::query::normalize::NormalizationResult;
 use traits::query::outlives_bounds::OutlivesBound;
@@ -590,6 +593,14 @@ define_queries! { <'tcx>
         ) -> Result<traits::EvaluationResult, traits::OverflowError>,
 
         /// Do not call this query directly: part of the `Eq` type-op
+        [] fn type_op_ascribe_user_type: TypeOpAscribeUserType(
+            CanonicalTypeOpAscribeUserTypeGoal<'tcx>
+        ) -> Result<
+            Lrc<Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>>,
+            NoSolution,
+        >,
+
+        /// Do not call this query directly: part of the `Eq` type-op
         [] fn type_op_eq: TypeOpEq(
             CanonicalTypeOpEqGoal<'tcx>
         ) -> Result<
diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs
index 71e435fea77..789658dcf72 100644
--- a/src/librustc/ty/query/plumbing.rs
+++ b/src/librustc/ty/query/plumbing.rs
@@ -1079,6 +1079,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
         DepKind::ImpliedOutlivesBounds |
         DepKind::DropckOutlives |
         DepKind::EvaluateObligation |
+        DepKind::TypeOpAscribeUserType |
         DepKind::TypeOpEq |
         DepKind::TypeOpSubtype |
         DepKind::TypeOpProvePredicate |
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index 6db10734474..ace012777c7 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -1008,6 +1008,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
 
                 let ty = self.tcx().type_of(def_id);
                 let ty = ty.subst(tcx, substs);
+                debug!("relate_type_and_user_type: ty of def-id is {:?}", ty);
                 let ty = self.normalize(ty, locations);
 
                 self.relate_types(ty, v1, a, locations, category)?;
diff --git a/src/librustc_traits/type_op.rs b/src/librustc_traits/type_op.rs
index a857cdbda45..bf4e5bda4eb 100644
--- a/src/librustc_traits/type_op.rs
+++ b/src/librustc_traits/type_op.rs
@@ -10,6 +10,7 @@
 
 use rustc::infer::canonical::{Canonical, QueryResponse};
 use rustc::infer::InferCtxt;
+use rustc::traits::query::type_op::ascribe_user_type::AscribeUserType;
 use rustc::traits::query::type_op::eq::Eq;
 use rustc::traits::query::type_op::normalize::Normalize;
 use rustc::traits::query::type_op::prove_predicate::ProvePredicate;
@@ -24,6 +25,7 @@ use std::fmt;
 
 crate fn provide(p: &mut Providers) {
     *p = Providers {
+        type_op_ascribe_user_type,
         type_op_eq,
         type_op_prove_predicate,
         type_op_subtype,
@@ -35,6 +37,18 @@ crate fn provide(p: &mut Providers) {
     };
 }
 
+fn type_op_ascribe_user_type<'tcx>(
+    tcx: TyCtxt<'_, 'tcx, 'tcx>,
+    canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, AscribeUserType<'tcx>>>,
+) -> Result<Lrc<Canonical<'tcx, QueryResponse<'tcx, ()>>>, NoSolution> {
+    tcx.infer_ctxt()
+        .enter_canonical_trait_query(&canonicalized, |infcx, fulfill_cx, key| {
+            let (param_env, AscribeUserType { mir_ty, variance, user_ty }) = key.into_parts();
+            drop((infcx, fulfill_cx, param_env, mir_ty, variance, user_ty));
+            Ok(())
+        })
+}
+
 fn type_op_eq<'tcx>(
     tcx: TyCtxt<'_, 'tcx, 'tcx>,
     canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Eq<'tcx>>>,