diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2018-10-23 20:31:57 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2018-10-24 15:12:40 -0400 |
| commit | 7c8887ccbf7104e98ead7539f3cfbd42332b5e4d (patch) | |
| tree | e0045abb25811d5fa20190a1fe463dac05ed9deb | |
| parent | f99911a4a0bead7dd1f9ef2f90442844434cc391 (diff) | |
| download | rust-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.rs | 6 | ||||
| -rw-r--r-- | src/librustc/mir/mod.rs | 8 | ||||
| -rw-r--r-- | src/librustc/traits/query/mod.rs | 3 | ||||
| -rw-r--r-- | src/librustc/traits/query/type_op/ascribe_user_type.rs | 74 | ||||
| -rw-r--r-- | src/librustc/traits/query/type_op/mod.rs | 1 | ||||
| -rw-r--r-- | src/librustc/ty/mod.rs | 2 | ||||
| -rw-r--r-- | src/librustc/ty/query/config.rs | 14 | ||||
| -rw-r--r-- | src/librustc/ty/query/mod.rs | 17 | ||||
| -rw-r--r-- | src/librustc/ty/query/plumbing.rs | 1 | ||||
| -rw-r--r-- | src/librustc_mir/borrow_check/nll/type_check/mod.rs | 1 | ||||
| -rw-r--r-- | src/librustc_traits/type_op.rs | 14 |
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>>>, |
