diff options
Diffstat (limited to 'crates/hir')
-rw-r--r-- | crates/hir/src/db.rs | 10 | ||||
-rw-r--r-- | crates/hir/src/display.rs | 23 | ||||
-rw-r--r-- | crates/hir/src/lib.rs | 122 | ||||
-rw-r--r-- | crates/hir/src/semantics.rs | 6 | ||||
-rw-r--r-- | crates/hir/src/source_analyzer.rs | 30 |
5 files changed, 107 insertions, 84 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..993772aac 100644 --- a/crates/hir/src/display.rs +++ b/crates/hir/src/display.rs | |||
@@ -13,29 +13,28 @@ use syntax::ast::{self, NameOwner}; | |||
13 | 13 | ||
14 | use crate::{ | 14 | use crate::{ |
15 | Adt, Const, ConstParam, Enum, Field, Function, GenericParam, HasVisibility, LifetimeParam, | 15 | Adt, Const, ConstParam, Enum, Field, Function, GenericParam, HasVisibility, LifetimeParam, |
16 | Module, Static, Struct, Substitution, Trait, Type, TypeAlias, TypeParam, Union, Variant, | 16 | Module, Static, Struct, Trait, TyBuilder, Type, TypeAlias, TypeParam, Union, Variant, |
17 | }; | 17 | }; |
18 | 18 | ||
19 | impl HirDisplay for Function { | 19 | impl HirDisplay for Function { |
20 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | 20 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { |
21 | let data = f.db.function_data(self.id); | 21 | let data = f.db.function_data(self.id); |
22 | write_visibility(self.module(f.db).id, self.visibility(f.db), f)?; | 22 | write_visibility(self.module(f.db).id, self.visibility(f.db), f)?; |
23 | let qual = &data.qualifier; | 23 | if data.is_default() { |
24 | if qual.is_default { | ||
25 | write!(f, "default ")?; | 24 | write!(f, "default ")?; |
26 | } | 25 | } |
27 | if qual.is_const { | 26 | if data.is_const() { |
28 | write!(f, "const ")?; | 27 | write!(f, "const ")?; |
29 | } | 28 | } |
30 | if qual.is_async { | 29 | if data.is_async() { |
31 | write!(f, "async ")?; | 30 | write!(f, "async ")?; |
32 | } | 31 | } |
33 | if qual.is_unsafe { | 32 | if data.is_unsafe() { |
34 | write!(f, "unsafe ")?; | 33 | write!(f, "unsafe ")?; |
35 | } | 34 | } |
36 | if let Some(abi) = &qual.abi { | 35 | if let Some(abi) = &data.abi { |
37 | // FIXME: String escape? | 36 | // FIXME: String escape? |
38 | write!(f, "extern \"{}\" ", abi)?; | 37 | write!(f, "extern \"{}\" ", &**abi)?; |
39 | } | 38 | } |
40 | write!(f, "fn {}", data.name)?; | 39 | write!(f, "fn {}", data.name)?; |
41 | 40 | ||
@@ -68,7 +67,7 @@ impl HirDisplay for Function { | |||
68 | write!(f, ", ")?; | 67 | write!(f, ", ")?; |
69 | } else { | 68 | } else { |
70 | first = false; | 69 | first = false; |
71 | if data.has_self_param { | 70 | if data.has_self_param() { |
72 | write_self_param(type_ref, f)?; | 71 | write_self_param(type_ref, f)?; |
73 | continue; | 72 | continue; |
74 | } | 73 | } |
@@ -88,10 +87,10 @@ impl HirDisplay for Function { | |||
88 | // `FunctionData::ret_type` will be `::core::future::Future<Output = ...>` for async fns. | 87 | // `FunctionData::ret_type` will be `::core::future::Future<Output = ...>` for async fns. |
89 | // Use ugly pattern match to strip the Future trait. | 88 | // Use ugly pattern match to strip the Future trait. |
90 | // Better way? | 89 | // Better way? |
91 | let ret_type = if !qual.is_async { | 90 | let ret_type = if !data.is_async() { |
92 | &data.ret_type | 91 | &data.ret_type |
93 | } else { | 92 | } else { |
94 | match &data.ret_type { | 93 | match &*data.ret_type { |
95 | TypeRef::ImplTrait(bounds) => match &bounds[0] { | 94 | TypeRef::ImplTrait(bounds) => match &bounds[0] { |
96 | TypeBound::Path(path) => { | 95 | TypeBound::Path(path) => { |
97 | path.segments().iter().last().unwrap().args_and_bindings.unwrap().bindings | 96 | path.segments().iter().last().unwrap().args_and_bindings.unwrap().bindings |
@@ -235,7 +234,7 @@ impl HirDisplay for TypeParam { | |||
235 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | 234 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { |
236 | write!(f, "{}", self.name(f.db))?; | 235 | write!(f, "{}", self.name(f.db))?; |
237 | let bounds = f.db.generic_predicates_for_param(self.id); | 236 | let bounds = f.db.generic_predicates_for_param(self.id); |
238 | let substs = Substitution::type_params(f.db, self.id.parent); | 237 | let substs = TyBuilder::type_params_subst(f.db, self.id.parent); |
239 | let predicates = bounds.iter().cloned().map(|b| b.subst(&substs)).collect::<Vec<_>>(); | 238 | let predicates = bounds.iter().cloned().map(|b| b.subst(&substs)).collect::<Vec<_>>(); |
240 | if !(predicates.is_empty() || f.omit_verbose_types()) { | 239 | if !(predicates.is_empty() || f.omit_verbose_types()) { |
241 | write_bounds_like_dyn_trait_with_prefix(":", &predicates, f)?; | 240 | write_bounds_like_dyn_trait_with_prefix(":", &predicates, f)?; |
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 4ee08ef21..e41efb385 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, |
@@ -54,11 +55,11 @@ use hir_ty::{ | |||
54 | autoderef, could_unify, | 55 | autoderef, could_unify, |
55 | method_resolution::{self, TyFingerprint}, | 56 | method_resolution::{self, TyFingerprint}, |
56 | primitive::UintTy, | 57 | primitive::UintTy, |
57 | to_assoc_type_id, | 58 | traits::FnTrait, |
58 | traits::{FnTrait, Solution, SolutionVariables}, | ||
59 | AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast, | 59 | AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast, |
60 | DebruijnIndex, InEnvironment, Interner, ProjectionTy, QuantifiedWhereClause, Scalar, | 60 | DebruijnIndex, InEnvironment, Interner, QuantifiedWhereClause, Scalar, Solution, |
61 | Substitution, TraitEnvironment, Ty, TyDefId, TyKind, TyVariableKind, WhereClause, | 61 | SolutionVariables, Substitution, TraitEnvironment, Ty, TyBuilder, TyDefId, TyKind, |
62 | TyVariableKind, WhereClause, | ||
62 | }; | 63 | }; |
63 | use itertools::Itertools; | 64 | use itertools::Itertools; |
64 | use rustc_hash::FxHashSet; | 65 | use rustc_hash::FxHashSet; |
@@ -514,7 +515,7 @@ impl Field { | |||
514 | VariantDef::Union(it) => it.id.into(), | 515 | VariantDef::Union(it) => it.id.into(), |
515 | VariantDef::Variant(it) => it.parent.id.into(), | 516 | VariantDef::Variant(it) => it.parent.id.into(), |
516 | }; | 517 | }; |
517 | let substs = Substitution::type_params(db, generic_def_id); | 518 | let substs = TyBuilder::type_params_subst(db, generic_def_id); |
518 | let ty = db.field_types(var_id)[self.id].clone().subst(&substs); | 519 | let ty = db.field_types(var_id)[self.id].clone().subst(&substs); |
519 | Type::new(db, self.parent.module(db).id.krate(), var_id, ty) | 520 | Type::new(db, self.parent.module(db).id.krate(), var_id, ty) |
520 | } | 521 | } |
@@ -831,7 +832,7 @@ impl Function { | |||
831 | } | 832 | } |
832 | 833 | ||
833 | pub fn self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> { | 834 | pub fn self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> { |
834 | if !db.function_data(self.id).has_self_param { | 835 | if !db.function_data(self.id).has_self_param() { |
835 | return None; | 836 | return None; |
836 | } | 837 | } |
837 | Some(SelfParam { func: self.id }) | 838 | Some(SelfParam { func: self.id }) |
@@ -863,7 +864,7 @@ impl Function { | |||
863 | } | 864 | } |
864 | 865 | ||
865 | pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool { | 866 | pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool { |
866 | db.function_data(self.id).qualifier.is_unsafe | 867 | db.function_data(self.id).is_unsafe() |
867 | } | 868 | } |
868 | 869 | ||
869 | pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { | 870 | pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { |
@@ -877,7 +878,7 @@ impl Function { | |||
877 | /// | 878 | /// |
878 | /// This is false in the case of required (not provided) trait methods. | 879 | /// This is false in the case of required (not provided) trait methods. |
879 | pub fn has_body(self, db: &dyn HirDatabase) -> bool { | 880 | pub fn has_body(self, db: &dyn HirDatabase) -> bool { |
880 | db.function_data(self.id).has_body | 881 | db.function_data(self.id).has_body() |
881 | } | 882 | } |
882 | 883 | ||
883 | /// A textual representation of the HIR of this function for debugging purposes. | 884 | /// A textual representation of the HIR of this function for debugging purposes. |
@@ -956,7 +957,7 @@ impl SelfParam { | |||
956 | func_data | 957 | func_data |
957 | .params | 958 | .params |
958 | .first() | 959 | .first() |
959 | .map(|param| match *param { | 960 | .map(|param| match &**param { |
960 | TypeRef::Reference(.., mutability) => match mutability { | 961 | TypeRef::Reference(.., mutability) => match mutability { |
961 | hir_def::type_ref::Mutability::Shared => Access::Shared, | 962 | hir_def::type_ref::Mutability::Shared => Access::Shared, |
962 | hir_def::type_ref::Mutability::Mut => Access::Exclusive, | 963 | hir_def::type_ref::Mutability::Mut => Access::Exclusive, |
@@ -1010,7 +1011,7 @@ impl Const { | |||
1010 | } | 1011 | } |
1011 | 1012 | ||
1012 | pub fn type_ref(self, db: &dyn HirDatabase) -> TypeRef { | 1013 | pub fn type_ref(self, db: &dyn HirDatabase) -> TypeRef { |
1013 | db.const_data(self.id).type_ref.clone() | 1014 | db.const_data(self.id).type_ref.as_ref().clone() |
1014 | } | 1015 | } |
1015 | } | 1016 | } |
1016 | 1017 | ||
@@ -1100,7 +1101,7 @@ impl TypeAlias { | |||
1100 | } | 1101 | } |
1101 | 1102 | ||
1102 | pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> { | 1103 | pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> { |
1103 | db.type_alias_data(self.id).type_ref.clone() | 1104 | db.type_alias_data(self.id).type_ref.as_deref().cloned() |
1104 | } | 1105 | } |
1105 | 1106 | ||
1106 | pub fn ty(self, db: &dyn HirDatabase) -> Type { | 1107 | pub fn ty(self, db: &dyn HirDatabase) -> Type { |
@@ -1128,7 +1129,7 @@ pub struct BuiltinType { | |||
1128 | impl BuiltinType { | 1129 | impl BuiltinType { |
1129 | pub fn ty(self, db: &dyn HirDatabase, module: Module) -> Type { | 1130 | pub fn ty(self, db: &dyn HirDatabase, module: Module) -> Type { |
1130 | let resolver = module.id.resolver(db.upcast()); | 1131 | let resolver = module.id.resolver(db.upcast()); |
1131 | Type::new_with_resolver(db, &resolver, Ty::builtin(self.inner)) | 1132 | Type::new_with_resolver(db, &resolver, TyBuilder::builtin(self.inner)) |
1132 | .expect("crate not present in resolver") | 1133 | .expect("crate not present in resolver") |
1133 | } | 1134 | } |
1134 | 1135 | ||
@@ -1501,7 +1502,7 @@ impl TypeParam { | |||
1501 | let resolver = self.id.parent.resolver(db.upcast()); | 1502 | let resolver = self.id.parent.resolver(db.upcast()); |
1502 | let krate = self.id.parent.module(db.upcast()).krate(); | 1503 | let krate = self.id.parent.module(db.upcast()).krate(); |
1503 | let ty = params.get(local_idx)?.clone(); | 1504 | let ty = params.get(local_idx)?.clone(); |
1504 | let subst = Substitution::type_params(db, self.id.parent); | 1505 | let subst = TyBuilder::type_params_subst(db, self.id.parent); |
1505 | let ty = ty.subst(&subst.prefix(local_idx)); | 1506 | let ty = ty.subst(&subst.prefix(local_idx)); |
1506 | Some(Type::new_with_resolver_inner(db, krate, &resolver, ty)) | 1507 | Some(Type::new_with_resolver_inner(db, krate, &resolver, ty)) |
1507 | } | 1508 | } |
@@ -1573,9 +1574,9 @@ impl Impl { | |||
1573 | }; | 1574 | }; |
1574 | 1575 | ||
1575 | let filter = |impl_def: &Impl| { | 1576 | let filter = |impl_def: &Impl| { |
1576 | let target_ty = impl_def.target_ty(db); | 1577 | let self_ty = impl_def.self_ty(db); |
1577 | let rref = target_ty.remove_ref(); | 1578 | let rref = self_ty.remove_ref(); |
1578 | ty.equals_ctor(rref.as_ref().map_or(&target_ty.ty, |it| &it.ty)) | 1579 | ty.equals_ctor(rref.as_ref().map_or(&self_ty.ty, |it| &it.ty)) |
1579 | }; | 1580 | }; |
1580 | 1581 | ||
1581 | let mut all = Vec::new(); | 1582 | let mut all = Vec::new(); |
@@ -1613,16 +1614,16 @@ impl Impl { | |||
1613 | 1614 | ||
1614 | // FIXME: the return type is wrong. This should be a hir version of | 1615 | // FIXME: the return type is wrong. This should be a hir version of |
1615 | // `TraitRef` (ie, resolved `TypeRef`). | 1616 | // `TraitRef` (ie, resolved `TypeRef`). |
1616 | pub fn target_trait(self, db: &dyn HirDatabase) -> Option<TypeRef> { | 1617 | pub fn trait_(self, db: &dyn HirDatabase) -> Option<TraitRef> { |
1617 | db.impl_data(self.id).target_trait.clone() | 1618 | db.impl_data(self.id).target_trait.as_deref().cloned() |
1618 | } | 1619 | } |
1619 | 1620 | ||
1620 | pub fn target_ty(self, db: &dyn HirDatabase) -> Type { | 1621 | pub fn self_ty(self, db: &dyn HirDatabase) -> Type { |
1621 | let impl_data = db.impl_data(self.id); | 1622 | let impl_data = db.impl_data(self.id); |
1622 | let resolver = self.id.resolver(db.upcast()); | 1623 | let resolver = self.id.resolver(db.upcast()); |
1623 | let krate = self.id.lookup(db.upcast()).container.krate(); | 1624 | let krate = self.id.lookup(db.upcast()).container.krate(); |
1624 | let ctx = hir_ty::TyLoweringContext::new(db, &resolver); | 1625 | let ctx = hir_ty::TyLoweringContext::new(db, &resolver); |
1625 | let ty = ctx.lower_ty(&impl_data.target_type); | 1626 | let ty = ctx.lower_ty(&impl_data.self_ty); |
1626 | Type::new_with_resolver_inner(db, krate, &resolver, ty) | 1627 | Type::new_with_resolver_inner(db, krate, &resolver, ty) |
1627 | } | 1628 | } |
1628 | 1629 | ||
@@ -1702,30 +1703,29 @@ impl Type { | |||
1702 | fn from_def( | 1703 | fn from_def( |
1703 | db: &dyn HirDatabase, | 1704 | db: &dyn HirDatabase, |
1704 | krate: CrateId, | 1705 | krate: CrateId, |
1705 | def: impl HasResolver + Into<TyDefId> + Into<GenericDefId>, | 1706 | def: impl HasResolver + Into<TyDefId>, |
1706 | ) -> Type { | 1707 | ) -> Type { |
1707 | let substs = Substitution::build_for_def(db, def).fill_with_unknown().build(); | 1708 | 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) | 1709 | Type::new(db, krate, def, ty) |
1710 | } | 1710 | } |
1711 | 1711 | ||
1712 | pub fn is_unit(&self) -> bool { | 1712 | pub fn is_unit(&self) -> bool { |
1713 | matches!(self.ty.interned(&Interner), TyKind::Tuple(0, ..)) | 1713 | matches!(self.ty.kind(&Interner), TyKind::Tuple(0, ..)) |
1714 | } | 1714 | } |
1715 | pub fn is_bool(&self) -> bool { | 1715 | pub fn is_bool(&self) -> bool { |
1716 | matches!(self.ty.interned(&Interner), TyKind::Scalar(Scalar::Bool)) | 1716 | matches!(self.ty.kind(&Interner), TyKind::Scalar(Scalar::Bool)) |
1717 | } | 1717 | } |
1718 | 1718 | ||
1719 | pub fn is_mutable_reference(&self) -> bool { | 1719 | pub fn is_mutable_reference(&self) -> bool { |
1720 | matches!(self.ty.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..)) | 1720 | matches!(self.ty.kind(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..)) |
1721 | } | 1721 | } |
1722 | 1722 | ||
1723 | pub fn is_usize(&self) -> bool { | 1723 | pub fn is_usize(&self) -> bool { |
1724 | matches!(self.ty.interned(&Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize))) | 1724 | matches!(self.ty.kind(&Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize))) |
1725 | } | 1725 | } |
1726 | 1726 | ||
1727 | pub fn remove_ref(&self) -> Option<Type> { | 1727 | pub fn remove_ref(&self) -> Option<Type> { |
1728 | match &self.ty.interned(&Interner) { | 1728 | match &self.ty.kind(&Interner) { |
1729 | TyKind::Ref(.., ty) => Some(self.derived(ty.clone())), | 1729 | TyKind::Ref(.., ty) => Some(self.derived(ty.clone())), |
1730 | _ => None, | 1730 | _ => None, |
1731 | } | 1731 | } |
@@ -1784,13 +1784,10 @@ impl Type { | |||
1784 | } | 1784 | } |
1785 | 1785 | ||
1786 | pub fn impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool { | 1786 | pub fn impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool { |
1787 | let trait_ref = hir_ty::TraitRef { | 1787 | let trait_ref = TyBuilder::trait_ref(db, trait_.id) |
1788 | trait_id: hir_ty::to_chalk_trait_id(trait_.id), | 1788 | .push(self.ty.clone()) |
1789 | substitution: Substitution::build_for_def(db, trait_.id) | 1789 | .fill(args.iter().map(|t| t.ty.clone())) |
1790 | .push(self.ty.clone()) | 1790 | .build(); |
1791 | .fill(args.iter().map(|t| t.ty.clone())) | ||
1792 | .build(), | ||
1793 | }; | ||
1794 | 1791 | ||
1795 | let goal = Canonical { | 1792 | let goal = Canonical { |
1796 | value: hir_ty::InEnvironment::new(self.env.env.clone(), trait_ref.cast(&Interner)), | 1793 | value: hir_ty::InEnvironment::new(self.env.env.clone(), trait_ref.cast(&Interner)), |
@@ -1803,11 +1800,10 @@ impl Type { | |||
1803 | pub fn normalize_trait_assoc_type( | 1800 | pub fn normalize_trait_assoc_type( |
1804 | &self, | 1801 | &self, |
1805 | db: &dyn HirDatabase, | 1802 | db: &dyn HirDatabase, |
1806 | trait_: Trait, | ||
1807 | args: &[Type], | 1803 | args: &[Type], |
1808 | alias: TypeAlias, | 1804 | alias: TypeAlias, |
1809 | ) -> Option<Type> { | 1805 | ) -> Option<Type> { |
1810 | let subst = Substitution::build_for_def(db, trait_.id) | 1806 | let projection = TyBuilder::assoc_type_projection(db, alias.id) |
1811 | .push(self.ty.clone()) | 1807 | .push(self.ty.clone()) |
1812 | .fill(args.iter().map(|t| t.ty.clone())) | 1808 | .fill(args.iter().map(|t| t.ty.clone())) |
1813 | .build(); | 1809 | .build(); |
@@ -1815,10 +1811,7 @@ impl Type { | |||
1815 | InEnvironment::new( | 1811 | InEnvironment::new( |
1816 | self.env.env.clone(), | 1812 | self.env.env.clone(), |
1817 | AliasEq { | 1813 | AliasEq { |
1818 | alias: AliasTy::Projection(ProjectionTy { | 1814 | 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)) | 1815 | ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)) |
1823 | .intern(&Interner), | 1816 | .intern(&Interner), |
1824 | } | 1817 | } |
@@ -1828,9 +1821,11 @@ impl Type { | |||
1828 | ); | 1821 | ); |
1829 | 1822 | ||
1830 | match db.trait_solve(self.krate, goal)? { | 1823 | match db.trait_solve(self.krate, goal)? { |
1831 | Solution::Unique(SolutionVariables(subst)) => { | 1824 | Solution::Unique(SolutionVariables(subst)) => subst |
1832 | subst.value.first().map(|ty| self.derived(ty.clone())) | 1825 | .value |
1833 | } | 1826 | .interned() |
1827 | .first() | ||
1828 | .map(|ty| self.derived(ty.assert_ty_ref(&Interner).clone())), | ||
1834 | Solution::Ambig(_) => None, | 1829 | Solution::Ambig(_) => None, |
1835 | } | 1830 | } |
1836 | } | 1831 | } |
@@ -1852,15 +1847,15 @@ impl Type { | |||
1852 | } | 1847 | } |
1853 | 1848 | ||
1854 | pub fn is_closure(&self) -> bool { | 1849 | pub fn is_closure(&self) -> bool { |
1855 | matches!(&self.ty.interned(&Interner), TyKind::Closure { .. }) | 1850 | matches!(&self.ty.kind(&Interner), TyKind::Closure { .. }) |
1856 | } | 1851 | } |
1857 | 1852 | ||
1858 | pub fn is_fn(&self) -> bool { | 1853 | pub fn is_fn(&self) -> bool { |
1859 | matches!(&self.ty.interned(&Interner), TyKind::FnDef(..) | TyKind::Function { .. }) | 1854 | matches!(&self.ty.kind(&Interner), TyKind::FnDef(..) | TyKind::Function { .. }) |
1860 | } | 1855 | } |
1861 | 1856 | ||
1862 | pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { | 1857 | pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { |
1863 | let adt_id = match self.ty.interned(&Interner) { | 1858 | let adt_id = match self.ty.kind(&Interner) { |
1864 | &TyKind::Adt(hir_ty::AdtId(adt_id), ..) => adt_id, | 1859 | &TyKind::Adt(hir_ty::AdtId(adt_id), ..) => adt_id, |
1865 | _ => return false, | 1860 | _ => return false, |
1866 | }; | 1861 | }; |
@@ -1873,14 +1868,14 @@ impl Type { | |||
1873 | } | 1868 | } |
1874 | 1869 | ||
1875 | pub fn is_raw_ptr(&self) -> bool { | 1870 | pub fn is_raw_ptr(&self) -> bool { |
1876 | matches!(&self.ty.interned(&Interner), TyKind::Raw(..)) | 1871 | matches!(&self.ty.kind(&Interner), TyKind::Raw(..)) |
1877 | } | 1872 | } |
1878 | 1873 | ||
1879 | pub fn contains_unknown(&self) -> bool { | 1874 | pub fn contains_unknown(&self) -> bool { |
1880 | return go(&self.ty); | 1875 | return go(&self.ty); |
1881 | 1876 | ||
1882 | fn go(ty: &Ty) -> bool { | 1877 | fn go(ty: &Ty) -> bool { |
1883 | match ty.interned(&Interner) { | 1878 | match ty.kind(&Interner) { |
1884 | TyKind::Unknown => true, | 1879 | TyKind::Unknown => true, |
1885 | 1880 | ||
1886 | TyKind::Adt(_, substs) | 1881 | TyKind::Adt(_, substs) |
@@ -1888,7 +1883,9 @@ impl Type { | |||
1888 | | TyKind::Tuple(_, substs) | 1883 | | TyKind::Tuple(_, substs) |
1889 | | TyKind::OpaqueType(_, substs) | 1884 | | TyKind::OpaqueType(_, substs) |
1890 | | TyKind::FnDef(_, substs) | 1885 | | TyKind::FnDef(_, substs) |
1891 | | TyKind::Closure(_, substs) => substs.iter().any(go), | 1886 | | TyKind::Closure(_, substs) => { |
1887 | substs.iter(&Interner).filter_map(|a| a.ty(&Interner)).any(go) | ||
1888 | } | ||
1892 | 1889 | ||
1893 | TyKind::Array(ty) | TyKind::Slice(ty) | TyKind::Raw(_, ty) | TyKind::Ref(_, ty) => { | 1890 | TyKind::Array(ty) | TyKind::Slice(ty) | TyKind::Raw(_, ty) | TyKind::Ref(_, ty) => { |
1894 | go(ty) | 1891 | go(ty) |
@@ -1909,7 +1906,7 @@ impl Type { | |||
1909 | } | 1906 | } |
1910 | 1907 | ||
1911 | pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { | 1908 | pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { |
1912 | let (variant_id, substs) = match self.ty.interned(&Interner) { | 1909 | let (variant_id, substs) = match self.ty.kind(&Interner) { |
1913 | &TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs), | 1910 | &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), | 1911 | &TyKind::Adt(hir_ty::AdtId(AdtId::UnionId(u)), ref substs) => (u.into(), substs), |
1915 | _ => return Vec::new(), | 1912 | _ => return Vec::new(), |
@@ -1926,8 +1923,11 @@ impl Type { | |||
1926 | } | 1923 | } |
1927 | 1924 | ||
1928 | pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { | 1925 | pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { |
1929 | if let TyKind::Tuple(_, substs) = &self.ty.interned(&Interner) { | 1926 | if let TyKind::Tuple(_, substs) = &self.ty.kind(&Interner) { |
1930 | substs.iter().map(|ty| self.derived(ty.clone())).collect() | 1927 | substs |
1928 | .iter(&Interner) | ||
1929 | .map(|ty| self.derived(ty.assert_ty_ref(&Interner).clone())) | ||
1930 | .collect() | ||
1931 | } else { | 1931 | } else { |
1932 | Vec::new() | 1932 | Vec::new() |
1933 | } | 1933 | } |
@@ -1972,8 +1972,9 @@ impl Type { | |||
1972 | .strip_references() | 1972 | .strip_references() |
1973 | .substs() | 1973 | .substs() |
1974 | .into_iter() | 1974 | .into_iter() |
1975 | .flat_map(|substs| substs.iter()) | 1975 | .flat_map(|substs| substs.iter(&Interner)) |
1976 | .map(move |ty| self.derived(ty.clone())) | 1976 | .filter_map(|arg| arg.ty(&Interner).cloned()) |
1977 | .map(move |ty| self.derived(ty)) | ||
1977 | } | 1978 | } |
1978 | 1979 | ||
1979 | pub fn iterate_method_candidates<T>( | 1980 | pub fn iterate_method_candidates<T>( |
@@ -2079,7 +2080,7 @@ impl Type { | |||
2079 | substs: &Substitution, | 2080 | substs: &Substitution, |
2080 | cb: &mut impl FnMut(Type), | 2081 | cb: &mut impl FnMut(Type), |
2081 | ) { | 2082 | ) { |
2082 | for ty in substs.iter() { | 2083 | for ty in substs.iter(&Interner).filter_map(|a| a.ty(&Interner)) { |
2083 | walk_type(db, &type_.derived(ty.clone()), cb); | 2084 | walk_type(db, &type_.derived(ty.clone()), cb); |
2084 | } | 2085 | } |
2085 | } | 2086 | } |
@@ -2095,7 +2096,12 @@ impl Type { | |||
2095 | WhereClause::Implemented(trait_ref) => { | 2096 | WhereClause::Implemented(trait_ref) => { |
2096 | cb(type_.clone()); | 2097 | cb(type_.clone()); |
2097 | // skip the self type. it's likely the type we just got the bounds from | 2098 | // 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) { | 2099 | for ty in trait_ref |
2100 | .substitution | ||
2101 | .iter(&Interner) | ||
2102 | .skip(1) | ||
2103 | .filter_map(|a| a.ty(&Interner)) | ||
2104 | { | ||
2099 | walk_type(db, &type_.derived(ty.clone()), cb); | 2105 | walk_type(db, &type_.derived(ty.clone()), cb); |
2100 | } | 2106 | } |
2101 | } | 2107 | } |
@@ -2106,7 +2112,7 @@ impl Type { | |||
2106 | 2112 | ||
2107 | fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { | 2113 | fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { |
2108 | let ty = type_.ty.strip_references(); | 2114 | let ty = type_.ty.strip_references(); |
2109 | match ty.interned(&Interner) { | 2115 | match ty.kind(&Interner) { |
2110 | TyKind::Adt(..) => { | 2116 | TyKind::Adt(..) => { |
2111 | cb(type_.derived(ty.clone())); | 2117 | cb(type_.derived(ty.clone())); |
2112 | } | 2118 | } |
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index d3caeef4e..3bf722d2a 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 | ||
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index 37d162b32..8e9ea0a03 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, Substitution, TyLoweringContext, |
24 | }; | 24 | }; |
25 | use syntax::{ | 25 | use syntax::{ |
26 | ast::{self, AstNode}, | 26 | ast::{self, AstNode}, |
@@ -466,7 +466,21 @@ fn resolve_hir_path_( | |||
466 | prefer_value_ns: bool, | 466 | prefer_value_ns: bool, |
467 | ) -> Option<PathResolution> { | 467 | ) -> Option<PathResolution> { |
468 | let types = || { | 468 | let types = || { |
469 | resolver.resolve_path_in_type_ns_fully(db.upcast(), path.mod_path()).map(|ty| match ty { | 469 | let (ty, unresolved) = match path.type_anchor() { |
470 | Some(type_ref) => { | ||
471 | let (_, res) = TyLoweringContext::new(db, resolver).lower_ty_ext(type_ref); | ||
472 | res.map(|ty_ns| (ty_ns, path.segments().first())) | ||
473 | } | ||
474 | None => { | ||
475 | let (ty, remaining) = | ||
476 | resolver.resolve_path_in_type_ns(db.upcast(), path.mod_path())?; | ||
477 | match remaining { | ||
478 | Some(remaining) if remaining > 1 => None, | ||
479 | _ => Some((ty, path.segments().get(1))), | ||
480 | } | ||
481 | } | ||
482 | }?; | ||
483 | let res = match ty { | ||
470 | TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), | 484 | TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), |
471 | TypeNs::GenericParam(id) => PathResolution::TypeParam(TypeParam { id }), | 485 | TypeNs::GenericParam(id) => PathResolution::TypeParam(TypeParam { id }), |
472 | TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { | 486 | TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { |
@@ -476,7 +490,17 @@ fn resolve_hir_path_( | |||
476 | TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()), | 490 | TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()), |
477 | TypeNs::BuiltinType(it) => PathResolution::Def(BuiltinType::from(it).into()), | 491 | TypeNs::BuiltinType(it) => PathResolution::Def(BuiltinType::from(it).into()), |
478 | TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()), | 492 | TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()), |
479 | }) | 493 | }; |
494 | match unresolved { | ||
495 | Some(unresolved) => res | ||
496 | .assoc_type_shorthand_candidates(db, |name, alias| { | ||
497 | (name == unresolved.name).then(|| alias) | ||
498 | }) | ||
499 | .map(TypeAlias::from) | ||
500 | .map(Into::into) | ||
501 | .map(PathResolution::Def), | ||
502 | None => Some(res), | ||
503 | } | ||
480 | }; | 504 | }; |
481 | 505 | ||
482 | let body_owner = resolver.body_owner(); | 506 | let body_owner = resolver.body_owner(); |