|
| 1 | +//! Compute the object-safety of a trait |
| 2 | +
|
1 | 3 | use chalk_ir::{DebruijnIndex, WhereClause};
|
2 | 4 | use hir_def::{
|
3 | 5 | lang_item::LangItem, AssocItemId, ConstId, FunctionId, GenericDefId, HasModule, TraitId,
|
4 | 6 | TypeAliasId,
|
5 | 7 | };
|
6 | 8 |
|
7 | 9 | use crate::{
|
8 |
| - all_super_traits, db::HirDatabase, generics::generics, layout::LayoutError, |
9 |
| - lower::callable_item_sig, make_single_type_binders, static_lifetime, wrap_empty_binders, DynTy, |
10 |
| - Interner, QuantifiedWhereClauses, Substitution, TyBuilder, TyKind, |
| 10 | + all_super_traits, db::HirDatabase, from_chalk_trait_id, generics::generics, |
| 11 | + layout::LayoutError, lower::callable_item_sig, make_single_type_binders, static_lifetime, |
| 12 | + utils::elaborate_clause_supertraits, wrap_empty_binders, DynTy, Interner, |
| 13 | + QuantifiedWhereClauses, Substitution, TyBuilder, TyKind, |
11 | 14 | };
|
12 | 15 |
|
13 | 16 | #[derive(Debug, Clone, PartialEq, Eq)]
|
@@ -79,14 +82,27 @@ pub fn object_safety_of_trait_query(
|
79 | 82 |
|
80 | 83 | fn generics_require_sized_self(db: &dyn HirDatabase, def: GenericDefId) -> bool {
|
81 | 84 | let krate = def.module(db.upcast()).krate();
|
82 |
| - let Some(_sized) = db.lang_item(krate, LangItem::Sized).and_then(|l| l.as_trait()) else { |
| 85 | + let Some(sized) = db.lang_item(krate, LangItem::Sized).and_then(|l| l.as_trait()) else { |
83 | 86 | return false;
|
84 | 87 | };
|
85 | 88 |
|
86 |
| - let _predicates = db.generic_predicates(def); |
87 |
| - // TODO: elaborate with `utils::elaborate_clause_supertraits` and check `Self: Sized` |
88 |
| - |
89 |
| - false |
| 89 | + let predicates = &*db.generic_predicates(def); |
| 90 | + let predicates = predicates.iter().map(|p| p.skip_binders().skip_binders().clone()); |
| 91 | + elaborate_clause_supertraits(db, predicates).any(|pred| match pred { |
| 92 | + WhereClause::Implemented(trait_ref) => { |
| 93 | + if from_chalk_trait_id(trait_ref.trait_id) == sized { |
| 94 | + if let TyKind::BoundVar(it) = |
| 95 | + *trait_ref.self_type_parameter(Interner).kind(Interner) |
| 96 | + { |
| 97 | + // Since `generic_predicates` is `Binder<Binder<..>>`, the `DebrujinIndex` of |
| 98 | + // self-parameter is `1` |
| 99 | + return it.index_if_bound_at(DebruijnIndex::new(1)).is_some_and(|i| i == 0); |
| 100 | + } |
| 101 | + } |
| 102 | + false |
| 103 | + } |
| 104 | + _ => false, |
| 105 | + }) |
90 | 106 | }
|
91 | 107 |
|
92 | 108 | fn object_safety_violation_for_assoc_item(
|
|
0 commit comments