about summary refs log tree commit diff
diff options
context:
space:
mode:
authorhkalbasi <hamidrezakalbasi@protonmail.com>2023-04-23 21:55:47 +0330
committerhkalbasi <hamidrezakalbasi@protonmail.com>2023-04-23 21:55:47 +0330
commit232f293c19700d21931cdea0a6c4afac97e77002 (patch)
tree06fb17e370259e116ece92d8be1f704aad0c9df0
parent2feabc4dc462644287372922928110eea4c60ca7 (diff)
downloadrust-232f293c19700d21931cdea0a6c4afac97e77002.tar.gz
rust-232f293c19700d21931cdea0a6c4afac97e77002.zip
Fix some typos in `StructFlags`
-rw-r--r--crates/hir-def/src/data/adt.rs2
-rw-r--r--crates/hir-ty/src/lang_items.rs2
-rw-r--r--crates/hir-ty/src/mir.rs9
-rw-r--r--crates/hir-ty/src/tests/method_resolution.rs51
-rw-r--r--crates/test-utils/src/minicore.rs25
5 files changed, 84 insertions, 5 deletions
diff --git a/crates/hir-def/src/data/adt.rs b/crates/hir-def/src/data/adt.rs
index 31f91317994..4eefd66d477 100644
--- a/crates/hir-def/src/data/adt.rs
+++ b/crates/hir-def/src/data/adt.rs
@@ -60,7 +60,7 @@ bitflags! {
         /// Indicates whether this struct is `ManuallyDrop`.
         const IS_MANUALLY_DROP = 1 << 6;
         /// Indicates whether this struct is `UnsafeCell`.
-        const IS_UNSAFE_CELL   = 1 << 6;
+        const IS_UNSAFE_CELL   = 1 << 7;
     }
 }
 
diff --git a/crates/hir-ty/src/lang_items.rs b/crates/hir-ty/src/lang_items.rs
index adfdb01e72a..85ed46b9632 100644
--- a/crates/hir-ty/src/lang_items.rs
+++ b/crates/hir-ty/src/lang_items.rs
@@ -7,7 +7,7 @@ use crate::db::HirDatabase;
 
 pub fn is_box(db: &dyn HirDatabase, adt: AdtId) -> bool {
     let AdtId::StructId(id) = adt else { return false };
-    db.struct_data(id).flags.contains(StructFlags::IS_UNSAFE_CELL)
+    db.struct_data(id).flags.contains(StructFlags::IS_BOX)
 }
 
 pub fn is_unsafe_cell(db: &dyn HirDatabase, adt: AdtId) -> bool {
diff --git a/crates/hir-ty/src/mir.rs b/crates/hir-ty/src/mir.rs
index d830ae263ba..1146431bcdf 100644
--- a/crates/hir-ty/src/mir.rs
+++ b/crates/hir-ty/src/mir.rs
@@ -3,8 +3,8 @@
 use std::{fmt::Display, iter};
 
 use crate::{
-    db::HirDatabase, infer::PointerCast, ClosureId, Const, ConstScalar, InferenceResult, Interner,
-    MemoryMap, Substitution, Ty, TyKind,
+    db::HirDatabase, display::HirDisplay, infer::PointerCast, lang_items::is_box, ClosureId, Const,
+    ConstScalar, InferenceResult, Interner, MemoryMap, Substitution, Ty, TyKind,
 };
 use chalk_ir::Mutability;
 use hir_def::{
@@ -115,8 +115,11 @@ impl<V, T> ProjectionElem<V, T> {
         match self {
             ProjectionElem::Deref => match &base.data(Interner).kind {
                 TyKind::Raw(_, inner) | TyKind::Ref(_, _, inner) => inner.clone(),
+                TyKind::Adt(adt, subst) if is_box(db, adt.0) => {
+                    subst.at(Interner, 0).assert_ty_ref(Interner).clone()
+                }
                 _ => {
-                    never!("Overloaded deref is not a projection");
+                    never!("Overloaded deref on type {} is not a projection", base.display(db));
                     return TyKind::Error.intern(Interner);
                 }
             },
diff --git a/crates/hir-ty/src/tests/method_resolution.rs b/crates/hir-ty/src/tests/method_resolution.rs
index f62a3cfabe8..1e57a4ae296 100644
--- a/crates/hir-ty/src/tests/method_resolution.rs
+++ b/crates/hir-ty/src/tests/method_resolution.rs
@@ -1939,3 +1939,54 @@ fn foo() {
 "#,
     );
 }
+
+#[test]
+fn box_deref_is_builtin() {
+    check(
+        r#"
+//- minicore: deref
+use core::ops::Deref;
+
+#[lang = "owned_box"]
+struct Box<T>(*mut T);
+
+impl<T> Box<T> {
+    fn new(t: T) -> Self {
+        loop {}
+    }
+}
+
+impl<T> Deref for Box<T> {
+    type Target = T;
+    fn deref(&self) -> &Self::Target;
+}
+
+struct Foo;
+impl Foo {
+    fn foo(&self) {}
+}
+fn test() {
+    Box::new(Foo).foo();
+  //^^^^^^^^^^^^^ adjustments: Deref(None), Borrow(Ref(Not))
+}
+"#,
+    );
+}
+
+#[test]
+fn manually_drop_deref_is_not_builtin() {
+    check(
+        r#"
+//- minicore: manually_drop, deref
+struct Foo;
+impl Foo {
+    fn foo(&self) {}
+}
+use core::mem::ManuallyDrop;
+fn test() {
+    ManuallyDrop::new(Foo).foo();
+  //^^^^^^^^^^^^^^^^^^^^^^ adjustments: Deref(Some(OverloadedDeref(Some(Not)))), Borrow(Ref(Not))
+}
+"#,
+    );
+}
diff --git a/crates/test-utils/src/minicore.rs b/crates/test-utils/src/minicore.rs
index 2f0c086092e..ca1dbf532c3 100644
--- a/crates/test-utils/src/minicore.rs
+++ b/crates/test-utils/src/minicore.rs
@@ -31,6 +31,7 @@
 //!     infallible:
 //!     iterator: option
 //!     iterators: iterator, fn
+//!     manually_drop: drop
 //!     non_zero:
 //!     option: panic
 //!     ord: eq, option
@@ -194,6 +195,30 @@ pub mod convert {
 
 // region:drop
 pub mod mem {
+    // region:manually_drop
+    #[lang = "manually_drop"]
+    #[repr(transparent)]
+    pub struct ManuallyDrop<T: ?Sized> {
+        value: T,
+    }
+
+    impl<T> ManuallyDrop<T> {
+        pub const fn new(value: T) -> ManuallyDrop<T> {
+            ManuallyDrop { value }
+        }
+    }
+
+    // region:deref
+    impl<T: ?Sized> crate::ops::Deref for ManuallyDrop<T> {
+        type Target = T;
+        fn deref(&self) -> &T {
+            &self.value
+        }
+    }
+    // endregion:deref
+
+    // endregion:manually_drop
+
     pub fn drop<T>(_x: T) {}
 }
 // endregion:drop