introduce a UserTypeAnnotation
enum
This commit is contained in:
parent
e339e84fff
commit
aed6e4a083
13 changed files with 126 additions and 88 deletions
|
@ -587,3 +587,16 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::ClosureOutlivesSubj
|
|||
}
|
||||
|
||||
impl_stable_hash_for!(struct mir::interpret::GlobalId<'tcx> { instance, promoted });
|
||||
|
||||
impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::UserTypeAnnotation<'gcx> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
mem::discriminant(self).hash_stable(hcx, hasher);
|
||||
match *self {
|
||||
mir::UserTypeAnnotation::Ty(ref ty) => {
|
||||
ty.hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<(CanonicalTy<'tcx>, Span)>,
|
||||
pub user_ty: Option<(UserTypeAnnotation<'tcx>, Span)>,
|
||||
|
||||
/// Name of the local, used in debuginfo and pretty-printing.
|
||||
///
|
||||
|
@ -1737,7 +1737,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, CanonicalTy<'tcx>),
|
||||
AscribeUserType(Place<'tcx>, ty::Variance, UserTypeAnnotation<'tcx>),
|
||||
|
||||
/// No-op. Useful for deleting instructions without affecting statement indices.
|
||||
Nop,
|
||||
|
@ -2188,7 +2188,7 @@ pub enum AggregateKind<'tcx> {
|
|||
&'tcx AdtDef,
|
||||
usize,
|
||||
&'tcx Substs<'tcx>,
|
||||
Option<CanonicalTy<'tcx>>,
|
||||
Option<UserTypeAnnotation<'tcx>>,
|
||||
Option<usize>,
|
||||
),
|
||||
|
||||
|
@ -2392,7 +2392,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
|
|||
/// this does not necessarily mean that they are "==" in Rust -- in
|
||||
/// particular one must be wary of `NaN`!
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
|
||||
pub struct Constant<'tcx> {
|
||||
pub span: Span,
|
||||
pub ty: Ty<'tcx>,
|
||||
|
@ -2402,11 +2402,25 @@ pub struct Constant<'tcx> {
|
|||
/// indicate that `Vec<_>` was explicitly specified.
|
||||
///
|
||||
/// Needed for NLL to impose user-given type constraints.
|
||||
pub user_ty: Option<CanonicalTy<'tcx>>,
|
||||
pub user_ty: Option<UserTypeAnnotation<'tcx>>,
|
||||
|
||||
pub literal: &'tcx ty::Const<'tcx>,
|
||||
}
|
||||
|
||||
/// A user-given type annotation attached to a constant. These arise
|
||||
/// from constants that are named via paths, like `Foo::<A>::new` and
|
||||
/// so forth.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
|
||||
pub enum UserTypeAnnotation<'tcx> {
|
||||
Ty(CanonicalTy<'tcx>),
|
||||
}
|
||||
|
||||
EnumTypeFoldableImpl! {
|
||||
impl<'tcx> TypeFoldable<'tcx> for UserTypeAnnotation<'tcx> {
|
||||
(UserTypeAnnotation::Ty)(ty),
|
||||
}
|
||||
}
|
||||
|
||||
newtype_index! {
|
||||
pub struct Promoted {
|
||||
DEBUG_FORMAT = "promoted[{}]"
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
use hir::def_id::DefId;
|
||||
use ty::subst::Substs;
|
||||
use ty::{CanonicalTy, ClosureSubsts, GeneratorSubsts, Region, Ty};
|
||||
use ty::{ClosureSubsts, GeneratorSubsts, Region, Ty};
|
||||
use mir::*;
|
||||
use syntax_pos::Span;
|
||||
|
||||
|
@ -147,9 +147,9 @@ macro_rules! make_mir_visitor {
|
|||
fn visit_ascribe_user_ty(&mut self,
|
||||
place: & $($mutability)* Place<'tcx>,
|
||||
variance: & $($mutability)* ty::Variance,
|
||||
c_ty: & $($mutability)* CanonicalTy<'tcx>,
|
||||
user_ty: & $($mutability)* UserTypeAnnotation<'tcx>,
|
||||
location: Location) {
|
||||
self.super_ascribe_user_ty(place, variance, c_ty, location);
|
||||
self.super_ascribe_user_ty(place, variance, user_ty, location);
|
||||
}
|
||||
|
||||
fn visit_place(&mut self,
|
||||
|
@ -214,8 +214,8 @@ macro_rules! make_mir_visitor {
|
|||
self.super_ty(ty);
|
||||
}
|
||||
|
||||
fn visit_user_ty(&mut self, ty: & $($mutability)* CanonicalTy<'tcx>) {
|
||||
self.super_canonical_ty(ty);
|
||||
fn visit_user_type_annotation(&mut self, ty: & $($mutability)* UserTypeAnnotation<'tcx>) {
|
||||
self.super_user_type_annotation(ty);
|
||||
}
|
||||
|
||||
fn visit_region(&mut self,
|
||||
|
@ -390,9 +390,9 @@ macro_rules! make_mir_visitor {
|
|||
StatementKind::AscribeUserType(
|
||||
ref $($mutability)* place,
|
||||
ref $($mutability)* variance,
|
||||
ref $($mutability)* c_ty,
|
||||
ref $($mutability)* user_ty,
|
||||
) => {
|
||||
self.visit_ascribe_user_ty(place, variance, c_ty, location);
|
||||
self.visit_ascribe_user_ty(place, variance, user_ty, location);
|
||||
}
|
||||
StatementKind::Nop => {}
|
||||
}
|
||||
|
@ -637,10 +637,10 @@ macro_rules! make_mir_visitor {
|
|||
fn super_ascribe_user_ty(&mut self,
|
||||
place: & $($mutability)* Place<'tcx>,
|
||||
_variance: & $($mutability)* ty::Variance,
|
||||
c_ty: & $($mutability)* CanonicalTy<'tcx>,
|
||||
user_ty: & $($mutability)* UserTypeAnnotation<'tcx>,
|
||||
location: Location) {
|
||||
self.visit_place(place, PlaceContext::Validate, location);
|
||||
self.visit_user_ty(c_ty);
|
||||
self.visit_user_type_annotation(user_ty);
|
||||
}
|
||||
|
||||
fn super_place(&mut self,
|
||||
|
@ -736,7 +736,7 @@ macro_rules! make_mir_visitor {
|
|||
source_info: *source_info,
|
||||
});
|
||||
if let Some((user_ty, _)) = user_ty {
|
||||
self.visit_user_ty(user_ty);
|
||||
self.visit_user_type_annotation(user_ty);
|
||||
}
|
||||
self.visit_source_info(source_info);
|
||||
self.visit_source_scope(visibility_scope);
|
||||
|
@ -783,7 +783,7 @@ macro_rules! make_mir_visitor {
|
|||
self.visit_source_scope(scope);
|
||||
}
|
||||
|
||||
fn super_canonical_ty(&mut self, _ty: & $($mutability)* CanonicalTy<'tcx>) {
|
||||
fn super_user_type_annotation(&mut self, _ty: & $($mutability)* UserTypeAnnotation<'tcx>) {
|
||||
}
|
||||
|
||||
fn super_ty(&mut self, _ty: & $($mutability)* Ty<'tcx>) {
|
||||
|
|
|
@ -18,9 +18,10 @@ 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::ty::fold::TypeFoldable;
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::ty::{self, CanonicalTy, ClosureSubsts, GeneratorSubsts, RegionVid};
|
||||
use rustc::ty::{self, ClosureSubsts, GeneratorSubsts, RegionVid};
|
||||
|
||||
pub(super) fn generate_constraints<'cx, 'gcx, 'tcx>(
|
||||
infcx: &InferCtxt<'cx, 'gcx, 'tcx>,
|
||||
|
@ -179,7 +180,7 @@ impl<'cg, 'cx, 'gcx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'gcx
|
|||
&mut self,
|
||||
_place: &Place<'tcx>,
|
||||
_variance: &ty::Variance,
|
||||
_c_ty: &CanonicalTy<'tcx>,
|
||||
_user_ty: &UserTypeAnnotation<'tcx>,
|
||||
_location: Location,
|
||||
) {
|
||||
}
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
// except according to those terms.
|
||||
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::ty::{self, CanonicalTy, ClosureSubsts, GeneratorSubsts, Ty, TypeFoldable};
|
||||
use rustc::mir::{BasicBlock, Location, Mir, Statement, StatementKind};
|
||||
use rustc::ty::{self, ClosureSubsts, GeneratorSubsts, Ty, TypeFoldable};
|
||||
use rustc::mir::{BasicBlock, Location, Mir, Statement, StatementKind, UserTypeAnnotation};
|
||||
use rustc::mir::visit::{MutVisitor, TyContext};
|
||||
use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
|
||||
|
||||
|
@ -65,12 +65,12 @@ impl<'a, 'gcx, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'gcx, 'tcx> {
|
|||
debug!("visit_ty: ty={:?}", ty);
|
||||
}
|
||||
|
||||
fn visit_user_ty(&mut self, _ty: &mut CanonicalTy<'tcx>) {
|
||||
// `user_ty` annotations represent the types that the user
|
||||
fn visit_user_type_annotation(&mut self, _ty: &mut UserTypeAnnotation<'tcx>) {
|
||||
// User type annotations represent the types that the user
|
||||
// wrote in the progarm. We don't want to erase the regions
|
||||
// from these types: rather, we want to add them as
|
||||
// constraints at type-check time.
|
||||
debug!("visit_user_ty: skipping renumber");
|
||||
debug!("visit_user_type_annotation: skipping renumber");
|
||||
}
|
||||
|
||||
fn visit_substs(&mut self, substs: &mut &'tcx Substs<'tcx>, location: Location) {
|
||||
|
|
|
@ -43,7 +43,7 @@ use rustc::traits::query::{Fallible, NoSolution};
|
|||
use rustc::traits::{ObligationCause, PredicateObligations};
|
||||
use rustc::ty::fold::TypeFoldable;
|
||||
use rustc::ty::subst::{Subst, UnpackedKind};
|
||||
use rustc::ty::{self, CanonicalTy, RegionVid, ToPolyTraitRef, Ty, TyCtxt, TyKind};
|
||||
use rustc::ty::{self, RegionVid, ToPolyTraitRef, Ty, TyCtxt, TyKind};
|
||||
use std::rc::Rc;
|
||||
use std::{fmt, iter};
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
|
@ -966,7 +966,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
&mut self,
|
||||
a: Ty<'tcx>,
|
||||
v: ty::Variance,
|
||||
b: CanonicalTy<'tcx>,
|
||||
b: UserTypeAnnotation<'tcx>,
|
||||
locations: Locations,
|
||||
category: ConstraintCategory,
|
||||
) -> Fallible<()> {
|
||||
|
@ -1837,7 +1837,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
/// If this rvalue supports a user-given type annotation, then
|
||||
/// extract and return it. This represents the final type of the
|
||||
/// rvalue and will be unified with the inferred type.
|
||||
fn rvalue_user_ty(&self, rvalue: &Rvalue<'tcx>) -> Option<CanonicalTy<'tcx>> {
|
||||
fn rvalue_user_ty(&self, rvalue: &Rvalue<'tcx>) -> Option<UserTypeAnnotation<'tcx>> {
|
||||
match rvalue {
|
||||
Rvalue::Use(_)
|
||||
| Rvalue::Repeat(..)
|
||||
|
|
|
@ -10,12 +10,12 @@
|
|||
|
||||
use borrow_check::nll::constraints::OutlivesConstraint;
|
||||
use borrow_check::nll::type_check::{BorrowCheckContext, Locations};
|
||||
use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
|
||||
use rustc::infer::nll_relate::{TypeRelating, TypeRelatingDelegate};
|
||||
use rustc::mir::ConstraintCategory;
|
||||
use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
|
||||
use rustc::mir::{ConstraintCategory, UserTypeAnnotation};
|
||||
use rustc::traits::query::Fallible;
|
||||
use rustc::ty::relate::TypeRelation;
|
||||
use rustc::ty::{self, CanonicalTy, Ty};
|
||||
use rustc::ty::{self, Ty};
|
||||
use syntax_pos::DUMMY_SP;
|
||||
|
||||
/// Adds sufficient constraints to ensure that `a <: b`.
|
||||
|
@ -61,20 +61,21 @@ pub(super) fn relate_type_and_user_type<'tcx>(
|
|||
infcx: &InferCtxt<'_, '_, 'tcx>,
|
||||
a: Ty<'tcx>,
|
||||
v: ty::Variance,
|
||||
canonical_b: CanonicalTy<'tcx>,
|
||||
user_ty: UserTypeAnnotation<'tcx>,
|
||||
locations: Locations,
|
||||
category: ConstraintCategory,
|
||||
borrowck_context: Option<&mut BorrowCheckContext<'_, 'tcx>>,
|
||||
) -> Fallible<Ty<'tcx>> {
|
||||
debug!(
|
||||
"relate_type_and_user_type(a={:?}, v={:?}, b={:?}, locations={:?})",
|
||||
a, v, canonical_b, locations
|
||||
a, v, user_ty, locations
|
||||
);
|
||||
|
||||
let (b, _values) = infcx.instantiate_canonical_with_fresh_inference_vars(
|
||||
DUMMY_SP,
|
||||
&canonical_b,
|
||||
);
|
||||
let (b, _values) = match user_ty {
|
||||
UserTypeAnnotation::Ty(canonical_ty) => {
|
||||
infcx.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &canonical_ty)
|
||||
}
|
||||
};
|
||||
|
||||
// The `TypeRelating` code assumes that the "canonical variables"
|
||||
// appear in the "a" side, so flip `Contravariant` ambient
|
||||
|
|
|
@ -20,7 +20,7 @@ use build::{GuardFrame, GuardFrameLocal, LocalsForNode};
|
|||
use hair::*;
|
||||
use rustc::hir;
|
||||
use rustc::mir::*;
|
||||
use rustc::ty::{self, CanonicalTy, Ty};
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc_data_structures::bit_set::BitSet;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use syntax::ast::{Name, NodeId};
|
||||
|
@ -491,7 +491,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||
pub fn visit_bindings(
|
||||
&mut self,
|
||||
pattern: &Pattern<'tcx>,
|
||||
mut pattern_user_ty: Option<(CanonicalTy<'tcx>, Span)>,
|
||||
mut pattern_user_ty: Option<(UserTypeAnnotation<'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<(CanonicalTy<'tcx>, Span)>,
|
||||
Option<(UserTypeAnnotation<'tcx>, Span)>,
|
||||
),
|
||||
) {
|
||||
match *pattern.kind {
|
||||
|
@ -626,7 +626,7 @@ struct Binding<'tcx> {
|
|||
struct Ascription<'tcx> {
|
||||
span: Span,
|
||||
source: Place<'tcx>,
|
||||
user_ty: CanonicalTy<'tcx>,
|
||||
user_ty: UserTypeAnnotation<'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<(CanonicalTy<'tcx>, Span)>,
|
||||
user_var_ty: Option<(UserTypeAnnotation<'tcx>, Span)>,
|
||||
has_guard: ArmHasGuard,
|
||||
opt_match_place: Option<(Option<Place<'tcx>>, Span)>,
|
||||
pat_span: Span,
|
||||
|
|
|
@ -86,12 +86,12 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||
let mut pattern = cx.pattern_from_hir(&local.pat);
|
||||
|
||||
if let Some(ty) = &local.ty {
|
||||
if let Some(user_ty) = cx.tables.user_provided_tys().get(ty.hir_id) {
|
||||
if let Some(&user_ty) = cx.tables.user_provided_tys().get(ty.hir_id) {
|
||||
pattern = Pattern {
|
||||
ty: pattern.ty,
|
||||
span: pattern.span,
|
||||
kind: Box::new(PatternKind::AscribeUserType {
|
||||
user_ty: *user_ty,
|
||||
user_ty: UserTypeAnnotation::Ty(user_ty),
|
||||
user_ty_span: ty.span,
|
||||
subpattern: pattern
|
||||
})
|
||||
|
|
|
@ -296,11 +296,11 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||
|
||||
let user_ty = cx.tables().user_substs(fun.hir_id)
|
||||
.map(|user_substs| {
|
||||
user_substs.unchecked_map(|user_substs| {
|
||||
UserTypeAnnotation::Ty(user_substs.unchecked_map(|user_substs| {
|
||||
// Here, we just pair an `AdtDef` with the
|
||||
// `user_substs`, so no new types etc are introduced.
|
||||
cx.tcx().mk_adt(adt_def, user_substs)
|
||||
})
|
||||
}))
|
||||
});
|
||||
|
||||
let field_refs = args.iter()
|
||||
|
@ -725,9 +725,11 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||
}
|
||||
hir::ExprKind::Type(ref source, ref ty) => {
|
||||
let user_provided_tys = cx.tables.user_provided_tys();
|
||||
let user_ty = *user_provided_tys
|
||||
.get(ty.hir_id)
|
||||
.expect(&format!("{:?} not found in user_provided_tys, source: {:?}", ty, source));
|
||||
let user_ty = UserTypeAnnotation::Ty(
|
||||
*user_provided_tys
|
||||
.get(ty.hir_id)
|
||||
.expect(&format!("{:?} not found in user_provided_tys, source: {:?}", ty, source))
|
||||
);
|
||||
if source.is_place_expr() {
|
||||
ExprKind::PlaceTypeAscription {
|
||||
source: source.to_ref(),
|
||||
|
@ -763,7 +765,7 @@ fn user_substs_applied_to_def(
|
|||
cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
hir_id: hir::HirId,
|
||||
def: &Def,
|
||||
) -> Option<CanonicalTy<'tcx>> {
|
||||
) -> Option<UserTypeAnnotation<'tcx>> {
|
||||
match def {
|
||||
// A reference to something callable -- e.g., a fn, method, or
|
||||
// a tuple-struct or tuple-variant. This has the type of a
|
||||
|
@ -772,11 +774,14 @@ fn user_substs_applied_to_def(
|
|||
Def::Method(_) |
|
||||
Def::StructCtor(_, CtorKind::Fn) |
|
||||
Def::VariantCtor(_, CtorKind::Fn) =>
|
||||
Some(cx.tables().user_substs(hir_id)?.unchecked_map(|user_substs| {
|
||||
// Here, we just pair a `DefId` with the
|
||||
// `user_substs`, so no new types etc are introduced.
|
||||
cx.tcx().mk_fn_def(def.def_id(), user_substs)
|
||||
})),
|
||||
Some(
|
||||
UserTypeAnnotation::Ty(cx.tables().user_substs(hir_id)?.unchecked_map(|user_substs| {
|
||||
// Here, we just pair a `DefId` with the
|
||||
// `user_substs`, so no new types etc are introduced.
|
||||
cx.tcx().mk_fn_def(def.def_id(), user_substs)
|
||||
}),
|
||||
)
|
||||
),
|
||||
|
||||
Def::Const(_def_id) |
|
||||
Def::AssociatedConst(_def_id) =>
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
//! unit-tested and separated from the Rust source and compiler data
|
||||
//! structures.
|
||||
|
||||
use rustc::mir::{BinOp, BorrowKind, Field, UnOp};
|
||||
use rustc::mir::{BinOp, BorrowKind, UserTypeAnnotation, Field, UnOp};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::middle::region;
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::ty::{AdtDef, CanonicalTy, UpvarSubsts, Region, Ty, Const};
|
||||
use rustc::ty::{AdtDef, UpvarSubsts, Region, Ty, Const};
|
||||
use rustc::hir;
|
||||
use syntax::ast;
|
||||
use syntax_pos::Span;
|
||||
|
@ -268,7 +268,7 @@ pub enum ExprKind<'tcx> {
|
|||
|
||||
/// Optional user-given substs: for something like `let x =
|
||||
/// Bar::<T> { ... }`.
|
||||
user_ty: Option<CanonicalTy<'tcx>>,
|
||||
user_ty: Option<UserTypeAnnotation<'tcx>>,
|
||||
|
||||
fields: Vec<FieldExprRef<'tcx>>,
|
||||
base: Option<FruInfo<'tcx>>
|
||||
|
@ -276,12 +276,12 @@ pub enum ExprKind<'tcx> {
|
|||
PlaceTypeAscription {
|
||||
source: ExprRef<'tcx>,
|
||||
/// Type that the user gave to this expression
|
||||
user_ty: CanonicalTy<'tcx>,
|
||||
user_ty: UserTypeAnnotation<'tcx>,
|
||||
},
|
||||
ValueTypeAscription {
|
||||
source: ExprRef<'tcx>,
|
||||
/// Type that the user gave to this expression
|
||||
user_ty: CanonicalTy<'tcx>,
|
||||
user_ty: UserTypeAnnotation<'tcx>,
|
||||
},
|
||||
Closure {
|
||||
closure_id: DefId,
|
||||
|
@ -291,13 +291,7 @@ pub enum ExprKind<'tcx> {
|
|||
},
|
||||
Literal {
|
||||
literal: &'tcx Const<'tcx>,
|
||||
|
||||
/// Optional user-given type: for something like
|
||||
/// `collect::<Vec<_>>`, this would be present and would
|
||||
/// indicate that `Vec<_>` was explicitly specified.
|
||||
///
|
||||
/// Needed for NLL to impose user-given type constraints.
|
||||
user_ty: Option<CanonicalTy<'tcx>>,
|
||||
user_ty: Option<UserTypeAnnotation<'tcx>>,
|
||||
},
|
||||
InlineAsm {
|
||||
asm: &'tcx hir::InlineAsm,
|
||||
|
|
|
@ -20,9 +20,9 @@ use const_eval::{const_field, const_variant_index};
|
|||
|
||||
use hair::util::UserAnnotatedTyHelpers;
|
||||
|
||||
use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability};
|
||||
use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability, UserTypeAnnotation};
|
||||
use rustc::mir::interpret::{Scalar, GlobalId, ConstValue, sign_extend};
|
||||
use rustc::ty::{self, CanonicalTy, TyCtxt, AdtDef, Ty, Region};
|
||||
use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty};
|
||||
use rustc::ty::subst::{Substs, Kind};
|
||||
use rustc::hir::{self, PatKind, RangeEnd};
|
||||
use rustc::hir::def::{Def, CtorKind};
|
||||
|
@ -69,7 +69,7 @@ pub enum PatternKind<'tcx> {
|
|||
Wild,
|
||||
|
||||
AscribeUserType {
|
||||
user_ty: CanonicalTy<'tcx>,
|
||||
user_ty: UserTypeAnnotation<'tcx>,
|
||||
subpattern: Pattern<'tcx>,
|
||||
user_ty_span: Span,
|
||||
},
|
||||
|
@ -980,7 +980,7 @@ 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>, CanonicalTy<'tcx>
|
||||
&'tcx Substs<'tcx>, &'tcx Kind<'tcx>, UserTypeAnnotation<'tcx>
|
||||
}
|
||||
|
||||
impl<'tcx> PatternFoldable<'tcx> for FieldPattern<'tcx> {
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
// except according to those terms.
|
||||
|
||||
use rustc::hir;
|
||||
use rustc::ty::{self, AdtDef, CanonicalTy, TyCtxt};
|
||||
use rustc::mir::UserTypeAnnotation;
|
||||
use rustc::ty::{self, AdtDef, TyCtxt};
|
||||
|
||||
crate trait UserAnnotatedTyHelpers<'gcx: 'tcx, 'tcx> {
|
||||
fn tcx(&self) -> TyCtxt<'_, 'gcx, 'tcx>;
|
||||
|
@ -20,32 +21,41 @@ crate trait UserAnnotatedTyHelpers<'gcx: 'tcx, 'tcx> {
|
|||
&self,
|
||||
hir_id: hir::HirId,
|
||||
adt_def: &'tcx AdtDef,
|
||||
) -> Option<CanonicalTy<'tcx>> {
|
||||
) -> Option<UserTypeAnnotation<'tcx>> {
|
||||
let user_substs = self.tables().user_substs(hir_id)?;
|
||||
Some(user_substs.unchecked_map(|user_substs| {
|
||||
// Here, we just pair an `AdtDef` with the
|
||||
// `user_substs`, so no new types etc are introduced.
|
||||
self.tcx().mk_adt(adt_def, user_substs)
|
||||
}))
|
||||
Some(UserTypeAnnotation::Ty(user_substs.unchecked_map(
|
||||
|user_substs| {
|
||||
// Here, we just pair an `AdtDef` with the
|
||||
// `user_substs`, so no new types etc are introduced.
|
||||
self.tcx().mk_adt(adt_def, user_substs)
|
||||
},
|
||||
)))
|
||||
}
|
||||
|
||||
/// Looks up the type associated with this hir-id and applies the
|
||||
/// user-given substitutions; the hir-id must map to a suitable
|
||||
/// type.
|
||||
fn user_substs_applied_to_ty_of_hir_id(&self, hir_id: hir::HirId) -> Option<CanonicalTy<'tcx>> {
|
||||
fn user_substs_applied_to_ty_of_hir_id(
|
||||
&self,
|
||||
hir_id: hir::HirId,
|
||||
) -> Option<UserTypeAnnotation<'tcx>> {
|
||||
let user_substs = self.tables().user_substs(hir_id)?;
|
||||
match &self.tables().node_id_to_type(hir_id).sty {
|
||||
ty::Adt(adt_def, _) => Some(user_substs.unchecked_map(|user_substs| {
|
||||
// Ok to call `unchecked_map` because we just pair an
|
||||
// `AdtDef` with the `user_substs`, so no new types
|
||||
// etc are introduced.
|
||||
self.tcx().mk_adt(adt_def, user_substs)
|
||||
})),
|
||||
ty::FnDef(def_id, _) => Some(user_substs.unchecked_map(|user_substs| {
|
||||
// Here, we just pair a `DefId` with the
|
||||
// `user_substs`, so no new types etc are introduced.
|
||||
self.tcx().mk_fn_def(*def_id, user_substs)
|
||||
})),
|
||||
ty::Adt(adt_def, _) => Some(UserTypeAnnotation::Ty(user_substs.unchecked_map(
|
||||
|user_substs| {
|
||||
// Ok to call `unchecked_map` because we just pair an
|
||||
// `AdtDef` with the `user_substs`, so no new types
|
||||
// etc are introduced.
|
||||
self.tcx().mk_adt(adt_def, user_substs)
|
||||
},
|
||||
))),
|
||||
ty::FnDef(def_id, _) => Some(UserTypeAnnotation::Ty(user_substs.unchecked_map(
|
||||
|user_substs| {
|
||||
// Here, we just pair a `DefId` with the
|
||||
// `user_substs`, so no new types etc are introduced.
|
||||
self.tcx().mk_fn_def(*def_id, user_substs)
|
||||
},
|
||||
))),
|
||||
sty => bug!(
|
||||
"sty: {:?} should not have user-substs {:?} recorded ",
|
||||
sty,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue