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/display.rs4
-rw-r--r--crates/hir/src/lib.rs121
-rw-r--r--crates/hir/src/semantics.rs11
-rw-r--r--crates/hir/src/source_analyzer.rs44
5 files changed, 119 insertions, 63 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/display.rs b/crates/hir/src/display.rs
index 993772aac..01a4d205f 100644
--- a/crates/hir/src/display.rs
+++ b/crates/hir/src/display.rs
@@ -9,6 +9,7 @@ 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::{
@@ -235,7 +236,8 @@ impl HirDisplay for TypeParam {
235 write!(f, "{}", self.name(f.db))?; 236 write!(f, "{}", self.name(f.db))?;
236 let bounds = f.db.generic_predicates_for_param(self.id); 237 let bounds = f.db.generic_predicates_for_param(self.id);
237 let substs = TyBuilder::type_params_subst(f.db, self.id.parent); 238 let substs = TyBuilder::type_params_subst(f.db, self.id.parent);
238 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<_>>();
239 if !(predicates.is_empty() || f.omit_verbose_types()) { 241 if !(predicates.is_empty() || f.omit_verbose_types()) {
240 write_bounds_like_dyn_trait_with_prefix(":", &predicates, f)?; 242 write_bounds_like_dyn_trait_with_prefix(":", &predicates, f)?;
241 } 243 }
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 19901ed33..0acfa582a 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -53,12 +53,14 @@ use hir_def::{
53use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind}; 53use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind};
54use hir_ty::{ 54use hir_ty::{
55 autoderef, could_unify, 55 autoderef, could_unify,
56 method_resolution::{self, TyFingerprint}, 56 method_resolution::{self, def_crates, TyFingerprint},
57 primitive::UintTy, 57 primitive::UintTy,
58 traits::{FnTrait, Solution, SolutionVariables}, 58 subst_prefix,
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, QuantifiedWhereClause, Scalar, Substitution, 61 DebruijnIndex, InEnvironment, Interner, QuantifiedWhereClause, Scalar, Solution, Substitution,
61 TraitEnvironment, Ty, TyBuilder, 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;
@@ -515,7 +517,7 @@ impl Field {
515 VariantDef::Variant(it) => it.parent.id.into(), 517 VariantDef::Variant(it) => it.parent.id.into(),
516 }; 518 };
517 let substs = TyBuilder::type_params_subst(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
@@ -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 {
@@ -1502,7 +1504,7 @@ impl TypeParam {
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 = TyBuilder::type_params_subst(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,7 +1569,7 @@ 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 };
@@ -1578,11 +1580,24 @@ impl Impl {
1578 ty.equals_ctor(rref.as_ref().map_or(&self_ty.ty, |it| &it.ty)) 1580 ty.equals_ctor(rref.as_ref().map_or(&self_ty.ty, |it| &it.ty))
1579 }; 1581 };
1580 1582
1583 let fp = TyFingerprint::for_inherent_impl(&ty);
1584 let fp = if let Some(fp) = fp {
1585 fp
1586 } else {
1587 return Vec::new();
1588 };
1589
1581 let mut all = Vec::new(); 1590 let mut all = Vec::new();
1582 def_crates.iter().for_each(|&id| { 1591 def_crates.iter().for_each(|&id| {
1583 all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter)) 1592 all.extend(
1593 db.inherent_impls_in_crate(id)
1594 .for_self_ty(&ty)
1595 .into_iter()
1596 .cloned()
1597 .map(Self::from)
1598 .filter(filter),
1599 )
1584 }); 1600 });
1585 let fp = TyFingerprint::for_impl(&ty);
1586 for id in def_crates 1601 for id in def_crates
1587 .iter() 1602 .iter()
1588 .flat_map(|&id| Crate { id }.transitive_reverse_dependencies(db)) 1603 .flat_map(|&id| Crate { id }.transitive_reverse_dependencies(db))
@@ -1590,13 +1605,12 @@ impl Impl {
1590 .chain(def_crates.iter().copied()) 1605 .chain(def_crates.iter().copied())
1591 .unique() 1606 .unique()
1592 { 1607 {
1593 match fp { 1608 all.extend(
1594 Some(fp) => all.extend( 1609 db.trait_impls_in_crate(id)
1595 db.trait_impls_in_crate(id).for_self_ty(fp).map(Self::from).filter(filter), 1610 .for_self_ty_without_blanket_impls(fp)
1596 ), 1611 .map(Self::from)
1597 None => all 1612 .filter(filter),
1598 .extend(db.trait_impls_in_crate(id).all_impls().map(Self::from).filter(filter)), 1613 );
1599 }
1600 } 1614 }
1601 all 1615 all
1602 } 1616 }
@@ -1789,7 +1803,7 @@ impl Type {
1789 .build(); 1803 .build();
1790 1804
1791 let goal = Canonical { 1805 let goal = Canonical {
1792 value: hir_ty::InEnvironment::new(self.env.env.clone(), trait_ref.cast(&Interner)), 1806 value: hir_ty::InEnvironment::new(&self.env.env, trait_ref.cast(&Interner)),
1793 binders: CanonicalVarKinds::empty(&Interner), 1807 binders: CanonicalVarKinds::empty(&Interner),
1794 }; 1808 };
1795 1809
@@ -1806,9 +1820,9 @@ impl Type {
1806 .push(self.ty.clone()) 1820 .push(self.ty.clone())
1807 .fill(args.iter().map(|t| t.ty.clone())) 1821 .fill(args.iter().map(|t| t.ty.clone()))
1808 .build(); 1822 .build();
1809 let goal = Canonical::new( 1823 let goal = hir_ty::make_canonical(
1810 InEnvironment::new( 1824 InEnvironment::new(
1811 self.env.env.clone(), 1825 &self.env.env,
1812 AliasEq { 1826 AliasEq {
1813 alias: AliasTy::Projection(projection), 1827 alias: AliasTy::Projection(projection),
1814 ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)) 1828 ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
@@ -1820,9 +1834,10 @@ impl Type {
1820 ); 1834 );
1821 1835
1822 match db.trait_solve(self.krate, goal)? { 1836 match db.trait_solve(self.krate, goal)? {
1823 Solution::Unique(SolutionVariables(subst)) => subst 1837 Solution::Unique(s) => s
1824 .value 1838 .value
1825 .interned(&Interner) 1839 .subst
1840 .as_slice(&Interner)
1826 .first() 1841 .first()
1827 .map(|ty| self.derived(ty.assert_ty_ref(&Interner).clone())), 1842 .map(|ty| self.derived(ty.assert_ty_ref(&Interner).clone())),
1828 Solution::Ambig(_) => None, 1843 Solution::Ambig(_) => None,
@@ -1875,7 +1890,7 @@ impl Type {
1875 1890
1876 fn go(ty: &Ty) -> bool { 1891 fn go(ty: &Ty) -> bool {
1877 match ty.kind(&Interner) { 1892 match ty.kind(&Interner) {
1878 TyKind::Unknown => true, 1893 TyKind::Error => true,
1879 1894
1880 TyKind::Adt(_, substs) 1895 TyKind::Adt(_, substs)
1881 | TyKind::AssociatedType(_, substs) 1896 | TyKind::AssociatedType(_, substs)
@@ -1886,9 +1901,10 @@ impl Type {
1886 substs.iter(&Interner).filter_map(|a| a.ty(&Interner)).any(go) 1901 substs.iter(&Interner).filter_map(|a| a.ty(&Interner)).any(go)
1887 } 1902 }
1888 1903
1889 TyKind::Array(ty) | TyKind::Slice(ty) | TyKind::Raw(_, ty) | TyKind::Ref(_, ty) => { 1904 TyKind::Array(ty, _)
1890 go(ty) 1905 | TyKind::Slice(ty)
1891 } 1906 | TyKind::Raw(_, ty)
1907 | TyKind::Ref(_, _, ty) => go(ty),
1892 1908
1893 TyKind::Scalar(_) 1909 TyKind::Scalar(_)
1894 | TyKind::Str 1910 | TyKind::Str
@@ -1899,7 +1915,9 @@ impl Type {
1899 | TyKind::Dyn(_) 1915 | TyKind::Dyn(_)
1900 | TyKind::Function(_) 1916 | TyKind::Function(_)
1901 | TyKind::Alias(_) 1917 | TyKind::Alias(_)
1902 | TyKind::ForeignType(_) => false, 1918 | TyKind::Foreign(_)
1919 | TyKind::Generator(..)
1920 | TyKind::GeneratorWitness(..) => false,
1903 } 1921 }
1904 } 1922 }
1905 } 1923 }
@@ -1915,7 +1933,7 @@ impl Type {
1915 .iter() 1933 .iter()
1916 .map(|(local_id, ty)| { 1934 .map(|(local_id, ty)| {
1917 let def = Field { parent: variant_id.into(), id: local_id }; 1935 let def = Field { parent: variant_id.into(), id: local_id };
1918 let ty = ty.clone().subst(substs); 1936 let ty = ty.clone().substitute(&Interner, substs);
1919 (def, self.derived(ty)) 1937 (def, self.derived(ty))
1920 }) 1938 })
1921 .collect() 1939 .collect()
@@ -1952,7 +1970,7 @@ impl Type {
1952 krate: Crate, 1970 krate: Crate,
1953 mut callback: impl FnMut(AssocItem) -> Option<T>, 1971 mut callback: impl FnMut(AssocItem) -> Option<T>,
1954 ) -> Option<T> { 1972 ) -> Option<T> {
1955 for krate in self.ty.def_crates(db, krate.id)? { 1973 for krate in def_crates(db, &self.ty, krate.id)? {
1956 let impls = db.inherent_impls_in_crate(krate); 1974 let impls = db.inherent_impls_in_crate(krate);
1957 1975
1958 for impl_def in impls.for_self_ty(&self.ty) { 1976 for impl_def in impls.for_self_ty(&self.ty) {
@@ -1969,9 +1987,9 @@ impl Type {
1969 pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ { 1987 pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ {
1970 self.ty 1988 self.ty
1971 .strip_references() 1989 .strip_references()
1972 .substs() 1990 .as_adt()
1973 .into_iter() 1991 .into_iter()
1974 .flat_map(|substs| substs.iter(&Interner)) 1992 .flat_map(|(_, substs)| substs.iter(&Interner))
1975 .filter_map(|arg| arg.ty(&Interner).cloned()) 1993 .filter_map(|arg| arg.ty(&Interner).cloned())
1976 .map(move |ty| self.derived(ty)) 1994 .map(move |ty| self.derived(ty))
1977 } 1995 }
@@ -2048,6 +2066,18 @@ impl Type {
2048 self.ty.dyn_trait().map(Into::into) 2066 self.ty.dyn_trait().map(Into::into)
2049 } 2067 }
2050 2068
2069 /// If a type can be represented as `dyn Trait`, returns all traits accessible via this type,
2070 /// or an empty iterator otherwise.
2071 pub fn applicable_inherent_traits<'a>(
2072 &'a self,
2073 db: &'a dyn HirDatabase,
2074 ) -> impl Iterator<Item = Trait> + 'a {
2075 self.autoderef(db)
2076 .filter_map(|derefed_type| derefed_type.ty.dyn_trait())
2077 .flat_map(move |dyn_trait_id| hir_ty::all_super_traits(db.upcast(), dyn_trait_id))
2078 .map(Trait::from)
2079 }
2080
2051 pub fn as_impl_traits(&self, db: &dyn HirDatabase) -> Option<Vec<Trait>> { 2081 pub fn as_impl_traits(&self, db: &dyn HirDatabase) -> Option<Vec<Trait>> {
2052 self.ty.impl_trait_bounds(db).map(|it| { 2082 self.ty.impl_trait_bounds(db).map(|it| {
2053 it.into_iter() 2083 it.into_iter()
@@ -2112,18 +2142,22 @@ impl Type {
2112 fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { 2142 fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) {
2113 let ty = type_.ty.strip_references(); 2143 let ty = type_.ty.strip_references();
2114 match ty.kind(&Interner) { 2144 match ty.kind(&Interner) {
2115 TyKind::Adt(..) => { 2145 TyKind::Adt(_, substs) => {
2116 cb(type_.derived(ty.clone())); 2146 cb(type_.derived(ty.clone()));
2147 walk_substs(db, type_, &substs, cb);
2117 } 2148 }
2118 TyKind::AssociatedType(..) => { 2149 TyKind::AssociatedType(_, substs) => {
2119 if let Some(_) = ty.associated_type_parent_trait(db) { 2150 if let Some(_) = ty.associated_type_parent_trait(db) {
2120 cb(type_.derived(ty.clone())); 2151 cb(type_.derived(ty.clone()));
2121 } 2152 }
2153 walk_substs(db, type_, &substs, cb);
2122 } 2154 }
2123 TyKind::OpaqueType(..) => { 2155 TyKind::OpaqueType(_, subst) => {
2124 if let Some(bounds) = ty.impl_trait_bounds(db) { 2156 if let Some(bounds) = ty.impl_trait_bounds(db) {
2125 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); 2157 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
2126 } 2158 }
2159
2160 walk_substs(db, type_, subst, cb);
2127 } 2161 }
2128 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => { 2162 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
2129 if let Some(bounds) = ty.impl_trait_bounds(db) { 2163 if let Some(bounds) = ty.impl_trait_bounds(db) {
@@ -2146,15 +2180,24 @@ impl Type {
2146 ); 2180 );
2147 } 2181 }
2148 2182
2149 TyKind::Ref(_, ty) | TyKind::Raw(_, ty) | TyKind::Array(ty) | TyKind::Slice(ty) => { 2183 TyKind::Ref(_, _, ty)
2184 | TyKind::Raw(_, ty)
2185 | TyKind::Array(ty, _)
2186 | TyKind::Slice(ty) => {
2150 walk_type(db, &type_.derived(ty.clone()), cb); 2187 walk_type(db, &type_.derived(ty.clone()), cb);
2151 } 2188 }
2152 2189
2190 TyKind::FnDef(_, substs)
2191 | TyKind::Tuple(_, substs)
2192 | TyKind::Closure(.., substs) => {
2193 walk_substs(db, type_, &substs, cb);
2194 }
2195 TyKind::Function(hir_ty::FnPointer { substitution, .. }) => {
2196 walk_substs(db, type_, &substitution.0, cb);
2197 }
2198
2153 _ => {} 2199 _ => {}
2154 } 2200 }
2155 if let Some(substs) = ty.substs() {
2156 walk_substs(db, type_, &substs, cb);
2157 }
2158 } 2201 }
2159 2202
2160 walk_type(db, self, &mut cb); 2203 walk_type(db, self, &mut cb);
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 3bf722d2a..62500602a 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -6,10 +6,11 @@ use std::{cell::RefCell, fmt, iter::successors};
6 6
7use base_db::{FileId, FileRange}; 7use base_db::{FileId, FileRange};
8use hir_def::{ 8use hir_def::{
9 body,
9 resolver::{self, HasResolver, Resolver, TypeNs}, 10 resolver::{self, HasResolver, Resolver, TypeNs},
10 AsMacroCall, FunctionId, TraitId, VariantId, 11 AsMacroCall, FunctionId, TraitId, VariantId,
11}; 12};
12use hir_expand::{hygiene::Hygiene, name::AsName, ExpansionInfo}; 13use hir_expand::{name::AsName, ExpansionInfo};
13use hir_ty::associated_type_shorthand_candidates; 14use hir_ty::associated_type_shorthand_candidates;
14use itertools::Itertools; 15use itertools::Itertools;
15use rustc_hash::{FxHashMap, FxHashSet}; 16use rustc_hash::{FxHashMap, FxHashSet};
@@ -494,9 +495,9 @@ impl<'db> SemanticsImpl<'db> {
494 fn resolve_method_call_as_callable(&self, call: &ast::MethodCallExpr) -> Option<Callable> { 495 fn resolve_method_call_as_callable(&self, call: &ast::MethodCallExpr) -> Option<Callable> {
495 // FIXME: this erases Substs 496 // FIXME: this erases Substs
496 let func = self.resolve_method_call(call)?; 497 let func = self.resolve_method_call(call)?;
497 let ty = self.db.value_ty(func.into()); 498 let (ty, _) = self.db.value_ty(func.into()).into_value_and_skipped_binders();
498 let resolver = self.analyze(call.syntax()).resolver; 499 let resolver = self.analyze(call.syntax()).resolver;
499 let ty = Type::new_with_resolver(self.db, &resolver, ty.value)?; 500 let ty = Type::new_with_resolver(self.db, &resolver, ty)?;
500 let mut res = ty.as_callable(self.db)?; 501 let mut res = ty.as_callable(self.db)?;
501 res.is_bound_method = true; 502 res.is_bound_method = true;
502 Some(res) 503 Some(res)
@@ -853,8 +854,8 @@ impl<'a> SemanticsScope<'a> {
853 /// Resolve a path as-if it was written at the given scope. This is 854 /// Resolve a path as-if it was written at the given scope. This is
854 /// necessary a heuristic, as it doesn't take hygiene into account. 855 /// necessary a heuristic, as it doesn't take hygiene into account.
855 pub fn speculative_resolve(&self, path: &ast::Path) -> Option<PathResolution> { 856 pub fn speculative_resolve(&self, path: &ast::Path) -> Option<PathResolution> {
856 let hygiene = Hygiene::new(self.db.upcast(), self.file_id); 857 let ctx = body::LowerCtx::new(self.db.upcast(), self.file_id);
857 let path = Path::from_src(path.clone(), &hygiene)?; 858 let path = Path::from_src(path.clone(), &ctx)?;
858 resolve_hir_path(self.db, &self.resolver, &path) 859 resolve_hir_path(self.db, &self.resolver, &path)
859 } 860 }
860} 861}
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index 8e9ea0a03..0895bd6f1 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -9,6 +9,7 @@ use std::{iter::once, sync::Arc};
9 9
10use hir_def::{ 10use hir_def::{
11 body::{ 11 body::{
12 self,
12 scope::{ExprScopes, ScopeId}, 13 scope::{ExprScopes, ScopeId},
13 Body, BodySourceMap, 14 Body, BodySourceMap,
14 }, 15 },
@@ -20,7 +21,7 @@ use hir_def::{
20use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile}; 21use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile};
21use hir_ty::{ 22use hir_ty::{
22 diagnostics::{record_literal_missing_fields, record_pattern_missing_fields}, 23 diagnostics::{record_literal_missing_fields, record_pattern_missing_fields},
23 InferenceResult, Substitution, TyLoweringContext, 24 InferenceResult, Interner, Substitution, TyExt, TyLoweringContext,
24}; 25};
25use syntax::{ 26use syntax::{
26 ast::{self, AstNode}, 27 ast::{self, AstNode},
@@ -161,14 +162,15 @@ impl SourceAnalyzer {
161 db: &dyn HirDatabase, 162 db: &dyn HirDatabase,
162 field: &ast::RecordExprField, 163 field: &ast::RecordExprField,
163 ) -> Option<(Field, Option<Local>)> { 164 ) -> Option<(Field, Option<Local>)> {
164 let expr_id = 165 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))?; 166 let expr = ast::Expr::from(record_expr);
167 let expr_id = self.body_source_map.as_ref()?.node_expr(InFile::new(self.file_id, &expr))?;
166 168
169 let local_name = field.field_name()?.as_name();
167 let local = if field.name_ref().is_some() { 170 let local = if field.name_ref().is_some() {
168 None 171 None
169 } else { 172 } else {
170 let local_name = field.field_name()?.as_name(); 173 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) { 174 match self.resolver.resolve_path_in_value_ns_fully(db.upcast(), &path) {
173 Some(ValueNs::LocalBinding(pat_id)) => { 175 Some(ValueNs::LocalBinding(pat_id)) => {
174 Some(Local { pat_id, parent: self.resolver.body_owner()? }) 176 Some(Local { pat_id, parent: self.resolver.body_owner()? })
@@ -176,18 +178,24 @@ impl SourceAnalyzer {
176 _ => None, 178 _ => None,
177 } 179 }
178 }; 180 };
179 let struct_field = self.infer.as_ref()?.record_field_resolution(expr_id)?; 181 let variant = self.infer.as_ref()?.variant_resolution_for_expr(expr_id)?;
180 Some((struct_field.into(), local)) 182 let variant_data = variant.variant_data(db.upcast());
183 let field = FieldId { parent: variant, local_id: variant_data.field(&local_name)? };
184 Some((field.into(), local))
181 } 185 }
182 186
183 pub(crate) fn resolve_record_pat_field( 187 pub(crate) fn resolve_record_pat_field(
184 &self, 188 &self,
185 _db: &dyn HirDatabase, 189 db: &dyn HirDatabase,
186 field: &ast::RecordPatField, 190 field: &ast::RecordPatField,
187 ) -> Option<Field> { 191 ) -> Option<Field> {
188 let pat_id = self.pat_id(&field.pat()?)?; 192 let field_name = field.field_name()?.as_name();
189 let struct_field = self.infer.as_ref()?.record_pat_field_resolution(pat_id)?; 193 let record_pat = ast::RecordPat::cast(field.syntax().parent().and_then(|p| p.parent())?)?;
190 Some(struct_field.into()) 194 let pat_id = self.pat_id(&record_pat.into())?;
195 let variant = self.infer.as_ref()?.variant_resolution_for_pat(pat_id)?;
196 let variant_data = variant.variant_data(db.upcast());
197 let field = FieldId { parent: variant, local_id: variant_data.field(&field_name)? };
198 Some(field.into())
191 } 199 }
192 200
193 pub(crate) fn resolve_macro_call( 201 pub(crate) fn resolve_macro_call(
@@ -195,8 +203,8 @@ impl SourceAnalyzer {
195 db: &dyn HirDatabase, 203 db: &dyn HirDatabase,
196 macro_call: InFile<&ast::MacroCall>, 204 macro_call: InFile<&ast::MacroCall>,
197 ) -> Option<MacroDef> { 205 ) -> Option<MacroDef> {
198 let hygiene = Hygiene::new(db.upcast(), macro_call.file_id); 206 let ctx = body::LowerCtx::new(db.upcast(), macro_call.file_id);
199 let path = macro_call.value.path().and_then(|ast| Path::from_src(ast, &hygiene))?; 207 let path = macro_call.value.path().and_then(|ast| Path::from_src(ast, &ctx))?;
200 self.resolver.resolve_path_as_macro(db.upcast(), path.mod_path()).map(|it| it.into()) 208 self.resolver.resolve_path_as_macro(db.upcast(), path.mod_path()).map(|it| it.into())
201 } 209 }
202 210
@@ -274,7 +282,9 @@ impl SourceAnalyzer {
274 } 282 }
275 283
276 // This must be a normal source file rather than macro file. 284 // This must be a normal source file rather than macro file.
277 let hir_path = Path::from_src(path.clone(), &Hygiene::new(db.upcast(), self.file_id))?; 285 let hygiene = Hygiene::new(db.upcast(), self.file_id);
286 let ctx = body::LowerCtx::with_hygiene(&hygiene);
287 let hir_path = Path::from_src(path.clone(), &ctx)?;
278 288
279 // Case where path is a qualifier of another path, e.g. foo::bar::Baz where we 289 // Case where path is a qualifier of another path, e.g. foo::bar::Baz where we
280 // trying to resolve foo::bar. 290 // trying to resolve foo::bar.
@@ -299,7 +309,7 @@ impl SourceAnalyzer {
299 let infer = self.infer.as_ref()?; 309 let infer = self.infer.as_ref()?;
300 310
301 let expr_id = self.expr_id(db, &literal.clone().into())?; 311 let expr_id = self.expr_id(db, &literal.clone().into())?;
302 let substs = infer.type_of_expr[expr_id].substs()?; 312 let substs = infer.type_of_expr[expr_id].as_adt()?.1;
303 313
304 let (variant, missing_fields, _exhaustive) = 314 let (variant, missing_fields, _exhaustive) =
305 record_literal_missing_fields(db, infer, expr_id, &body[expr_id])?; 315 record_literal_missing_fields(db, infer, expr_id, &body[expr_id])?;
@@ -317,7 +327,7 @@ impl SourceAnalyzer {
317 let infer = self.infer.as_ref()?; 327 let infer = self.infer.as_ref()?;
318 328
319 let pat_id = self.pat_id(&pattern.clone().into())?; 329 let pat_id = self.pat_id(&pattern.clone().into())?;
320 let substs = infer.type_of_pat[pat_id].substs()?; 330 let substs = infer.type_of_pat[pat_id].as_adt()?.1;
321 331
322 let (variant, missing_fields, _exhaustive) = 332 let (variant, missing_fields, _exhaustive) =
323 record_pattern_missing_fields(db, infer, pat_id, &body[pat_id])?; 333 record_pattern_missing_fields(db, infer, pat_id, &body[pat_id])?;
@@ -339,7 +349,7 @@ impl SourceAnalyzer {
339 .into_iter() 349 .into_iter()
340 .map(|local_id| { 350 .map(|local_id| {
341 let field = FieldId { parent: variant, local_id }; 351 let field = FieldId { parent: variant, local_id };
342 let ty = field_types[local_id].clone().subst(substs); 352 let ty = field_types[local_id].clone().substitute(&Interner, substs);
343 (field.into(), Type::new_with_resolver_inner(db, krate, &self.resolver, ty)) 353 (field.into(), Type::new_with_resolver_inner(db, krate, &self.resolver, ty))
344 }) 354 })
345 .collect() 355 .collect()