Added mir::UserTypeProjection, a stub for a structure that projects *into* a given UserTypeAnnotation.

(That is, it will pull out some component type held or referenced by
the type annotation.)

Note: this still needs to actually do projection itself. That comes in
a later commit
This commit is contained in:
Felix S. Klock II 2018-10-22 11:58:06 +02:00
parent 36d8432a6d
commit 28ce99df86
10 changed files with 71 additions and 33 deletions

View File

@ -606,3 +606,5 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::UserTypeAnnotation<
}
}
}
impl_stable_hash_for!(struct mir::UserTypeProjection<'tcx> { base });

View File

@ -710,7 +710,7 @@ pub struct LocalDecl<'tcx> {
/// e.g. via `let x: T`, then we carry that type here. The MIR
/// borrow checker needs this information since it can affect
/// region inference.
pub user_ty: Option<(UserTypeAnnotation<'tcx>, Span)>,
pub user_ty: Option<(UserTypeProjection<'tcx>, Span)>,
/// Name of the local, used in debuginfo and pretty-printing.
///
@ -1741,7 +1741,7 @@ pub enum StatementKind<'tcx> {
/// - `Contravariant` -- requires that `T_y :> T`
/// - `Invariant` -- requires that `T_y == T`
/// - `Bivariant` -- no effect
AscribeUserType(Place<'tcx>, ty::Variance, Box<UserTypeAnnotation<'tcx>>),
AscribeUserType(Place<'tcx>, ty::Variance, Box<UserTypeProjection<'tcx>>),
/// No-op. Useful for deleting instructions without affecting statement indices.
Nop,
@ -2449,6 +2449,17 @@ EnumLiftImpl! {
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub struct UserTypeProjection<'tcx> {
pub base: UserTypeAnnotation<'tcx>,
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection<'tcx> {
base
}
}
newtype_index! {
pub struct Promoted {
DEBUG_FORMAT = "promoted[{}]"

View File

@ -147,7 +147,7 @@ macro_rules! make_mir_visitor {
fn visit_ascribe_user_ty(&mut self,
place: & $($mutability)* Place<'tcx>,
variance: & $($mutability)* ty::Variance,
user_ty: & $($mutability)* UserTypeAnnotation<'tcx>,
user_ty: & $($mutability)* UserTypeProjection<'tcx>,
location: Location) {
self.super_ascribe_user_ty(place, variance, user_ty, location);
}
@ -213,6 +213,13 @@ macro_rules! make_mir_visitor {
self.super_ty(ty);
}
fn visit_user_type_projection(
&mut self,
ty: & $($mutability)* UserTypeProjection<'tcx>,
) {
self.super_user_type_projection(ty);
}
fn visit_user_type_annotation(
&mut self,
ty: & $($mutability)* UserTypeAnnotation<'tcx>,
@ -639,10 +646,10 @@ macro_rules! make_mir_visitor {
fn super_ascribe_user_ty(&mut self,
place: & $($mutability)* Place<'tcx>,
_variance: & $($mutability)* ty::Variance,
user_ty: & $($mutability)* UserTypeAnnotation<'tcx>,
user_ty: & $($mutability)* UserTypeProjection<'tcx>,
location: Location) {
self.visit_place(place, PlaceContext::Validate, location);
self.visit_user_type_annotation(user_ty);
self.visit_user_type_projection(user_ty);
}
fn super_place(&mut self,
@ -737,7 +744,7 @@ macro_rules! make_mir_visitor {
source_info: *source_info,
});
if let Some((user_ty, _)) = user_ty {
self.visit_user_type_annotation(user_ty);
self.visit_user_type_projection(user_ty);
}
self.visit_source_info(source_info);
self.visit_source_scope(visibility_scope);
@ -784,6 +791,16 @@ macro_rules! make_mir_visitor {
self.visit_source_scope(scope);
}
fn super_user_type_projection(
&mut self,
ty: & $($mutability)* UserTypeProjection<'tcx>,
) {
let UserTypeProjection {
ref $($mutability)* base,
} = *ty;
self.visit_user_type_annotation(base)
}
fn super_user_type_annotation(
&mut self,
_ty: & $($mutability)* UserTypeAnnotation<'tcx>,

View File

@ -18,7 +18,7 @@ use rustc::mir::visit::TyContext;
use rustc::mir::visit::Visitor;
use rustc::mir::{BasicBlock, BasicBlockData, Location, Mir, Place, Rvalue};
use rustc::mir::{Statement, Terminator};
use rustc::mir::UserTypeAnnotation;
use rustc::mir::UserTypeProjection;
use rustc::ty::fold::TypeFoldable;
use rustc::ty::subst::Substs;
use rustc::ty::{self, ClosureSubsts, GeneratorSubsts, RegionVid};
@ -183,7 +183,7 @@ impl<'cg, 'cx, 'gcx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'gcx
&mut self,
_place: &Place<'tcx>,
_variance: &ty::Variance,
_user_ty: &UserTypeAnnotation<'tcx>,
_user_ty: &UserTypeProjection<'tcx>,
_location: Location,
) {
}

View File

@ -284,7 +284,7 @@ impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> {
if let Err(terr) = self.cx.relate_type_and_user_type(
constant.ty,
ty::Variance::Invariant,
user_ty,
UserTypeProjection { base: user_ty },
location.to_locations(),
ConstraintCategory::Boring,
) {
@ -971,7 +971,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
&mut self,
a: Ty<'tcx>,
v: ty::Variance,
user_ty: UserTypeAnnotation<'tcx>,
user_ty: UserTypeProjection<'tcx>,
locations: Locations,
category: ConstraintCategory,
) -> Fallible<()> {
@ -980,7 +980,8 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
a, v, user_ty, locations,
);
match user_ty {
// FIXME
match user_ty.base {
UserTypeAnnotation::Ty(canonical_ty) => {
let (ty, _) = self.infcx
.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &canonical_ty);
@ -1172,7 +1173,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
if let Err(terr) = self.relate_type_and_user_type(
rv_ty,
ty::Variance::Invariant,
user_ty,
UserTypeProjection { base: user_ty },
location.to_locations(),
ConstraintCategory::Boring,
) {

View File

@ -147,7 +147,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
kind: StatementKind::AscribeUserType(
place.clone(),
Variance::Invariant,
box user_ty,
box UserTypeProjection { base: user_ty },
),
},
);
@ -167,7 +167,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
kind: StatementKind::AscribeUserType(
Place::Local(temp.clone()),
Variance::Invariant,
box user_ty,
box UserTypeProjection { base: user_ty },
),
},
);

View File

@ -491,7 +491,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
pub(super) fn visit_bindings(
&mut self,
pattern: &Pattern<'tcx>,
mut pattern_user_ty: Option<(PatternTypeAnnotation<'tcx>, Span)>,
mut pattern_user_ty: Option<(PatternTypeProjection<'tcx>, Span)>,
f: &mut impl FnMut(
&mut Self,
Mutability,
@ -500,7 +500,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
NodeId,
Span,
Ty<'tcx>,
Option<(PatternTypeAnnotation<'tcx>, Span)>,
Option<(PatternTypeProjection<'tcx>, Span)>,
),
) {
match *pattern.kind {
@ -626,7 +626,7 @@ struct Binding<'tcx> {
struct Ascription<'tcx> {
span: Span,
source: Place<'tcx>,
user_ty: PatternTypeAnnotation<'tcx>,
user_ty: PatternTypeProjection<'tcx>,
}
#[derive(Clone, Debug)]
@ -1470,7 +1470,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
num_patterns: usize,
var_id: NodeId,
var_ty: Ty<'tcx>,
user_var_ty: Option<(PatternTypeAnnotation<'tcx>, Span)>,
user_var_ty: Option<(PatternTypeProjection<'tcx>, Span)>,
has_guard: ArmHasGuard,
opt_match_place: Option<(Option<Place<'tcx>>, Span)>,
pat_span: Span,
@ -1489,7 +1489,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let local = LocalDecl::<'tcx> {
mutability,
ty: var_ty,
user_ty: user_var_ty.map(|(pat_ty, span)|(pat_ty.user_ty(), span)),
user_ty: user_var_ty.map(|(ut, sp)| (ut.user_ty(), sp)),
name: Some(name),
source_info,
visibility_scope,

View File

@ -91,7 +91,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
ty: pattern.ty,
span: pattern.span,
kind: Box::new(PatternKind::AscribeUserType {
user_ty: PatternTypeAnnotation::from_c_ty(user_ty),
user_ty: PatternTypeProjection::from_canonical_ty(user_ty),
user_ty_span: ty.span,
subpattern: pattern
})

View File

@ -27,7 +27,7 @@ use self::cx::Cx;
pub mod cx;
pub mod pattern;
pub use self::pattern::{BindingMode, Pattern, PatternKind, PatternTypeAnnotation, FieldPattern};
pub use self::pattern::{BindingMode, Pattern, PatternKind, PatternTypeProjection, FieldPattern};
mod util;

View File

@ -20,7 +20,8 @@ use const_eval::{const_field, const_variant_index};
use hair::util::UserAnnotatedTyHelpers;
use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability, UserTypeAnnotation};
use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability};
use rustc::mir::{UserTypeAnnotation, UserTypeProjection};
use rustc::mir::interpret::{Scalar, GlobalId, ConstValue, sign_extend};
use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty};
use rustc::ty::subst::{Substs, Kind};
@ -65,17 +66,22 @@ pub struct Pattern<'tcx> {
}
#[derive(Copy, Clone, Debug)]
pub struct PatternTypeAnnotation<'tcx>(UserTypeAnnotation<'tcx>);
pub struct PatternTypeProjection<'tcx>(UserTypeProjection<'tcx>);
impl<'tcx> PatternTypeAnnotation<'tcx> {
pub(crate) fn from_c_ty(c_ty: ty::CanonicalTy<'tcx>) -> Self {
Self::from_u_ty(UserTypeAnnotation::Ty(c_ty))
}
pub(crate) fn from_u_ty(u_ty: UserTypeAnnotation<'tcx>) -> Self {
PatternTypeAnnotation(u_ty)
impl<'tcx> PatternTypeProjection<'tcx> {
pub(crate) fn from_canonical_ty(c_ty: ty::CanonicalTy<'tcx>) -> Self {
Self::from_user_type(UserTypeAnnotation::Ty(c_ty))
}
pub(crate) fn user_ty(self) -> UserTypeAnnotation<'tcx> { self.0 }
pub(crate) fn from_user_type(u_ty: UserTypeAnnotation<'tcx>) -> Self {
Self::from_user_type_proj(UserTypeProjection { base: u_ty })
}
pub(crate) fn from_user_type_proj(u_ty: UserTypeProjection<'tcx>) -> Self {
PatternTypeProjection(u_ty)
}
pub(crate) fn user_ty(self) -> UserTypeProjection<'tcx> { self.0 }
}
#[derive(Clone, Debug)]
@ -83,7 +89,7 @@ pub enum PatternKind<'tcx> {
Wild,
AscribeUserType {
user_ty: PatternTypeAnnotation<'tcx>,
user_ty: PatternTypeProjection<'tcx>,
subpattern: Pattern<'tcx>,
user_ty_span: Span,
},
@ -704,7 +710,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
debug!("pattern user_ty = {:?} for pattern at {:?}", user_ty, span);
let pat_ty = PatternTypeAnnotation::from_u_ty(user_ty);
let pat_ty = PatternTypeProjection::from_user_type(user_ty);
kind = PatternKind::AscribeUserType {
subpattern,
user_ty: pat_ty,
@ -995,7 +1001,8 @@ macro_rules! CloneImpls {
CloneImpls!{ <'tcx>
Span, Field, Mutability, ast::Name, ast::NodeId, usize, &'tcx ty::Const<'tcx>,
Region<'tcx>, Ty<'tcx>, BindingMode<'tcx>, &'tcx AdtDef,
&'tcx Substs<'tcx>, &'tcx Kind<'tcx>, UserTypeAnnotation<'tcx>, PatternTypeAnnotation<'tcx>
&'tcx Substs<'tcx>, &'tcx Kind<'tcx>, UserTypeAnnotation<'tcx>,
UserTypeProjection<'tcx>, PatternTypeProjection<'tcx>
}
impl<'tcx> PatternFoldable<'tcx> for FieldPattern<'tcx> {