aboutsummaryrefslogtreecommitdiff
path: root/crates/hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir/src')
-rw-r--r--crates/hir/src/lib.rs98
-rw-r--r--crates/hir/src/source_analyzer.rs33
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::{
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 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};
64use itertools::Itertools; 65use itertools::Itertools;
65use rustc_hash::FxHashSet; 66use 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::{
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, Interner, Substitution, TyLoweringContext, 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])?;