]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_mir/build/matches/mod.rs
Refactoring: added `PatternTypeAnnotation` wrapper around `UserTypeAnnotation` to...
[rust.git] / src / librustc_mir / build / matches / mod.rs
index c2a7172d54cca22cf2a105366bf4d27a510d2c67..0d456a091c2059789857daec9b6c93c379efa68b 100644 (file)
@@ -20,7 +20,7 @@
 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};
@@ -178,7 +178,7 @@ pub fn match_expr(
         // If there are no match guards then we don't need any fake borrows,
         // so don't track them.
         let mut fake_borrows = if has_guard && tcx.generate_borrow_of_any_match_input() {
-            Some(FxHashMap())
+            Some(FxHashMap::default())
         } else {
             None
         };
@@ -240,7 +240,7 @@ pub fn match_expr(
         end_block.unit()
     }
 
-    pub fn expr_into_pattern(
+    pub(super) fn expr_into_pattern(
         &mut self,
         mut block: BasicBlock,
         irrefutable_pat: Pattern<'tcx>,
@@ -265,7 +265,7 @@ pub fn expr_into_pattern(
                     block,
                     Statement {
                         source_info,
-                        kind: StatementKind::FakeRead(FakeReadCause::ForLet, place.clone()),
+                        kind: StatementKind::FakeRead(FakeReadCause::ForLet, place),
                     },
                 );
 
@@ -291,31 +291,33 @@ pub fn expr_into_pattern(
                     },
                     ..
                 },
-                user_ty: ascription_user_ty,
+                user_ty: pat_ascription_ty,
+                user_ty_span,
             } => {
                 let place =
                     self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard);
                 unpack!(block = self.into(&place, block, initializer));
 
-                let source_info = self.source_info(irrefutable_pat.span);
+                // Inject a fake read, see comments on `FakeReadCause::ForLet`.
+                let pattern_source_info = self.source_info(irrefutable_pat.span);
                 self.cfg.push(
                     block,
                     Statement {
-                        source_info,
-                        kind: StatementKind::AscribeUserType(
-                            place.clone(),
-                            ty::Variance::Invariant,
-                            ascription_user_ty,
-                        ),
+                        source_info: pattern_source_info,
+                        kind: StatementKind::FakeRead(FakeReadCause::ForLet, place.clone()),
                     },
                 );
 
-                // Inject a fake read, see comments on `FakeReadCause::ForLet`.
+                let ty_source_info = self.source_info(user_ty_span);
                 self.cfg.push(
                     block,
                     Statement {
-                        source_info,
-                        kind: StatementKind::FakeRead(FakeReadCause::ForLet, place.clone()),
+                        source_info: ty_source_info,
+                        kind: StatementKind::AscribeUserType(
+                            place,
+                            ty::Variance::Invariant,
+                            box pat_ascription_ty.user_ty(),
+                        ),
                     },
                 );
 
@@ -486,10 +488,10 @@ pub fn schedule_drop_for_binding(&mut self, var: NodeId, span: Span, for_guard:
         );
     }
 
-    pub fn visit_bindings(
+    pub(super) fn visit_bindings(
         &mut self,
         pattern: &Pattern<'tcx>,
-        mut pattern_user_ty: Option<CanonicalTy<'tcx>>,
+        mut pattern_user_ty: Option<(PatternTypeAnnotation<'tcx>, Span)>,
         f: &mut impl FnMut(
             &mut Self,
             Mutability,
@@ -498,7 +500,7 @@ pub fn visit_bindings(
             NodeId,
             Span,
             Ty<'tcx>,
-            Option<CanonicalTy<'tcx>>,
+            Option<(PatternTypeAnnotation<'tcx>, Span)>,
         ),
     ) {
         match *pattern.kind {
@@ -549,16 +551,15 @@ pub fn visit_bindings(
                 // FIXME(#47184): extract or handle `pattern_user_ty` somehow
                 self.visit_bindings(subpattern, None, f);
             }
-            PatternKind::AscribeUserType { ref subpattern, user_ty } => {
+            PatternKind::AscribeUserType { ref subpattern, user_ty, user_ty_span } => {
                 // This corresponds to something like
                 //
                 // ```
-                // let (p1: T1): T2 = ...;
+                // let A::<'a>(_): A<'static> = ...;
                 // ```
                 //
-                // Not presently possible, though maybe someday.
-                assert!(pattern_user_ty.is_none());
-                self.visit_bindings(subpattern, Some(user_ty), f)
+                // FIXME(#47184): handle `pattern_user_ty` somehow
+                self.visit_bindings(subpattern, Some((user_ty, user_ty_span)), f)
             }
             PatternKind::Leaf { ref subpatterns }
             | PatternKind::Variant {
@@ -625,7 +626,7 @@ struct Binding<'tcx> {
 struct Ascription<'tcx> {
     span: Span,
     source: Place<'tcx>,
-    user_ty: CanonicalTy<'tcx>,
+    user_ty: PatternTypeAnnotation<'tcx>,
 }
 
 #[derive(Clone, Debug)]
@@ -1322,7 +1323,7 @@ fn ascribe_types<'pat>(
                     kind: StatementKind::AscribeUserType(
                         ascription.source.clone(),
                         ty::Variance::Covariant,
-                        ascription.user_ty,
+                        box ascription.user_ty.user_ty(),
                     ),
                 },
             );
@@ -1469,7 +1470,7 @@ fn declare_binding(
         num_patterns: usize,
         var_id: NodeId,
         var_ty: Ty<'tcx>,
-        user_var_ty: Option<CanonicalTy<'tcx>>,
+        user_var_ty: Option<(PatternTypeAnnotation<'tcx>, Span)>,
         has_guard: ArmHasGuard,
         opt_match_place: Option<(Option<Place<'tcx>>, Span)>,
         pat_span: Span,
@@ -1488,7 +1489,7 @@ fn declare_binding(
         let local = LocalDecl::<'tcx> {
             mutability,
             ty: var_ty,
-            user_ty: user_var_ty,
+            user_ty: user_var_ty.map(|(pat_ty, span)|(pat_ty.user_ty(), span)),
             name: Some(name),
             source_info,
             visibility_scope,