]> git.lizzy.rs Git - rust.git/commitdiff
Try normalizing types without RevealAll in ParamEnv in mir validation
authorNilstrieb <48135649+Nilstrieb@users.noreply.github.com>
Wed, 3 Aug 2022 20:24:47 +0000 (22:24 +0200)
committernils <48135649+Nilstrieb@users.noreply.github.com>
Mon, 29 Aug 2022 14:27:52 +0000 (16:27 +0200)
Before, the MIR validator used RevealAll in its ParamEnv for type
checking. This could cause false negatives in some cases due to
RevealAll ParamEnvs not always use all predicates as expected here.

Since some MIR passes like inlining use RevealAll as well, keep using
it in the MIR validator too, but when it fails usign RevealAll, also
try the check without it, to stop false negatives.

compiler/rustc_const_eval/src/transform/validate.rs
src/test/ui/mir/issue-99866.rs [new file with mode: 0644]

index 45a94972c1134b8fd2cd4523713e724fe5ccf5fc..ddde9ff4c0281b7d2bd64a2364a5f83ec9e21bad 100644 (file)
@@ -181,16 +181,28 @@ fn mir_assign_valid_types(&self, src: Ty<'tcx>, dest: Ty<'tcx>) -> bool {
         if (src, dest).has_opaque_types() {
             return true;
         }
+
+        let try_equal_with_param_env = |param_env| {
+            let src = self.tcx.normalize_erasing_regions(param_env, src);
+            let dest = self.tcx.normalize_erasing_regions(param_env, dest);
+            // Type-changing assignments can happen when subtyping is used. While
+            // all normal lifetimes are erased, higher-ranked types with their
+            // late-bound lifetimes are still around and can lead to type
+            // differences. So we compare ignoring lifetimes.
+            equal_up_to_regions(self.tcx, param_env, src, dest)
+        };
+
         // Normalize projections and things like that.
+        // First, try with reveal_all. This might not work in some cases, as the predicates
+        // can be cleared in reveal_all mode. We try the reveal first anyways as it is used
+        // by some other passes like inlining as well.
         let param_env = self.param_env.with_reveal_all_normalized(self.tcx);
-        let src = self.tcx.normalize_erasing_regions(param_env, src);
-        let dest = self.tcx.normalize_erasing_regions(param_env, dest);
-
-        // Type-changing assignments can happen when subtyping is used. While
-        // all normal lifetimes are erased, higher-ranked types with their
-        // late-bound lifetimes are still around and can lead to type
-        // differences. So we compare ignoring lifetimes.
-        equal_up_to_regions(self.tcx, param_env, src, dest)
+        if try_equal_with_param_env(param_env) {
+            true
+        } else {
+            // If this fails, we can try it without the reveal.
+            try_equal_with_param_env(self.param_env)
+        }
     }
 }
 
diff --git a/src/test/ui/mir/issue-99866.rs b/src/test/ui/mir/issue-99866.rs
new file mode 100644 (file)
index 0000000..d39ae6e
--- /dev/null
@@ -0,0 +1,25 @@
+// check-pass
+pub trait Backend {
+    type DescriptorSetLayout;
+}
+
+pub struct Back;
+
+impl Backend for Back {
+    type DescriptorSetLayout = u32;
+}
+
+pub struct HalSetLayouts {
+    vertex_layout: <Back as Backend>::DescriptorSetLayout,
+}
+
+impl HalSetLayouts {
+    pub fn iter<DSL>(self) -> DSL
+    where
+        Back: Backend<DescriptorSetLayout = DSL>,
+    {
+        self.vertex_layout
+    }
+}
+
+fn main() {}