diff options
| author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-04-06 14:32:15 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-04-06 14:32:15 +0100 |
| commit | 12e86433ab57ee8b1c96b8da0480fd311752487b (patch) | |
| tree | 7f4d2f298c242cc64432cf5c015f77c29f7e5a25 /crates/hir_ty/src | |
| parent | 4414071074759dee637e0ce968805de63e60da7b (diff) | |
| parent | bc993bbe85a231a7aa0414c6bea65d31d7375277 (diff) | |
Merge #8368
8368: Move Ty accessors to TyExt r=flodiebold a=Veykril
CC #8313
Co-authored-by: Lukas Wirth <[email protected]>
Diffstat (limited to 'crates/hir_ty/src')
| -rw-r--r-- | crates/hir_ty/src/builder.rs | 2 | ||||
| -rw-r--r-- | crates/hir_ty/src/chalk_ext.rs | 229 | ||||
| -rw-r--r-- | crates/hir_ty/src/diagnostics/match_check.rs | 2 | ||||
| -rw-r--r-- | crates/hir_ty/src/diagnostics/unsafe_check.rs | 4 | ||||
| -rw-r--r-- | crates/hir_ty/src/infer.rs | 2 | ||||
| -rw-r--r-- | crates/hir_ty/src/infer/coerce.rs | 2 | ||||
| -rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 3 | ||||
| -rw-r--r-- | crates/hir_ty/src/infer/pat.rs | 2 | ||||
| -rw-r--r-- | crates/hir_ty/src/infer/path.rs | 4 | ||||
| -rw-r--r-- | crates/hir_ty/src/lib.rs | 214 | ||||
| -rw-r--r-- | crates/hir_ty/src/method_resolution.rs | 2 | ||||
| -rw-r--r-- | crates/hir_ty/src/traits/chalk.rs | 2 |
12 files changed, 244 insertions, 224 deletions
diff --git a/crates/hir_ty/src/builder.rs b/crates/hir_ty/src/builder.rs index 791915fe0..09512d1ce 100644 --- a/crates/hir_ty/src/builder.rs +++ b/crates/hir_ty/src/builder.rs | |||
| @@ -13,7 +13,7 @@ use smallvec::SmallVec; | |||
| 13 | use crate::{ | 13 | use crate::{ |
| 14 | db::HirDatabase, primitive, to_assoc_type_id, to_chalk_trait_id, utils::generics, Binders, | 14 | db::HirDatabase, primitive, to_assoc_type_id, to_chalk_trait_id, utils::generics, Binders, |
| 15 | CallableSig, FnPointer, FnSig, FnSubst, GenericArg, Interner, ProjectionTy, Substitution, | 15 | CallableSig, FnPointer, FnSig, FnSubst, GenericArg, Interner, ProjectionTy, Substitution, |
| 16 | TraitRef, Ty, TyDefId, TyKind, TypeWalk, ValueTyDefId, | 16 | TraitRef, Ty, TyDefId, TyExt, TyKind, TypeWalk, ValueTyDefId, |
| 17 | }; | 17 | }; |
| 18 | 18 | ||
| 19 | /// This is a builder for `Ty` or anything that needs a `Substitution`. | 19 | /// This is a builder for `Ty` or anything that needs a `Substitution`. |
diff --git a/crates/hir_ty/src/chalk_ext.rs b/crates/hir_ty/src/chalk_ext.rs index 0f4cb43e9..8e8a1aa48 100644 --- a/crates/hir_ty/src/chalk_ext.rs +++ b/crates/hir_ty/src/chalk_ext.rs | |||
| @@ -1,20 +1,243 @@ | |||
| 1 | //! Various extensions traits for Chalk types. | 1 | //! Various extensions traits for Chalk types. |
| 2 | 2 | ||
| 3 | use hir_def::{AssocContainerId, Lookup, TraitId}; | 3 | use chalk_ir::Mutability; |
| 4 | use hir_def::{ | ||
| 5 | type_ref::Rawness, AssocContainerId, FunctionId, GenericDefId, HasModule, Lookup, TraitId, | ||
| 6 | }; | ||
| 4 | 7 | ||
| 5 | use crate::{ | 8 | use crate::{ |
| 6 | db::HirDatabase, from_assoc_type_id, to_chalk_trait_id, Interner, ProjectionTy, TraitRef, Ty, | 9 | db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, |
| 7 | TyKind, | 10 | from_placeholder_idx, to_chalk_trait_id, AdtId, AliasEq, AliasTy, Binders, CallableDefId, |
| 11 | CallableSig, ImplTraitId, Interner, Lifetime, ProjectionTy, QuantifiedWhereClause, | ||
| 12 | Substitution, TraitRef, Ty, TyBuilder, TyKind, WhereClause, | ||
| 8 | }; | 13 | }; |
| 9 | 14 | ||
| 10 | pub trait TyExt { | 15 | pub trait TyExt { |
| 11 | fn is_unit(&self) -> bool; | 16 | fn is_unit(&self) -> bool; |
| 17 | fn is_never(&self) -> bool; | ||
| 18 | fn is_unknown(&self) -> bool; | ||
| 19 | |||
| 20 | fn as_adt(&self) -> Option<(hir_def::AdtId, &Substitution)>; | ||
| 21 | fn as_tuple(&self) -> Option<&Substitution>; | ||
| 22 | fn as_fn_def(&self, db: &dyn HirDatabase) -> Option<FunctionId>; | ||
| 23 | fn as_reference(&self) -> Option<(&Ty, Lifetime, Mutability)>; | ||
| 24 | fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)>; | ||
| 25 | fn as_generic_def(&self, db: &dyn HirDatabase) -> Option<GenericDefId>; | ||
| 26 | |||
| 27 | fn callable_def(&self, db: &dyn HirDatabase) -> Option<CallableDefId>; | ||
| 28 | fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig>; | ||
| 29 | |||
| 30 | fn strip_references(&self) -> &Ty; | ||
| 31 | |||
| 32 | /// If this is a `dyn Trait`, returns that trait. | ||
| 33 | fn dyn_trait(&self) -> Option<TraitId>; | ||
| 34 | |||
| 35 | fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<QuantifiedWhereClause>>; | ||
| 36 | fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId>; | ||
| 12 | } | 37 | } |
| 13 | 38 | ||
| 14 | impl TyExt for Ty { | 39 | impl TyExt for Ty { |
| 15 | fn is_unit(&self) -> bool { | 40 | fn is_unit(&self) -> bool { |
| 16 | matches!(self.kind(&Interner), TyKind::Tuple(0, _)) | 41 | matches!(self.kind(&Interner), TyKind::Tuple(0, _)) |
| 17 | } | 42 | } |
| 43 | |||
| 44 | fn is_never(&self) -> bool { | ||
| 45 | matches!(self.kind(&Interner), TyKind::Never) | ||
| 46 | } | ||
| 47 | |||
| 48 | fn is_unknown(&self) -> bool { | ||
| 49 | matches!(self.kind(&Interner), TyKind::Error) | ||
| 50 | } | ||
| 51 | |||
| 52 | fn as_adt(&self) -> Option<(hir_def::AdtId, &Substitution)> { | ||
| 53 | match self.kind(&Interner) { | ||
| 54 | TyKind::Adt(AdtId(adt), parameters) => Some((*adt, parameters)), | ||
| 55 | _ => None, | ||
| 56 | } | ||
| 57 | } | ||
| 58 | |||
| 59 | fn as_tuple(&self) -> Option<&Substitution> { | ||
| 60 | match self.kind(&Interner) { | ||
| 61 | TyKind::Tuple(_, substs) => Some(substs), | ||
| 62 | _ => None, | ||
| 63 | } | ||
| 64 | } | ||
| 65 | |||
| 66 | fn as_fn_def(&self, db: &dyn HirDatabase) -> Option<FunctionId> { | ||
| 67 | if let Some(CallableDefId::FunctionId(func)) = self.callable_def(db) { | ||
| 68 | Some(func) | ||
| 69 | } else { | ||
| 70 | None | ||
| 71 | } | ||
| 72 | } | ||
| 73 | fn as_reference(&self) -> Option<(&Ty, Lifetime, Mutability)> { | ||
| 74 | match self.kind(&Interner) { | ||
| 75 | TyKind::Ref(mutability, lifetime, ty) => Some((ty, *lifetime, *mutability)), | ||
| 76 | _ => None, | ||
| 77 | } | ||
| 78 | } | ||
| 79 | |||
| 80 | fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { | ||
| 81 | match self.kind(&Interner) { | ||
| 82 | TyKind::Ref(mutability, _, ty) => Some((ty, Rawness::Ref, *mutability)), | ||
| 83 | TyKind::Raw(mutability, ty) => Some((ty, Rawness::RawPtr, *mutability)), | ||
| 84 | _ => None, | ||
| 85 | } | ||
| 86 | } | ||
| 87 | |||
| 88 | fn as_generic_def(&self, db: &dyn HirDatabase) -> Option<GenericDefId> { | ||
| 89 | match *self.kind(&Interner) { | ||
| 90 | TyKind::Adt(AdtId(adt), ..) => Some(adt.into()), | ||
| 91 | TyKind::FnDef(callable, ..) => { | ||
| 92 | Some(db.lookup_intern_callable_def(callable.into()).into()) | ||
| 93 | } | ||
| 94 | TyKind::AssociatedType(type_alias, ..) => Some(from_assoc_type_id(type_alias).into()), | ||
| 95 | TyKind::Foreign(type_alias, ..) => Some(from_foreign_def_id(type_alias).into()), | ||
| 96 | _ => None, | ||
| 97 | } | ||
| 98 | } | ||
| 99 | |||
| 100 | fn callable_def(&self, db: &dyn HirDatabase) -> Option<CallableDefId> { | ||
| 101 | match self.kind(&Interner) { | ||
| 102 | &TyKind::FnDef(def, ..) => Some(db.lookup_intern_callable_def(def.into())), | ||
| 103 | _ => None, | ||
| 104 | } | ||
| 105 | } | ||
| 106 | |||
| 107 | fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> { | ||
| 108 | match self.kind(&Interner) { | ||
| 109 | TyKind::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)), | ||
| 110 | TyKind::FnDef(def, parameters) => { | ||
| 111 | let callable_def = db.lookup_intern_callable_def((*def).into()); | ||
| 112 | let sig = db.callable_item_signature(callable_def); | ||
| 113 | Some(sig.substitute(&Interner, ¶meters)) | ||
| 114 | } | ||
| 115 | TyKind::Closure(.., substs) => { | ||
| 116 | let sig_param = substs.at(&Interner, 0).assert_ty_ref(&Interner); | ||
| 117 | sig_param.callable_sig(db) | ||
| 118 | } | ||
| 119 | _ => None, | ||
| 120 | } | ||
| 121 | } | ||
| 122 | |||
| 123 | fn dyn_trait(&self) -> Option<TraitId> { | ||
| 124 | let trait_ref = match self.kind(&Interner) { | ||
| 125 | TyKind::Dyn(dyn_ty) => dyn_ty.bounds.skip_binders().interned().get(0).and_then(|b| { | ||
| 126 | match b.skip_binders() { | ||
| 127 | WhereClause::Implemented(trait_ref) => Some(trait_ref), | ||
| 128 | _ => None, | ||
| 129 | } | ||
| 130 | }), | ||
| 131 | _ => None, | ||
| 132 | }?; | ||
| 133 | Some(from_chalk_trait_id(trait_ref.trait_id)) | ||
| 134 | } | ||
| 135 | |||
| 136 | fn strip_references(&self) -> &Ty { | ||
| 137 | let mut t: &Ty = self; | ||
| 138 | while let TyKind::Ref(_mutability, _lifetime, ty) = t.kind(&Interner) { | ||
| 139 | t = ty; | ||
| 140 | } | ||
| 141 | t | ||
| 142 | } | ||
| 143 | |||
| 144 | fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<QuantifiedWhereClause>> { | ||
| 145 | match self.kind(&Interner) { | ||
| 146 | TyKind::OpaqueType(opaque_ty_id, ..) => { | ||
| 147 | match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) { | ||
| 148 | ImplTraitId::AsyncBlockTypeImplTrait(def, _expr) => { | ||
| 149 | let krate = def.module(db.upcast()).krate(); | ||
| 150 | if let Some(future_trait) = db | ||
| 151 | .lang_item(krate, "future_trait".into()) | ||
| 152 | .and_then(|item| item.as_trait()) | ||
| 153 | { | ||
| 154 | // This is only used by type walking. | ||
| 155 | // Parameters will be walked outside, and projection predicate is not used. | ||
| 156 | // So just provide the Future trait. | ||
| 157 | let impl_bound = Binders::empty( | ||
| 158 | &Interner, | ||
| 159 | WhereClause::Implemented(TraitRef { | ||
| 160 | trait_id: to_chalk_trait_id(future_trait), | ||
| 161 | substitution: Substitution::empty(&Interner), | ||
| 162 | }), | ||
| 163 | ); | ||
| 164 | Some(vec![impl_bound]) | ||
| 165 | } else { | ||
| 166 | None | ||
| 167 | } | ||
| 168 | } | ||
| 169 | ImplTraitId::ReturnTypeImplTrait(..) => None, | ||
| 170 | } | ||
| 171 | } | ||
| 172 | TyKind::Alias(AliasTy::Opaque(opaque_ty)) => { | ||
| 173 | let predicates = match db.lookup_intern_impl_trait_id(opaque_ty.opaque_ty_id.into()) | ||
| 174 | { | ||
| 175 | ImplTraitId::ReturnTypeImplTrait(func, idx) => { | ||
| 176 | db.return_type_impl_traits(func).map(|it| { | ||
| 177 | let data = (*it) | ||
| 178 | .as_ref() | ||
| 179 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); | ||
| 180 | data.substitute(&Interner, &opaque_ty.substitution) | ||
| 181 | }) | ||
| 182 | } | ||
| 183 | // It always has an parameter for Future::Output type. | ||
| 184 | ImplTraitId::AsyncBlockTypeImplTrait(..) => unreachable!(), | ||
| 185 | }; | ||
| 186 | |||
| 187 | predicates.map(|it| it.into_value_and_skipped_binders().0) | ||
| 188 | } | ||
| 189 | TyKind::Placeholder(idx) => { | ||
| 190 | let id = from_placeholder_idx(db, *idx); | ||
| 191 | let generic_params = db.generic_params(id.parent); | ||
| 192 | let param_data = &generic_params.types[id.local_id]; | ||
| 193 | match param_data.provenance { | ||
| 194 | hir_def::generics::TypeParamProvenance::ArgumentImplTrait => { | ||
| 195 | let substs = TyBuilder::type_params_subst(db, id.parent); | ||
| 196 | let predicates = db | ||
| 197 | .generic_predicates(id.parent) | ||
| 198 | .into_iter() | ||
| 199 | .map(|pred| pred.clone().substitute(&Interner, &substs)) | ||
| 200 | .filter(|wc| match &wc.skip_binders() { | ||
| 201 | WhereClause::Implemented(tr) => { | ||
| 202 | tr.self_type_parameter(&Interner) == self | ||
| 203 | } | ||
| 204 | WhereClause::AliasEq(AliasEq { | ||
| 205 | alias: AliasTy::Projection(proj), | ||
| 206 | ty: _, | ||
| 207 | }) => proj.self_type_parameter(&Interner) == self, | ||
| 208 | _ => false, | ||
| 209 | }) | ||
| 210 | .collect::<Vec<_>>(); | ||
| 211 | |||
| 212 | Some(predicates) | ||
| 213 | } | ||
| 214 | _ => None, | ||
| 215 | } | ||
| 216 | } | ||
| 217 | _ => None, | ||
| 218 | } | ||
| 219 | } | ||
| 220 | |||
| 221 | fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> { | ||
| 222 | match self.kind(&Interner) { | ||
| 223 | TyKind::AssociatedType(id, ..) => { | ||
| 224 | match from_assoc_type_id(*id).lookup(db.upcast()).container { | ||
| 225 | AssocContainerId::TraitId(trait_id) => Some(trait_id), | ||
| 226 | _ => None, | ||
| 227 | } | ||
| 228 | } | ||
| 229 | TyKind::Alias(AliasTy::Projection(projection_ty)) => { | ||
| 230 | match from_assoc_type_id(projection_ty.associated_ty_id) | ||
| 231 | .lookup(db.upcast()) | ||
| 232 | .container | ||
| 233 | { | ||
| 234 | AssocContainerId::TraitId(trait_id) => Some(trait_id), | ||
| 235 | _ => None, | ||
| 236 | } | ||
| 237 | } | ||
| 238 | _ => None, | ||
| 239 | } | ||
| 240 | } | ||
| 18 | } | 241 | } |
| 19 | 242 | ||
| 20 | pub trait ProjectionTyExt { | 243 | pub trait ProjectionTyExt { |
diff --git a/crates/hir_ty/src/diagnostics/match_check.rs b/crates/hir_ty/src/diagnostics/match_check.rs index 34291578a..e9762622f 100644 --- a/crates/hir_ty/src/diagnostics/match_check.rs +++ b/crates/hir_ty/src/diagnostics/match_check.rs | |||
| @@ -227,7 +227,7 @@ use hir_def::{ | |||
| 227 | use la_arena::Idx; | 227 | use la_arena::Idx; |
| 228 | use smallvec::{smallvec, SmallVec}; | 228 | use smallvec::{smallvec, SmallVec}; |
| 229 | 229 | ||
| 230 | use crate::{db::HirDatabase, AdtId, InferenceResult, Interner, TyKind}; | 230 | use crate::{db::HirDatabase, AdtId, InferenceResult, Interner, TyExt, TyKind}; |
| 231 | 231 | ||
| 232 | #[derive(Debug, Clone, Copy)] | 232 | #[derive(Debug, Clone, Copy)] |
| 233 | /// Either a pattern from the source code being analyzed, represented as | 233 | /// Either a pattern from the source code being analyzed, represented as |
diff --git a/crates/hir_ty/src/diagnostics/unsafe_check.rs b/crates/hir_ty/src/diagnostics/unsafe_check.rs index b5efe9df5..ed97dc0e3 100644 --- a/crates/hir_ty/src/diagnostics/unsafe_check.rs +++ b/crates/hir_ty/src/diagnostics/unsafe_check.rs | |||
| @@ -11,7 +11,9 @@ use hir_def::{ | |||
| 11 | }; | 11 | }; |
| 12 | use hir_expand::diagnostics::DiagnosticSink; | 12 | use hir_expand::diagnostics::DiagnosticSink; |
| 13 | 13 | ||
| 14 | use crate::{db::HirDatabase, diagnostics::MissingUnsafe, InferenceResult, Interner, TyKind}; | 14 | use crate::{ |
| 15 | db::HirDatabase, diagnostics::MissingUnsafe, InferenceResult, Interner, TyExt, TyKind, | ||
| 16 | }; | ||
| 15 | 17 | ||
| 16 | pub(super) struct UnsafeValidator<'a, 'b: 'a> { | 18 | pub(super) struct UnsafeValidator<'a, 'b: 'a> { |
| 17 | owner: DefWithBodyId, | 19 | owner: DefWithBodyId, |
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index 1c3faf5cb..5146d873b 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs | |||
| @@ -42,7 +42,7 @@ use super::{ | |||
| 42 | }; | 42 | }; |
| 43 | use crate::{ | 43 | use crate::{ |
| 44 | db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, | 44 | db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, |
| 45 | to_assoc_type_id, AliasEq, AliasTy, Interner, TyBuilder, TyKind, | 45 | to_assoc_type_id, AliasEq, AliasTy, Interner, TyBuilder, TyExt, TyKind, |
| 46 | }; | 46 | }; |
| 47 | 47 | ||
| 48 | // This lint has a false positive here. See the link below for details. | 48 | // This lint has a false positive here. See the link below for details. |
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs index d6c48870a..159a53a63 100644 --- a/crates/hir_ty/src/infer/coerce.rs +++ b/crates/hir_ty/src/infer/coerce.rs | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | use chalk_ir::{cast::Cast, Mutability, TyVariableKind}; | 7 | use chalk_ir::{cast::Cast, Mutability, TyVariableKind}; |
| 8 | use hir_def::lang_item::LangItemTarget; | 8 | use hir_def::lang_item::LangItemTarget; |
| 9 | 9 | ||
| 10 | use crate::{autoderef, Interner, Solution, Ty, TyBuilder, TyKind}; | 10 | use crate::{autoderef, Interner, Solution, Ty, TyBuilder, TyExt, TyKind}; |
| 11 | 11 | ||
| 12 | use super::{InEnvironment, InferenceContext}; | 12 | use super::{InEnvironment, InferenceContext}; |
| 13 | 13 | ||
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 53d94fd0d..dab137ae1 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
| @@ -23,7 +23,8 @@ use crate::{ | |||
| 23 | traits::{chalk::from_chalk, FnTrait}, | 23 | traits::{chalk::from_chalk, FnTrait}, |
| 24 | utils::{generics, variant_data, Generics}, | 24 | utils::{generics, variant_data, Generics}, |
| 25 | AdtId, Binders, CallableDefId, FnPointer, FnSig, FnSubst, InEnvironment, Interner, | 25 | AdtId, Binders, CallableDefId, FnPointer, FnSig, FnSubst, InEnvironment, Interner, |
| 26 | ProjectionTyExt, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyKind, TypeWalk, | 26 | ProjectionTyExt, Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyExt, TyKind, |
| 27 | TypeWalk, | ||
| 27 | }; | 28 | }; |
| 28 | 29 | ||
| 29 | use super::{ | 30 | use super::{ |
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs index c1d7a6b76..fc2bc3ef8 100644 --- a/crates/hir_ty/src/infer/pat.rs +++ b/crates/hir_ty/src/infer/pat.rs | |||
| @@ -14,7 +14,7 @@ use hir_expand::name::Name; | |||
| 14 | use super::{BindingMode, Expectation, InferenceContext}; | 14 | use super::{BindingMode, Expectation, InferenceContext}; |
| 15 | use crate::{ | 15 | use crate::{ |
| 16 | lower::lower_to_chalk_mutability, static_lifetime, utils::variant_data, Interner, Substitution, | 16 | lower::lower_to_chalk_mutability, static_lifetime, utils::variant_data, Interner, Substitution, |
| 17 | Ty, TyBuilder, TyKind, | 17 | Ty, TyBuilder, TyExt, TyKind, |
| 18 | }; | 18 | }; |
| 19 | 19 | ||
| 20 | impl<'a> InferenceContext<'a> { | 20 | impl<'a> InferenceContext<'a> { |
diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs index 14f705173..b19d67bb1 100644 --- a/crates/hir_ty/src/infer/path.rs +++ b/crates/hir_ty/src/infer/path.rs | |||
| @@ -10,7 +10,9 @@ use hir_def::{ | |||
| 10 | }; | 10 | }; |
| 11 | use hir_expand::name::Name; | 11 | use hir_expand::name::Name; |
| 12 | 12 | ||
| 13 | use crate::{method_resolution, Interner, Substitution, Ty, TyBuilder, TyKind, ValueTyDefId}; | 13 | use crate::{ |
| 14 | method_resolution, Interner, Substitution, Ty, TyBuilder, TyExt, TyKind, ValueTyDefId, | ||
| 15 | }; | ||
| 14 | 16 | ||
| 15 | use super::{ExprOrPatId, InferenceContext, TraitRef}; | 17 | use super::{ExprOrPatId, InferenceContext, TraitRef}; |
| 16 | 18 | ||
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index a2a5bcc07..f5b658cba 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
| @@ -30,13 +30,11 @@ mod test_db; | |||
| 30 | 30 | ||
| 31 | use std::sync::Arc; | 31 | use std::sync::Arc; |
| 32 | 32 | ||
| 33 | use chalk_ir::UintTy; | ||
| 34 | use itertools::Itertools; | ||
| 35 | |||
| 36 | use base_db::salsa; | 33 | use base_db::salsa; |
| 34 | use chalk_ir::UintTy; | ||
| 37 | use hir_def::{ | 35 | use hir_def::{ |
| 38 | expr::ExprId, type_ref::Rawness, AssocContainerId, ConstParamId, FunctionId, GenericDefId, | 36 | expr::ExprId, type_ref::Rawness, ConstParamId, LifetimeParamId, TraitId, TypeAliasId, |
| 39 | HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId, | 37 | TypeParamId, |
| 40 | }; | 38 | }; |
| 41 | 39 | ||
| 42 | use crate::{db::HirDatabase, display::HirDisplay, utils::generics}; | 40 | use crate::{db::HirDatabase, display::HirDisplay, utils::generics}; |
| @@ -171,65 +169,6 @@ impl CallableSig { | |||
| 171 | } | 169 | } |
| 172 | 170 | ||
| 173 | impl Ty { | 171 | impl Ty { |
| 174 | pub fn as_reference(&self) -> Option<(&Ty, Lifetime, Mutability)> { | ||
| 175 | match self.kind(&Interner) { | ||
| 176 | TyKind::Ref(mutability, lifetime, ty) => Some((ty, *lifetime, *mutability)), | ||
| 177 | _ => None, | ||
| 178 | } | ||
| 179 | } | ||
| 180 | |||
| 181 | pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { | ||
| 182 | match self.kind(&Interner) { | ||
| 183 | TyKind::Ref(mutability, _, ty) => Some((ty, Rawness::Ref, *mutability)), | ||
| 184 | TyKind::Raw(mutability, ty) => Some((ty, Rawness::RawPtr, *mutability)), | ||
| 185 | _ => None, | ||
| 186 | } | ||
| 187 | } | ||
| 188 | |||
| 189 | pub fn strip_references(&self) -> &Ty { | ||
| 190 | let mut t: &Ty = self; | ||
| 191 | |||
| 192 | while let TyKind::Ref(_mutability, _lifetime, ty) = t.kind(&Interner) { | ||
| 193 | t = ty; | ||
| 194 | } | ||
| 195 | |||
| 196 | t | ||
| 197 | } | ||
| 198 | |||
| 199 | pub fn as_adt(&self) -> Option<(hir_def::AdtId, &Substitution)> { | ||
| 200 | match self.kind(&Interner) { | ||
| 201 | TyKind::Adt(AdtId(adt), parameters) => Some((*adt, parameters)), | ||
| 202 | _ => None, | ||
| 203 | } | ||
| 204 | } | ||
| 205 | |||
| 206 | pub fn as_tuple(&self) -> Option<&Substitution> { | ||
| 207 | match self.kind(&Interner) { | ||
| 208 | TyKind::Tuple(_, substs) => Some(substs), | ||
| 209 | _ => None, | ||
| 210 | } | ||
| 211 | } | ||
| 212 | |||
| 213 | pub fn as_generic_def(&self, db: &dyn HirDatabase) -> Option<GenericDefId> { | ||
| 214 | match *self.kind(&Interner) { | ||
| 215 | TyKind::Adt(AdtId(adt), ..) => Some(adt.into()), | ||
| 216 | TyKind::FnDef(callable, ..) => { | ||
| 217 | Some(db.lookup_intern_callable_def(callable.into()).into()) | ||
| 218 | } | ||
| 219 | TyKind::AssociatedType(type_alias, ..) => Some(from_assoc_type_id(type_alias).into()), | ||
| 220 | TyKind::Foreign(type_alias, ..) => Some(from_foreign_def_id(type_alias).into()), | ||
| 221 | _ => None, | ||
| 222 | } | ||
| 223 | } | ||
| 224 | |||
| 225 | pub fn is_never(&self) -> bool { | ||
| 226 | matches!(self.kind(&Interner), TyKind::Never) | ||
| 227 | } | ||
| 228 | |||
| 229 | pub fn is_unknown(&self) -> bool { | ||
| 230 | matches!(self.kind(&Interner), TyKind::Error) | ||
| 231 | } | ||
| 232 | |||
| 233 | pub fn equals_ctor(&self, other: &Ty) -> bool { | 172 | pub fn equals_ctor(&self, other: &Ty) -> bool { |
| 234 | match (self.kind(&Interner), other.kind(&Interner)) { | 173 | match (self.kind(&Interner), other.kind(&Interner)) { |
| 235 | (TyKind::Adt(adt, ..), TyKind::Adt(adt2, ..)) => adt == adt2, | 174 | (TyKind::Adt(adt, ..), TyKind::Adt(adt2, ..)) => adt == adt2, |
| @@ -260,24 +199,6 @@ impl Ty { | |||
| 260 | } | 199 | } |
| 261 | } | 200 | } |
| 262 | 201 | ||
| 263 | /// If this is a `dyn Trait` type, this returns the `Trait` part. | ||
| 264 | fn dyn_trait_ref(&self) -> Option<&TraitRef> { | ||
| 265 | match self.kind(&Interner) { | ||
| 266 | TyKind::Dyn(dyn_ty) => dyn_ty.bounds.skip_binders().interned().get(0).and_then(|b| { | ||
| 267 | match b.skip_binders() { | ||
| 268 | WhereClause::Implemented(trait_ref) => Some(trait_ref), | ||
| 269 | _ => None, | ||
| 270 | } | ||
| 271 | }), | ||
| 272 | _ => None, | ||
| 273 | } | ||
| 274 | } | ||
| 275 | |||
| 276 | /// If this is a `dyn Trait`, returns that trait. | ||
| 277 | pub fn dyn_trait(&self) -> Option<TraitId> { | ||
| 278 | self.dyn_trait_ref().map(|it| it.trait_id).map(from_chalk_trait_id) | ||
| 279 | } | ||
| 280 | |||
| 281 | fn builtin_deref(&self) -> Option<Ty> { | 202 | fn builtin_deref(&self) -> Option<Ty> { |
| 282 | match self.kind(&Interner) { | 203 | match self.kind(&Interner) { |
| 283 | TyKind::Ref(.., ty) => Some(ty.clone()), | 204 | TyKind::Ref(.., ty) => Some(ty.clone()), |
| @@ -286,37 +207,6 @@ impl Ty { | |||
| 286 | } | 207 | } |
| 287 | } | 208 | } |
| 288 | 209 | ||
| 289 | pub fn callable_def(&self, db: &dyn HirDatabase) -> Option<CallableDefId> { | ||
| 290 | match self.kind(&Interner) { | ||
| 291 | &TyKind::FnDef(def, ..) => Some(db.lookup_intern_callable_def(def.into())), | ||
| 292 | _ => None, | ||
| 293 | } | ||
| 294 | } | ||
| 295 | |||
| 296 | pub fn as_fn_def(&self, db: &dyn HirDatabase) -> Option<FunctionId> { | ||
| 297 | if let Some(CallableDefId::FunctionId(func)) = self.callable_def(db) { | ||
| 298 | Some(func) | ||
| 299 | } else { | ||
| 300 | None | ||
| 301 | } | ||
| 302 | } | ||
| 303 | |||
| 304 | pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> { | ||
| 305 | match self.kind(&Interner) { | ||
| 306 | TyKind::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)), | ||
| 307 | TyKind::FnDef(def, parameters) => { | ||
| 308 | let callable_def = db.lookup_intern_callable_def((*def).into()); | ||
| 309 | let sig = db.callable_item_signature(callable_def); | ||
| 310 | Some(sig.substitute(&Interner, ¶meters)) | ||
| 311 | } | ||
| 312 | TyKind::Closure(.., substs) => { | ||
| 313 | let sig_param = substs.at(&Interner, 0).assert_ty_ref(&Interner); | ||
| 314 | sig_param.callable_sig(db) | ||
| 315 | } | ||
| 316 | _ => None, | ||
| 317 | } | ||
| 318 | } | ||
| 319 | |||
| 320 | /// Returns the type parameters of this type if it has some (i.e. is an ADT | 210 | /// Returns the type parameters of this type if it has some (i.e. is an ADT |
| 321 | /// or function); so if `self` is `Option<u32>`, this returns the `u32`. | 211 | /// or function); so if `self` is `Option<u32>`, this returns the `u32`. |
| 322 | pub fn substs(&self) -> Option<&Substitution> { | 212 | pub fn substs(&self) -> Option<&Substitution> { |
| @@ -344,104 +234,6 @@ impl Ty { | |||
| 344 | _ => None, | 234 | _ => None, |
| 345 | } | 235 | } |
| 346 | } | 236 | } |
| 347 | |||
| 348 | pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<QuantifiedWhereClause>> { | ||
| 349 | match self.kind(&Interner) { | ||
| 350 | TyKind::OpaqueType(opaque_ty_id, ..) => { | ||
| 351 | match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) { | ||
| 352 | ImplTraitId::AsyncBlockTypeImplTrait(def, _expr) => { | ||
| 353 | let krate = def.module(db.upcast()).krate(); | ||
| 354 | if let Some(future_trait) = db | ||
| 355 | .lang_item(krate, "future_trait".into()) | ||
| 356 | .and_then(|item| item.as_trait()) | ||
| 357 | { | ||
| 358 | // This is only used by type walking. | ||
| 359 | // Parameters will be walked outside, and projection predicate is not used. | ||
| 360 | // So just provide the Future trait. | ||
| 361 | let impl_bound = Binders::empty( | ||
| 362 | &Interner, | ||
| 363 | WhereClause::Implemented(TraitRef { | ||
| 364 | trait_id: to_chalk_trait_id(future_trait), | ||
| 365 | substitution: Substitution::empty(&Interner), | ||
| 366 | }), | ||
| 367 | ); | ||
| 368 | Some(vec![impl_bound]) | ||
| 369 | } else { | ||
| 370 | None | ||
| 371 | } | ||
| 372 | } | ||
| 373 | ImplTraitId::ReturnTypeImplTrait(..) => None, | ||
| 374 | } | ||
| 375 | } | ||
| 376 | TyKind::Alias(AliasTy::Opaque(opaque_ty)) => { | ||
| 377 | let predicates = match db.lookup_intern_impl_trait_id(opaque_ty.opaque_ty_id.into()) | ||
| 378 | { | ||
| 379 | ImplTraitId::ReturnTypeImplTrait(func, idx) => { | ||
| 380 | db.return_type_impl_traits(func).map(|it| { | ||
| 381 | let data = (*it) | ||
| 382 | .as_ref() | ||
| 383 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); | ||
| 384 | data.substitute(&Interner, &opaque_ty.substitution) | ||
| 385 | }) | ||
| 386 | } | ||
| 387 | // It always has an parameter for Future::Output type. | ||
| 388 | ImplTraitId::AsyncBlockTypeImplTrait(..) => unreachable!(), | ||
| 389 | }; | ||
| 390 | |||
| 391 | predicates.map(|it| it.into_value_and_skipped_binders().0) | ||
| 392 | } | ||
| 393 | TyKind::Placeholder(idx) => { | ||
| 394 | let id = from_placeholder_idx(db, *idx); | ||
| 395 | let generic_params = db.generic_params(id.parent); | ||
| 396 | let param_data = &generic_params.types[id.local_id]; | ||
| 397 | match param_data.provenance { | ||
| 398 | hir_def::generics::TypeParamProvenance::ArgumentImplTrait => { | ||
| 399 | let substs = TyBuilder::type_params_subst(db, id.parent); | ||
| 400 | let predicates = db | ||
| 401 | .generic_predicates(id.parent) | ||
| 402 | .into_iter() | ||
| 403 | .map(|pred| pred.clone().substitute(&Interner, &substs)) | ||
| 404 | .filter(|wc| match &wc.skip_binders() { | ||
| 405 | WhereClause::Implemented(tr) => { | ||
| 406 | tr.self_type_parameter(&Interner) == self | ||
| 407 | } | ||
| 408 | WhereClause::AliasEq(AliasEq { | ||
| 409 | alias: AliasTy::Projection(proj), | ||
| 410 | ty: _, | ||
| 411 | }) => proj.self_type_parameter(&Interner) == self, | ||
| 412 | _ => false, | ||
| 413 | }) | ||
| 414 | .collect_vec(); | ||
| 415 | |||
| 416 | Some(predicates) | ||
| 417 | } | ||
| 418 | _ => None, | ||
| 419 | } | ||
| 420 | } | ||
| 421 | _ => None, | ||
| 422 | } | ||
| 423 | } | ||
| 424 | |||
| 425 | pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> { | ||
| 426 | match self.kind(&Interner) { | ||
| 427 | TyKind::AssociatedType(id, ..) => { | ||
| 428 | match from_assoc_type_id(*id).lookup(db.upcast()).container { | ||
| 429 | AssocContainerId::TraitId(trait_id) => Some(trait_id), | ||
| 430 | _ => None, | ||
| 431 | } | ||
| 432 | } | ||
| 433 | TyKind::Alias(AliasTy::Projection(projection_ty)) => { | ||
| 434 | match from_assoc_type_id(projection_ty.associated_ty_id) | ||
| 435 | .lookup(db.upcast()) | ||
| 436 | .container | ||
| 437 | { | ||
| 438 | AssocContainerId::TraitId(trait_id) => Some(trait_id), | ||
| 439 | _ => None, | ||
| 440 | } | ||
| 441 | } | ||
| 442 | _ => None, | ||
| 443 | } | ||
| 444 | } | ||
| 445 | } | 237 | } |
| 446 | 238 | ||
| 447 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] | 239 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] |
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index 5042bfbca..ee725fd46 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs | |||
| @@ -22,7 +22,7 @@ use crate::{ | |||
| 22 | static_lifetime, | 22 | static_lifetime, |
| 23 | utils::all_super_traits, | 23 | utils::all_super_traits, |
| 24 | AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSig, ForeignDefId, | 24 | AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSig, ForeignDefId, |
| 25 | InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, Ty, TyBuilder, TyKind, | 25 | InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, Ty, TyBuilder, TyExt, TyKind, |
| 26 | TypeWalk, | 26 | TypeWalk, |
| 27 | }; | 27 | }; |
| 28 | 28 | ||
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs index 5a8b5cd86..f03b92422 100644 --- a/crates/hir_ty/src/traits/chalk.rs +++ b/crates/hir_ty/src/traits/chalk.rs | |||
| @@ -22,7 +22,7 @@ use crate::{ | |||
| 22 | to_assoc_type_id, to_chalk_trait_id, | 22 | to_assoc_type_id, to_chalk_trait_id, |
| 23 | utils::generics, | 23 | utils::generics, |
| 24 | AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId, ProjectionTy, Substitution, | 24 | AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId, ProjectionTy, Substitution, |
| 25 | TraitRef, Ty, TyBuilder, TyKind, WhereClause, | 25 | TraitRef, Ty, TyBuilder, TyExt, TyKind, WhereClause, |
| 26 | }; | 26 | }; |
| 27 | use mapping::{ | 27 | use mapping::{ |
| 28 | convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue, | 28 | convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue, |
