about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-10-12 12:00:50 +0000
committerbors <bors@rust-lang.org>2018-10-12 12:00:50 +0000
commite9e27e6a6258b3adf00a5dd35d2676656224880d (patch)
tree32202eba23a393846aa58d688b983e147d8e0181 /src
parent849a0e9c40ef79efec0802334fe10406ea3e7256 (diff)
parent76f8a90d53a3f212820e95260257105dd1da9910 (diff)
downloadrust-e9e27e6a6258b3adf00a5dd35d2676656224880d.tar.gz
rust-e9e27e6a6258b3adf00a5dd35d2676656224880d.zip
Auto merge of #54715 - oli-obk:nll_deref_promotion, r=RalfJung
Fix #54224 (const promotion regression)

r? @eddyb
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs36
-rw-r--r--src/test/ui/consts/issue-54224.rs14
-rw-r--r--src/test/ui/consts/issue-54224.stderr23
3 files changed, 59 insertions, 14 deletions
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 17fe78d325c..5e7050caeaf 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -495,20 +495,22 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                     this.super_place(place, context, location);
                     match proj.elem {
                         ProjectionElem::Deref => {
-                            if let Mode::Fn = this.mode {
-                                this.add(Qualif::NOT_CONST);
-                            } else {
-                                let base_ty = proj.base.ty(this.mir, this.tcx).to_ty(this.tcx);
-                                if let ty::RawPtr(_) = base_ty.sty {
-                                    if !this.tcx.sess.features_untracked().const_raw_ptr_deref {
-                                        emit_feature_err(
-                                            &this.tcx.sess.parse_sess, "const_raw_ptr_deref",
-                                            this.span, GateIssue::Language,
-                                            &format!(
-                                                "dereferencing raw pointers in {}s is unstable",
-                                                this.mode,
-                                            ),
-                                        );
+                            this.add(Qualif::NOT_CONST);
+                            let base_ty = proj.base.ty(this.mir, this.tcx).to_ty(this.tcx);
+                            match this.mode {
+                                Mode::Fn => {},
+                                _ => {
+                                    if let ty::RawPtr(_) = base_ty.sty {
+                                        if !this.tcx.sess.features_untracked().const_raw_ptr_deref {
+                                            emit_feature_err(
+                                                &this.tcx.sess.parse_sess, "const_raw_ptr_deref",
+                                                this.span, GateIssue::Language,
+                                                &format!(
+                                                    "dereferencing raw pointers in {}s is unstable",
+                                                    this.mode,
+                                                ),
+                                            );
+                                        }
                                     }
                                 }
                             }
@@ -732,8 +734,11 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                     (CastTy::Ptr(_), CastTy::Int(_)) |
                     (CastTy::FnPtr, CastTy::Int(_)) => {
                         if let Mode::Fn = self.mode {
+                            // in normal functions, mark such casts as not promotable
                             self.add(Qualif::NOT_CONST);
                         } else if !self.tcx.sess.features_untracked().const_raw_ptr_to_usize_cast {
+                            // in const fn and constants require the feature gate
+                            // FIXME: make it unsafe inside const fn and constants
                             emit_feature_err(
                                 &self.tcx.sess.parse_sess, "const_raw_ptr_to_usize_cast",
                                 self.span, GateIssue::Language,
@@ -756,8 +761,11 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                             op == BinOp::Offset);
 
                     if let Mode::Fn = self.mode {
+                        // raw pointer operations are not allowed inside promoteds
                         self.add(Qualif::NOT_CONST);
                     } else if !self.tcx.sess.features_untracked().const_compare_raw_pointers {
+                        // require the feature gate inside constants and const fn
+                        // FIXME: make it unsafe to use these operations
                         emit_feature_err(
                             &self.tcx.sess.parse_sess,
                             "const_compare_raw_pointers",
diff --git a/src/test/ui/consts/issue-54224.rs b/src/test/ui/consts/issue-54224.rs
new file mode 100644
index 00000000000..b5a8fe8819c
--- /dev/null
+++ b/src/test/ui/consts/issue-54224.rs
@@ -0,0 +1,14 @@
+#![feature(nll)]
+
+const FOO: Option<&[[u8; 3]]> = Some(&[*b"foo"]); //~ ERROR temporary value dropped while borrowed
+
+use std::borrow::Cow;
+
+pub const X: [u8; 3] = *b"ABC";
+pub const Y: Cow<'static, [ [u8; 3] ]> = Cow::Borrowed(&[X]);
+
+
+pub const Z: Cow<'static, [ [u8; 3] ]> = Cow::Borrowed(&[*b"ABC"]);
+//~^ ERROR temporary value dropped while borrowed
+
+fn main() {}
diff --git a/src/test/ui/consts/issue-54224.stderr b/src/test/ui/consts/issue-54224.stderr
new file mode 100644
index 00000000000..39879254cf8
--- /dev/null
+++ b/src/test/ui/consts/issue-54224.stderr
@@ -0,0 +1,23 @@
+error[E0716]: temporary value dropped while borrowed
+  --> $DIR/issue-54224.rs:3:39
+   |
+LL | const FOO: Option<&[[u8; 3]]> = Some(&[*b"foo"]); //~ ERROR temporary value dropped while borrowed
+   |                                       ^^^^^^^^^- temporary value is freed at the end of this statement
+   |                                       |
+   |                                       creates a temporary which is freed while still in use
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error[E0716]: temporary value dropped while borrowed
+  --> $DIR/issue-54224.rs:11:57
+   |
+LL | pub const Z: Cow<'static, [ [u8; 3] ]> = Cow::Borrowed(&[*b"ABC"]);
+   |                                                         ^^^^^^^^^- temporary value is freed at the end of this statement
+   |                                                         |
+   |                                                         creates a temporary which is freed while still in use
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0716`.