about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2022-04-16 07:12:46 +0200
committerGitHub <noreply@github.com>2022-04-16 07:12:46 +0200
commitfd7a1f153d2598e59ed7014f6ee7054a1e4ac8e4 (patch)
tree78c3a227e7009f6133ccb4d6bb7be3fe06b5dfa0
parentea131bca17144d01434cc5ec5d12cb03bc69dbcb (diff)
parentd5f3863204b655ad4498f08c3a02dc320b7b6ea1 (diff)
downloadrust-fd7a1f153d2598e59ed7014f6ee7054a1e4ac8e4.tar.gz
rust-fd7a1f153d2598e59ed7014f6ee7054a1e4ac8e4.zip
Rollup merge of #96004 - JakobDegen:fix-validator-ice, r=petrochenkov
Consider lifetimes when comparing types for equality in MIR validator

Closes #95978 .
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs7
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs3
-rw-r--r--src/test/ui/mir/issue-95978-validator-lifetime-comparison.rs10
3 files changed, 15 insertions, 5 deletions
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 01af9585135..79d427ccc44 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -315,9 +315,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                                     | ty::FnPtr(..)
                             )
                         }
-                        // None of the possible types have lifetimes, so we can just compare
-                        // directly
-                        if a != b {
+                        // The function pointer types can have lifetimes
+                        if !self.mir_assign_valid_types(a, b) {
                             self.fail(
                                 location,
                                 format!("Cannot compare unequal types {:?} and {:?}", a, b),
@@ -464,7 +463,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                 };
                 // since CopyNonOverlapping is parametrized by 1 type,
                 // we only need to check that they are equal and not keep an extra parameter.
-                if op_src_ty != op_dst_ty {
+                if !self.mir_assign_valid_types(op_src_ty, op_dst_ty) {
                     self.fail(location, format!("bad arg ({:?} != {:?})", op_src_ty, op_dst_ty));
                 }
 
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index db7e973fb62..49769b7ae3d 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -2518,7 +2518,8 @@ pub enum Rvalue<'tcx> {
     /// * `Offset` has the same semantics as [`offset`](pointer::offset), except that the second
     ///   parameter may be a `usize` as well.
     /// * The comparison operations accept `bool`s, `char`s, signed or unsigned integers, floats,
-    ///   raw pointers, or function pointers of matching types and return a `bool`.
+    ///   raw pointers, or function pointers and return a `bool`. The types of the operands must be
+    ///   matching, up to the usual caveat of the lifetimes in function pointers.
     /// * Left and right shift operations accept signed or unsigned integers not necessarily of the
     ///   same type and return a value of the same type as their LHS. Like in Rust, the RHS is
     ///   truncated as needed.
diff --git a/src/test/ui/mir/issue-95978-validator-lifetime-comparison.rs b/src/test/ui/mir/issue-95978-validator-lifetime-comparison.rs
new file mode 100644
index 00000000000..cd6c5bf2719
--- /dev/null
+++ b/src/test/ui/mir/issue-95978-validator-lifetime-comparison.rs
@@ -0,0 +1,10 @@
+// check-pass
+// compile-flags: -Zvalidate-mir
+
+fn foo(_a: &str) {}
+
+fn main() {
+    let x = foo as fn(&'static str);
+
+    let _ = x == foo;
+}