introduce (but do not use) ascribe_user_type goal
Lots of annoying boilerplate.
This commit is contained in:
parent
f99911a4a0
commit
7c8887ccbf
11 changed files with 133 additions and 8 deletions
|
|
@ -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>),
|
||||
|
|
|
|||
|
|
@ -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[{}]"
|
||||
|
|
|
|||
|
|
@ -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>>>;
|
||||
|
||||
|
|
|
|||
74
src/librustc/traits/query/type_op/ascribe_user_type.rs
Normal file
74
src/librustc/traits/query/type_op/ascribe_user_type.rs
Normal file
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -589,6 +592,14 @@ define_queries! { <'tcx>
|
|||
CanonicalPredicateGoal<'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>
|
||||
|
|
|
|||
|
|
@ -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 |
|
||||
|
|
|
|||
|
|
@ -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)?;
|
||||
|
|
|
|||
|
|
@ -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>>>,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue