Skip to content

Commit aed6e4a

Browse files
committed
introduce a UserTypeAnnotation enum
1 parent e339e84 commit aed6e4a

File tree

13 files changed

+126
-88
lines changed

13 files changed

+126
-88
lines changed

src/librustc/ich/impls_mir.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,3 +587,16 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::ClosureOutlivesSubj
587587
}
588588

589589
impl_stable_hash_for!(struct mir::interpret::GlobalId<'tcx> { instance, promoted });
590+
591+
impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::UserTypeAnnotation<'gcx> {
592+
fn hash_stable<W: StableHasherResult>(&self,
593+
hcx: &mut StableHashingContext<'a>,
594+
hasher: &mut StableHasher<W>) {
595+
mem::discriminant(self).hash_stable(hcx, hasher);
596+
match *self {
597+
mir::UserTypeAnnotation::Ty(ref ty) => {
598+
ty.hash_stable(hcx, hasher);
599+
}
600+
}
601+
}
602+
}

src/librustc/mir/mod.rs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,7 @@ pub struct LocalDecl<'tcx> {
710710
/// e.g. via `let x: T`, then we carry that type here. The MIR
711711
/// borrow checker needs this information since it can affect
712712
/// region inference.
713-
pub user_ty: Option<(CanonicalTy<'tcx>, Span)>,
713+
pub user_ty: Option<(UserTypeAnnotation<'tcx>, Span)>,
714714

715715
/// Name of the local, used in debuginfo and pretty-printing.
716716
///
@@ -1737,7 +1737,7 @@ pub enum StatementKind<'tcx> {
17371737
/// - `Contravariant` -- requires that `T_y :> T`
17381738
/// - `Invariant` -- requires that `T_y == T`
17391739
/// - `Bivariant` -- no effect
1740-
AscribeUserType(Place<'tcx>, ty::Variance, CanonicalTy<'tcx>),
1740+
AscribeUserType(Place<'tcx>, ty::Variance, UserTypeAnnotation<'tcx>),
17411741

17421742
/// No-op. Useful for deleting instructions without affecting statement indices.
17431743
Nop,
@@ -2188,7 +2188,7 @@ pub enum AggregateKind<'tcx> {
21882188
&'tcx AdtDef,
21892189
usize,
21902190
&'tcx Substs<'tcx>,
2191-
Option<CanonicalTy<'tcx>>,
2191+
Option<UserTypeAnnotation<'tcx>>,
21922192
Option<usize>,
21932193
),
21942194

@@ -2392,7 +2392,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
23922392
/// this does not necessarily mean that they are "==" in Rust -- in
23932393
/// particular one must be wary of `NaN`!
23942394
2395-
#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
2395+
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
23962396
pub struct Constant<'tcx> {
23972397
pub span: Span,
23982398
pub ty: Ty<'tcx>,
@@ -2402,11 +2402,25 @@ pub struct Constant<'tcx> {
24022402
/// indicate that `Vec<_>` was explicitly specified.
24032403
///
24042404
/// Needed for NLL to impose user-given type constraints.
2405-
pub user_ty: Option<CanonicalTy<'tcx>>,
2405+
pub user_ty: Option<UserTypeAnnotation<'tcx>>,
24062406

24072407
pub literal: &'tcx ty::Const<'tcx>,
24082408
}
24092409

2410+
/// A user-given type annotation attached to a constant. These arise
2411+
/// from constants that are named via paths, like `Foo::<A>::new` and
2412+
/// so forth.
2413+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
2414+
pub enum UserTypeAnnotation<'tcx> {
2415+
Ty(CanonicalTy<'tcx>),
2416+
}
2417+
2418+
EnumTypeFoldableImpl! {
2419+
impl<'tcx> TypeFoldable<'tcx> for UserTypeAnnotation<'tcx> {
2420+
(UserTypeAnnotation::Ty)(ty),
2421+
}
2422+
}
2423+
24102424
newtype_index! {
24112425
pub struct Promoted {
24122426
DEBUG_FORMAT = "promoted[{}]"

src/librustc/mir/visit.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
use hir::def_id::DefId;
1212
use ty::subst::Substs;
13-
use ty::{CanonicalTy, ClosureSubsts, GeneratorSubsts, Region, Ty};
13+
use ty::{ClosureSubsts, GeneratorSubsts, Region, Ty};
1414
use mir::*;
1515
use syntax_pos::Span;
1616

@@ -147,9 +147,9 @@ macro_rules! make_mir_visitor {
147147
fn visit_ascribe_user_ty(&mut self,
148148
place: & $($mutability)* Place<'tcx>,
149149
variance: & $($mutability)* ty::Variance,
150-
c_ty: & $($mutability)* CanonicalTy<'tcx>,
150+
user_ty: & $($mutability)* UserTypeAnnotation<'tcx>,
151151
location: Location) {
152-
self.super_ascribe_user_ty(place, variance, c_ty, location);
152+
self.super_ascribe_user_ty(place, variance, user_ty, location);
153153
}
154154

155155
fn visit_place(&mut self,
@@ -214,8 +214,8 @@ macro_rules! make_mir_visitor {
214214
self.super_ty(ty);
215215
}
216216

217-
fn visit_user_ty(&mut self, ty: & $($mutability)* CanonicalTy<'tcx>) {
218-
self.super_canonical_ty(ty);
217+
fn visit_user_type_annotation(&mut self, ty: & $($mutability)* UserTypeAnnotation<'tcx>) {
218+
self.super_user_type_annotation(ty);
219219
}
220220

221221
fn visit_region(&mut self,
@@ -390,9 +390,9 @@ macro_rules! make_mir_visitor {
390390
StatementKind::AscribeUserType(
391391
ref $($mutability)* place,
392392
ref $($mutability)* variance,
393-
ref $($mutability)* c_ty,
393+
ref $($mutability)* user_ty,
394394
) => {
395-
self.visit_ascribe_user_ty(place, variance, c_ty, location);
395+
self.visit_ascribe_user_ty(place, variance, user_ty, location);
396396
}
397397
StatementKind::Nop => {}
398398
}
@@ -637,10 +637,10 @@ macro_rules! make_mir_visitor {
637637
fn super_ascribe_user_ty(&mut self,
638638
place: & $($mutability)* Place<'tcx>,
639639
_variance: & $($mutability)* ty::Variance,
640-
c_ty: & $($mutability)* CanonicalTy<'tcx>,
640+
user_ty: & $($mutability)* UserTypeAnnotation<'tcx>,
641641
location: Location) {
642642
self.visit_place(place, PlaceContext::Validate, location);
643-
self.visit_user_ty(c_ty);
643+
self.visit_user_type_annotation(user_ty);
644644
}
645645

646646
fn super_place(&mut self,
@@ -736,7 +736,7 @@ macro_rules! make_mir_visitor {
736736
source_info: *source_info,
737737
});
738738
if let Some((user_ty, _)) = user_ty {
739-
self.visit_user_ty(user_ty);
739+
self.visit_user_type_annotation(user_ty);
740740
}
741741
self.visit_source_info(source_info);
742742
self.visit_source_scope(visibility_scope);
@@ -783,7 +783,7 @@ macro_rules! make_mir_visitor {
783783
self.visit_source_scope(scope);
784784
}
785785

786-
fn super_canonical_ty(&mut self, _ty: & $($mutability)* CanonicalTy<'tcx>) {
786+
fn super_user_type_annotation(&mut self, _ty: & $($mutability)* UserTypeAnnotation<'tcx>) {
787787
}
788788

789789
fn super_ty(&mut self, _ty: & $($mutability)* Ty<'tcx>) {

src/librustc_mir/borrow_check/nll/constraint_generation.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ use rustc::mir::visit::TyContext;
1818
use rustc::mir::visit::Visitor;
1919
use rustc::mir::{BasicBlock, BasicBlockData, Location, Mir, Place, Rvalue};
2020
use rustc::mir::{Statement, Terminator};
21+
use rustc::mir::UserTypeAnnotation;
2122
use rustc::ty::fold::TypeFoldable;
2223
use rustc::ty::subst::Substs;
23-
use rustc::ty::{self, CanonicalTy, ClosureSubsts, GeneratorSubsts, RegionVid};
24+
use rustc::ty::{self, ClosureSubsts, GeneratorSubsts, RegionVid};
2425

2526
pub(super) fn generate_constraints<'cx, 'gcx, 'tcx>(
2627
infcx: &InferCtxt<'cx, 'gcx, 'tcx>,
@@ -179,7 +180,7 @@ impl<'cg, 'cx, 'gcx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'gcx
179180
&mut self,
180181
_place: &Place<'tcx>,
181182
_variance: &ty::Variance,
182-
_c_ty: &CanonicalTy<'tcx>,
183+
_user_ty: &UserTypeAnnotation<'tcx>,
183184
_location: Location,
184185
) {
185186
}

src/librustc_mir/borrow_check/nll/renumber.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
// except according to those terms.
1010

1111
use rustc::ty::subst::Substs;
12-
use rustc::ty::{self, CanonicalTy, ClosureSubsts, GeneratorSubsts, Ty, TypeFoldable};
13-
use rustc::mir::{BasicBlock, Location, Mir, Statement, StatementKind};
12+
use rustc::ty::{self, ClosureSubsts, GeneratorSubsts, Ty, TypeFoldable};
13+
use rustc::mir::{BasicBlock, Location, Mir, Statement, StatementKind, UserTypeAnnotation};
1414
use rustc::mir::visit::{MutVisitor, TyContext};
1515
use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
1616

@@ -65,12 +65,12 @@ impl<'a, 'gcx, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'gcx, 'tcx> {
6565
debug!("visit_ty: ty={:?}", ty);
6666
}
6767

68-
fn visit_user_ty(&mut self, _ty: &mut CanonicalTy<'tcx>) {
69-
// `user_ty` annotations represent the types that the user
68+
fn visit_user_type_annotation(&mut self, _ty: &mut UserTypeAnnotation<'tcx>) {
69+
// User type annotations represent the types that the user
7070
// wrote in the progarm. We don't want to erase the regions
7171
// from these types: rather, we want to add them as
7272
// constraints at type-check time.
73-
debug!("visit_user_ty: skipping renumber");
73+
debug!("visit_user_type_annotation: skipping renumber");
7474
}
7575

7676
fn visit_substs(&mut self, substs: &mut &'tcx Substs<'tcx>, location: Location) {

src/librustc_mir/borrow_check/nll/type_check/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ use rustc::traits::query::{Fallible, NoSolution};
4343
use rustc::traits::{ObligationCause, PredicateObligations};
4444
use rustc::ty::fold::TypeFoldable;
4545
use rustc::ty::subst::{Subst, UnpackedKind};
46-
use rustc::ty::{self, CanonicalTy, RegionVid, ToPolyTraitRef, Ty, TyCtxt, TyKind};
46+
use rustc::ty::{self, RegionVid, ToPolyTraitRef, Ty, TyCtxt, TyKind};
4747
use std::rc::Rc;
4848
use std::{fmt, iter};
4949
use syntax_pos::{Span, DUMMY_SP};
@@ -966,7 +966,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
966966
&mut self,
967967
a: Ty<'tcx>,
968968
v: ty::Variance,
969-
b: CanonicalTy<'tcx>,
969+
b: UserTypeAnnotation<'tcx>,
970970
locations: Locations,
971971
category: ConstraintCategory,
972972
) -> Fallible<()> {
@@ -1837,7 +1837,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
18371837
/// If this rvalue supports a user-given type annotation, then
18381838
/// extract and return it. This represents the final type of the
18391839
/// rvalue and will be unified with the inferred type.
1840-
fn rvalue_user_ty(&self, rvalue: &Rvalue<'tcx>) -> Option<CanonicalTy<'tcx>> {
1840+
fn rvalue_user_ty(&self, rvalue: &Rvalue<'tcx>) -> Option<UserTypeAnnotation<'tcx>> {
18411841
match rvalue {
18421842
Rvalue::Use(_)
18431843
| Rvalue::Repeat(..)

src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010

1111
use borrow_check::nll::constraints::OutlivesConstraint;
1212
use borrow_check::nll::type_check::{BorrowCheckContext, Locations};
13-
use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
1413
use rustc::infer::nll_relate::{TypeRelating, TypeRelatingDelegate};
15-
use rustc::mir::ConstraintCategory;
14+
use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
15+
use rustc::mir::{ConstraintCategory, UserTypeAnnotation};
1616
use rustc::traits::query::Fallible;
1717
use rustc::ty::relate::TypeRelation;
18-
use rustc::ty::{self, CanonicalTy, Ty};
18+
use rustc::ty::{self, Ty};
1919
use syntax_pos::DUMMY_SP;
2020

2121
/// Adds sufficient constraints to ensure that `a <: b`.
@@ -61,20 +61,21 @@ pub(super) fn relate_type_and_user_type<'tcx>(
6161
infcx: &InferCtxt<'_, '_, 'tcx>,
6262
a: Ty<'tcx>,
6363
v: ty::Variance,
64-
canonical_b: CanonicalTy<'tcx>,
64+
user_ty: UserTypeAnnotation<'tcx>,
6565
locations: Locations,
6666
category: ConstraintCategory,
6767
borrowck_context: Option<&mut BorrowCheckContext<'_, 'tcx>>,
6868
) -> Fallible<Ty<'tcx>> {
6969
debug!(
7070
"relate_type_and_user_type(a={:?}, v={:?}, b={:?}, locations={:?})",
71-
a, v, canonical_b, locations
71+
a, v, user_ty, locations
7272
);
7373

74-
let (b, _values) = infcx.instantiate_canonical_with_fresh_inference_vars(
75-
DUMMY_SP,
76-
&canonical_b,
77-
);
74+
let (b, _values) = match user_ty {
75+
UserTypeAnnotation::Ty(canonical_ty) => {
76+
infcx.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &canonical_ty)
77+
}
78+
};
7879

7980
// The `TypeRelating` code assumes that the "canonical variables"
8081
// appear in the "a" side, so flip `Contravariant` ambient

src/librustc_mir/build/matches/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use build::{GuardFrame, GuardFrameLocal, LocalsForNode};
2020
use hair::*;
2121
use rustc::hir;
2222
use rustc::mir::*;
23-
use rustc::ty::{self, CanonicalTy, Ty};
23+
use rustc::ty::{self, Ty};
2424
use rustc_data_structures::bit_set::BitSet;
2525
use rustc_data_structures::fx::FxHashMap;
2626
use syntax::ast::{Name, NodeId};
@@ -491,7 +491,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
491491
pub fn visit_bindings(
492492
&mut self,
493493
pattern: &Pattern<'tcx>,
494-
mut pattern_user_ty: Option<(CanonicalTy<'tcx>, Span)>,
494+
mut pattern_user_ty: Option<(UserTypeAnnotation<'tcx>, Span)>,
495495
f: &mut impl FnMut(
496496
&mut Self,
497497
Mutability,
@@ -500,7 +500,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
500500
NodeId,
501501
Span,
502502
Ty<'tcx>,
503-
Option<(CanonicalTy<'tcx>, Span)>,
503+
Option<(UserTypeAnnotation<'tcx>, Span)>,
504504
),
505505
) {
506506
match *pattern.kind {
@@ -626,7 +626,7 @@ struct Binding<'tcx> {
626626
struct Ascription<'tcx> {
627627
span: Span,
628628
source: Place<'tcx>,
629-
user_ty: CanonicalTy<'tcx>,
629+
user_ty: UserTypeAnnotation<'tcx>,
630630
}
631631

632632
#[derive(Clone, Debug)]
@@ -1470,7 +1470,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
14701470
num_patterns: usize,
14711471
var_id: NodeId,
14721472
var_ty: Ty<'tcx>,
1473-
user_var_ty: Option<(CanonicalTy<'tcx>, Span)>,
1473+
user_var_ty: Option<(UserTypeAnnotation<'tcx>, Span)>,
14741474
has_guard: ArmHasGuard,
14751475
opt_match_place: Option<(Option<Place<'tcx>>, Span)>,
14761476
pat_span: Span,

src/librustc_mir/hair/cx/block.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,12 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
8686
let mut pattern = cx.pattern_from_hir(&local.pat);
8787

8888
if let Some(ty) = &local.ty {
89-
if let Some(user_ty) = cx.tables.user_provided_tys().get(ty.hir_id) {
89+
if let Some(&user_ty) = cx.tables.user_provided_tys().get(ty.hir_id) {
9090
pattern = Pattern {
9191
ty: pattern.ty,
9292
span: pattern.span,
9393
kind: Box::new(PatternKind::AscribeUserType {
94-
user_ty: *user_ty,
94+
user_ty: UserTypeAnnotation::Ty(user_ty),
9595
user_ty_span: ty.span,
9696
subpattern: pattern
9797
})

src/librustc_mir/hair/cx/expr.rs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -296,11 +296,11 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
296296

297297
let user_ty = cx.tables().user_substs(fun.hir_id)
298298
.map(|user_substs| {
299-
user_substs.unchecked_map(|user_substs| {
299+
UserTypeAnnotation::Ty(user_substs.unchecked_map(|user_substs| {
300300
// Here, we just pair an `AdtDef` with the
301301
// `user_substs`, so no new types etc are introduced.
302302
cx.tcx().mk_adt(adt_def, user_substs)
303-
})
303+
}))
304304
});
305305

306306
let field_refs = args.iter()
@@ -725,9 +725,11 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
725725
}
726726
hir::ExprKind::Type(ref source, ref ty) => {
727727
let user_provided_tys = cx.tables.user_provided_tys();
728-
let user_ty = *user_provided_tys
729-
.get(ty.hir_id)
730-
.expect(&format!("{:?} not found in user_provided_tys, source: {:?}", ty, source));
728+
let user_ty = UserTypeAnnotation::Ty(
729+
*user_provided_tys
730+
.get(ty.hir_id)
731+
.expect(&format!("{:?} not found in user_provided_tys, source: {:?}", ty, source))
732+
);
731733
if source.is_place_expr() {
732734
ExprKind::PlaceTypeAscription {
733735
source: source.to_ref(),
@@ -763,7 +765,7 @@ fn user_substs_applied_to_def(
763765
cx: &mut Cx<'a, 'gcx, 'tcx>,
764766
hir_id: hir::HirId,
765767
def: &Def,
766-
) -> Option<CanonicalTy<'tcx>> {
768+
) -> Option<UserTypeAnnotation<'tcx>> {
767769
match def {
768770
// A reference to something callable -- e.g., a fn, method, or
769771
// a tuple-struct or tuple-variant. This has the type of a
@@ -772,11 +774,14 @@ fn user_substs_applied_to_def(
772774
Def::Method(_) |
773775
Def::StructCtor(_, CtorKind::Fn) |
774776
Def::VariantCtor(_, CtorKind::Fn) =>
775-
Some(cx.tables().user_substs(hir_id)?.unchecked_map(|user_substs| {
776-
// Here, we just pair a `DefId` with the
777-
// `user_substs`, so no new types etc are introduced.
778-
cx.tcx().mk_fn_def(def.def_id(), user_substs)
779-
})),
777+
Some(
778+
UserTypeAnnotation::Ty(cx.tables().user_substs(hir_id)?.unchecked_map(|user_substs| {
779+
// Here, we just pair a `DefId` with the
780+
// `user_substs`, so no new types etc are introduced.
781+
cx.tcx().mk_fn_def(def.def_id(), user_substs)
782+
}),
783+
)
784+
),
780785

781786
Def::Const(_def_id) |
782787
Def::AssociatedConst(_def_id) =>

0 commit comments

Comments
 (0)