From 1397836380555850ec4c34419682e312e41a4e26 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 30 Sep 2018 19:45:31 +0200 Subject: [PATCH 1/2] do not promote comparing function pointers --- src/librustc_mir/transform/qualify_consts.rs | 2 +- src/librustc_passes/rvalue_promotion.rs | 2 +- src/test/run-pass/issues/issue-54696.rs | 8 ++++++++ 3 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 src/test/run-pass/issues/issue-54696.rs diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index a6e2cad5094..2811848424b 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -750,7 +750,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { } Rvalue::BinaryOp(op, ref lhs, _) => { - if let ty::RawPtr(_) = lhs.ty(self.mir, self.tcx).sty { + if let ty::RawPtr(_) | ty::FnPtr(..) = lhs.ty(self.mir, self.tcx).sty { assert!(op == BinOp::Eq || op == BinOp::Ne || op == BinOp::Le || op == BinOp::Lt || op == BinOp::Ge || op == BinOp::Gt || diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index 82880046520..efe59e4face 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -348,7 +348,7 @@ fn check_expr_kind<'a, 'tcx>( return NotPromotable; } match v.tables.node_id_to_type(lhs.hir_id).sty { - ty::RawPtr(_) => { + ty::RawPtr(_) | ty::FnPtr(..) => { assert!(op.node == hir::BinOpKind::Eq || op.node == hir::BinOpKind::Ne || op.node == hir::BinOpKind::Le || op.node == hir::BinOpKind::Lt || op.node == hir::BinOpKind::Ge || op.node == hir::BinOpKind::Gt); diff --git a/src/test/run-pass/issues/issue-54696.rs b/src/test/run-pass/issues/issue-54696.rs new file mode 100644 index 00000000000..d8408ed8549 --- /dev/null +++ b/src/test/run-pass/issues/issue-54696.rs @@ -0,0 +1,8 @@ +// run-pass + +fn main() { + // We shouldn't promote this + &(main as fn() == main as fn()); + // Also check nested case + &(&(main as fn()) == &(main as fn())); +} From 4cbfc9398d93d9eb0b1178b129f80de9be5c8ef9 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 30 Sep 2018 20:25:19 +0200 Subject: [PATCH 2/2] also compile-fail test fn ptr comparison promotion --- .../const-eval/promoted_raw_ptr_ops.nll.stderr | 15 +++++++++++++-- .../ui/consts/const-eval/promoted_raw_ptr_ops.rs | 1 + .../consts/const-eval/promoted_raw_ptr_ops.stderr | 15 +++++++++++++-- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/test/ui/consts/const-eval/promoted_raw_ptr_ops.nll.stderr b/src/test/ui/consts/const-eval/promoted_raw_ptr_ops.nll.stderr index bc8a99f5548..f31d962852e 100644 --- a/src/test/ui/consts/const-eval/promoted_raw_ptr_ops.nll.stderr +++ b/src/test/ui/consts/const-eval/promoted_raw_ptr_ops.nll.stderr @@ -14,7 +14,7 @@ error[E0716]: temporary value dropped while borrowed | LL | let y: &'static usize = &(&1 as *const i32 as usize + 1); //~ ERROR does not live long enough | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use -LL | let z: &'static i32 = &(unsafe { *(42 as *const i32) }); //~ ERROR does not live long enough +... LL | } | - temporary value is freed at the end of this statement | @@ -25,11 +25,22 @@ error[E0716]: temporary value dropped while borrowed | LL | let z: &'static i32 = &(unsafe { *(42 as *const i32) }); //~ ERROR does not live long enough | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use +LL | let a: &'static bool = &(main as fn() == main as fn()); //~ ERROR does not live long enough LL | } | - temporary value is freed at the end of this statement | = note: borrowed value must be valid for the static lifetime... -error: aborting due to 3 previous errors +error[E0716]: temporary value dropped while borrowed + --> $DIR/promoted_raw_ptr_ops.rs:18:29 + | +LL | let a: &'static bool = &(main as fn() == main as fn()); //~ ERROR does not live long enough + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use +LL | } + | - temporary value is freed at the end of this statement + | + = note: borrowed value must be valid for the static lifetime... + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0716`. diff --git a/src/test/ui/consts/const-eval/promoted_raw_ptr_ops.rs b/src/test/ui/consts/const-eval/promoted_raw_ptr_ops.rs index 3b437f69d8d..c915886ca25 100644 --- a/src/test/ui/consts/const-eval/promoted_raw_ptr_ops.rs +++ b/src/test/ui/consts/const-eval/promoted_raw_ptr_ops.rs @@ -15,4 +15,5 @@ fn main() { //~^ ERROR does not live long enough let y: &'static usize = &(&1 as *const i32 as usize + 1); //~ ERROR does not live long enough let z: &'static i32 = &(unsafe { *(42 as *const i32) }); //~ ERROR does not live long enough + let a: &'static bool = &(main as fn() == main as fn()); //~ ERROR does not live long enough } diff --git a/src/test/ui/consts/const-eval/promoted_raw_ptr_ops.stderr b/src/test/ui/consts/const-eval/promoted_raw_ptr_ops.stderr index 90c73c095fb..baf12c5ac59 100644 --- a/src/test/ui/consts/const-eval/promoted_raw_ptr_ops.stderr +++ b/src/test/ui/consts/const-eval/promoted_raw_ptr_ops.stderr @@ -14,7 +14,7 @@ error[E0597]: borrowed value does not live long enough | LL | let y: &'static usize = &(&1 as *const i32 as usize + 1); //~ ERROR does not live long enough | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ temporary value does not live long enough -LL | let z: &'static i32 = &(unsafe { *(42 as *const i32) }); //~ ERROR does not live long enough +... LL | } | - temporary value only lives until here | @@ -25,11 +25,22 @@ error[E0597]: borrowed value does not live long enough | LL | let z: &'static i32 = &(unsafe { *(42 as *const i32) }); //~ ERROR does not live long enough | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ temporary value does not live long enough +LL | let a: &'static bool = &(main as fn() == main as fn()); //~ ERROR does not live long enough LL | } | - temporary value only lives until here | = note: borrowed value must be valid for the static lifetime... -error: aborting due to 3 previous errors +error[E0597]: borrowed value does not live long enough + --> $DIR/promoted_raw_ptr_ops.rs:18:29 + | +LL | let a: &'static bool = &(main as fn() == main as fn()); //~ ERROR does not live long enough + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ temporary value does not live long enough +LL | } + | - temporary value only lives until here + | + = note: borrowed value must be valid for the static lifetime... + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0597`.