about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYuki Okushi <jtitor@2k36.org>2021-08-06 11:21:35 +0900
committerGitHub <noreply@github.com>2021-08-06 11:21:35 +0900
commit8bad35095b3dcd424fd2d1802f77f3923c8a5487 (patch)
treefc4484d33c1bfd4b3ceee4fab22a58547c18d2cc
parent41076a8ac94659e2f062f211f0e1b334155b72ab (diff)
parentfa4671500273991967b293dd611e645512608d98 (diff)
downloadrust-8bad35095b3dcd424fd2d1802f77f3923c8a5487.tar.gz
rust-8bad35095b3dcd424fd2d1802f77f3923c8a5487.zip
Rollup merge of #87770 - BoxyUwU:cec-drop-impl, r=lcnr
permit drop impls with generic constants in where clauses

Fixes #79248

`==` is not sufficient to check for equality between unevaluated consts which causes the above issue because the const in `[(); N - 1]:` on the impl and the const in `[(); N - 1]:` on the struct def are not seen as equal. Any predicate that can contain an unevaluated const cant use `==` here as it will cause us to incorrectly emit an error.

I dont know much about chalk but it seems like we ought to be relating the `TypeWellFormedFromEnv` instead of `==` as it contains a `Ty` so I added that too...

r? ``````@lcnr``````
-rw-r--r--compiler/rustc_typeck/src/check/dropck.rs13
-rw-r--r--src/test/ui/const-generics/const_evaluatable_checked/drop_impl.rs16
2 files changed, 26 insertions, 3 deletions
diff --git a/compiler/rustc_typeck/src/check/dropck.rs b/compiler/rustc_typeck/src/check/dropck.rs
index 01276495c18..17f5020300d 100644
--- a/compiler/rustc_typeck/src/check/dropck.rs
+++ b/compiler/rustc_typeck/src/check/dropck.rs
@@ -218,9 +218,9 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
 
         // This closure is a more robust way to check `Predicate` equality
         // than simple `==` checks (which were the previous implementation).
-        // It relies on `ty::relate` for `TraitPredicate` and `ProjectionPredicate`
-        // (which implement the Relate trait), while delegating on simple equality
-        // for the other `Predicate`.
+        // It relies on `ty::relate` for `TraitPredicate`, `ProjectionPredicate`,
+        // `ConstEvaluatable` and `TypeOutlives` (which implement the Relate trait),
+        // while delegating on simple equality for the other `Predicate`.
         // This implementation solves (Issue #59497) and (Issue #58311).
         // It is unclear to me at the moment whether the approach based on `relate`
         // could be extended easily also to the other `Predicate`.
@@ -235,6 +235,13 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
                 (ty::PredicateKind::Projection(a), ty::PredicateKind::Projection(b)) => {
                     relator.relate(predicate.rebind(a), p.rebind(b)).is_ok()
                 }
+                (
+                    ty::PredicateKind::ConstEvaluatable(def_a, substs_a),
+                    ty::PredicateKind::ConstEvaluatable(def_b, substs_b),
+                ) => tcx.try_unify_abstract_consts(((def_a, substs_a), (def_b, substs_b))),
+                (ty::PredicateKind::TypeOutlives(a), ty::PredicateKind::TypeOutlives(b)) => {
+                    relator.relate(predicate.rebind(a.0), p.rebind(b.0)).is_ok()
+                }
                 _ => predicate == p,
             }
         };
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/drop_impl.rs b/src/test/ui/const-generics/const_evaluatable_checked/drop_impl.rs
new file mode 100644
index 00000000000..41fb5d70afd
--- /dev/null
+++ b/src/test/ui/const-generics/const_evaluatable_checked/drop_impl.rs
@@ -0,0 +1,16 @@
+//check-pass
+#![feature(const_generics, const_evaluatable_checked)]
+#![allow(incomplete_features)]
+
+struct Foo<const N: usize>
+where
+    [(); N + 1]: ;
+
+impl<const N: usize> Drop for Foo<N>
+where
+    [(); N + 1]: ,
+{
+    fn drop(&mut self) {}
+}
+
+fn main() {}