diff options
Diffstat (limited to 'crates/hir')
-rw-r--r-- | crates/hir/Cargo.toml | 2 | ||||
-rw-r--r-- | crates/hir/src/display.rs | 4 | ||||
-rw-r--r-- | crates/hir/src/lib.rs | 121 | ||||
-rw-r--r-- | crates/hir/src/semantics.rs | 11 | ||||
-rw-r--r-- | crates/hir/src/source_analyzer.rs | 44 |
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 | |||
13 | log = "0.4.8" | 13 | log = "0.4.8" |
14 | rustc-hash = "1.1.0" | 14 | rustc-hash = "1.1.0" |
15 | either = "1.5.3" | 15 | either = "1.5.3" |
16 | arrayvec = "0.6" | 16 | arrayvec = "0.7" |
17 | itertools = "0.10.0" | 17 | itertools = "0.10.0" |
18 | smallvec = "1.4.0" | 18 | smallvec = "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 | }; |
12 | use hir_ty::Interner; | ||
12 | use syntax::ast::{self, NameOwner}; | 13 | use syntax::ast::{self, NameOwner}; |
13 | 14 | ||
14 | use crate::{ | 15 | use crate::{ |
@@ -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::{ | |||
53 | use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind}; | 53 | use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind}; |
54 | use hir_ty::{ | 54 | use 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 | }; |
63 | use itertools::Itertools; | 65 | use itertools::Itertools; |
64 | use rustc_hash::FxHashSet; | 66 | use 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); | |||
701 | impl Adt { | 703 | impl Adt { |
702 | pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { | 704 | pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { |
703 | let subst = db.generic_defaults(self.into()); | 705 | let subst = db.generic_defaults(self.into()); |
704 | subst.iter().any(|ty| ty.value.is_unknown()) | 706 | subst.iter().any(|ty| ty.skip_binders().is_unknown()) |
705 | } | 707 | } |
706 | 708 | ||
707 | /// Turns this ADT into a type. Any type parameters of the ADT will be | 709 | /// Turns this ADT into a type. Any type parameters of the ADT will be |
@@ -1088,7 +1090,7 @@ pub struct TypeAlias { | |||
1088 | impl TypeAlias { | 1090 | impl TypeAlias { |
1089 | pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { | 1091 | pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { |
1090 | let subst = db.generic_defaults(self.id.into()); | 1092 | let subst = db.generic_defaults(self.id.into()); |
1091 | subst.iter().any(|ty| ty.value.is_unknown()) | 1093 | subst.iter().any(|ty| ty.skip_binders().is_unknown()) |
1092 | } | 1094 | } |
1093 | 1095 | ||
1094 | pub fn module(self, db: &dyn HirDatabase) -> Module { | 1096 | pub fn module(self, db: &dyn HirDatabase) -> Module { |
@@ -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 | ||
7 | use base_db::{FileId, FileRange}; | 7 | use base_db::{FileId, FileRange}; |
8 | use hir_def::{ | 8 | use 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 | }; |
12 | use hir_expand::{hygiene::Hygiene, name::AsName, ExpansionInfo}; | 13 | use hir_expand::{name::AsName, ExpansionInfo}; |
13 | use hir_ty::associated_type_shorthand_candidates; | 14 | use hir_ty::associated_type_shorthand_candidates; |
14 | use itertools::Itertools; | 15 | use itertools::Itertools; |
15 | use rustc_hash::{FxHashMap, FxHashSet}; | 16 | use 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 | ||
10 | use hir_def::{ | 10 | use 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::{ | |||
20 | use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile}; | 21 | use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile}; |
21 | use hir_ty::{ | 22 | use 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 | }; |
25 | use syntax::{ | 26 | use 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() |