aboutsummaryrefslogtreecommitdiff
path: root/crates/hir
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir')
-rw-r--r--crates/hir/src/db.rs10
-rw-r--r--crates/hir/src/display.rs23
-rw-r--r--crates/hir/src/lib.rs122
-rw-r--r--crates/hir/src/semantics.rs6
-rw-r--r--crates/hir/src/source_analyzer.rs30
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
3pub use hir_def::db::{ 3pub 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};
12pub use hir_expand::db::{ 4pub 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
14use crate::{ 14use 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
19impl HirDisplay for Function { 19impl 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};
63use itertools::Itertools; 64use itertools::Itertools;
64use rustc_hash::FxHashSet; 65use 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 {
1128impl BuiltinType { 1129impl 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::{
20use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile}; 20use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile};
21use hir_ty::{ 21use 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};
25use syntax::{ 25use 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();