Skip to content

Commit 1b835da

Browse files
committed
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`?
2 parents bc78ebd + 232f293 commit 1b835da

File tree

5 files changed

+84
-5
lines changed

5 files changed

+84
-5
lines changed

crates/hir-def/src/data/adt.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ bitflags! {
6060
/// Indicates whether this struct is `ManuallyDrop`.
6161
const IS_MANUALLY_DROP = 1 << 6;
6262
/// Indicates whether this struct is `UnsafeCell`.
63-
const IS_UNSAFE_CELL = 1 << 6;
63+
const IS_UNSAFE_CELL = 1 << 7;
6464
}
6565
}
6666

crates/hir-ty/src/lang_items.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::db::HirDatabase;
77

88
pub fn is_box(db: &dyn HirDatabase, adt: AdtId) -> bool {
99
let AdtId::StructId(id) = adt else { return false };
10-
db.struct_data(id).flags.contains(StructFlags::IS_UNSAFE_CELL)
10+
db.struct_data(id).flags.contains(StructFlags::IS_BOX)
1111
}
1212

1313
pub fn is_unsafe_cell(db: &dyn HirDatabase, adt: AdtId) -> bool {

crates/hir-ty/src/mir.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
use std::{fmt::Display, iter};
44

55
use crate::{
6-
db::HirDatabase, infer::PointerCast, ClosureId, Const, ConstScalar, InferenceResult, Interner,
7-
MemoryMap, Substitution, Ty, TyKind,
6+
db::HirDatabase, display::HirDisplay, infer::PointerCast, lang_items::is_box, ClosureId, Const,
7+
ConstScalar, InferenceResult, Interner, MemoryMap, Substitution, Ty, TyKind,
88
};
99
use chalk_ir::Mutability;
1010
use hir_def::{
@@ -115,8 +115,11 @@ impl<V, T> ProjectionElem<V, T> {
115115
match self {
116116
ProjectionElem::Deref => match &base.data(Interner).kind {
117117
TyKind::Raw(_, inner) | TyKind::Ref(_, _, inner) => inner.clone(),
118+
TyKind::Adt(adt, subst) if is_box(db, adt.0) => {
119+
subst.at(Interner, 0).assert_ty_ref(Interner).clone()
120+
}
118121
_ => {
119-
never!("Overloaded deref is not a projection");
122+
never!("Overloaded deref on type {} is not a projection", base.display(db));
120123
return TyKind::Error.intern(Interner);
121124
}
122125
},

crates/hir-ty/src/tests/method_resolution.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1939,3 +1939,54 @@ fn foo() {
19391939
"#,
19401940
);
19411941
}
1942+
1943+
#[test]
1944+
fn box_deref_is_builtin() {
1945+
check(
1946+
r#"
1947+
//- minicore: deref
1948+
use core::ops::Deref;
1949+
1950+
#[lang = "owned_box"]
1951+
struct Box<T>(*mut T);
1952+
1953+
impl<T> Box<T> {
1954+
fn new(t: T) -> Self {
1955+
loop {}
1956+
}
1957+
}
1958+
1959+
impl<T> Deref for Box<T> {
1960+
type Target = T;
1961+
fn deref(&self) -> &Self::Target;
1962+
}
1963+
1964+
struct Foo;
1965+
impl Foo {
1966+
fn foo(&self) {}
1967+
}
1968+
fn test() {
1969+
Box::new(Foo).foo();
1970+
//^^^^^^^^^^^^^ adjustments: Deref(None), Borrow(Ref(Not))
1971+
}
1972+
"#,
1973+
);
1974+
}
1975+
1976+
#[test]
1977+
fn manually_drop_deref_is_not_builtin() {
1978+
check(
1979+
r#"
1980+
//- minicore: manually_drop, deref
1981+
struct Foo;
1982+
impl Foo {
1983+
fn foo(&self) {}
1984+
}
1985+
use core::mem::ManuallyDrop;
1986+
fn test() {
1987+
ManuallyDrop::new(Foo).foo();
1988+
//^^^^^^^^^^^^^^^^^^^^^^ adjustments: Deref(Some(OverloadedDeref(Some(Not)))), Borrow(Ref(Not))
1989+
}
1990+
"#,
1991+
);
1992+
}

crates/test-utils/src/minicore.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
//! infallible:
3232
//! iterator: option
3333
//! iterators: iterator, fn
34+
//! manually_drop: drop
3435
//! non_zero:
3536
//! option: panic
3637
//! ord: eq, option
@@ -194,6 +195,30 @@ pub mod convert {
194195

195196
// region:drop
196197
pub mod mem {
198+
// region:manually_drop
199+
#[lang = "manually_drop"]
200+
#[repr(transparent)]
201+
pub struct ManuallyDrop<T: ?Sized> {
202+
value: T,
203+
}
204+
205+
impl<T> ManuallyDrop<T> {
206+
pub const fn new(value: T) -> ManuallyDrop<T> {
207+
ManuallyDrop { value }
208+
}
209+
}
210+
211+
// region:deref
212+
impl<T: ?Sized> crate::ops::Deref for ManuallyDrop<T> {
213+
type Target = T;
214+
fn deref(&self) -> &T {
215+
&self.value
216+
}
217+
}
218+
// endregion:deref
219+
220+
// endregion:manually_drop
221+
197222
pub fn drop<T>(_x: T) {}
198223
}
199224
// endregion:drop

0 commit comments

Comments
 (0)