|
1 | 1 | //! Various extensions traits for Chalk types.
|
2 | 2 |
|
3 |
| -use chalk_ir::{FloatTy, IntTy, Mutability, Scalar, TyVariableKind, UintTy}; |
| 3 | +use chalk_ir::{cast::Cast, FloatTy, IntTy, Mutability, Scalar, TyVariableKind, UintTy}; |
4 | 4 | use hir_def::{
|
5 | 5 | builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType, BuiltinUint},
|
6 | 6 | generics::TypeOrConstParamData,
|
7 | 7 | lang_item::LangItem,
|
8 | 8 | type_ref::Rawness,
|
9 |
| - FunctionId, GenericDefId, HasModule, ItemContainerId, Lookup, TraitId, |
| 9 | + DefWithBodyId, FunctionId, GenericDefId, HasModule, ItemContainerId, Lookup, TraitId, |
10 | 10 | };
|
11 | 11 |
|
12 | 12 | use crate::{
|
13 |
| - db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, |
14 |
| - from_placeholder_idx, to_chalk_trait_id, utils::generics, AdtId, AliasEq, AliasTy, Binders, |
15 |
| - CallableDefId, CallableSig, ClosureId, DynTy, FnPointer, ImplTraitId, Interner, Lifetime, |
16 |
| - ProjectionTy, QuantifiedWhereClause, Substitution, TraitRef, Ty, TyBuilder, TyKind, TypeFlags, |
17 |
| - WhereClause, |
| 13 | + db::HirDatabase, |
| 14 | + from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, from_placeholder_idx, |
| 15 | + to_chalk_trait_id, |
| 16 | + utils::{generics, ClosureSubst}, |
| 17 | + AdtId, AliasEq, AliasTy, Binders, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, |
| 18 | + ClosureId, DynTy, FnPointer, ImplTraitId, InEnvironment, Interner, Lifetime, ProjectionTy, |
| 19 | + QuantifiedWhereClause, Substitution, TraitRef, Ty, TyBuilder, TyKind, TypeFlags, WhereClause, |
18 | 20 | };
|
19 | 21 |
|
20 | 22 | pub trait TyExt {
|
@@ -46,6 +48,7 @@ pub trait TyExt {
|
46 | 48 |
|
47 | 49 | fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<QuantifiedWhereClause>>;
|
48 | 50 | fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId>;
|
| 51 | + fn is_copy(self, db: &dyn HirDatabase, owner: DefWithBodyId) -> bool; |
49 | 52 |
|
50 | 53 | /// FIXME: Get rid of this, it's not a good abstraction
|
51 | 54 | fn equals_ctor(&self, other: &Ty) -> bool;
|
@@ -185,10 +188,7 @@ impl TyExt for Ty {
|
185 | 188 | let sig = db.callable_item_signature(callable_def);
|
186 | 189 | Some(sig.substitute(Interner, parameters))
|
187 | 190 | }
|
188 |
| - TyKind::Closure(.., substs) => { |
189 |
| - let sig_param = substs.at(Interner, 0).assert_ty_ref(Interner); |
190 |
| - sig_param.callable_sig(db) |
191 |
| - } |
| 191 | + TyKind::Closure(.., substs) => ClosureSubst(substs).sig_ty().callable_sig(db), |
192 | 192 | _ => None,
|
193 | 193 | }
|
194 | 194 | }
|
@@ -327,6 +327,20 @@ impl TyExt for Ty {
|
327 | 327 | }
|
328 | 328 | }
|
329 | 329 |
|
| 330 | + fn is_copy(self, db: &dyn HirDatabase, owner: DefWithBodyId) -> bool { |
| 331 | + let crate_id = owner.module(db.upcast()).krate(); |
| 332 | + let Some(copy_trait) = db.lang_item(crate_id, LangItem::Copy).and_then(|x| x.as_trait()) else { |
| 333 | + return false; |
| 334 | + }; |
| 335 | + let trait_ref = TyBuilder::trait_ref(db, copy_trait).push(self).build(); |
| 336 | + let env = db.trait_environment_for_body(owner); |
| 337 | + let goal = Canonical { |
| 338 | + value: InEnvironment::new(&env.env, trait_ref.cast(Interner)), |
| 339 | + binders: CanonicalVarKinds::empty(Interner), |
| 340 | + }; |
| 341 | + db.trait_solve(crate_id, None, goal).is_some() |
| 342 | + } |
| 343 | + |
330 | 344 | fn equals_ctor(&self, other: &Ty) -> bool {
|
331 | 345 | match (self.kind(Interner), other.kind(Interner)) {
|
332 | 346 | (TyKind::Adt(adt, ..), TyKind::Adt(adt2, ..)) => adt == adt2,
|
|
0 commit comments