Skip to content

Commit dc50b0f

Browse files
committed
feat: Implement object safety
1 parent 095926e commit dc50b0f

File tree

19 files changed

+821
-66
lines changed

19 files changed

+821
-66
lines changed

crates/hir-ty/src/chalk_db.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -381,9 +381,9 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
381381
TyKind::Error.intern(Interner)
382382
}
383383

384-
fn is_object_safe(&self, _trait_id: chalk_ir::TraitId<Interner>) -> bool {
385-
// FIXME: implement actual object safety
386-
true
384+
fn is_object_safe(&self, trait_id: chalk_ir::TraitId<Interner>) -> bool {
385+
let trait_ = from_chalk_trait_id(trait_id);
386+
self.db.object_safety(trait_).is_none()
387387
}
388388

389389
fn closure_kind(

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2007,7 +2007,7 @@ fn function_traits() {
20072007
);
20082008
check_number(
20092009
r#"
2010-
//- minicore: coerce_unsized, fn
2010+
//- minicore: coerce_unsized, fn, dispatch_from_dyn
20112011
fn add2(x: u8) -> u8 {
20122012
x + 2
20132013
}
@@ -2062,7 +2062,7 @@ fn function_traits() {
20622062
fn dyn_trait() {
20632063
check_number(
20642064
r#"
2065-
//- minicore: coerce_unsized, index, slice
2065+
//- minicore: coerce_unsized, index, slice, dispatch_from_dyn
20662066
trait Foo {
20672067
fn foo(&self) -> u8 { 10 }
20682068
}
@@ -2085,7 +2085,7 @@ fn dyn_trait() {
20852085
);
20862086
check_number(
20872087
r#"
2088-
//- minicore: coerce_unsized, index, slice
2088+
//- minicore: coerce_unsized, index, slice, dispatch_from_dyn
20892089
trait Foo {
20902090
fn foo(&self) -> i32 { 10 }
20912091
}
@@ -2109,7 +2109,7 @@ fn dyn_trait() {
21092109
);
21102110
check_number(
21112111
r#"
2112-
//- minicore: coerce_unsized, index, slice
2112+
//- minicore: coerce_unsized, index, slice, dispatch_from_dyn
21132113
trait A {
21142114
fn x(&self) -> i32;
21152115
}

crates/hir-ty/src/consteval/tests/intrinsics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ fn size_of_val() {
8989
);
9090
check_number(
9191
r#"
92-
//- minicore: coerce_unsized, fmt, builtin_impls
92+
//- minicore: coerce_unsized, fmt, builtin_impls, dispatch_from_dyn
9393
extern "rust-intrinsic" {
9494
pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
9595
}

crates/hir-ty/src/db.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use base_db::{
1111
use hir_def::{
1212
db::DefDatabase, hir::ExprId, layout::TargetDataLayout, AdtId, BlockId, CallableDefId,
1313
ConstParamId, DefWithBodyId, EnumVariantId, FunctionId, GeneralConstId, GenericDefId, ImplId,
14-
LifetimeParamId, LocalFieldId, StaticId, TypeAliasId, TypeOrConstParamId, VariantId,
14+
LifetimeParamId, LocalFieldId, StaticId, TraitId, TypeAliasId, TypeOrConstParamId, VariantId,
1515
};
1616
use la_arena::ArenaMap;
1717
use smallvec::SmallVec;
@@ -24,6 +24,7 @@ use crate::{
2424
lower::{GenericDefaults, GenericPredicates},
2525
method_resolution::{InherentImpls, TraitImpls, TyFingerprint},
2626
mir::{BorrowckResult, MirBody, MirLowerError},
27+
object_safety::ObjectSafetyViolation,
2728
Binders, ClosureId, Const, FnDefId, ImplTraitId, ImplTraits, InferenceResult, Interner,
2829
PolyFnSig, Substitution, TraitEnvironment, TraitRef, Ty, TyDefId, ValueTyDefId,
2930
};
@@ -107,6 +108,12 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
107108
#[salsa::invoke(crate::layout::target_data_layout_query)]
108109
fn target_data_layout(&self, krate: CrateId) -> Result<Arc<TargetDataLayout>, Arc<str>>;
109110

111+
#[salsa::invoke(crate::object_safety::object_safety_query)]
112+
fn object_safety(&self, trait_: TraitId) -> Option<ObjectSafetyViolation>;
113+
114+
#[salsa::invoke(crate::object_safety::object_safety_of_trait_query)]
115+
fn object_safety_of_trait(&self, trait_: TraitId) -> Option<ObjectSafetyViolation>;
116+
110117
#[salsa::invoke(crate::lower::ty_query)]
111118
#[salsa::cycle(crate::lower::ty_recover)]
112119
fn ty(&self, def: TyDefId) -> Binders<Ty>;

crates/hir-ty/src/generics.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,22 @@ impl Generics {
225225
}
226226
}
227227

228+
pub(crate) fn trait_self_param_idx(db: &dyn DefDatabase, def: GenericDefId) -> Option<usize> {
229+
match def {
230+
GenericDefId::TraitId(_) | GenericDefId::ImplId(_) => {
231+
let params = db.generic_params(def);
232+
params.trait_self_param().map(|idx| idx.into_raw().into_u32() as usize)
233+
}
234+
_ => {
235+
let parent_def = parent_generic_def(db, def)?;
236+
let parent_params = db.generic_params(parent_def);
237+
let parent_self_idx = parent_params.trait_self_param()?.into_raw().into_u32() as usize;
238+
let self_params = db.generic_params(def);
239+
Some(self_params.len() + parent_self_idx)
240+
}
241+
}
242+
}
243+
228244
fn parent_generic_def(db: &dyn DefDatabase, def: GenericDefId) -> Option<GenericDefId> {
229245
let container = match def {
230246
GenericDefId::FunctionId(it) => it.lookup(db).container,

crates/hir-ty/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ pub mod lang_items;
4040
pub mod layout;
4141
pub mod method_resolution;
4242
pub mod mir;
43+
pub mod object_safety;
4344
pub mod primitive;
4445
pub mod traits;
4546

crates/hir-ty/src/lower.rs

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ use crate::{
5858
},
5959
db::HirDatabase,
6060
error_lifetime,
61-
generics::{generics, Generics},
61+
generics::{generics, trait_self_param_idx, Generics},
6262
make_binders,
6363
mapping::{from_chalk_trait_id, lt_to_placeholder_idx, ToChalk},
6464
static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
@@ -1747,21 +1747,7 @@ fn implicitly_sized_clauses<'a, 'subst: 'a>(
17471747
.lang_item(resolver.krate(), LangItem::Sized)
17481748
.and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id))?;
17491749

1750-
let get_trait_self_idx = |container: ItemContainerId| {
1751-
if matches!(container, ItemContainerId::TraitId(_)) {
1752-
let generics = generics(db.upcast(), def);
1753-
Some(generics.len_self())
1754-
} else {
1755-
None
1756-
}
1757-
};
1758-
let trait_self_idx = match def {
1759-
GenericDefId::TraitId(_) => Some(0),
1760-
GenericDefId::FunctionId(it) => get_trait_self_idx(it.lookup(db.upcast()).container),
1761-
GenericDefId::ConstId(it) => get_trait_self_idx(it.lookup(db.upcast()).container),
1762-
GenericDefId::TypeAliasId(it) => get_trait_self_idx(it.lookup(db.upcast()).container),
1763-
_ => None,
1764-
};
1750+
let trait_self_idx = trait_self_param_idx(db.upcast(), def);
17651751

17661752
Some(
17671753
substitution

crates/hir-ty/src/mir/eval/tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -849,7 +849,7 @@ fn main() {
849849
fn regression_14966() {
850850
check_pass(
851851
r#"
852-
//- minicore: fn, copy, coerce_unsized
852+
//- minicore: fn, copy, coerce_unsized, dispatch_from_dyn
853853
trait A<T> {
854854
fn a(&self) {}
855855
}

0 commit comments

Comments
 (0)