aboutsummaryrefslogtreecommitdiff
path: root/crates/hir
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir')
-rw-r--r--crates/hir/Cargo.toml2
-rw-r--r--crates/hir/src/db.rs10
-rw-r--r--crates/hir/src/display.rs27
-rw-r--r--crates/hir/src/lib.rs192
-rw-r--r--crates/hir/src/semantics.rs14
-rw-r--r--crates/hir/src/semantics/source_to_def.rs5
-rw-r--r--crates/hir/src/source_analyzer.rs63
7 files changed, 181 insertions, 132 deletions
diff --git a/crates/hir/Cargo.toml b/crates/hir/Cargo.toml
index 2ef5bcbc9..9e329656f 100644
--- a/crates/hir/Cargo.toml
+++ b/crates/hir/Cargo.toml
@@ -13,7 +13,7 @@ doctest = false
13log = "0.4.8" 13log = "0.4.8"
14rustc-hash = "1.1.0" 14rustc-hash = "1.1.0"
15either = "1.5.3" 15either = "1.5.3"
16arrayvec = "0.6" 16arrayvec = "0.7"
17itertools = "0.10.0" 17itertools = "0.10.0"
18smallvec = "1.4.0" 18smallvec = "1.4.0"
19 19
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..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};
12use hir_ty::Interner;
12use syntax::ast::{self, NameOwner}; 13use syntax::ast::{self, NameOwner};
13 14
14use crate::{ 15use 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
19impl HirDisplay for Function { 20impl 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};
52use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind}; 53use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind};
53use hir_ty::{ 54use 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};
63use itertools::Itertools; 65use itertools::Itertools;
64use rustc_hash::FxHashSet; 66use 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);
701impl Adt { 703impl 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 {
1088impl TypeAlias { 1090impl 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 {
1128impl BuiltinType { 1130impl 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::{
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, Interner, Substitution, TyExt, TyLoweringContext,
24}; 24};
25use syntax::{ 25use 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();