aboutsummaryrefslogtreecommitdiff
path: root/crates/hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir/src')
-rw-r--r--crates/hir/src/display.rs441
-rw-r--r--crates/hir/src/lib.rs256
-rw-r--r--crates/hir/src/semantics.rs8
-rw-r--r--crates/hir/src/semantics/source_to_def.rs22
-rw-r--r--crates/hir/src/source_analyzer.rs5
5 files changed, 637 insertions, 95 deletions
diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs
new file mode 100644
index 000000000..44cdcc296
--- /dev/null
+++ b/crates/hir/src/display.rs
@@ -0,0 +1,441 @@
1//! HirDisplay implementations for various hir types.
2use hir_def::{
3 adt::VariantData,
4 generics::{TypeParamProvenance, WherePredicate, WherePredicateTypeTarget},
5 type_ref::{TypeBound, TypeRef},
6 AdtId, GenericDefId,
7};
8use hir_ty::display::{
9 write_bounds_like_dyn_trait_with_prefix, write_visibility, HirDisplay, HirDisplayError,
10 HirFormatter,
11};
12use syntax::ast::{self, NameOwner};
13
14use crate::{
15 Const, ConstParam, Enum, Field, Function, HasVisibility, Module, Static, Struct, Substs, Trait,
16 Type, TypeAlias, TypeParam, Union, Variant,
17};
18
19impl HirDisplay for Function {
20 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
21 let data = f.db.function_data(self.id);
22 write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
23 let qual = &data.qualifier;
24 if qual.is_default {
25 write!(f, "default ")?;
26 }
27 if qual.is_const {
28 write!(f, "const ")?;
29 }
30 if qual.is_async {
31 write!(f, "async ")?;
32 }
33 if qual.is_unsafe {
34 write!(f, "unsafe ")?;
35 }
36 if let Some(abi) = &qual.abi {
37 // FIXME: String escape?
38 write!(f, "extern \"{}\" ", abi)?;
39 }
40 write!(f, "fn {}", data.name)?;
41
42 write_generic_params(GenericDefId::FunctionId(self.id), f)?;
43
44 write!(f, "(")?;
45
46 let write_self_param = |ty: &TypeRef, f: &mut HirFormatter| match ty {
47 TypeRef::Path(p) if p.is_self_type() => write!(f, "self"),
48 TypeRef::Reference(inner, lifetime, mut_) if matches!(&**inner,TypeRef::Path(p) if p.is_self_type()) =>
49 {
50 write!(f, "&")?;
51 if let Some(lifetime) = lifetime {
52 write!(f, "{} ", lifetime.name)?;
53 }
54 if let hir_def::type_ref::Mutability::Mut = mut_ {
55 write!(f, "mut ")?;
56 }
57 write!(f, "self")
58 }
59 _ => {
60 write!(f, "self: ")?;
61 ty.hir_fmt(f)
62 }
63 };
64
65 let mut first = true;
66 for (param, type_ref) in self.assoc_fn_params(f.db).into_iter().zip(&data.params) {
67 if !first {
68 write!(f, ", ")?;
69 } else {
70 first = false;
71 if data.has_self_param {
72 write_self_param(type_ref, f)?;
73 continue;
74 }
75 }
76 match param.pattern_source(f.db) {
77 Some(ast::Pat::IdentPat(p)) if p.name().is_some() => {
78 write!(f, "{}: ", p.name().unwrap())?
79 }
80 _ => write!(f, "_: ")?,
81 }
82 // FIXME: Use resolved `param.ty` or raw `type_ref`?
83 // The former will ignore lifetime arguments currently.
84 type_ref.hir_fmt(f)?;
85 }
86 write!(f, ")")?;
87
88 // `FunctionData::ret_type` will be `::core::future::Future<Output = ...>` for async fns.
89 // Use ugly pattern match to strip the Future trait.
90 // Better way?
91 let ret_type = if !qual.is_async {
92 &data.ret_type
93 } else {
94 match &data.ret_type {
95 TypeRef::ImplTrait(bounds) => match &bounds[0] {
96 TypeBound::Path(path) => {
97 path.segments().iter().last().unwrap().args_and_bindings.unwrap().bindings
98 [0]
99 .type_ref
100 .as_ref()
101 .unwrap()
102 }
103 _ => panic!("Async fn ret_type should be impl Future"),
104 },
105 _ => panic!("Async fn ret_type should be impl Future"),
106 }
107 };
108
109 match ret_type {
110 TypeRef::Tuple(tup) if tup.is_empty() => {}
111 ty => {
112 write!(f, " -> ")?;
113 ty.hir_fmt(f)?;
114 }
115 }
116
117 write_where_clause(GenericDefId::FunctionId(self.id), f)?;
118
119 Ok(())
120 }
121}
122
123impl HirDisplay for Struct {
124 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
125 write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
126 write!(f, "struct ")?;
127 write!(f, "{}", self.name(f.db))?;
128 let def_id = GenericDefId::AdtId(AdtId::StructId(self.id));
129 write_generic_params(def_id, f)?;
130 write_where_clause(def_id, f)?;
131 Ok(())
132 }
133}
134
135impl HirDisplay for Enum {
136 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
137 write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
138 write!(f, "enum ")?;
139 write!(f, "{}", self.name(f.db))?;
140 let def_id = GenericDefId::AdtId(AdtId::EnumId(self.id));
141 write_generic_params(def_id, f)?;
142 write_where_clause(def_id, f)?;
143 Ok(())
144 }
145}
146
147impl HirDisplay for Union {
148 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
149 write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
150 write!(f, "union ")?;
151 write!(f, "{}", self.name(f.db))?;
152 let def_id = GenericDefId::AdtId(AdtId::UnionId(self.id));
153 write_generic_params(def_id, f)?;
154 write_where_clause(def_id, f)?;
155 Ok(())
156 }
157}
158
159impl HirDisplay for Field {
160 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
161 write_visibility(self.parent.module(f.db).id, self.visibility(f.db), f)?;
162 write!(f, "{}: ", self.name(f.db))?;
163 self.signature_ty(f.db).hir_fmt(f)
164 }
165}
166
167impl HirDisplay for Variant {
168 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
169 write!(f, "{}", self.name(f.db))?;
170 let data = self.variant_data(f.db);
171 match &*data {
172 VariantData::Unit => {}
173 VariantData::Tuple(fields) => {
174 write!(f, "(")?;
175 let mut first = true;
176 for (_, field) in fields.iter() {
177 if first {
178 first = false;
179 } else {
180 write!(f, ", ")?;
181 }
182 // Enum variant fields must be pub.
183 field.type_ref.hir_fmt(f)?;
184 }
185 write!(f, ")")?;
186 }
187 VariantData::Record(fields) => {
188 write!(f, " {{")?;
189 let mut first = true;
190 for (_, field) in fields.iter() {
191 if first {
192 first = false;
193 write!(f, " ")?;
194 } else {
195 write!(f, ", ")?;
196 }
197 // Enum variant fields must be pub.
198 write!(f, "{}: ", field.name)?;
199 field.type_ref.hir_fmt(f)?;
200 }
201 write!(f, " }}")?;
202 }
203 }
204 Ok(())
205 }
206}
207
208impl HirDisplay for Type {
209 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
210 self.ty.value.hir_fmt(f)
211 }
212}
213
214impl HirDisplay for TypeParam {
215 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
216 write!(f, "{}", self.name(f.db))?;
217 let bounds = f.db.generic_predicates_for_param(self.id);
218 let substs = Substs::type_params(f.db, self.id.parent);
219 let predicates = bounds.iter().cloned().map(|b| b.subst(&substs)).collect::<Vec<_>>();
220 if !(predicates.is_empty() || f.omit_verbose_types()) {
221 write_bounds_like_dyn_trait_with_prefix(":", &predicates, f)?;
222 }
223 Ok(())
224 }
225}
226
227impl HirDisplay for ConstParam {
228 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
229 write!(f, "const {}: ", self.name(f.db))?;
230 self.ty(f.db).hir_fmt(f)
231 }
232}
233
234fn write_generic_params(def: GenericDefId, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
235 let params = f.db.generic_params(def);
236 if params.lifetimes.is_empty()
237 && params.consts.is_empty()
238 && params
239 .types
240 .iter()
241 .all(|(_, param)| !matches!(param.provenance, TypeParamProvenance::TypeParamList))
242 {
243 return Ok(());
244 }
245 write!(f, "<")?;
246
247 let mut first = true;
248 let mut delim = |f: &mut HirFormatter| {
249 if first {
250 first = false;
251 Ok(())
252 } else {
253 write!(f, ", ")
254 }
255 };
256 for (_, lifetime) in params.lifetimes.iter() {
257 delim(f)?;
258 write!(f, "{}", lifetime.name)?;
259 }
260 for (_, ty) in params.types.iter() {
261 if ty.provenance != TypeParamProvenance::TypeParamList {
262 continue;
263 }
264 if let Some(name) = &ty.name {
265 delim(f)?;
266 write!(f, "{}", name)?;
267 if let Some(default) = &ty.default {
268 write!(f, " = ")?;
269 default.hir_fmt(f)?;
270 }
271 }
272 }
273 for (_, konst) in params.consts.iter() {
274 delim(f)?;
275 write!(f, "const {}: ", konst.name)?;
276 konst.ty.hir_fmt(f)?;
277 }
278
279 write!(f, ">")?;
280 Ok(())
281}
282
283fn write_where_clause(def: GenericDefId, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
284 let params = f.db.generic_params(def);
285 if params.where_predicates.is_empty() {
286 return Ok(());
287 }
288
289 let write_target = |target: &WherePredicateTypeTarget, f: &mut HirFormatter| match target {
290 WherePredicateTypeTarget::TypeRef(ty) => ty.hir_fmt(f),
291 WherePredicateTypeTarget::TypeParam(id) => match &params.types[*id].name {
292 Some(name) => write!(f, "{}", name),
293 None => write!(f, "{{unnamed}}"),
294 },
295 };
296
297 write!(f, "\nwhere")?;
298
299 for (pred_idx, pred) in params.where_predicates.iter().enumerate() {
300 let prev_pred =
301 if pred_idx == 0 { None } else { Some(&params.where_predicates[pred_idx - 1]) };
302
303 let new_predicate = |f: &mut HirFormatter| {
304 write!(f, "{}", if pred_idx == 0 { "\n " } else { ",\n " })
305 };
306
307 match pred {
308 WherePredicate::TypeBound { target, bound } => {
309 if matches!(prev_pred, Some(WherePredicate::TypeBound { target: target_, .. }) if target_ == target)
310 {
311 write!(f, " + ")?;
312 } else {
313 new_predicate(f)?;
314 write_target(target, f)?;
315 write!(f, ": ")?;
316 }
317 bound.hir_fmt(f)?;
318 }
319 WherePredicate::Lifetime { target, bound } => {
320 if matches!(prev_pred, Some(WherePredicate::Lifetime { target: target_, .. }) if target_ == target)
321 {
322 write!(f, " + {}", bound.name)?;
323 } else {
324 new_predicate(f)?;
325 write!(f, "{}: {}", target.name, bound.name)?;
326 }
327 }
328 WherePredicate::ForLifetime { lifetimes, target, bound } => {
329 if matches!(
330 prev_pred,
331 Some(WherePredicate::ForLifetime { lifetimes: lifetimes_, target: target_, .. })
332 if lifetimes_ == lifetimes && target_ == target,
333 ) {
334 write!(f, " + ")?;
335 } else {
336 new_predicate(f)?;
337 write!(f, "for<")?;
338 for (idx, lifetime) in lifetimes.iter().enumerate() {
339 if idx != 0 {
340 write!(f, ", ")?;
341 }
342 write!(f, "{}", lifetime)?;
343 }
344 write!(f, "> ")?;
345 write_target(target, f)?;
346 write!(f, ": ")?;
347 }
348 bound.hir_fmt(f)?;
349 }
350 }
351 }
352
353 // End of final predicate. There must be at least one predicate here.
354 write!(f, ",")?;
355
356 Ok(())
357}
358
359impl HirDisplay for Const {
360 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
361 write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
362 let data = f.db.const_data(self.id);
363 write!(f, "const ")?;
364 match &data.name {
365 Some(name) => write!(f, "{}: ", name)?,
366 None => write!(f, "_: ")?,
367 }
368 data.type_ref.hir_fmt(f)?;
369 Ok(())
370 }
371}
372
373impl HirDisplay for Static {
374 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
375 write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
376 let data = f.db.static_data(self.id);
377 write!(f, "static ")?;
378 if data.mutable {
379 write!(f, "mut ")?;
380 }
381 match &data.name {
382 Some(name) => write!(f, "{}: ", name)?,
383 None => write!(f, "_: ")?,
384 }
385 data.type_ref.hir_fmt(f)?;
386 Ok(())
387 }
388}
389
390impl HirDisplay for Trait {
391 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
392 write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
393 let data = f.db.trait_data(self.id);
394 if data.is_unsafe {
395 write!(f, "unsafe ")?;
396 }
397 if data.is_auto {
398 write!(f, "auto ")?;
399 }
400 write!(f, "trait {}", data.name)?;
401 let def_id = GenericDefId::TraitId(self.id);
402 write_generic_params(def_id, f)?;
403 if !data.bounds.is_empty() {
404 write!(f, ": ")?;
405 f.write_joined(&*data.bounds, " + ")?;
406 }
407 write_where_clause(def_id, f)?;
408 Ok(())
409 }
410}
411
412impl HirDisplay for TypeAlias {
413 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
414 write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
415 let data = f.db.type_alias_data(self.id);
416 write!(f, "type {}", data.name)?;
417 if !data.bounds.is_empty() {
418 write!(f, ": ")?;
419 f.write_joined(&data.bounds, " + ")?;
420 }
421 if let Some(ty) = &data.type_ref {
422 write!(f, " = ")?;
423 ty.hir_fmt(f)?;
424 }
425 Ok(())
426 }
427}
428
429impl HirDisplay for Module {
430 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
431 // FIXME: Module doesn't have visibility saved in data.
432 match self.name(f.db) {
433 Some(name) => write!(f, "mod {}", name),
434 None if self.crate_root(f.db) == *self => match self.krate().display_name(f.db) {
435 Some(name) => write!(f, "extern crate {}", name),
436 None => write!(f, "extern crate {{unknown}}"),
437 },
438 None => write!(f, "mod {{unnamed}}"),
439 }
440 }
441}
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 8d082994a..f0bc2c7b9 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -29,6 +29,8 @@ mod has_source;
29pub mod diagnostics; 29pub mod diagnostics;
30pub mod db; 30pub mod db;
31 31
32mod display;
33
32use std::{iter, sync::Arc}; 34use std::{iter, sync::Arc};
33 35
34use arrayvec::ArrayVec; 36use arrayvec::ArrayVec;
@@ -50,12 +52,13 @@ use hir_def::{
50use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind}; 52use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind};
51use hir_ty::{ 53use hir_ty::{
52 autoderef, 54 autoderef,
53 display::{write_bounds_like_dyn_trait_with_prefix, HirDisplayError, HirFormatter}, 55 method_resolution::{self, TyFingerprint},
54 method_resolution, 56 primitive::UintTy,
57 to_assoc_type_id,
55 traits::{FnTrait, Solution, SolutionVariables}, 58 traits::{FnTrait, Solution, SolutionVariables},
56 AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate, 59 AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate,
57 InEnvironment, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment, 60 InEnvironment, Interner, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, Ty,
58 Ty, TyDefId, TyVariableKind, 61 TyDefId, TyKind, TyVariableKind,
59}; 62};
60use rustc_hash::FxHashSet; 63use rustc_hash::FxHashSet;
61use stdx::{format_to, impl_from}; 64use stdx::{format_to, impl_from};
@@ -266,8 +269,7 @@ impl ModuleDef {
266 } 269 }
267 270
268 pub fn canonical_path(&self, db: &dyn HirDatabase) -> Option<String> { 271 pub fn canonical_path(&self, db: &dyn HirDatabase) -> Option<String> {
269 let mut segments = Vec::new(); 272 let mut segments = vec![self.name(db)?.to_string()];
270 segments.push(self.name(db)?.to_string());
271 for m in self.module(db)?.path_to_root(db) { 273 for m in self.module(db)?.path_to_root(db) {
272 segments.extend(m.name(db).map(|it| it.to_string())) 274 segments.extend(m.name(db).map(|it| it.to_string()))
273 } 275 }
@@ -571,6 +573,12 @@ impl Struct {
571 } 573 }
572} 574}
573 575
576impl HasVisibility for Struct {
577 fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
578 db.struct_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
579 }
580}
581
574#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 582#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
575pub struct Union { 583pub struct Union {
576 pub(crate) id: UnionId, 584 pub(crate) id: UnionId,
@@ -603,6 +611,12 @@ impl Union {
603 } 611 }
604} 612}
605 613
614impl HasVisibility for Union {
615 fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
616 db.union_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
617 }
618}
619
606#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 620#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
607pub struct Enum { 621pub struct Enum {
608 pub(crate) id: EnumId, 622 pub(crate) id: EnumId,
@@ -630,6 +644,12 @@ impl Enum {
630 } 644 }
631} 645}
632 646
647impl HasVisibility for Enum {
648 fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
649 db.enum_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
650 }
651}
652
633#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 653#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
634pub struct Variant { 654pub struct Variant {
635 pub(crate) parent: Enum, 655 pub(crate) parent: Enum,
@@ -677,7 +697,7 @@ impl_from!(Struct, Union, Enum for Adt);
677impl Adt { 697impl Adt {
678 pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { 698 pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool {
679 let subst = db.generic_defaults(self.into()); 699 let subst = db.generic_defaults(self.into());
680 subst.iter().any(|ty| &ty.value == &Ty::Unknown) 700 subst.iter().any(|ty| ty.value.is_unknown())
681 } 701 }
682 702
683 /// Turns this ADT into a type. Any type parameters of the ADT will be 703 /// Turns this ADT into a type. Any type parameters of the ADT will be
@@ -696,8 +716,8 @@ impl Adt {
696 } 716 }
697 } 717 }
698 718
699 pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> { 719 pub fn krate(self, db: &dyn HirDatabase) -> Crate {
700 Some(self.module(db).krate()) 720 self.module(db).krate()
701 } 721 }
702 722
703 pub fn name(self, db: &dyn HirDatabase) -> Name { 723 pub fn name(self, db: &dyn HirDatabase) -> Name {
@@ -802,7 +822,7 @@ impl Function {
802 let krate = self.id.lookup(db.upcast()).container.module(db.upcast()).krate(); 822 let krate = self.id.lookup(db.upcast()).container.module(db.upcast()).krate();
803 let ret_type = &db.function_data(self.id).ret_type; 823 let ret_type = &db.function_data(self.id).ret_type;
804 let ctx = hir_ty::TyLoweringContext::new(db, &resolver); 824 let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
805 let ty = Ty::from_hir_ext(&ctx, ret_type).0; 825 let ty = ctx.lower_ty(ret_type);
806 Type::new_with_resolver_inner(db, krate, &resolver, ty) 826 Type::new_with_resolver_inner(db, krate, &resolver, ty)
807 } 827 }
808 828
@@ -817,19 +837,20 @@ impl Function {
817 let resolver = self.id.resolver(db.upcast()); 837 let resolver = self.id.resolver(db.upcast());
818 let krate = self.id.lookup(db.upcast()).container.module(db.upcast()).krate(); 838 let krate = self.id.lookup(db.upcast()).container.module(db.upcast()).krate();
819 let ctx = hir_ty::TyLoweringContext::new(db, &resolver); 839 let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
820 let environment = TraitEnvironment::lower(db, &resolver); 840 let environment = db.trait_environment(self.id.into());
821 db.function_data(self.id) 841 db.function_data(self.id)
822 .params 842 .params
823 .iter() 843 .iter()
824 .map(|type_ref| { 844 .enumerate()
845 .map(|(idx, type_ref)| {
825 let ty = Type { 846 let ty = Type {
826 krate, 847 krate,
827 ty: InEnvironment { 848 ty: InEnvironment {
828 value: Ty::from_hir_ext(&ctx, type_ref).0, 849 value: ctx.lower_ty(type_ref),
829 environment: environment.clone(), 850 environment: environment.clone(),
830 }, 851 },
831 }; 852 };
832 Param { ty } 853 Param { func: self, ty, idx }
833 }) 854 })
834 .collect() 855 .collect()
835 } 856 }
@@ -843,7 +864,7 @@ impl Function {
843 } 864 }
844 865
845 pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool { 866 pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool {
846 db.function_data(self.id).is_unsafe 867 db.function_data(self.id).qualifier.is_unsafe
847 } 868 }
848 869
849 pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { 870 pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) {
@@ -892,6 +913,9 @@ impl From<hir_ty::Mutability> for Access {
892 913
893#[derive(Debug)] 914#[derive(Debug)]
894pub struct Param { 915pub struct Param {
916 func: Function,
917 /// The index in parameter list, including self parameter.
918 idx: usize,
895 ty: Type, 919 ty: Type,
896} 920}
897 921
@@ -899,6 +923,15 @@ impl Param {
899 pub fn ty(&self) -> &Type { 923 pub fn ty(&self) -> &Type {
900 &self.ty 924 &self.ty
901 } 925 }
926
927 pub fn pattern_source(&self, db: &dyn HirDatabase) -> Option<ast::Pat> {
928 let params = self.func.source(db)?.value.param_list()?;
929 if params.self_param().is_some() {
930 params.params().nth(self.idx.checked_sub(1)?)?.pat()
931 } else {
932 params.params().nth(self.idx)?.pat()
933 }
934 }
902} 935}
903 936
904#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 937#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -956,6 +989,10 @@ impl Const {
956 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { 989 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
957 db.const_data(self.id).name.clone() 990 db.const_data(self.id).name.clone()
958 } 991 }
992
993 pub fn type_ref(self, db: &dyn HirDatabase) -> TypeRef {
994 db.const_data(self.id).type_ref.clone()
995 }
959} 996}
960 997
961impl HasVisibility for Const { 998impl HasVisibility for Const {
@@ -989,6 +1026,12 @@ impl Static {
989 } 1026 }
990} 1027}
991 1028
1029impl HasVisibility for Static {
1030 fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
1031 db.static_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
1032 }
1033}
1034
992#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 1035#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
993pub struct Trait { 1036pub struct Trait {
994 pub(crate) id: TraitId, 1037 pub(crate) id: TraitId,
@@ -1008,7 +1051,13 @@ impl Trait {
1008 } 1051 }
1009 1052
1010 pub fn is_auto(self, db: &dyn HirDatabase) -> bool { 1053 pub fn is_auto(self, db: &dyn HirDatabase) -> bool {
1011 db.trait_data(self.id).auto 1054 db.trait_data(self.id).is_auto
1055 }
1056}
1057
1058impl HasVisibility for Trait {
1059 fn visibility(&self, db: &dyn HirDatabase) -> Visibility {
1060 db.trait_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast()))
1012 } 1061 }
1013} 1062}
1014 1063
@@ -1020,15 +1069,15 @@ pub struct TypeAlias {
1020impl TypeAlias { 1069impl TypeAlias {
1021 pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { 1070 pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool {
1022 let subst = db.generic_defaults(self.id.into()); 1071 let subst = db.generic_defaults(self.id.into());
1023 subst.iter().any(|ty| &ty.value == &Ty::Unknown) 1072 subst.iter().any(|ty| ty.value.is_unknown())
1024 } 1073 }
1025 1074
1026 pub fn module(self, db: &dyn HirDatabase) -> Module { 1075 pub fn module(self, db: &dyn HirDatabase) -> Module {
1027 Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } 1076 Module { id: self.id.lookup(db.upcast()).module(db.upcast()) }
1028 } 1077 }
1029 1078
1030 pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> { 1079 pub fn krate(self, db: &dyn HirDatabase) -> Crate {
1031 Some(self.module(db).krate()) 1080 self.module(db).krate()
1032 } 1081 }
1033 1082
1034 pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> { 1083 pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> {
@@ -1392,7 +1441,7 @@ impl TypeParam {
1392 pub fn ty(self, db: &dyn HirDatabase) -> Type { 1441 pub fn ty(self, db: &dyn HirDatabase) -> Type {
1393 let resolver = self.id.parent.resolver(db.upcast()); 1442 let resolver = self.id.parent.resolver(db.upcast());
1394 let krate = self.id.parent.module(db.upcast()).krate(); 1443 let krate = self.id.parent.module(db.upcast()).krate();
1395 let ty = Ty::Placeholder(self.id); 1444 let ty = TyKind::Placeholder(hir_ty::to_placeholder_idx(db, self.id)).intern(&Interner);
1396 Type::new_with_resolver_inner(db, krate, &resolver, ty) 1445 Type::new_with_resolver_inner(db, krate, &resolver, ty)
1397 } 1446 }
1398 1447
@@ -1420,19 +1469,6 @@ impl TypeParam {
1420 } 1469 }
1421} 1470}
1422 1471
1423impl HirDisplay for TypeParam {
1424 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
1425 write!(f, "{}", self.name(f.db))?;
1426 let bounds = f.db.generic_predicates_for_param(self.id);
1427 let substs = Substs::type_params(f.db, self.id.parent);
1428 let predicates = bounds.iter().cloned().map(|b| b.subst(&substs)).collect::<Vec<_>>();
1429 if !(predicates.is_empty() || f.omit_verbose_types()) {
1430 write_bounds_like_dyn_trait_with_prefix(":", &predicates, f)?;
1431 }
1432 Ok(())
1433 }
1434}
1435
1436#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 1472#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1437pub struct LifetimeParam { 1473pub struct LifetimeParam {
1438 pub(crate) id: LifetimeParamId, 1474 pub(crate) id: LifetimeParamId,
@@ -1491,9 +1527,44 @@ impl Impl {
1491 1527
1492 inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect() 1528 inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect()
1493 } 1529 }
1494 pub fn for_trait(db: &dyn HirDatabase, krate: Crate, trait_: Trait) -> Vec<Impl> { 1530
1495 let impls = db.trait_impls_in_crate(krate.id); 1531 pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty }: Type) -> Vec<Impl> {
1496 impls.for_trait(trait_.id).map(Self::from).collect() 1532 let def_crates = match ty.value.def_crates(db, krate) {
1533 Some(def_crates) => def_crates,
1534 None => return Vec::new(),
1535 };
1536
1537 let filter = |impl_def: &Impl| {
1538 let target_ty = impl_def.target_ty(db);
1539 let rref = target_ty.remove_ref();
1540 ty.value.equals_ctor(rref.as_ref().map_or(&target_ty.ty.value, |it| &it.ty.value))
1541 };
1542
1543 let mut all = Vec::new();
1544 def_crates.into_iter().for_each(|id| {
1545 all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter))
1546 });
1547 let fp = TyFingerprint::for_impl(&ty.value);
1548 for id in db.crate_graph().iter() {
1549 match fp {
1550 Some(fp) => all.extend(
1551 db.trait_impls_in_crate(id).for_self_ty(fp).map(Self::from).filter(filter),
1552 ),
1553 None => all
1554 .extend(db.trait_impls_in_crate(id).all_impls().map(Self::from).filter(filter)),
1555 }
1556 }
1557 all
1558 }
1559
1560 pub fn all_for_trait(db: &dyn HirDatabase, trait_: Trait) -> Vec<Impl> {
1561 let krate = trait_.module(db).krate();
1562 let mut all = Vec::new();
1563 for Crate { id } in krate.reverse_dependencies(db).into_iter().chain(Some(krate)) {
1564 let impls = db.trait_impls_in_crate(id);
1565 all.extend(impls.for_trait(trait_.id).map(Self::from))
1566 }
1567 all
1497 } 1568 }
1498 1569
1499 // FIXME: the return type is wrong. This should be a hir version of 1570 // FIXME: the return type is wrong. This should be a hir version of
@@ -1507,7 +1578,7 @@ impl Impl {
1507 let resolver = self.id.resolver(db.upcast()); 1578 let resolver = self.id.resolver(db.upcast());
1508 let krate = self.id.lookup(db.upcast()).container.krate(); 1579 let krate = self.id.lookup(db.upcast()).container.krate();
1509 let ctx = hir_ty::TyLoweringContext::new(db, &resolver); 1580 let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
1510 let ty = Ty::from_hir(&ctx, &impl_data.target_type); 1581 let ty = ctx.lower_ty(&impl_data.target_type);
1511 Type::new_with_resolver_inner(db, krate, &resolver, ty) 1582 Type::new_with_resolver_inner(db, krate, &resolver, ty)
1512 } 1583 }
1513 1584
@@ -1571,13 +1642,15 @@ impl Type {
1571 resolver: &Resolver, 1642 resolver: &Resolver,
1572 ty: Ty, 1643 ty: Ty,
1573 ) -> Type { 1644 ) -> Type {
1574 let environment = TraitEnvironment::lower(db, &resolver); 1645 let environment =
1646 resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d));
1575 Type { krate, ty: InEnvironment { value: ty, environment } } 1647 Type { krate, ty: InEnvironment { value: ty, environment } }
1576 } 1648 }
1577 1649
1578 fn new(db: &dyn HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type { 1650 fn new(db: &dyn HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type {
1579 let resolver = lexical_env.resolver(db.upcast()); 1651 let resolver = lexical_env.resolver(db.upcast());
1580 let environment = TraitEnvironment::lower(db, &resolver); 1652 let environment =
1653 resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d));
1581 Type { krate, ty: InEnvironment { value: ty, environment } } 1654 Type { krate, ty: InEnvironment { value: ty, environment } }
1582 } 1655 }
1583 1656
@@ -1592,25 +1665,29 @@ impl Type {
1592 } 1665 }
1593 1666
1594 pub fn is_unit(&self) -> bool { 1667 pub fn is_unit(&self) -> bool {
1595 matches!(self.ty.value, Ty::Tuple(0, ..)) 1668 matches!(self.ty.value.interned(&Interner), TyKind::Tuple(0, ..))
1596 } 1669 }
1597 pub fn is_bool(&self) -> bool { 1670 pub fn is_bool(&self) -> bool {
1598 matches!(self.ty.value, Ty::Scalar(Scalar::Bool)) 1671 matches!(self.ty.value.interned(&Interner), TyKind::Scalar(Scalar::Bool))
1599 } 1672 }
1600 1673
1601 pub fn is_mutable_reference(&self) -> bool { 1674 pub fn is_mutable_reference(&self) -> bool {
1602 matches!(self.ty.value, Ty::Ref(hir_ty::Mutability::Mut, ..)) 1675 matches!(self.ty.value.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..))
1676 }
1677
1678 pub fn is_usize(&self) -> bool {
1679 matches!(self.ty.value.interned(&Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize)))
1603 } 1680 }
1604 1681
1605 pub fn remove_ref(&self) -> Option<Type> { 1682 pub fn remove_ref(&self) -> Option<Type> {
1606 match &self.ty.value { 1683 match &self.ty.value.interned(&Interner) {
1607 Ty::Ref(.., substs) => Some(self.derived(substs[0].clone())), 1684 TyKind::Ref(.., ty) => Some(self.derived(ty.clone())),
1608 _ => None, 1685 _ => None,
1609 } 1686 }
1610 } 1687 }
1611 1688
1612 pub fn is_unknown(&self) -> bool { 1689 pub fn is_unknown(&self) -> bool {
1613 matches!(self.ty.value, Ty::Unknown) 1690 self.ty.value.is_unknown()
1614 } 1691 }
1615 1692
1616 /// Checks that particular type `ty` implements `std::future::Future`. 1693 /// Checks that particular type `ty` implements `std::future::Future`.
@@ -1691,8 +1768,11 @@ impl Type {
1691 .fill(args.iter().map(|t| t.ty.value.clone())) 1768 .fill(args.iter().map(|t| t.ty.value.clone()))
1692 .build(); 1769 .build();
1693 let predicate = ProjectionPredicate { 1770 let predicate = ProjectionPredicate {
1694 projection_ty: ProjectionTy { associated_ty: alias.id, parameters: subst }, 1771 projection_ty: ProjectionTy {
1695 ty: Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)), 1772 associated_ty_id: to_assoc_type_id(alias.id),
1773 substitution: subst,
1774 },
1775 ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner),
1696 }; 1776 };
1697 let goal = Canonical { 1777 let goal = Canonical {
1698 value: InEnvironment::new( 1778 value: InEnvironment::new(
@@ -1720,26 +1800,23 @@ impl Type {
1720 } 1800 }
1721 1801
1722 pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> { 1802 pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> {
1723 let def = match self.ty.value { 1803 let def = self.ty.value.callable_def(db);
1724 Ty::FnDef(def, _) => Some(def),
1725 _ => None,
1726 };
1727 1804
1728 let sig = self.ty.value.callable_sig(db)?; 1805 let sig = self.ty.value.callable_sig(db)?;
1729 Some(Callable { ty: self.clone(), sig, def, is_bound_method: false }) 1806 Some(Callable { ty: self.clone(), sig, def, is_bound_method: false })
1730 } 1807 }
1731 1808
1732 pub fn is_closure(&self) -> bool { 1809 pub fn is_closure(&self) -> bool {
1733 matches!(&self.ty.value, Ty::Closure { .. }) 1810 matches!(&self.ty.value.interned(&Interner), TyKind::Closure { .. })
1734 } 1811 }
1735 1812
1736 pub fn is_fn(&self) -> bool { 1813 pub fn is_fn(&self) -> bool {
1737 matches!(&self.ty.value, Ty::FnDef(..) | Ty::Function { .. }) 1814 matches!(&self.ty.value.interned(&Interner), TyKind::FnDef(..) | TyKind::Function { .. })
1738 } 1815 }
1739 1816
1740 pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { 1817 pub fn is_packed(&self, db: &dyn HirDatabase) -> bool {
1741 let adt_id = match self.ty.value { 1818 let adt_id = match self.ty.value.interned(&Interner) {
1742 Ty::Adt(hir_ty::AdtId(adt_id), ..) => adt_id, 1819 &TyKind::Adt(hir_ty::AdtId(adt_id), ..) => adt_id,
1743 _ => return false, 1820 _ => return false,
1744 }; 1821 };
1745 1822
@@ -1751,24 +1828,45 @@ impl Type {
1751 } 1828 }
1752 1829
1753 pub fn is_raw_ptr(&self) -> bool { 1830 pub fn is_raw_ptr(&self) -> bool {
1754 matches!(&self.ty.value, Ty::Raw(..)) 1831 matches!(&self.ty.value.interned(&Interner), TyKind::Raw(..))
1755 } 1832 }
1756 1833
1757 pub fn contains_unknown(&self) -> bool { 1834 pub fn contains_unknown(&self) -> bool {
1758 return go(&self.ty.value); 1835 return go(&self.ty.value);
1759 1836
1760 fn go(ty: &Ty) -> bool { 1837 fn go(ty: &Ty) -> bool {
1761 match ty { 1838 match ty.interned(&Interner) {
1762 Ty::Unknown => true, 1839 TyKind::Unknown => true,
1763 _ => ty.substs().map_or(false, |substs| substs.iter().any(go)), 1840
1841 TyKind::Adt(_, substs)
1842 | TyKind::AssociatedType(_, substs)
1843 | TyKind::Tuple(_, substs)
1844 | TyKind::OpaqueType(_, substs)
1845 | TyKind::FnDef(_, substs)
1846 | TyKind::Closure(_, substs) => substs.iter().any(go),
1847
1848 TyKind::Array(ty) | TyKind::Slice(ty) | TyKind::Raw(_, ty) | TyKind::Ref(_, ty) => {
1849 go(ty)
1850 }
1851
1852 TyKind::Scalar(_)
1853 | TyKind::Str
1854 | TyKind::Never
1855 | TyKind::Placeholder(_)
1856 | TyKind::BoundVar(_)
1857 | TyKind::InferenceVar(_, _)
1858 | TyKind::Dyn(_)
1859 | TyKind::Function(_)
1860 | TyKind::Alias(_)
1861 | TyKind::ForeignType(_) => false,
1764 } 1862 }
1765 } 1863 }
1766 } 1864 }
1767 1865
1768 pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { 1866 pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> {
1769 let (variant_id, substs) = match self.ty.value { 1867 let (variant_id, substs) = match self.ty.value.interned(&Interner) {
1770 Ty::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs), 1868 &TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs),
1771 Ty::Adt(hir_ty::AdtId(AdtId::UnionId(u)), ref substs) => (u.into(), substs), 1869 &TyKind::Adt(hir_ty::AdtId(AdtId::UnionId(u)), ref substs) => (u.into(), substs),
1772 _ => return Vec::new(), 1870 _ => return Vec::new(),
1773 }; 1871 };
1774 1872
@@ -1783,7 +1881,7 @@ impl Type {
1783 } 1881 }
1784 1882
1785 pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { 1883 pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> {
1786 if let Ty::Tuple(_, substs) = &self.ty.value { 1884 if let TyKind::Tuple(_, substs) = &self.ty.value.interned(&Interner) {
1787 substs.iter().map(|ty| self.derived(ty.clone())).collect() 1885 substs.iter().map(|ty| self.derived(ty.clone())).collect()
1788 } else { 1886 } else {
1789 Vec::new() 1887 Vec::new()
@@ -1918,12 +2016,6 @@ impl Type {
1918 self.ty.value.associated_type_parent_trait(db).map(Into::into) 2016 self.ty.value.associated_type_parent_trait(db).map(Into::into)
1919 } 2017 }
1920 2018
1921 // FIXME: provide required accessors such that it becomes implementable from outside.
1922 pub fn is_equal_for_find_impls(&self, other: &Type) -> bool {
1923 let rref = other.remove_ref();
1924 self.ty.value.equals_ctor(rref.as_ref().map_or(&other.ty.value, |it| &it.ty.value))
1925 }
1926
1927 fn derived(&self, ty: Ty) -> Type { 2019 fn derived(&self, ty: Ty) -> Type {
1928 Type { 2020 Type {
1929 krate: self.krate, 2021 krate: self.krate,
@@ -1965,36 +2057,40 @@ impl Type {
1965 2057
1966 fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { 2058 fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) {
1967 let ty = type_.ty.value.strip_references(); 2059 let ty = type_.ty.value.strip_references();
1968 match ty { 2060 match ty.interned(&Interner) {
1969 Ty::Adt(..) => { 2061 TyKind::Adt(..) => {
1970 cb(type_.derived(ty.clone())); 2062 cb(type_.derived(ty.clone()));
1971 } 2063 }
1972 Ty::AssociatedType(..) => { 2064 TyKind::AssociatedType(..) => {
1973 if let Some(_) = ty.associated_type_parent_trait(db) { 2065 if let Some(_) = ty.associated_type_parent_trait(db) {
1974 cb(type_.derived(ty.clone())); 2066 cb(type_.derived(ty.clone()));
1975 } 2067 }
1976 } 2068 }
1977 Ty::OpaqueType(..) => { 2069 TyKind::OpaqueType(..) => {
1978 if let Some(bounds) = ty.impl_trait_bounds(db) { 2070 if let Some(bounds) = ty.impl_trait_bounds(db) {
1979 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); 2071 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
1980 } 2072 }
1981 } 2073 }
1982 Ty::Alias(AliasTy::Opaque(opaque_ty)) => { 2074 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
1983 if let Some(bounds) = ty.impl_trait_bounds(db) { 2075 if let Some(bounds) = ty.impl_trait_bounds(db) {
1984 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); 2076 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
1985 } 2077 }
1986 2078
1987 walk_substs(db, type_, &opaque_ty.parameters, cb); 2079 walk_substs(db, type_, &opaque_ty.substitution, cb);
1988 } 2080 }
1989 Ty::Placeholder(_) => { 2081 TyKind::Placeholder(_) => {
1990 if let Some(bounds) = ty.impl_trait_bounds(db) { 2082 if let Some(bounds) = ty.impl_trait_bounds(db) {
1991 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); 2083 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
1992 } 2084 }
1993 } 2085 }
1994 Ty::Dyn(bounds) => { 2086 TyKind::Dyn(bounds) => {
1995 walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb); 2087 walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb);
1996 } 2088 }
1997 2089
2090 TyKind::Ref(_, ty) | TyKind::Raw(_, ty) | TyKind::Array(ty) | TyKind::Slice(ty) => {
2091 walk_type(db, &type_.derived(ty.clone()), cb);
2092 }
2093
1998 _ => {} 2094 _ => {}
1999 } 2095 }
2000 if let Some(substs) = ty.substs() { 2096 if let Some(substs) = ty.substs() {
@@ -2006,12 +2102,6 @@ impl Type {
2006 } 2102 }
2007} 2103}
2008 2104
2009impl HirDisplay for Type {
2010 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
2011 self.ty.value.hir_fmt(f)
2012 }
2013}
2014
2015// FIXME: closures 2105// FIXME: closures
2016#[derive(Debug)] 2106#[derive(Debug)]
2017pub struct Callable { 2107pub struct Callable {
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 945638cc5..519339c0c 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -259,6 +259,10 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
259 } 259 }
260 260
261 pub fn to_module_def(&self, file: FileId) -> Option<Module> { 261 pub fn to_module_def(&self, file: FileId) -> Option<Module> {
262 self.imp.to_module_def(file).next()
263 }
264
265 pub fn to_module_defs(&self, file: FileId) -> impl Iterator<Item = Module> {
262 self.imp.to_module_def(file) 266 self.imp.to_module_def(file)
263 } 267 }
264 268
@@ -537,8 +541,8 @@ impl<'db> SemanticsImpl<'db> {
537 f(&mut ctx) 541 f(&mut ctx)
538 } 542 }
539 543
540 fn to_module_def(&self, file: FileId) -> Option<Module> { 544 fn to_module_def(&self, file: FileId) -> impl Iterator<Item = Module> {
541 self.with_ctx(|ctx| ctx.file_to_def(file)).map(Module::from) 545 self.with_ctx(|ctx| ctx.file_to_def(file)).into_iter().map(Module::from)
542 } 546 }
543 547
544 fn scope(&self, node: &SyntaxNode) -> SemanticsScope<'db> { 548 fn scope(&self, node: &SyntaxNode) -> SemanticsScope<'db> {
diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs
index 6c612ee86..e9d820140 100644
--- a/crates/hir/src/semantics/source_to_def.rs
+++ b/crates/hir/src/semantics/source_to_def.rs
@@ -12,6 +12,7 @@ use hir_def::{
12}; 12};
13use hir_expand::{name::AsName, AstId, MacroDefKind}; 13use hir_expand::{name::AsName, AstId, MacroDefKind};
14use rustc_hash::FxHashMap; 14use rustc_hash::FxHashMap;
15use smallvec::SmallVec;
15use stdx::impl_from; 16use stdx::impl_from;
16use syntax::{ 17use syntax::{
17 ast::{self, NameOwner}, 18 ast::{self, NameOwner},
@@ -28,14 +29,19 @@ pub(super) struct SourceToDefCtx<'a, 'b> {
28} 29}
29 30
30impl SourceToDefCtx<'_, '_> { 31impl SourceToDefCtx<'_, '_> {
31 pub(super) fn file_to_def(&mut self, file: FileId) -> Option<ModuleId> { 32 pub(super) fn file_to_def(&mut self, file: FileId) -> SmallVec<[ModuleId; 1]> {
32 let _p = profile::span("SourceBinder::to_module_def"); 33 let _p = profile::span("SourceBinder::to_module_def");
33 self.db.relevant_crates(file).iter().find_map(|&crate_id| { 34 let mut mods = SmallVec::new();
35 for &crate_id in self.db.relevant_crates(file).iter() {
34 // FIXME: inner items 36 // FIXME: inner items
35 let crate_def_map = self.db.crate_def_map(crate_id); 37 let crate_def_map = self.db.crate_def_map(crate_id);
36 let local_id = crate_def_map.modules_for_file(file).next()?; 38 mods.extend(
37 Some(crate_def_map.module_id(local_id)) 39 crate_def_map
38 }) 40 .modules_for_file(file)
41 .map(|local_id| crate_def_map.module_id(local_id)),
42 )
43 }
44 mods
39 } 45 }
40 46
41 pub(super) fn module_to_def(&mut self, src: InFile<ast::Module>) -> Option<ModuleId> { 47 pub(super) fn module_to_def(&mut self, src: InFile<ast::Module>) -> Option<ModuleId> {
@@ -55,7 +61,7 @@ impl SourceToDefCtx<'_, '_> {
55 Some(parent_declaration) => self.module_to_def(parent_declaration), 61 Some(parent_declaration) => self.module_to_def(parent_declaration),
56 None => { 62 None => {
57 let file_id = src.file_id.original_file(self.db.upcast()); 63 let file_id = src.file_id.original_file(self.db.upcast());
58 self.file_to_def(file_id) 64 self.file_to_def(file_id).get(0).copied()
59 } 65 }
60 }?; 66 }?;
61 67
@@ -185,7 +191,7 @@ impl SourceToDefCtx<'_, '_> {
185 ) -> Option<MacroDefId> { 191 ) -> Option<MacroDefId> {
186 let kind = MacroDefKind::Declarative; 192 let kind = MacroDefKind::Declarative;
187 let file_id = src.file_id.original_file(self.db.upcast()); 193 let file_id = src.file_id.original_file(self.db.upcast());
188 let krate = self.file_to_def(file_id)?.krate(); 194 let krate = self.file_to_def(file_id).get(0).copied()?.krate();
189 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);
190 let ast_id = Some(AstId::new(src.file_id, file_ast_id.upcast())); 196 let ast_id = Some(AstId::new(src.file_id, file_ast_id.upcast()));
191 Some(MacroDefId { krate, ast_id, kind, local_inner: false }) 197 Some(MacroDefId { krate, ast_id, kind, local_inner: false })
@@ -245,7 +251,7 @@ impl SourceToDefCtx<'_, '_> {
245 return Some(res); 251 return Some(res);
246 } 252 }
247 253
248 let def = self.file_to_def(src.file_id.original_file(self.db.upcast()))?; 254 let def = self.file_to_def(src.file_id.original_file(self.db.upcast())).get(0).copied()?;
249 Some(def.into()) 255 Some(def.into())
250 } 256 }
251 257
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index d546512cb..4d59293e9 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -161,8 +161,9 @@ 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 = field.expr()?; 164 let expr_id =
165 let expr_id = self.expr_id(db, &expr)?; 165 self.body_source_map.as_ref()?.node_field(InFile::new(self.file_id, field))?;
166
166 let local = if field.name_ref().is_some() { 167 let local = if field.name_ref().is_some() {
167 None 168 None
168 } else { 169 } else {