Skip to content

Commit

Permalink
Auto merge of rust-lang#17814 - ShoyuVanilla:object-safety, r=Veykril
Browse files Browse the repository at this point in the history
feat: Implement object safety and its hovering hint

Resolves rust-lang#17779

- [x] Fill missing implementations
- [x] Hover rendering
- [x] Implement object safety's own test suite, like layout
- [x] Add test cases (from rustc maybe)
- [x] Clean up ugly codes
- [x] Add doc string
  • Loading branch information
bors committed Aug 29, 2024
2 parents 23bea2b + a54a7a8 commit 28142e4
Show file tree
Hide file tree
Showing 19 changed files with 1,194 additions and 66 deletions.
6 changes: 3 additions & 3 deletions src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,9 +381,9 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
TyKind::Error.intern(Interner)
}

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

fn closure_kind(
Expand Down
8 changes: 4 additions & 4 deletions src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2007,7 +2007,7 @@ fn function_traits() {
);
check_number(
r#"
//- minicore: coerce_unsized, fn
//- minicore: coerce_unsized, fn, dispatch_from_dyn
fn add2(x: u8) -> u8 {
x + 2
}
Expand Down Expand Up @@ -2062,7 +2062,7 @@ fn function_traits() {
fn dyn_trait() {
check_number(
r#"
//- minicore: coerce_unsized, index, slice
//- minicore: coerce_unsized, index, slice, dispatch_from_dyn
trait Foo {
fn foo(&self) -> u8 { 10 }
}
Expand All @@ -2085,7 +2085,7 @@ fn dyn_trait() {
);
check_number(
r#"
//- minicore: coerce_unsized, index, slice
//- minicore: coerce_unsized, index, slice, dispatch_from_dyn
trait Foo {
fn foo(&self) -> i32 { 10 }
}
Expand All @@ -2109,7 +2109,7 @@ fn dyn_trait() {
);
check_number(
r#"
//- minicore: coerce_unsized, index, slice
//- minicore: coerce_unsized, index, slice, dispatch_from_dyn
trait A {
fn x(&self) -> i32;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ fn size_of_val() {
);
check_number(
r#"
//- minicore: coerce_unsized, fmt, builtin_impls
//- minicore: coerce_unsized, fmt, builtin_impls, dispatch_from_dyn
extern "rust-intrinsic" {
pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
}
Expand Down
6 changes: 5 additions & 1 deletion src/tools/rust-analyzer/crates/hir-ty/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use base_db::{
use hir_def::{
db::DefDatabase, hir::ExprId, layout::TargetDataLayout, AdtId, BlockId, CallableDefId,
ConstParamId, DefWithBodyId, EnumVariantId, FunctionId, GeneralConstId, GenericDefId, ImplId,
LifetimeParamId, LocalFieldId, StaticId, TypeAliasId, TypeOrConstParamId, VariantId,
LifetimeParamId, LocalFieldId, StaticId, TraitId, TypeAliasId, TypeOrConstParamId, VariantId,
};
use la_arena::ArenaMap;
use smallvec::SmallVec;
Expand All @@ -24,6 +24,7 @@ use crate::{
lower::{GenericDefaults, GenericPredicates},
method_resolution::{InherentImpls, TraitImpls, TyFingerprint},
mir::{BorrowckResult, MirBody, MirLowerError},
object_safety::ObjectSafetyViolation,
Binders, ClosureId, Const, FnDefId, ImplTraitId, ImplTraits, InferenceResult, Interner,
PolyFnSig, Substitution, TraitEnvironment, TraitRef, Ty, TyDefId, ValueTyDefId,
};
Expand Down Expand Up @@ -107,6 +108,9 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
#[salsa::invoke(crate::layout::target_data_layout_query)]
fn target_data_layout(&self, krate: CrateId) -> Result<Arc<TargetDataLayout>, Arc<str>>;

#[salsa::invoke(crate::object_safety::object_safety_of_trait_query)]
fn object_safety_of_trait(&self, trait_: TraitId) -> Option<ObjectSafetyViolation>;

#[salsa::invoke(crate::lower::ty_query)]
#[salsa::cycle(crate::lower::ty_recover)]
fn ty(&self, def: TyDefId) -> Binders<Ty>;
Expand Down
17 changes: 17 additions & 0 deletions src/tools/rust-analyzer/crates/hir-ty/src/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,23 @@ impl Generics {
}
}

pub(crate) fn trait_self_param_idx(db: &dyn DefDatabase, def: GenericDefId) -> Option<usize> {
match def {
GenericDefId::TraitId(_) | GenericDefId::TraitAliasId(_) => {
let params = db.generic_params(def);
params.trait_self_param().map(|idx| idx.into_raw().into_u32() as usize)
}
GenericDefId::ImplId(_) => None,
_ => {
let parent_def = parent_generic_def(db, def)?;
let parent_params = db.generic_params(parent_def);
let parent_self_idx = parent_params.trait_self_param()?.into_raw().into_u32() as usize;
let self_params = db.generic_params(def);
Some(self_params.len() + parent_self_idx)
}
}
}

fn parent_generic_def(db: &dyn DefDatabase, def: GenericDefId) -> Option<GenericDefId> {
let container = match def {
GenericDefId::FunctionId(it) => it.lookup(db).container,
Expand Down
1 change: 1 addition & 0 deletions src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ pub mod lang_items;
pub mod layout;
pub mod method_resolution;
pub mod mir;
pub mod object_safety;
pub mod primitive;
pub mod traits;

Expand Down
18 changes: 2 additions & 16 deletions src/tools/rust-analyzer/crates/hir-ty/src/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ use crate::{
},
db::HirDatabase,
error_lifetime,
generics::{generics, Generics},
generics::{generics, trait_self_param_idx, Generics},
make_binders,
mapping::{from_chalk_trait_id, lt_to_placeholder_idx, ToChalk},
static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
Expand Down Expand Up @@ -1747,21 +1747,7 @@ fn implicitly_sized_clauses<'a, 'subst: 'a>(
.lang_item(resolver.krate(), LangItem::Sized)
.and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id))?;

let get_trait_self_idx = |container: ItemContainerId| {
if matches!(container, ItemContainerId::TraitId(_)) {
let generics = generics(db.upcast(), def);
Some(generics.len_self())
} else {
None
}
};
let trait_self_idx = match def {
GenericDefId::TraitId(_) => Some(0),
GenericDefId::FunctionId(it) => get_trait_self_idx(it.lookup(db.upcast()).container),
GenericDefId::ConstId(it) => get_trait_self_idx(it.lookup(db.upcast()).container),
GenericDefId::TypeAliasId(it) => get_trait_self_idx(it.lookup(db.upcast()).container),
_ => None,
};
let trait_self_idx = trait_self_param_idx(db.upcast(), def);

Some(
substitution
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -849,7 +849,7 @@ fn main() {
fn regression_14966() {
check_pass(
r#"
//- minicore: fn, copy, coerce_unsized
//- minicore: fn, copy, coerce_unsized, dispatch_from_dyn
trait A<T> {
fn a(&self) {}
}
Expand Down
Loading

0 comments on commit 28142e4

Please sign in to comment.