diff options
Diffstat (limited to 'crates/hir')
-rw-r--r-- | crates/hir/src/lib.rs | 98 | ||||
-rw-r--r-- | crates/hir/src/source_analyzer.rs | 33 |
2 files changed, 84 insertions, 47 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 003821981..eba46a056 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -53,13 +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 | subst_prefix, | ||
58 | traits::FnTrait, | 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, Solution, | 61 | DebruijnIndex, InEnvironment, Interner, QuantifiedWhereClause, Scalar, Solution, Substitution, |
61 | SolutionVariables, Substitution, TraitEnvironment, Ty, TyBuilder, TyDefId, TyKind, | 62 | TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyDefId, TyExt, TyKind, TyVariableKind, |
62 | TyVariableKind, WhereClause, | 63 | WhereClause, |
63 | }; | 64 | }; |
64 | use itertools::Itertools; | 65 | use itertools::Itertools; |
65 | use rustc_hash::FxHashSet; | 66 | use rustc_hash::FxHashSet; |
@@ -1503,7 +1504,7 @@ impl TypeParam { | |||
1503 | let krate = self.id.parent.module(db.upcast()).krate(); | 1504 | let krate = self.id.parent.module(db.upcast()).krate(); |
1504 | let ty = params.get(local_idx)?.clone(); | 1505 | let ty = params.get(local_idx)?.clone(); |
1505 | let subst = TyBuilder::type_params_subst(db, self.id.parent); | 1506 | let subst = TyBuilder::type_params_subst(db, self.id.parent); |
1506 | let ty = ty.substitute(&Interner, &subst.prefix(local_idx)); | 1507 | let ty = ty.substitute(&Interner, &subst_prefix(&subst, local_idx)); |
1507 | Some(Type::new_with_resolver_inner(db, krate, &resolver, ty)) | 1508 | Some(Type::new_with_resolver_inner(db, krate, &resolver, ty)) |
1508 | } | 1509 | } |
1509 | } | 1510 | } |
@@ -1568,7 +1569,7 @@ impl Impl { | |||
1568 | } | 1569 | } |
1569 | 1570 | ||
1570 | 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> { |
1571 | let def_crates = match ty.def_crates(db, krate) { | 1572 | let def_crates = match def_crates(db, &ty, krate) { |
1572 | Some(def_crates) => def_crates, | 1573 | Some(def_crates) => def_crates, |
1573 | None => return Vec::new(), | 1574 | None => return Vec::new(), |
1574 | }; | 1575 | }; |
@@ -1579,11 +1580,24 @@ impl Impl { | |||
1579 | 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)) |
1580 | }; | 1581 | }; |
1581 | 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 | |||
1582 | let mut all = Vec::new(); | 1590 | let mut all = Vec::new(); |
1583 | def_crates.iter().for_each(|&id| { | 1591 | def_crates.iter().for_each(|&id| { |
1584 | 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 | ) | ||
1585 | }); | 1600 | }); |
1586 | let fp = TyFingerprint::for_impl(&ty); | ||
1587 | for id in def_crates | 1601 | for id in def_crates |
1588 | .iter() | 1602 | .iter() |
1589 | .flat_map(|&id| Crate { id }.transitive_reverse_dependencies(db)) | 1603 | .flat_map(|&id| Crate { id }.transitive_reverse_dependencies(db)) |
@@ -1591,13 +1605,12 @@ impl Impl { | |||
1591 | .chain(def_crates.iter().copied()) | 1605 | .chain(def_crates.iter().copied()) |
1592 | .unique() | 1606 | .unique() |
1593 | { | 1607 | { |
1594 | match fp { | 1608 | all.extend( |
1595 | Some(fp) => all.extend( | 1609 | db.trait_impls_in_crate(id) |
1596 | db.trait_impls_in_crate(id).for_self_ty(fp).map(Self::from).filter(filter), | 1610 | .for_self_ty_without_blanket_impls(fp) |
1597 | ), | 1611 | .map(Self::from) |
1598 | None => all | 1612 | .filter(filter), |
1599 | .extend(db.trait_impls_in_crate(id).all_impls().map(Self::from).filter(filter)), | 1613 | ); |
1600 | } | ||
1601 | } | 1614 | } |
1602 | all | 1615 | all |
1603 | } | 1616 | } |
@@ -1790,7 +1803,7 @@ impl Type { | |||
1790 | .build(); | 1803 | .build(); |
1791 | 1804 | ||
1792 | let goal = Canonical { | 1805 | let goal = Canonical { |
1793 | 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)), |
1794 | binders: CanonicalVarKinds::empty(&Interner), | 1807 | binders: CanonicalVarKinds::empty(&Interner), |
1795 | }; | 1808 | }; |
1796 | 1809 | ||
@@ -1807,9 +1820,9 @@ impl Type { | |||
1807 | .push(self.ty.clone()) | 1820 | .push(self.ty.clone()) |
1808 | .fill(args.iter().map(|t| t.ty.clone())) | 1821 | .fill(args.iter().map(|t| t.ty.clone())) |
1809 | .build(); | 1822 | .build(); |
1810 | let goal = Canonical::new( | 1823 | let goal = hir_ty::make_canonical( |
1811 | InEnvironment::new( | 1824 | InEnvironment::new( |
1812 | self.env.env.clone(), | 1825 | &self.env.env, |
1813 | AliasEq { | 1826 | AliasEq { |
1814 | alias: AliasTy::Projection(projection), | 1827 | alias: AliasTy::Projection(projection), |
1815 | ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)) | 1828 | ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)) |
@@ -1821,9 +1834,10 @@ impl Type { | |||
1821 | ); | 1834 | ); |
1822 | 1835 | ||
1823 | match db.trait_solve(self.krate, goal)? { | 1836 | match db.trait_solve(self.krate, goal)? { |
1824 | Solution::Unique(SolutionVariables(subst)) => subst | 1837 | Solution::Unique(s) => s |
1825 | .value | 1838 | .value |
1826 | .interned() | 1839 | .subst |
1840 | .as_slice(&Interner) | ||
1827 | .first() | 1841 | .first() |
1828 | .map(|ty| self.derived(ty.assert_ty_ref(&Interner).clone())), | 1842 | .map(|ty| self.derived(ty.assert_ty_ref(&Interner).clone())), |
1829 | Solution::Ambig(_) => None, | 1843 | Solution::Ambig(_) => None, |
@@ -1887,9 +1901,10 @@ impl Type { | |||
1887 | substs.iter(&Interner).filter_map(|a| a.ty(&Interner)).any(go) | 1901 | substs.iter(&Interner).filter_map(|a| a.ty(&Interner)).any(go) |
1888 | } | 1902 | } |
1889 | 1903 | ||
1890 | TyKind::Array(ty) | TyKind::Slice(ty) | TyKind::Raw(_, ty) | TyKind::Ref(_, ty) => { | 1904 | TyKind::Array(ty, _) |
1891 | go(ty) | 1905 | | TyKind::Slice(ty) |
1892 | } | 1906 | | TyKind::Raw(_, ty) |
1907 | | TyKind::Ref(_, _, ty) => go(ty), | ||
1893 | 1908 | ||
1894 | TyKind::Scalar(_) | 1909 | TyKind::Scalar(_) |
1895 | | TyKind::Str | 1910 | | TyKind::Str |
@@ -1900,7 +1915,9 @@ impl Type { | |||
1900 | | TyKind::Dyn(_) | 1915 | | TyKind::Dyn(_) |
1901 | | TyKind::Function(_) | 1916 | | TyKind::Function(_) |
1902 | | TyKind::Alias(_) | 1917 | | TyKind::Alias(_) |
1903 | | TyKind::Foreign(_) => false, | 1918 | | TyKind::Foreign(_) |
1919 | | TyKind::Generator(..) | ||
1920 | | TyKind::GeneratorWitness(..) => false, | ||
1904 | } | 1921 | } |
1905 | } | 1922 | } |
1906 | } | 1923 | } |
@@ -1953,7 +1970,7 @@ impl Type { | |||
1953 | krate: Crate, | 1970 | krate: Crate, |
1954 | mut callback: impl FnMut(AssocItem) -> Option<T>, | 1971 | mut callback: impl FnMut(AssocItem) -> Option<T>, |
1955 | ) -> Option<T> { | 1972 | ) -> Option<T> { |
1956 | for krate in self.ty.def_crates(db, krate.id)? { | 1973 | for krate in def_crates(db, &self.ty, krate.id)? { |
1957 | let impls = db.inherent_impls_in_crate(krate); | 1974 | let impls = db.inherent_impls_in_crate(krate); |
1958 | 1975 | ||
1959 | for impl_def in impls.for_self_ty(&self.ty) { | 1976 | for impl_def in impls.for_self_ty(&self.ty) { |
@@ -1970,9 +1987,9 @@ impl Type { | |||
1970 | pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ { | 1987 | pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ { |
1971 | self.ty | 1988 | self.ty |
1972 | .strip_references() | 1989 | .strip_references() |
1973 | .substs() | 1990 | .as_adt() |
1974 | .into_iter() | 1991 | .into_iter() |
1975 | .flat_map(|substs| substs.iter(&Interner)) | 1992 | .flat_map(|(_, substs)| substs.iter(&Interner)) |
1976 | .filter_map(|arg| arg.ty(&Interner).cloned()) | 1993 | .filter_map(|arg| arg.ty(&Interner).cloned()) |
1977 | .map(move |ty| self.derived(ty)) | 1994 | .map(move |ty| self.derived(ty)) |
1978 | } | 1995 | } |
@@ -2113,18 +2130,22 @@ impl Type { | |||
2113 | fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { | 2130 | fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { |
2114 | let ty = type_.ty.strip_references(); | 2131 | let ty = type_.ty.strip_references(); |
2115 | match ty.kind(&Interner) { | 2132 | match ty.kind(&Interner) { |
2116 | TyKind::Adt(..) => { | 2133 | TyKind::Adt(_, substs) => { |
2117 | cb(type_.derived(ty.clone())); | 2134 | cb(type_.derived(ty.clone())); |
2135 | walk_substs(db, type_, &substs, cb); | ||
2118 | } | 2136 | } |
2119 | TyKind::AssociatedType(..) => { | 2137 | TyKind::AssociatedType(_, substs) => { |
2120 | if let Some(_) = ty.associated_type_parent_trait(db) { | 2138 | if let Some(_) = ty.associated_type_parent_trait(db) { |
2121 | cb(type_.derived(ty.clone())); | 2139 | cb(type_.derived(ty.clone())); |
2122 | } | 2140 | } |
2141 | walk_substs(db, type_, &substs, cb); | ||
2123 | } | 2142 | } |
2124 | TyKind::OpaqueType(..) => { | 2143 | TyKind::OpaqueType(_, subst) => { |
2125 | if let Some(bounds) = ty.impl_trait_bounds(db) { | 2144 | if let Some(bounds) = ty.impl_trait_bounds(db) { |
2126 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); | 2145 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); |
2127 | } | 2146 | } |
2147 | |||
2148 | walk_substs(db, type_, subst, cb); | ||
2128 | } | 2149 | } |
2129 | TyKind::Alias(AliasTy::Opaque(opaque_ty)) => { | 2150 | TyKind::Alias(AliasTy::Opaque(opaque_ty)) => { |
2130 | if let Some(bounds) = ty.impl_trait_bounds(db) { | 2151 | if let Some(bounds) = ty.impl_trait_bounds(db) { |
@@ -2147,15 +2168,24 @@ impl Type { | |||
2147 | ); | 2168 | ); |
2148 | } | 2169 | } |
2149 | 2170 | ||
2150 | TyKind::Ref(_, ty) | TyKind::Raw(_, ty) | TyKind::Array(ty) | TyKind::Slice(ty) => { | 2171 | TyKind::Ref(_, _, ty) |
2172 | | TyKind::Raw(_, ty) | ||
2173 | | TyKind::Array(ty, _) | ||
2174 | | TyKind::Slice(ty) => { | ||
2151 | walk_type(db, &type_.derived(ty.clone()), cb); | 2175 | walk_type(db, &type_.derived(ty.clone()), cb); |
2152 | } | 2176 | } |
2153 | 2177 | ||
2178 | TyKind::FnDef(_, substs) | ||
2179 | | TyKind::Tuple(_, substs) | ||
2180 | | TyKind::Closure(.., substs) => { | ||
2181 | walk_substs(db, type_, &substs, cb); | ||
2182 | } | ||
2183 | TyKind::Function(hir_ty::FnPointer { substitution, .. }) => { | ||
2184 | walk_substs(db, type_, &substitution.0, cb); | ||
2185 | } | ||
2186 | |||
2154 | _ => {} | 2187 | _ => {} |
2155 | } | 2188 | } |
2156 | if let Some(substs) = ty.substs() { | ||
2157 | walk_substs(db, type_, &substs, cb); | ||
2158 | } | ||
2159 | } | 2189 | } |
2160 | 2190 | ||
2161 | walk_type(db, self, &mut cb); | 2191 | walk_type(db, self, &mut cb); |
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index 4ce1c2080..847d2537d 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs | |||
@@ -20,7 +20,7 @@ use hir_def::{ | |||
20 | use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile}; | 20 | use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile}; |
21 | use hir_ty::{ | 21 | use hir_ty::{ |
22 | diagnostics::{record_literal_missing_fields, record_pattern_missing_fields}, | 22 | diagnostics::{record_literal_missing_fields, record_pattern_missing_fields}, |
23 | InferenceResult, Interner, Substitution, TyLoweringContext, | 23 | InferenceResult, Interner, Substitution, TyExt, TyLoweringContext, |
24 | }; | 24 | }; |
25 | use syntax::{ | 25 | use 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])?; |