diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index a6e2cad509408..1281fc96c0da7 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -496,20 +496,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, + ), + ); + } } } } @@ -733,8 +735,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, @@ -757,8 +762,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 0000000000000..b5a8fe8819cdd --- /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 0000000000000..39879254cf85d --- /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`.