diff options
Diffstat (limited to 'crates/hir/src')
-rw-r--r-- | crates/hir/src/db.rs | 10 | ||||
-rw-r--r-- | crates/hir/src/display.rs | 27 | ||||
-rw-r--r-- | crates/hir/src/lib.rs | 192 | ||||
-rw-r--r-- | crates/hir/src/semantics.rs | 14 | ||||
-rw-r--r-- | crates/hir/src/semantics/source_to_def.rs | 5 | ||||
-rw-r--r-- | crates/hir/src/source_analyzer.rs | 63 |
6 files changed, 180 insertions, 131 deletions
diff --git a/crates/hir/src/db.rs b/crates/hir/src/db.rs index 1902a8d16..df5758342 100644 --- a/crates/hir/src/db.rs +++ b/crates/hir/src/db.rs | |||
@@ -1,14 +1,6 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | pub use hir_def::db::{ | 3 | pub use hir_def::db::*; |
4 | AttrsQuery, BlockDefMapQuery, BodyQuery, BodyWithSourceMapQuery, ConstDataQuery, | ||
5 | CrateDefMapQueryQuery, CrateLangItemsQuery, DefDatabase, DefDatabaseStorage, EnumDataQuery, | ||
6 | ExprScopesQuery, FileItemTreeQuery, FunctionDataQuery, GenericParamsQuery, ImplDataQuery, | ||
7 | ImportMapQuery, InternConstQuery, InternDatabase, InternDatabaseStorage, InternEnumQuery, | ||
8 | InternFunctionQuery, InternImplQuery, InternStaticQuery, InternStructQuery, InternTraitQuery, | ||
9 | InternTypeAliasQuery, InternUnionQuery, LangItemQuery, StaticDataQuery, StructDataQuery, | ||
10 | TraitDataQuery, TypeAliasDataQuery, UnionDataQuery, | ||
11 | }; | ||
12 | pub use hir_expand::db::{ | 4 | pub use hir_expand::db::{ |
13 | AstDatabase, AstDatabaseStorage, AstIdMapQuery, HygieneFrameQuery, InternEagerExpansionQuery, | 5 | AstDatabase, AstDatabaseStorage, AstIdMapQuery, HygieneFrameQuery, InternEagerExpansionQuery, |
14 | InternMacroQuery, MacroArgTextQuery, MacroDefQuery, MacroExpandQuery, ParseMacroExpansionQuery, | 6 | InternMacroQuery, MacroArgTextQuery, MacroDefQuery, MacroExpandQuery, ParseMacroExpansionQuery, |
diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs index 97a78ca25..01a4d205f 100644 --- a/crates/hir/src/display.rs +++ b/crates/hir/src/display.rs | |||
@@ -9,33 +9,33 @@ use hir_ty::display::{ | |||
9 | write_bounds_like_dyn_trait_with_prefix, write_visibility, HirDisplay, HirDisplayError, | 9 | write_bounds_like_dyn_trait_with_prefix, write_visibility, HirDisplay, HirDisplayError, |
10 | HirFormatter, | 10 | HirFormatter, |
11 | }; | 11 | }; |
12 | use hir_ty::Interner; | ||
12 | use syntax::ast::{self, NameOwner}; | 13 | use syntax::ast::{self, NameOwner}; |
13 | 14 | ||
14 | use crate::{ | 15 | use crate::{ |
15 | Adt, Const, ConstParam, Enum, Field, Function, GenericParam, HasVisibility, LifetimeParam, | 16 | Adt, Const, ConstParam, Enum, Field, Function, GenericParam, HasVisibility, LifetimeParam, |
16 | Module, Static, Struct, Substitution, Trait, Type, TypeAlias, TypeParam, Union, Variant, | 17 | Module, Static, Struct, Trait, TyBuilder, Type, TypeAlias, TypeParam, Union, Variant, |
17 | }; | 18 | }; |
18 | 19 | ||
19 | impl HirDisplay for Function { | 20 | impl HirDisplay for Function { |
20 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | 21 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { |
21 | let data = f.db.function_data(self.id); | 22 | let data = f.db.function_data(self.id); |
22 | write_visibility(self.module(f.db).id, self.visibility(f.db), f)?; | 23 | write_visibility(self.module(f.db).id, self.visibility(f.db), f)?; |
23 | let qual = &data.qualifier; | 24 | if data.is_default() { |
24 | if qual.is_default { | ||
25 | write!(f, "default ")?; | 25 | write!(f, "default ")?; |
26 | } | 26 | } |
27 | if qual.is_const { | 27 | if data.is_const() { |
28 | write!(f, "const ")?; | 28 | write!(f, "const ")?; |
29 | } | 29 | } |
30 | if qual.is_async { | 30 | if data.is_async() { |
31 | write!(f, "async ")?; | 31 | write!(f, "async ")?; |
32 | } | 32 | } |
33 | if qual.is_unsafe { | 33 | if data.is_unsafe() { |
34 | write!(f, "unsafe ")?; | 34 | write!(f, "unsafe ")?; |
35 | } | 35 | } |
36 | if let Some(abi) = &qual.abi { | 36 | if let Some(abi) = &data.abi { |
37 | // FIXME: String escape? | 37 | // FIXME: String escape? |
38 | write!(f, "extern \"{}\" ", abi)?; | 38 | write!(f, "extern \"{}\" ", &**abi)?; |
39 | } | 39 | } |
40 | write!(f, "fn {}", data.name)?; | 40 | write!(f, "fn {}", data.name)?; |
41 | 41 | ||
@@ -68,7 +68,7 @@ impl HirDisplay for Function { | |||
68 | write!(f, ", ")?; | 68 | write!(f, ", ")?; |
69 | } else { | 69 | } else { |
70 | first = false; | 70 | first = false; |
71 | if data.has_self_param { | 71 | if data.has_self_param() { |
72 | write_self_param(type_ref, f)?; | 72 | write_self_param(type_ref, f)?; |
73 | continue; | 73 | continue; |
74 | } | 74 | } |
@@ -88,10 +88,10 @@ impl HirDisplay for Function { | |||
88 | // `FunctionData::ret_type` will be `::core::future::Future<Output = ...>` for async fns. | 88 | // `FunctionData::ret_type` will be `::core::future::Future<Output = ...>` for async fns. |
89 | // Use ugly pattern match to strip the Future trait. | 89 | // Use ugly pattern match to strip the Future trait. |
90 | // Better way? | 90 | // Better way? |
91 | let ret_type = if !qual.is_async { | 91 | let ret_type = if !data.is_async() { |
92 | &data.ret_type | 92 | &data.ret_type |
93 | } else { | 93 | } else { |
94 | match &data.ret_type { | 94 | match &*data.ret_type { |
95 | TypeRef::ImplTrait(bounds) => match &bounds[0] { | 95 | TypeRef::ImplTrait(bounds) => match &bounds[0] { |
96 | TypeBound::Path(path) => { | 96 | TypeBound::Path(path) => { |
97 | path.segments().iter().last().unwrap().args_and_bindings.unwrap().bindings | 97 | path.segments().iter().last().unwrap().args_and_bindings.unwrap().bindings |
@@ -235,8 +235,9 @@ impl HirDisplay for TypeParam { | |||
235 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | 235 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { |
236 | write!(f, "{}", self.name(f.db))?; | 236 | write!(f, "{}", self.name(f.db))?; |
237 | let bounds = f.db.generic_predicates_for_param(self.id); | 237 | let bounds = f.db.generic_predicates_for_param(self.id); |
238 | let substs = Substitution::type_params(f.db, self.id.parent); | 238 | let substs = TyBuilder::type_params_subst(f.db, self.id.parent); |
239 | let predicates = bounds.iter().cloned().map(|b| b.subst(&substs)).collect::<Vec<_>>(); | 239 | let predicates = |
240 | bounds.iter().cloned().map(|b| b.substitute(&Interner, &substs)).collect::<Vec<_>>(); | ||
240 | if !(predicates.is_empty() || f.omit_verbose_types()) { | 241 | if !(predicates.is_empty() || f.omit_verbose_types()) { |
241 | write_bounds_like_dyn_trait_with_prefix(":", &predicates, f)?; | 242 | write_bounds_like_dyn_trait_with_prefix(":", &predicates, f)?; |
242 | } | 243 | } |
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 05a60e158..0afc06906 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -44,6 +44,7 @@ use hir_def::{ | |||
44 | per_ns::PerNs, | 44 | per_ns::PerNs, |
45 | resolver::{HasResolver, Resolver}, | 45 | resolver::{HasResolver, Resolver}, |
46 | src::HasSource as _, | 46 | src::HasSource as _, |
47 | type_ref::TraitRef, | ||
47 | AdtId, AssocContainerId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, | 48 | AdtId, AssocContainerId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, |
48 | DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, ImplId, LifetimeParamId, | 49 | DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, ImplId, LifetimeParamId, |
49 | LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, | 50 | LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, |
@@ -51,14 +52,15 @@ use hir_def::{ | |||
51 | }; | 52 | }; |
52 | use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind}; | 53 | use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind}; |
53 | use hir_ty::{ | 54 | use hir_ty::{ |
54 | autoderef, | 55 | autoderef, could_unify, |
55 | method_resolution::{self, TyFingerprint}, | 56 | method_resolution::{self, def_crates, TyFingerprint}, |
56 | primitive::UintTy, | 57 | primitive::UintTy, |
57 | to_assoc_type_id, | 58 | subst_prefix, |
58 | traits::{FnTrait, Solution, SolutionVariables}, | 59 | traits::FnTrait, |
59 | AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast, | 60 | AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast, |
60 | DebruijnIndex, InEnvironment, Interner, ProjectionTy, QuantifiedWhereClause, Scalar, | 61 | DebruijnIndex, InEnvironment, Interner, QuantifiedWhereClause, Scalar, Solution, Substitution, |
61 | Substitution, TraitEnvironment, Ty, TyDefId, TyKind, TyVariableKind, WhereClause, | 62 | TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyDefId, TyExt, TyKind, TyVariableKind, |
63 | WhereClause, | ||
62 | }; | 64 | }; |
63 | use itertools::Itertools; | 65 | use itertools::Itertools; |
64 | use rustc_hash::FxHashSet; | 66 | use rustc_hash::FxHashSet; |
@@ -514,8 +516,8 @@ impl Field { | |||
514 | VariantDef::Union(it) => it.id.into(), | 516 | VariantDef::Union(it) => it.id.into(), |
515 | VariantDef::Variant(it) => it.parent.id.into(), | 517 | VariantDef::Variant(it) => it.parent.id.into(), |
516 | }; | 518 | }; |
517 | let substs = Substitution::type_params(db, generic_def_id); | 519 | let substs = TyBuilder::type_params_subst(db, generic_def_id); |
518 | let ty = db.field_types(var_id)[self.id].clone().subst(&substs); | 520 | let ty = db.field_types(var_id)[self.id].clone().substitute(&Interner, &substs); |
519 | Type::new(db, self.parent.module(db).id.krate(), var_id, ty) | 521 | Type::new(db, self.parent.module(db).id.krate(), var_id, ty) |
520 | } | 522 | } |
521 | 523 | ||
@@ -701,7 +703,7 @@ impl_from!(Struct, Union, Enum for Adt); | |||
701 | impl Adt { | 703 | impl Adt { |
702 | pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { | 704 | pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { |
703 | let subst = db.generic_defaults(self.into()); | 705 | let subst = db.generic_defaults(self.into()); |
704 | subst.iter().any(|ty| ty.value.is_unknown()) | 706 | subst.iter().any(|ty| ty.skip_binders().is_unknown()) |
705 | } | 707 | } |
706 | 708 | ||
707 | /// Turns this ADT into a type. Any type parameters of the ADT will be | 709 | /// Turns this ADT into a type. Any type parameters of the ADT will be |
@@ -831,7 +833,7 @@ impl Function { | |||
831 | } | 833 | } |
832 | 834 | ||
833 | pub fn self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> { | 835 | pub fn self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> { |
834 | if !db.function_data(self.id).has_self_param { | 836 | if !db.function_data(self.id).has_self_param() { |
835 | return None; | 837 | return None; |
836 | } | 838 | } |
837 | Some(SelfParam { func: self.id }) | 839 | Some(SelfParam { func: self.id }) |
@@ -863,7 +865,7 @@ impl Function { | |||
863 | } | 865 | } |
864 | 866 | ||
865 | pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool { | 867 | pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool { |
866 | db.function_data(self.id).qualifier.is_unsafe | 868 | db.function_data(self.id).is_unsafe() |
867 | } | 869 | } |
868 | 870 | ||
869 | pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { | 871 | pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { |
@@ -877,7 +879,7 @@ impl Function { | |||
877 | /// | 879 | /// |
878 | /// This is false in the case of required (not provided) trait methods. | 880 | /// This is false in the case of required (not provided) trait methods. |
879 | pub fn has_body(self, db: &dyn HirDatabase) -> bool { | 881 | pub fn has_body(self, db: &dyn HirDatabase) -> bool { |
880 | db.function_data(self.id).has_body | 882 | db.function_data(self.id).has_body() |
881 | } | 883 | } |
882 | 884 | ||
883 | /// A textual representation of the HIR of this function for debugging purposes. | 885 | /// A textual representation of the HIR of this function for debugging purposes. |
@@ -956,7 +958,7 @@ impl SelfParam { | |||
956 | func_data | 958 | func_data |
957 | .params | 959 | .params |
958 | .first() | 960 | .first() |
959 | .map(|param| match *param { | 961 | .map(|param| match &**param { |
960 | TypeRef::Reference(.., mutability) => match mutability { | 962 | TypeRef::Reference(.., mutability) => match mutability { |
961 | hir_def::type_ref::Mutability::Shared => Access::Shared, | 963 | hir_def::type_ref::Mutability::Shared => Access::Shared, |
962 | hir_def::type_ref::Mutability::Mut => Access::Exclusive, | 964 | hir_def::type_ref::Mutability::Mut => Access::Exclusive, |
@@ -1010,7 +1012,7 @@ impl Const { | |||
1010 | } | 1012 | } |
1011 | 1013 | ||
1012 | pub fn type_ref(self, db: &dyn HirDatabase) -> TypeRef { | 1014 | pub fn type_ref(self, db: &dyn HirDatabase) -> TypeRef { |
1013 | db.const_data(self.id).type_ref.clone() | 1015 | db.const_data(self.id).type_ref.as_ref().clone() |
1014 | } | 1016 | } |
1015 | } | 1017 | } |
1016 | 1018 | ||
@@ -1088,7 +1090,7 @@ pub struct TypeAlias { | |||
1088 | impl TypeAlias { | 1090 | impl TypeAlias { |
1089 | pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { | 1091 | pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { |
1090 | let subst = db.generic_defaults(self.id.into()); | 1092 | let subst = db.generic_defaults(self.id.into()); |
1091 | subst.iter().any(|ty| ty.value.is_unknown()) | 1093 | subst.iter().any(|ty| ty.skip_binders().is_unknown()) |
1092 | } | 1094 | } |
1093 | 1095 | ||
1094 | pub fn module(self, db: &dyn HirDatabase) -> Module { | 1096 | pub fn module(self, db: &dyn HirDatabase) -> Module { |
@@ -1100,7 +1102,7 @@ impl TypeAlias { | |||
1100 | } | 1102 | } |
1101 | 1103 | ||
1102 | pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> { | 1104 | pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> { |
1103 | db.type_alias_data(self.id).type_ref.clone() | 1105 | db.type_alias_data(self.id).type_ref.as_deref().cloned() |
1104 | } | 1106 | } |
1105 | 1107 | ||
1106 | pub fn ty(self, db: &dyn HirDatabase) -> Type { | 1108 | pub fn ty(self, db: &dyn HirDatabase) -> Type { |
@@ -1128,7 +1130,7 @@ pub struct BuiltinType { | |||
1128 | impl BuiltinType { | 1130 | impl BuiltinType { |
1129 | pub fn ty(self, db: &dyn HirDatabase, module: Module) -> Type { | 1131 | pub fn ty(self, db: &dyn HirDatabase, module: Module) -> Type { |
1130 | let resolver = module.id.resolver(db.upcast()); | 1132 | let resolver = module.id.resolver(db.upcast()); |
1131 | Type::new_with_resolver(db, &resolver, Ty::builtin(self.inner)) | 1133 | Type::new_with_resolver(db, &resolver, TyBuilder::builtin(self.inner)) |
1132 | .expect("crate not present in resolver") | 1134 | .expect("crate not present in resolver") |
1133 | } | 1135 | } |
1134 | 1136 | ||
@@ -1501,8 +1503,8 @@ impl TypeParam { | |||
1501 | let resolver = self.id.parent.resolver(db.upcast()); | 1503 | let resolver = self.id.parent.resolver(db.upcast()); |
1502 | let krate = self.id.parent.module(db.upcast()).krate(); | 1504 | let krate = self.id.parent.module(db.upcast()).krate(); |
1503 | let ty = params.get(local_idx)?.clone(); | 1505 | let ty = params.get(local_idx)?.clone(); |
1504 | let subst = Substitution::type_params(db, self.id.parent); | 1506 | let subst = TyBuilder::type_params_subst(db, self.id.parent); |
1505 | let ty = ty.subst(&subst.prefix(local_idx)); | 1507 | let ty = ty.substitute(&Interner, &subst_prefix(&subst, local_idx)); |
1506 | Some(Type::new_with_resolver_inner(db, krate, &resolver, ty)) | 1508 | Some(Type::new_with_resolver_inner(db, krate, &resolver, ty)) |
1507 | } | 1509 | } |
1508 | } | 1510 | } |
@@ -1567,15 +1569,15 @@ impl Impl { | |||
1567 | } | 1569 | } |
1568 | 1570 | ||
1569 | pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty, .. }: Type) -> Vec<Impl> { | 1571 | pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty, .. }: Type) -> Vec<Impl> { |
1570 | let def_crates = match ty.def_crates(db, krate) { | 1572 | let def_crates = match def_crates(db, &ty, krate) { |
1571 | Some(def_crates) => def_crates, | 1573 | Some(def_crates) => def_crates, |
1572 | None => return Vec::new(), | 1574 | None => return Vec::new(), |
1573 | }; | 1575 | }; |
1574 | 1576 | ||
1575 | let filter = |impl_def: &Impl| { | 1577 | let filter = |impl_def: &Impl| { |
1576 | let target_ty = impl_def.target_ty(db); | 1578 | let self_ty = impl_def.self_ty(db); |
1577 | let rref = target_ty.remove_ref(); | 1579 | let rref = self_ty.remove_ref(); |
1578 | ty.equals_ctor(rref.as_ref().map_or(&target_ty.ty, |it| &it.ty)) | 1580 | ty.equals_ctor(rref.as_ref().map_or(&self_ty.ty, |it| &it.ty)) |
1579 | }; | 1581 | }; |
1580 | 1582 | ||
1581 | let mut all = Vec::new(); | 1583 | let mut all = Vec::new(); |
@@ -1613,16 +1615,16 @@ impl Impl { | |||
1613 | 1615 | ||
1614 | // FIXME: the return type is wrong. This should be a hir version of | 1616 | // FIXME: the return type is wrong. This should be a hir version of |
1615 | // `TraitRef` (ie, resolved `TypeRef`). | 1617 | // `TraitRef` (ie, resolved `TypeRef`). |
1616 | pub fn target_trait(self, db: &dyn HirDatabase) -> Option<TypeRef> { | 1618 | pub fn trait_(self, db: &dyn HirDatabase) -> Option<TraitRef> { |
1617 | db.impl_data(self.id).target_trait.clone() | 1619 | db.impl_data(self.id).target_trait.as_deref().cloned() |
1618 | } | 1620 | } |
1619 | 1621 | ||
1620 | pub fn target_ty(self, db: &dyn HirDatabase) -> Type { | 1622 | pub fn self_ty(self, db: &dyn HirDatabase) -> Type { |
1621 | let impl_data = db.impl_data(self.id); | 1623 | let impl_data = db.impl_data(self.id); |
1622 | let resolver = self.id.resolver(db.upcast()); | 1624 | let resolver = self.id.resolver(db.upcast()); |
1623 | let krate = self.id.lookup(db.upcast()).container.krate(); | 1625 | let krate = self.id.lookup(db.upcast()).container.krate(); |
1624 | let ctx = hir_ty::TyLoweringContext::new(db, &resolver); | 1626 | let ctx = hir_ty::TyLoweringContext::new(db, &resolver); |
1625 | let ty = ctx.lower_ty(&impl_data.target_type); | 1627 | let ty = ctx.lower_ty(&impl_data.self_ty); |
1626 | Type::new_with_resolver_inner(db, krate, &resolver, ty) | 1628 | Type::new_with_resolver_inner(db, krate, &resolver, ty) |
1627 | } | 1629 | } |
1628 | 1630 | ||
@@ -1702,30 +1704,29 @@ impl Type { | |||
1702 | fn from_def( | 1704 | fn from_def( |
1703 | db: &dyn HirDatabase, | 1705 | db: &dyn HirDatabase, |
1704 | krate: CrateId, | 1706 | krate: CrateId, |
1705 | def: impl HasResolver + Into<TyDefId> + Into<GenericDefId>, | 1707 | def: impl HasResolver + Into<TyDefId>, |
1706 | ) -> Type { | 1708 | ) -> Type { |
1707 | let substs = Substitution::build_for_def(db, def).fill_with_unknown().build(); | 1709 | let ty = TyBuilder::def_ty(db, def.into()).fill_with_unknown().build(); |
1708 | let ty = db.ty(def.into()).subst(&substs); | ||
1709 | Type::new(db, krate, def, ty) | 1710 | Type::new(db, krate, def, ty) |
1710 | } | 1711 | } |
1711 | 1712 | ||
1712 | pub fn is_unit(&self) -> bool { | 1713 | pub fn is_unit(&self) -> bool { |
1713 | matches!(self.ty.interned(&Interner), TyKind::Tuple(0, ..)) | 1714 | matches!(self.ty.kind(&Interner), TyKind::Tuple(0, ..)) |
1714 | } | 1715 | } |
1715 | pub fn is_bool(&self) -> bool { | 1716 | pub fn is_bool(&self) -> bool { |
1716 | matches!(self.ty.interned(&Interner), TyKind::Scalar(Scalar::Bool)) | 1717 | matches!(self.ty.kind(&Interner), TyKind::Scalar(Scalar::Bool)) |
1717 | } | 1718 | } |
1718 | 1719 | ||
1719 | pub fn is_mutable_reference(&self) -> bool { | 1720 | pub fn is_mutable_reference(&self) -> bool { |
1720 | matches!(self.ty.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..)) | 1721 | matches!(self.ty.kind(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..)) |
1721 | } | 1722 | } |
1722 | 1723 | ||
1723 | pub fn is_usize(&self) -> bool { | 1724 | pub fn is_usize(&self) -> bool { |
1724 | matches!(self.ty.interned(&Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize))) | 1725 | matches!(self.ty.kind(&Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize))) |
1725 | } | 1726 | } |
1726 | 1727 | ||
1727 | pub fn remove_ref(&self) -> Option<Type> { | 1728 | pub fn remove_ref(&self) -> Option<Type> { |
1728 | match &self.ty.interned(&Interner) { | 1729 | match &self.ty.kind(&Interner) { |
1729 | TyKind::Ref(.., ty) => Some(self.derived(ty.clone())), | 1730 | TyKind::Ref(.., ty) => Some(self.derived(ty.clone())), |
1730 | _ => None, | 1731 | _ => None, |
1731 | } | 1732 | } |
@@ -1784,16 +1785,13 @@ impl Type { | |||
1784 | } | 1785 | } |
1785 | 1786 | ||
1786 | pub fn impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool { | 1787 | pub fn impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool { |
1787 | let trait_ref = hir_ty::TraitRef { | 1788 | let trait_ref = TyBuilder::trait_ref(db, trait_.id) |
1788 | trait_id: hir_ty::to_chalk_trait_id(trait_.id), | 1789 | .push(self.ty.clone()) |
1789 | substitution: Substitution::build_for_def(db, trait_.id) | 1790 | .fill(args.iter().map(|t| t.ty.clone())) |
1790 | .push(self.ty.clone()) | 1791 | .build(); |
1791 | .fill(args.iter().map(|t| t.ty.clone())) | ||
1792 | .build(), | ||
1793 | }; | ||
1794 | 1792 | ||
1795 | let goal = Canonical { | 1793 | let goal = Canonical { |
1796 | value: hir_ty::InEnvironment::new(self.env.env.clone(), trait_ref.cast(&Interner)), | 1794 | value: hir_ty::InEnvironment::new(&self.env.env, trait_ref.cast(&Interner)), |
1797 | binders: CanonicalVarKinds::empty(&Interner), | 1795 | binders: CanonicalVarKinds::empty(&Interner), |
1798 | }; | 1796 | }; |
1799 | 1797 | ||
@@ -1803,22 +1801,18 @@ impl Type { | |||
1803 | pub fn normalize_trait_assoc_type( | 1801 | pub fn normalize_trait_assoc_type( |
1804 | &self, | 1802 | &self, |
1805 | db: &dyn HirDatabase, | 1803 | db: &dyn HirDatabase, |
1806 | trait_: Trait, | ||
1807 | args: &[Type], | 1804 | args: &[Type], |
1808 | alias: TypeAlias, | 1805 | alias: TypeAlias, |
1809 | ) -> Option<Type> { | 1806 | ) -> Option<Type> { |
1810 | let subst = Substitution::build_for_def(db, trait_.id) | 1807 | let projection = TyBuilder::assoc_type_projection(db, alias.id) |
1811 | .push(self.ty.clone()) | 1808 | .push(self.ty.clone()) |
1812 | .fill(args.iter().map(|t| t.ty.clone())) | 1809 | .fill(args.iter().map(|t| t.ty.clone())) |
1813 | .build(); | 1810 | .build(); |
1814 | let goal = Canonical::new( | 1811 | let goal = hir_ty::make_canonical( |
1815 | InEnvironment::new( | 1812 | InEnvironment::new( |
1816 | self.env.env.clone(), | 1813 | &self.env.env, |
1817 | AliasEq { | 1814 | AliasEq { |
1818 | alias: AliasTy::Projection(ProjectionTy { | 1815 | alias: AliasTy::Projection(projection), |
1819 | associated_ty_id: to_assoc_type_id(alias.id), | ||
1820 | substitution: subst, | ||
1821 | }), | ||
1822 | ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)) | 1816 | ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)) |
1823 | .intern(&Interner), | 1817 | .intern(&Interner), |
1824 | } | 1818 | } |
@@ -1828,9 +1822,12 @@ impl Type { | |||
1828 | ); | 1822 | ); |
1829 | 1823 | ||
1830 | match db.trait_solve(self.krate, goal)? { | 1824 | match db.trait_solve(self.krate, goal)? { |
1831 | Solution::Unique(SolutionVariables(subst)) => { | 1825 | Solution::Unique(s) => s |
1832 | subst.value.first().map(|ty| self.derived(ty.clone())) | 1826 | .value |
1833 | } | 1827 | .subst |
1828 | .interned() | ||
1829 | .first() | ||
1830 | .map(|ty| self.derived(ty.assert_ty_ref(&Interner).clone())), | ||
1834 | Solution::Ambig(_) => None, | 1831 | Solution::Ambig(_) => None, |
1835 | } | 1832 | } |
1836 | } | 1833 | } |
@@ -1852,15 +1849,15 @@ impl Type { | |||
1852 | } | 1849 | } |
1853 | 1850 | ||
1854 | pub fn is_closure(&self) -> bool { | 1851 | pub fn is_closure(&self) -> bool { |
1855 | matches!(&self.ty.interned(&Interner), TyKind::Closure { .. }) | 1852 | matches!(&self.ty.kind(&Interner), TyKind::Closure { .. }) |
1856 | } | 1853 | } |
1857 | 1854 | ||
1858 | pub fn is_fn(&self) -> bool { | 1855 | pub fn is_fn(&self) -> bool { |
1859 | matches!(&self.ty.interned(&Interner), TyKind::FnDef(..) | TyKind::Function { .. }) | 1856 | matches!(&self.ty.kind(&Interner), TyKind::FnDef(..) | TyKind::Function { .. }) |
1860 | } | 1857 | } |
1861 | 1858 | ||
1862 | pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { | 1859 | pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { |
1863 | let adt_id = match self.ty.interned(&Interner) { | 1860 | let adt_id = match self.ty.kind(&Interner) { |
1864 | &TyKind::Adt(hir_ty::AdtId(adt_id), ..) => adt_id, | 1861 | &TyKind::Adt(hir_ty::AdtId(adt_id), ..) => adt_id, |
1865 | _ => return false, | 1862 | _ => return false, |
1866 | }; | 1863 | }; |
@@ -1873,27 +1870,30 @@ impl Type { | |||
1873 | } | 1870 | } |
1874 | 1871 | ||
1875 | pub fn is_raw_ptr(&self) -> bool { | 1872 | pub fn is_raw_ptr(&self) -> bool { |
1876 | matches!(&self.ty.interned(&Interner), TyKind::Raw(..)) | 1873 | matches!(&self.ty.kind(&Interner), TyKind::Raw(..)) |
1877 | } | 1874 | } |
1878 | 1875 | ||
1879 | pub fn contains_unknown(&self) -> bool { | 1876 | pub fn contains_unknown(&self) -> bool { |
1880 | return go(&self.ty); | 1877 | return go(&self.ty); |
1881 | 1878 | ||
1882 | fn go(ty: &Ty) -> bool { | 1879 | fn go(ty: &Ty) -> bool { |
1883 | match ty.interned(&Interner) { | 1880 | match ty.kind(&Interner) { |
1884 | TyKind::Unknown => true, | 1881 | TyKind::Error => true, |
1885 | 1882 | ||
1886 | TyKind::Adt(_, substs) | 1883 | TyKind::Adt(_, substs) |
1887 | | TyKind::AssociatedType(_, substs) | 1884 | | TyKind::AssociatedType(_, substs) |
1888 | | TyKind::Tuple(_, substs) | 1885 | | TyKind::Tuple(_, substs) |
1889 | | TyKind::OpaqueType(_, substs) | 1886 | | TyKind::OpaqueType(_, substs) |
1890 | | TyKind::FnDef(_, substs) | 1887 | | TyKind::FnDef(_, substs) |
1891 | | TyKind::Closure(_, substs) => substs.iter().any(go), | 1888 | | TyKind::Closure(_, substs) => { |
1892 | 1889 | substs.iter(&Interner).filter_map(|a| a.ty(&Interner)).any(go) | |
1893 | TyKind::Array(ty) | TyKind::Slice(ty) | TyKind::Raw(_, ty) | TyKind::Ref(_, ty) => { | ||
1894 | go(ty) | ||
1895 | } | 1890 | } |
1896 | 1891 | ||
1892 | TyKind::Array(ty, _) | ||
1893 | | TyKind::Slice(ty) | ||
1894 | | TyKind::Raw(_, ty) | ||
1895 | | TyKind::Ref(_, _, ty) => go(ty), | ||
1896 | |||
1897 | TyKind::Scalar(_) | 1897 | TyKind::Scalar(_) |
1898 | | TyKind::Str | 1898 | | TyKind::Str |
1899 | | TyKind::Never | 1899 | | TyKind::Never |
@@ -1903,13 +1903,13 @@ impl Type { | |||
1903 | | TyKind::Dyn(_) | 1903 | | TyKind::Dyn(_) |
1904 | | TyKind::Function(_) | 1904 | | TyKind::Function(_) |
1905 | | TyKind::Alias(_) | 1905 | | TyKind::Alias(_) |
1906 | | TyKind::ForeignType(_) => false, | 1906 | | TyKind::Foreign(_) => false, |
1907 | } | 1907 | } |
1908 | } | 1908 | } |
1909 | } | 1909 | } |
1910 | 1910 | ||
1911 | pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { | 1911 | pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { |
1912 | let (variant_id, substs) = match self.ty.interned(&Interner) { | 1912 | let (variant_id, substs) = match self.ty.kind(&Interner) { |
1913 | &TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs), | 1913 | &TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs), |
1914 | &TyKind::Adt(hir_ty::AdtId(AdtId::UnionId(u)), ref substs) => (u.into(), substs), | 1914 | &TyKind::Adt(hir_ty::AdtId(AdtId::UnionId(u)), ref substs) => (u.into(), substs), |
1915 | _ => return Vec::new(), | 1915 | _ => return Vec::new(), |
@@ -1919,15 +1919,18 @@ impl Type { | |||
1919 | .iter() | 1919 | .iter() |
1920 | .map(|(local_id, ty)| { | 1920 | .map(|(local_id, ty)| { |
1921 | let def = Field { parent: variant_id.into(), id: local_id }; | 1921 | let def = Field { parent: variant_id.into(), id: local_id }; |
1922 | let ty = ty.clone().subst(substs); | 1922 | let ty = ty.clone().substitute(&Interner, substs); |
1923 | (def, self.derived(ty)) | 1923 | (def, self.derived(ty)) |
1924 | }) | 1924 | }) |
1925 | .collect() | 1925 | .collect() |
1926 | } | 1926 | } |
1927 | 1927 | ||
1928 | pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { | 1928 | pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { |
1929 | if let TyKind::Tuple(_, substs) = &self.ty.interned(&Interner) { | 1929 | if let TyKind::Tuple(_, substs) = &self.ty.kind(&Interner) { |
1930 | substs.iter().map(|ty| self.derived(ty.clone())).collect() | 1930 | substs |
1931 | .iter(&Interner) | ||
1932 | .map(|ty| self.derived(ty.assert_ty_ref(&Interner).clone())) | ||
1933 | .collect() | ||
1931 | } else { | 1934 | } else { |
1932 | Vec::new() | 1935 | Vec::new() |
1933 | } | 1936 | } |
@@ -1953,7 +1956,7 @@ impl Type { | |||
1953 | krate: Crate, | 1956 | krate: Crate, |
1954 | mut callback: impl FnMut(AssocItem) -> Option<T>, | 1957 | mut callback: impl FnMut(AssocItem) -> Option<T>, |
1955 | ) -> Option<T> { | 1958 | ) -> Option<T> { |
1956 | for krate in self.ty.def_crates(db, krate.id)? { | 1959 | for krate in def_crates(db, &self.ty, krate.id)? { |
1957 | let impls = db.inherent_impls_in_crate(krate); | 1960 | let impls = db.inherent_impls_in_crate(krate); |
1958 | 1961 | ||
1959 | for impl_def in impls.for_self_ty(&self.ty) { | 1962 | for impl_def in impls.for_self_ty(&self.ty) { |
@@ -1970,10 +1973,11 @@ impl Type { | |||
1970 | pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ { | 1973 | pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ { |
1971 | self.ty | 1974 | self.ty |
1972 | .strip_references() | 1975 | .strip_references() |
1973 | .substs() | 1976 | .as_adt() |
1974 | .into_iter() | 1977 | .into_iter() |
1975 | .flat_map(|substs| substs.iter()) | 1978 | .flat_map(|(_, substs)| substs.iter(&Interner)) |
1976 | .map(move |ty| self.derived(ty.clone())) | 1979 | .filter_map(|arg| arg.ty(&Interner).cloned()) |
1980 | .map(move |ty| self.derived(ty)) | ||
1977 | } | 1981 | } |
1978 | 1982 | ||
1979 | pub fn iterate_method_candidates<T>( | 1983 | pub fn iterate_method_candidates<T>( |
@@ -2079,7 +2083,7 @@ impl Type { | |||
2079 | substs: &Substitution, | 2083 | substs: &Substitution, |
2080 | cb: &mut impl FnMut(Type), | 2084 | cb: &mut impl FnMut(Type), |
2081 | ) { | 2085 | ) { |
2082 | for ty in substs.iter() { | 2086 | for ty in substs.iter(&Interner).filter_map(|a| a.ty(&Interner)) { |
2083 | walk_type(db, &type_.derived(ty.clone()), cb); | 2087 | walk_type(db, &type_.derived(ty.clone()), cb); |
2084 | } | 2088 | } |
2085 | } | 2089 | } |
@@ -2095,7 +2099,12 @@ impl Type { | |||
2095 | WhereClause::Implemented(trait_ref) => { | 2099 | WhereClause::Implemented(trait_ref) => { |
2096 | cb(type_.clone()); | 2100 | cb(type_.clone()); |
2097 | // skip the self type. it's likely the type we just got the bounds from | 2101 | // skip the self type. it's likely the type we just got the bounds from |
2098 | for ty in trait_ref.substitution.iter().skip(1) { | 2102 | for ty in trait_ref |
2103 | .substitution | ||
2104 | .iter(&Interner) | ||
2105 | .skip(1) | ||
2106 | .filter_map(|a| a.ty(&Interner)) | ||
2107 | { | ||
2099 | walk_type(db, &type_.derived(ty.clone()), cb); | 2108 | walk_type(db, &type_.derived(ty.clone()), cb); |
2100 | } | 2109 | } |
2101 | } | 2110 | } |
@@ -2106,19 +2115,23 @@ impl Type { | |||
2106 | 2115 | ||
2107 | fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { | 2116 | fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { |
2108 | let ty = type_.ty.strip_references(); | 2117 | let ty = type_.ty.strip_references(); |
2109 | match ty.interned(&Interner) { | 2118 | match ty.kind(&Interner) { |
2110 | TyKind::Adt(..) => { | 2119 | TyKind::Adt(_, substs) => { |
2111 | cb(type_.derived(ty.clone())); | 2120 | cb(type_.derived(ty.clone())); |
2121 | walk_substs(db, type_, &substs, cb); | ||
2112 | } | 2122 | } |
2113 | TyKind::AssociatedType(..) => { | 2123 | TyKind::AssociatedType(_, substs) => { |
2114 | if let Some(_) = ty.associated_type_parent_trait(db) { | 2124 | if let Some(_) = ty.associated_type_parent_trait(db) { |
2115 | cb(type_.derived(ty.clone())); | 2125 | cb(type_.derived(ty.clone())); |
2116 | } | 2126 | } |
2127 | walk_substs(db, type_, &substs, cb); | ||
2117 | } | 2128 | } |
2118 | TyKind::OpaqueType(..) => { | 2129 | TyKind::OpaqueType(_, subst) => { |
2119 | if let Some(bounds) = ty.impl_trait_bounds(db) { | 2130 | if let Some(bounds) = ty.impl_trait_bounds(db) { |
2120 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); | 2131 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); |
2121 | } | 2132 | } |
2133 | |||
2134 | walk_substs(db, type_, subst, cb); | ||
2122 | } | 2135 | } |
2123 | TyKind::Alias(AliasTy::Opaque(opaque_ty)) => { | 2136 | TyKind::Alias(AliasTy::Opaque(opaque_ty)) => { |
2124 | if let Some(bounds) = ty.impl_trait_bounds(db) { | 2137 | if let Some(bounds) = ty.impl_trait_bounds(db) { |
@@ -2141,19 +2154,32 @@ impl Type { | |||
2141 | ); | 2154 | ); |
2142 | } | 2155 | } |
2143 | 2156 | ||
2144 | TyKind::Ref(_, ty) | TyKind::Raw(_, ty) | TyKind::Array(ty) | TyKind::Slice(ty) => { | 2157 | TyKind::Ref(_, _, ty) |
2158 | | TyKind::Raw(_, ty) | ||
2159 | | TyKind::Array(ty, _) | ||
2160 | | TyKind::Slice(ty) => { | ||
2145 | walk_type(db, &type_.derived(ty.clone()), cb); | 2161 | walk_type(db, &type_.derived(ty.clone()), cb); |
2146 | } | 2162 | } |
2147 | 2163 | ||
2164 | TyKind::FnDef(_, substs) | ||
2165 | | TyKind::Tuple(_, substs) | ||
2166 | | TyKind::Closure(.., substs) => { | ||
2167 | walk_substs(db, type_, &substs, cb); | ||
2168 | } | ||
2169 | TyKind::Function(hir_ty::FnPointer { substitution, .. }) => { | ||
2170 | walk_substs(db, type_, &substitution.0, cb); | ||
2171 | } | ||
2172 | |||
2148 | _ => {} | 2173 | _ => {} |
2149 | } | 2174 | } |
2150 | if let Some(substs) = ty.substs() { | ||
2151 | walk_substs(db, type_, &substs, cb); | ||
2152 | } | ||
2153 | } | 2175 | } |
2154 | 2176 | ||
2155 | walk_type(db, self, &mut cb); | 2177 | walk_type(db, self, &mut cb); |
2156 | } | 2178 | } |
2179 | |||
2180 | pub fn could_unify_with(&self, other: &Type) -> bool { | ||
2181 | could_unify(&self.ty, &other.ty) | ||
2182 | } | ||
2157 | } | 2183 | } |
2158 | 2184 | ||
2159 | // FIXME: closures | 2185 | // FIXME: closures |
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 1198e3f0b..7955bf0b5 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs | |||
@@ -76,9 +76,11 @@ impl PathResolution { | |||
76 | pub fn assoc_type_shorthand_candidates<R>( | 76 | pub fn assoc_type_shorthand_candidates<R>( |
77 | &self, | 77 | &self, |
78 | db: &dyn HirDatabase, | 78 | db: &dyn HirDatabase, |
79 | mut cb: impl FnMut(TypeAlias) -> Option<R>, | 79 | mut cb: impl FnMut(&Name, TypeAlias) -> Option<R>, |
80 | ) -> Option<R> { | 80 | ) -> Option<R> { |
81 | associated_type_shorthand_candidates(db, self.in_type_ns()?, |_, _, id| cb(id.into())) | 81 | associated_type_shorthand_candidates(db, self.in_type_ns()?, |name, _, id| { |
82 | cb(name, id.into()) | ||
83 | }) | ||
82 | } | 84 | } |
83 | } | 85 | } |
84 | 86 | ||
@@ -445,7 +447,7 @@ impl<'db> SemanticsImpl<'db> { | |||
445 | } | 447 | } |
446 | }; | 448 | }; |
447 | gpl.lifetime_params() | 449 | gpl.lifetime_params() |
448 | .find(|tp| tp.lifetime().as_ref().map(|lt| lt.text()) == Some(text)) | 450 | .find(|tp| tp.lifetime().as_ref().map(|lt| lt.text()).as_ref() == Some(&text)) |
449 | })?; | 451 | })?; |
450 | let src = self.find_file(lifetime_param.syntax().clone()).with_value(lifetime_param); | 452 | let src = self.find_file(lifetime_param.syntax().clone()).with_value(lifetime_param); |
451 | ToDef::to_def(self, src) | 453 | ToDef::to_def(self, src) |
@@ -492,9 +494,9 @@ impl<'db> SemanticsImpl<'db> { | |||
492 | fn resolve_method_call_as_callable(&self, call: &ast::MethodCallExpr) -> Option<Callable> { | 494 | fn resolve_method_call_as_callable(&self, call: &ast::MethodCallExpr) -> Option<Callable> { |
493 | // FIXME: this erases Substs | 495 | // FIXME: this erases Substs |
494 | let func = self.resolve_method_call(call)?; | 496 | let func = self.resolve_method_call(call)?; |
495 | let ty = self.db.value_ty(func.into()); | 497 | let (ty, _) = self.db.value_ty(func.into()).into_value_and_skipped_binders(); |
496 | let resolver = self.analyze(call.syntax()).resolver; | 498 | let resolver = self.analyze(call.syntax()).resolver; |
497 | let ty = Type::new_with_resolver(self.db, &resolver, ty.value)?; | 499 | let ty = Type::new_with_resolver(self.db, &resolver, ty)?; |
498 | let mut res = ty.as_callable(self.db)?; | 500 | let mut res = ty.as_callable(self.db)?; |
499 | res.is_bound_method = true; | 501 | res.is_bound_method = true; |
500 | Some(res) | 502 | Some(res) |
@@ -768,7 +770,7 @@ to_def_impls![ | |||
768 | (crate::TypeParam, ast::TypeParam, type_param_to_def), | 770 | (crate::TypeParam, ast::TypeParam, type_param_to_def), |
769 | (crate::LifetimeParam, ast::LifetimeParam, lifetime_param_to_def), | 771 | (crate::LifetimeParam, ast::LifetimeParam, lifetime_param_to_def), |
770 | (crate::ConstParam, ast::ConstParam, const_param_to_def), | 772 | (crate::ConstParam, ast::ConstParam, const_param_to_def), |
771 | (crate::MacroDef, ast::MacroRules, macro_rules_to_def), | 773 | (crate::MacroDef, ast::Macro, macro_to_def), |
772 | (crate::Local, ast::IdentPat, bind_pat_to_def), | 774 | (crate::Local, ast::IdentPat, bind_pat_to_def), |
773 | (crate::Local, ast::SelfParam, self_param_to_def), | 775 | (crate::Local, ast::SelfParam, self_param_to_def), |
774 | (crate::Label, ast::Label, label_to_def), | 776 | (crate::Label, ast::Label, label_to_def), |
diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs index 762809fcd..9a5a2255f 100644 --- a/crates/hir/src/semantics/source_to_def.rs +++ b/crates/hir/src/semantics/source_to_def.rs | |||
@@ -191,10 +191,7 @@ impl SourceToDefCtx<'_, '_> { | |||
191 | } | 191 | } |
192 | 192 | ||
193 | // FIXME: use DynMap as well? | 193 | // FIXME: use DynMap as well? |
194 | pub(super) fn macro_rules_to_def( | 194 | pub(super) fn macro_to_def(&mut self, src: InFile<ast::Macro>) -> Option<MacroDefId> { |
195 | &mut self, | ||
196 | src: InFile<ast::MacroRules>, | ||
197 | ) -> Option<MacroDefId> { | ||
198 | let file_ast_id = self.db.ast_id_map(src.file_id).ast_id(&src.value); | 195 | let file_ast_id = self.db.ast_id_map(src.file_id).ast_id(&src.value); |
199 | let ast_id = AstId::new(src.file_id, file_ast_id.upcast()); | 196 | let ast_id = AstId::new(src.file_id, file_ast_id.upcast()); |
200 | let kind = MacroDefKind::Declarative(ast_id); | 197 | let kind = MacroDefKind::Declarative(ast_id); |
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index 37d162b32..847d2537d 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs | |||
@@ -20,7 +20,7 @@ use hir_def::{ | |||
20 | use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile}; | 20 | use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile}; |
21 | use hir_ty::{ | 21 | use hir_ty::{ |
22 | diagnostics::{record_literal_missing_fields, record_pattern_missing_fields}, | 22 | diagnostics::{record_literal_missing_fields, record_pattern_missing_fields}, |
23 | InferenceResult, Substitution, | 23 | InferenceResult, Interner, Substitution, TyExt, TyLoweringContext, |
24 | }; | 24 | }; |
25 | use syntax::{ | 25 | use syntax::{ |
26 | ast::{self, AstNode}, | 26 | ast::{self, AstNode}, |
@@ -161,14 +161,15 @@ impl SourceAnalyzer { | |||
161 | db: &dyn HirDatabase, | 161 | db: &dyn HirDatabase, |
162 | field: &ast::RecordExprField, | 162 | field: &ast::RecordExprField, |
163 | ) -> Option<(Field, Option<Local>)> { | 163 | ) -> Option<(Field, Option<Local>)> { |
164 | let expr_id = | 164 | let record_expr = ast::RecordExpr::cast(field.syntax().parent().and_then(|p| p.parent())?)?; |
165 | self.body_source_map.as_ref()?.node_field(InFile::new(self.file_id, field))?; | 165 | let expr = ast::Expr::from(record_expr); |
166 | let expr_id = self.body_source_map.as_ref()?.node_expr(InFile::new(self.file_id, &expr))?; | ||
166 | 167 | ||
168 | let local_name = field.field_name()?.as_name(); | ||
167 | let local = if field.name_ref().is_some() { | 169 | let local = if field.name_ref().is_some() { |
168 | None | 170 | None |
169 | } else { | 171 | } else { |
170 | let local_name = field.field_name()?.as_name(); | 172 | let path = ModPath::from_segments(PathKind::Plain, once(local_name.clone())); |
171 | let path = ModPath::from_segments(PathKind::Plain, once(local_name)); | ||
172 | match self.resolver.resolve_path_in_value_ns_fully(db.upcast(), &path) { | 173 | match self.resolver.resolve_path_in_value_ns_fully(db.upcast(), &path) { |
173 | Some(ValueNs::LocalBinding(pat_id)) => { | 174 | Some(ValueNs::LocalBinding(pat_id)) => { |
174 | Some(Local { pat_id, parent: self.resolver.body_owner()? }) | 175 | Some(Local { pat_id, parent: self.resolver.body_owner()? }) |
@@ -176,18 +177,24 @@ impl SourceAnalyzer { | |||
176 | _ => None, | 177 | _ => None, |
177 | } | 178 | } |
178 | }; | 179 | }; |
179 | let struct_field = self.infer.as_ref()?.record_field_resolution(expr_id)?; | 180 | let variant = self.infer.as_ref()?.variant_resolution_for_expr(expr_id)?; |
180 | Some((struct_field.into(), local)) | 181 | let variant_data = variant.variant_data(db.upcast()); |
182 | let field = FieldId { parent: variant, local_id: variant_data.field(&local_name)? }; | ||
183 | Some((field.into(), local)) | ||
181 | } | 184 | } |
182 | 185 | ||
183 | pub(crate) fn resolve_record_pat_field( | 186 | pub(crate) fn resolve_record_pat_field( |
184 | &self, | 187 | &self, |
185 | _db: &dyn HirDatabase, | 188 | db: &dyn HirDatabase, |
186 | field: &ast::RecordPatField, | 189 | field: &ast::RecordPatField, |
187 | ) -> Option<Field> { | 190 | ) -> Option<Field> { |
188 | let pat_id = self.pat_id(&field.pat()?)?; | 191 | let field_name = field.field_name()?.as_name(); |
189 | let struct_field = self.infer.as_ref()?.record_pat_field_resolution(pat_id)?; | 192 | let record_pat = ast::RecordPat::cast(field.syntax().parent().and_then(|p| p.parent())?)?; |
190 | Some(struct_field.into()) | 193 | let pat_id = self.pat_id(&record_pat.into())?; |
194 | let variant = self.infer.as_ref()?.variant_resolution_for_pat(pat_id)?; | ||
195 | let variant_data = variant.variant_data(db.upcast()); | ||
196 | let field = FieldId { parent: variant, local_id: variant_data.field(&field_name)? }; | ||
197 | Some(field.into()) | ||
191 | } | 198 | } |
192 | 199 | ||
193 | pub(crate) fn resolve_macro_call( | 200 | pub(crate) fn resolve_macro_call( |
@@ -299,7 +306,7 @@ impl SourceAnalyzer { | |||
299 | let infer = self.infer.as_ref()?; | 306 | let infer = self.infer.as_ref()?; |
300 | 307 | ||
301 | let expr_id = self.expr_id(db, &literal.clone().into())?; | 308 | let expr_id = self.expr_id(db, &literal.clone().into())?; |
302 | let substs = infer.type_of_expr[expr_id].substs()?; | 309 | let substs = infer.type_of_expr[expr_id].as_adt()?.1; |
303 | 310 | ||
304 | let (variant, missing_fields, _exhaustive) = | 311 | let (variant, missing_fields, _exhaustive) = |
305 | record_literal_missing_fields(db, infer, expr_id, &body[expr_id])?; | 312 | record_literal_missing_fields(db, infer, expr_id, &body[expr_id])?; |
@@ -317,7 +324,7 @@ impl SourceAnalyzer { | |||
317 | let infer = self.infer.as_ref()?; | 324 | let infer = self.infer.as_ref()?; |
318 | 325 | ||
319 | let pat_id = self.pat_id(&pattern.clone().into())?; | 326 | let pat_id = self.pat_id(&pattern.clone().into())?; |
320 | let substs = infer.type_of_pat[pat_id].substs()?; | 327 | let substs = infer.type_of_pat[pat_id].as_adt()?.1; |
321 | 328 | ||
322 | let (variant, missing_fields, _exhaustive) = | 329 | let (variant, missing_fields, _exhaustive) = |
323 | record_pattern_missing_fields(db, infer, pat_id, &body[pat_id])?; | 330 | record_pattern_missing_fields(db, infer, pat_id, &body[pat_id])?; |
@@ -339,7 +346,7 @@ impl SourceAnalyzer { | |||
339 | .into_iter() | 346 | .into_iter() |
340 | .map(|local_id| { | 347 | .map(|local_id| { |
341 | let field = FieldId { parent: variant, local_id }; | 348 | let field = FieldId { parent: variant, local_id }; |
342 | let ty = field_types[local_id].clone().subst(substs); | 349 | let ty = field_types[local_id].clone().substitute(&Interner, substs); |
343 | (field.into(), Type::new_with_resolver_inner(db, krate, &self.resolver, ty)) | 350 | (field.into(), Type::new_with_resolver_inner(db, krate, &self.resolver, ty)) |
344 | }) | 351 | }) |
345 | .collect() | 352 | .collect() |
@@ -466,7 +473,21 @@ fn resolve_hir_path_( | |||
466 | prefer_value_ns: bool, | 473 | prefer_value_ns: bool, |
467 | ) -> Option<PathResolution> { | 474 | ) -> Option<PathResolution> { |
468 | let types = || { | 475 | let types = || { |
469 | resolver.resolve_path_in_type_ns_fully(db.upcast(), path.mod_path()).map(|ty| match ty { | 476 | let (ty, unresolved) = match path.type_anchor() { |
477 | Some(type_ref) => { | ||
478 | let (_, res) = TyLoweringContext::new(db, resolver).lower_ty_ext(type_ref); | ||
479 | res.map(|ty_ns| (ty_ns, path.segments().first())) | ||
480 | } | ||
481 | None => { | ||
482 | let (ty, remaining) = | ||
483 | resolver.resolve_path_in_type_ns(db.upcast(), path.mod_path())?; | ||
484 | match remaining { | ||
485 | Some(remaining) if remaining > 1 => None, | ||
486 | _ => Some((ty, path.segments().get(1))), | ||
487 | } | ||
488 | } | ||
489 | }?; | ||
490 | let res = match ty { | ||
470 | TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), | 491 | TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), |
471 | TypeNs::GenericParam(id) => PathResolution::TypeParam(TypeParam { id }), | 492 | TypeNs::GenericParam(id) => PathResolution::TypeParam(TypeParam { id }), |
472 | TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { | 493 | TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { |
@@ -476,7 +497,17 @@ fn resolve_hir_path_( | |||
476 | TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()), | 497 | TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()), |
477 | TypeNs::BuiltinType(it) => PathResolution::Def(BuiltinType::from(it).into()), | 498 | TypeNs::BuiltinType(it) => PathResolution::Def(BuiltinType::from(it).into()), |
478 | TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()), | 499 | TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()), |
479 | }) | 500 | }; |
501 | match unresolved { | ||
502 | Some(unresolved) => res | ||
503 | .assoc_type_shorthand_candidates(db, |name, alias| { | ||
504 | (name == unresolved.name).then(|| alias) | ||
505 | }) | ||
506 | .map(TypeAlias::from) | ||
507 | .map(Into::into) | ||
508 | .map(PathResolution::Def), | ||
509 | None => Some(res), | ||
510 | } | ||
480 | }; | 511 | }; |
481 | 512 | ||
482 | let body_owner = resolver.body_owner(); | 513 | let body_owner = resolver.body_owner(); |