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