]> git.lizzy.rs Git - rust.git/commitdiff
Ignore `Drop` and `Destruct` bounds for now
authorFlorian Diebold <flodiebold@gmail.com>
Fri, 8 Apr 2022 12:29:43 +0000 (14:29 +0200)
committerFlorian Diebold <flodiebold@gmail.com>
Fri, 8 Apr 2022 12:29:43 +0000 (14:29 +0200)
- `T: ~const Drop` has a special meaning in Rust 1.61 that we don't implement.
  (So ideally, we'd only ignore `~const Drop`, but this should be fine
  for now.)
- `Destruct` impls are built-in in 1.62 (current nightlies as of 08-04-2022), so until
  the builtin impls are supported by Chalk, we ignore them as well.
  Since `Destruct` is implemented for everything in non-const contexts
  IIUC, this should also work fine.

Fixes #11932.

crates/hir_ty/src/lower.rs
crates/hir_ty/src/tests/regression.rs

index ca6241c5d1a9000505644871791fa546b5343161..24eff4cc9a9fcbfc67a4d3ba961750ebf3070c29 100644 (file)
@@ -14,6 +14,7 @@
 use chalk_ir::{cast::Cast, fold::Shift, Mutability, Safety};
 use hir_def::generics::TypeOrConstParamData;
 use hir_def::intern::Interned;
+use hir_def::lang_item::lang_attr;
 use hir_def::path::{ModPath, PathKind};
 use hir_def::type_ref::ConstScalarOrPath;
 use hir_def::{
@@ -863,7 +864,23 @@ pub(crate) fn lower_type_bound(
         let trait_ref = match bound {
             TypeBound::Path(path, TraitBoundModifier::None) => {
                 bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
-                bindings.clone().map(WhereClause::Implemented).map(crate::wrap_empty_binders)
+                bindings
+                    .clone()
+                    .filter(|tr| {
+                        // ignore `T: Drop` or `T: Destruct` bounds.
+                        // - `T: ~const Drop` has a special meaning in Rust 1.61 that we don't implement.
+                        //   (So ideally, we'd only ignore `~const Drop` here)
+                        // - `Destruct` impls are built-in in 1.62 (current nightlies as of 08-04-2022), so until
+                        //   the builtin impls are supported by Chalk, we ignore them here.
+                        if let Some(lang) = lang_attr(self.db.upcast(), tr.hir_trait_id()) {
+                            if lang == "drop" || lang == "destruct" {
+                                return false;
+                            }
+                        }
+                        true
+                    })
+                    .map(WhereClause::Implemented)
+                    .map(crate::wrap_empty_binders)
             }
             TypeBound::Path(path, TraitBoundModifier::Maybe) => {
                 let sized_trait = self
index 37f321a0f008ecac7acc719ccbc0bc00af94fe89..a02ec6f85c6f6c865fd659300afaf2b5f59ae256 100644 (file)
@@ -1505,3 +1505,82 @@ fn f(s: S) {
 "#,
     );
 }
+
+#[test]
+fn rust_161_option_clone() {
+    check_types(
+        r#"
+//- minicore: option, drop
+
+fn test(o: &Option<i32>) {
+    o.my_clone();
+  //^^^^^^^^^^^^ Option<i32>
+}
+
+pub trait MyClone: Sized {
+    fn my_clone(&self) -> Self;
+}
+
+impl<T> const MyClone for Option<T>
+where
+    T: ~const MyClone + ~const Drop + ~const Destruct,
+{
+    fn my_clone(&self) -> Self {
+        match self {
+            Some(x) => Some(x.my_clone()),
+            None => None,
+        }
+    }
+}
+
+impl const MyClone for i32 {
+    fn my_clone(&self) -> Self {
+        *self
+    }
+}
+
+pub trait Destruct {}
+
+impl<T: ?Sized> const Destruct for T {}
+"#,
+    );
+}
+
+#[test]
+fn rust_162_option_clone() {
+    check_types(
+        r#"
+//- minicore: option, drop
+
+fn test(o: &Option<i32>) {
+    o.my_clone();
+  //^^^^^^^^^^^^ Option<i32>
+}
+
+pub trait MyClone: Sized {
+    fn my_clone(&self) -> Self;
+}
+
+impl<T> const MyClone for Option<T>
+where
+    T: ~const MyClone + ~const Destruct,
+{
+    fn my_clone(&self) -> Self {
+        match self {
+            Some(x) => Some(x.my_clone()),
+            None => None,
+        }
+    }
+}
+
+impl const MyClone for i32 {
+    fn my_clone(&self) -> Self {
+        *self
+    }
+}
+
+#[lang = "destruct"]
+pub trait Destruct {}
+"#,
+    );
+}