Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #14639 - HKalbasi:dev2, r=Veykril
Fix some typos in `StructFlags` And a question: what is the benefit of storing things like `IS_BOX` in struct flags over using `lang_attr`?
bors 2023-04-24
parent bc78ebd · parent 232f293 · commit 1b835da
-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 31f9131799..4eefd66d47 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 adfdb01e72..85ed46b963 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 6d8e73655e..fef0077119 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 f62a3cfabe..1e57a4ae29 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 2f0c086092..ca1dbf532c 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