about summary refs log tree commit diff
diff options
context:
space:
mode:
authorKeith Yeung <kungfukeith11@gmail.com>2018-10-02 09:31:46 -0700
committerNiko Matsakis <niko@alum.mit.edu>2018-10-19 09:34:28 -0400
commit80ad300b890c07d4c95fbf63c0f9cd3e397e545f (patch)
tree9f802c9584daa5b88556107a7d53ba355484ca0a
parente20fa70bb349026226616b92ea44f7bdfd270d75 (diff)
downloadrust-80ad300b890c07d4c95fbf63c0f9cd3e397e545f.tar.gz
rust-80ad300b890c07d4c95fbf63c0f9cd3e397e545f.zip
Wrap cast expressions inside of ValueTypeAscription
-rw-r--r--src/librustc_mir/hair/cx/expr.rs23
-rw-r--r--src/librustc_typeck/check/mod.rs2
-rw-r--r--src/test/ui/nll/user-annotations/cast_static_lifetime.rs17
3 files changed, 40 insertions, 2 deletions
diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs
index 04dd1aa3c88..796f6753e95 100644
--- a/src/librustc_mir/hair/cx/expr.rs
+++ b/src/librustc_mir/hair/cx/expr.rs
@@ -637,7 +637,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                 name: Field::new(cx.tcx.field_index(expr.id, cx.tables)),
             }
         }
-        hir::ExprKind::Cast(ref source, _) => {
+        hir::ExprKind::Cast(ref source, ref ty) => {
             // Check to see if this cast is a "coercion cast", where the cast is actually done
             // using a coercion (or is a no-op).
             if let Some(&TyCastKind::CoercionCast) = cx.tables()
@@ -714,7 +714,26 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                 } else {
                     source.to_ref()
                 };
-                ExprKind::Cast { source }
+
+                let cast = ExprKind::Cast { source };
+
+                if let Some(user_ty) = cx.tables.user_provided_tys().get(ty.hir_id) {
+                    // NOTE: Creating a new Expr and wrapping a Cast inside of it may be
+                    //       inefficient, revisit this when performance becomes an issue.
+                    let cast_expr = Expr {
+                        temp_lifetime,
+                        ty: expr_ty,
+                        span: expr.span,
+                        kind: cast,
+                    };
+
+                    ExprKind::ValueTypeAscription {
+                        source: cast_expr.to_ref(),
+                        user_ty: UserTypeAnnotation::Ty(*user_ty),
+                    }
+                } else {
+                    cast
+                }
             }
         }
         hir::ExprKind::Type(ref source, ref ty) => {
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 14ce1bb4ccd..e6922d1c4c7 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -4166,6 +4166,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
                     match cast::CastCheck::new(self, e, t_expr, t_cast, t.span, expr.span) {
                         Ok(cast_check) => {
+                            let c_ty = self.infcx.canonicalize_response(&t_cast);
+                            self.tables.borrow_mut().user_provided_tys_mut().insert(t.hir_id, c_ty);
                             deferred_cast_checks.push(cast_check);
                             t_cast
                         }
diff --git a/src/test/ui/nll/user-annotations/cast_static_lifetime.rs b/src/test/ui/nll/user-annotations/cast_static_lifetime.rs
new file mode 100644
index 00000000000..aa2cf85dfd9
--- /dev/null
+++ b/src/test/ui/nll/user-annotations/cast_static_lifetime.rs
@@ -0,0 +1,17 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(warnings)]
+#![feature(nll)]
+
+fn main() {
+    let x = 22_u32;
+    let y: &u32 = (&x) as &'static u32;
+}