diff options
Diffstat (limited to 'crates/hir')
-rw-r--r-- | crates/hir/src/display.rs | 467 | ||||
-rw-r--r-- | crates/hir/src/lib.rs | 129 | ||||
-rw-r--r-- | crates/hir/src/semantics.rs | 30 | ||||
-rw-r--r-- | crates/hir/src/source_analyzer.rs | 4 |
4 files changed, 586 insertions, 44 deletions
diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs new file mode 100644 index 000000000..9f6d7be48 --- /dev/null +++ b/crates/hir/src/display.rs | |||
@@ -0,0 +1,467 @@ | |||
1 | //! HirDisplay implementations for various hir types. | ||
2 | use hir_def::{ | ||
3 | adt::VariantData, | ||
4 | generics::{TypeParamProvenance, WherePredicate, WherePredicateTypeTarget}, | ||
5 | type_ref::{TypeBound, TypeRef}, | ||
6 | AdtId, GenericDefId, | ||
7 | }; | ||
8 | use hir_ty::display::{ | ||
9 | write_bounds_like_dyn_trait_with_prefix, write_visibility, HirDisplay, HirDisplayError, | ||
10 | HirFormatter, | ||
11 | }; | ||
12 | use syntax::ast::{self, NameOwner}; | ||
13 | |||
14 | use crate::{ | ||
15 | Adt, Const, ConstParam, Enum, Field, Function, GenericParam, HasVisibility, LifetimeParam, | ||
16 | Module, Static, Struct, Substitution, Trait, Type, TypeAlias, TypeParam, Union, Variant, | ||
17 | }; | ||
18 | |||
19 | impl 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 | |||
123 | impl HirDisplay for Adt { | ||
124 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
125 | match self { | ||
126 | Adt::Struct(it) => it.hir_fmt(f), | ||
127 | Adt::Union(it) => it.hir_fmt(f), | ||
128 | Adt::Enum(it) => it.hir_fmt(f), | ||
129 | } | ||
130 | } | ||
131 | } | ||
132 | |||
133 | impl HirDisplay for Struct { | ||
134 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
135 | write_visibility(self.module(f.db).id, self.visibility(f.db), f)?; | ||
136 | write!(f, "struct ")?; | ||
137 | write!(f, "{}", self.name(f.db))?; | ||
138 | let def_id = GenericDefId::AdtId(AdtId::StructId(self.id)); | ||
139 | write_generic_params(def_id, f)?; | ||
140 | write_where_clause(def_id, f)?; | ||
141 | Ok(()) | ||
142 | } | ||
143 | } | ||
144 | |||
145 | impl HirDisplay for Enum { | ||
146 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
147 | write_visibility(self.module(f.db).id, self.visibility(f.db), f)?; | ||
148 | write!(f, "enum ")?; | ||
149 | write!(f, "{}", self.name(f.db))?; | ||
150 | let def_id = GenericDefId::AdtId(AdtId::EnumId(self.id)); | ||
151 | write_generic_params(def_id, f)?; | ||
152 | write_where_clause(def_id, f)?; | ||
153 | Ok(()) | ||
154 | } | ||
155 | } | ||
156 | |||
157 | impl HirDisplay for Union { | ||
158 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
159 | write_visibility(self.module(f.db).id, self.visibility(f.db), f)?; | ||
160 | write!(f, "union ")?; | ||
161 | write!(f, "{}", self.name(f.db))?; | ||
162 | let def_id = GenericDefId::AdtId(AdtId::UnionId(self.id)); | ||
163 | write_generic_params(def_id, f)?; | ||
164 | write_where_clause(def_id, f)?; | ||
165 | Ok(()) | ||
166 | } | ||
167 | } | ||
168 | |||
169 | impl HirDisplay for Field { | ||
170 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
171 | write_visibility(self.parent.module(f.db).id, self.visibility(f.db), f)?; | ||
172 | write!(f, "{}: ", self.name(f.db))?; | ||
173 | self.signature_ty(f.db).hir_fmt(f) | ||
174 | } | ||
175 | } | ||
176 | |||
177 | impl HirDisplay for Variant { | ||
178 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
179 | write!(f, "{}", self.name(f.db))?; | ||
180 | let data = self.variant_data(f.db); | ||
181 | match &*data { | ||
182 | VariantData::Unit => {} | ||
183 | VariantData::Tuple(fields) => { | ||
184 | write!(f, "(")?; | ||
185 | let mut first = true; | ||
186 | for (_, field) in fields.iter() { | ||
187 | if first { | ||
188 | first = false; | ||
189 | } else { | ||
190 | write!(f, ", ")?; | ||
191 | } | ||
192 | // Enum variant fields must be pub. | ||
193 | field.type_ref.hir_fmt(f)?; | ||
194 | } | ||
195 | write!(f, ")")?; | ||
196 | } | ||
197 | VariantData::Record(fields) => { | ||
198 | write!(f, " {{")?; | ||
199 | let mut first = true; | ||
200 | for (_, field) in fields.iter() { | ||
201 | if first { | ||
202 | first = false; | ||
203 | write!(f, " ")?; | ||
204 | } else { | ||
205 | write!(f, ", ")?; | ||
206 | } | ||
207 | // Enum variant fields must be pub. | ||
208 | write!(f, "{}: ", field.name)?; | ||
209 | field.type_ref.hir_fmt(f)?; | ||
210 | } | ||
211 | write!(f, " }}")?; | ||
212 | } | ||
213 | } | ||
214 | Ok(()) | ||
215 | } | ||
216 | } | ||
217 | |||
218 | impl HirDisplay for Type { | ||
219 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
220 | self.ty.value.hir_fmt(f) | ||
221 | } | ||
222 | } | ||
223 | |||
224 | impl HirDisplay for GenericParam { | ||
225 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
226 | match self { | ||
227 | GenericParam::TypeParam(it) => it.hir_fmt(f), | ||
228 | GenericParam::LifetimeParam(it) => it.hir_fmt(f), | ||
229 | GenericParam::ConstParam(it) => it.hir_fmt(f), | ||
230 | } | ||
231 | } | ||
232 | } | ||
233 | |||
234 | impl HirDisplay for TypeParam { | ||
235 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
236 | write!(f, "{}", self.name(f.db))?; | ||
237 | let bounds = f.db.generic_predicates_for_param(self.id); | ||
238 | let substs = Substitution::type_params(f.db, self.id.parent); | ||
239 | let predicates = bounds.iter().cloned().map(|b| b.subst(&substs)).collect::<Vec<_>>(); | ||
240 | if !(predicates.is_empty() || f.omit_verbose_types()) { | ||
241 | write_bounds_like_dyn_trait_with_prefix(":", &predicates, f)?; | ||
242 | } | ||
243 | Ok(()) | ||
244 | } | ||
245 | } | ||
246 | |||
247 | impl HirDisplay for LifetimeParam { | ||
248 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
249 | write!(f, "{}", self.name(f.db)) | ||
250 | } | ||
251 | } | ||
252 | |||
253 | impl HirDisplay for ConstParam { | ||
254 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
255 | write!(f, "const {}: ", self.name(f.db))?; | ||
256 | self.ty(f.db).hir_fmt(f) | ||
257 | } | ||
258 | } | ||
259 | |||
260 | fn write_generic_params(def: GenericDefId, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
261 | let params = f.db.generic_params(def); | ||
262 | if params.lifetimes.is_empty() | ||
263 | && params.consts.is_empty() | ||
264 | && params | ||
265 | .types | ||
266 | .iter() | ||
267 | .all(|(_, param)| !matches!(param.provenance, TypeParamProvenance::TypeParamList)) | ||
268 | { | ||
269 | return Ok(()); | ||
270 | } | ||
271 | write!(f, "<")?; | ||
272 | |||
273 | let mut first = true; | ||
274 | let mut delim = |f: &mut HirFormatter| { | ||
275 | if first { | ||
276 | first = false; | ||
277 | Ok(()) | ||
278 | } else { | ||
279 | write!(f, ", ") | ||
280 | } | ||
281 | }; | ||
282 | for (_, lifetime) in params.lifetimes.iter() { | ||
283 | delim(f)?; | ||
284 | write!(f, "{}", lifetime.name)?; | ||
285 | } | ||
286 | for (_, ty) in params.types.iter() { | ||
287 | if ty.provenance != TypeParamProvenance::TypeParamList { | ||
288 | continue; | ||
289 | } | ||
290 | if let Some(name) = &ty.name { | ||
291 | delim(f)?; | ||
292 | write!(f, "{}", name)?; | ||
293 | if let Some(default) = &ty.default { | ||
294 | write!(f, " = ")?; | ||
295 | default.hir_fmt(f)?; | ||
296 | } | ||
297 | } | ||
298 | } | ||
299 | for (_, konst) in params.consts.iter() { | ||
300 | delim(f)?; | ||
301 | write!(f, "const {}: ", konst.name)?; | ||
302 | konst.ty.hir_fmt(f)?; | ||
303 | } | ||
304 | |||
305 | write!(f, ">")?; | ||
306 | Ok(()) | ||
307 | } | ||
308 | |||
309 | fn write_where_clause(def: GenericDefId, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
310 | let params = f.db.generic_params(def); | ||
311 | if params.where_predicates.is_empty() { | ||
312 | return Ok(()); | ||
313 | } | ||
314 | |||
315 | let write_target = |target: &WherePredicateTypeTarget, f: &mut HirFormatter| match target { | ||
316 | WherePredicateTypeTarget::TypeRef(ty) => ty.hir_fmt(f), | ||
317 | WherePredicateTypeTarget::TypeParam(id) => match ¶ms.types[*id].name { | ||
318 | Some(name) => write!(f, "{}", name), | ||
319 | None => write!(f, "{{unnamed}}"), | ||
320 | }, | ||
321 | }; | ||
322 | |||
323 | write!(f, "\nwhere")?; | ||
324 | |||
325 | for (pred_idx, pred) in params.where_predicates.iter().enumerate() { | ||
326 | let prev_pred = | ||
327 | if pred_idx == 0 { None } else { Some(¶ms.where_predicates[pred_idx - 1]) }; | ||
328 | |||
329 | let new_predicate = |f: &mut HirFormatter| { | ||
330 | write!(f, "{}", if pred_idx == 0 { "\n " } else { ",\n " }) | ||
331 | }; | ||
332 | |||
333 | match pred { | ||
334 | WherePredicate::TypeBound { target, bound } => { | ||
335 | if matches!(prev_pred, Some(WherePredicate::TypeBound { target: target_, .. }) if target_ == target) | ||
336 | { | ||
337 | write!(f, " + ")?; | ||
338 | } else { | ||
339 | new_predicate(f)?; | ||
340 | write_target(target, f)?; | ||
341 | write!(f, ": ")?; | ||
342 | } | ||
343 | bound.hir_fmt(f)?; | ||
344 | } | ||
345 | WherePredicate::Lifetime { target, bound } => { | ||
346 | if matches!(prev_pred, Some(WherePredicate::Lifetime { target: target_, .. }) if target_ == target) | ||
347 | { | ||
348 | write!(f, " + {}", bound.name)?; | ||
349 | } else { | ||
350 | new_predicate(f)?; | ||
351 | write!(f, "{}: {}", target.name, bound.name)?; | ||
352 | } | ||
353 | } | ||
354 | WherePredicate::ForLifetime { lifetimes, target, bound } => { | ||
355 | if matches!( | ||
356 | prev_pred, | ||
357 | Some(WherePredicate::ForLifetime { lifetimes: lifetimes_, target: target_, .. }) | ||
358 | if lifetimes_ == lifetimes && target_ == target, | ||
359 | ) { | ||
360 | write!(f, " + ")?; | ||
361 | } else { | ||
362 | new_predicate(f)?; | ||
363 | write!(f, "for<")?; | ||
364 | for (idx, lifetime) in lifetimes.iter().enumerate() { | ||
365 | if idx != 0 { | ||
366 | write!(f, ", ")?; | ||
367 | } | ||
368 | write!(f, "{}", lifetime)?; | ||
369 | } | ||
370 | write!(f, "> ")?; | ||
371 | write_target(target, f)?; | ||
372 | write!(f, ": ")?; | ||
373 | } | ||
374 | bound.hir_fmt(f)?; | ||
375 | } | ||
376 | } | ||
377 | } | ||
378 | |||
379 | // End of final predicate. There must be at least one predicate here. | ||
380 | write!(f, ",")?; | ||
381 | |||
382 | Ok(()) | ||
383 | } | ||
384 | |||
385 | impl HirDisplay for Const { | ||
386 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
387 | write_visibility(self.module(f.db).id, self.visibility(f.db), f)?; | ||
388 | let data = f.db.const_data(self.id); | ||
389 | write!(f, "const ")?; | ||
390 | match &data.name { | ||
391 | Some(name) => write!(f, "{}: ", name)?, | ||
392 | None => write!(f, "_: ")?, | ||
393 | } | ||
394 | data.type_ref.hir_fmt(f)?; | ||
395 | Ok(()) | ||
396 | } | ||
397 | } | ||
398 | |||
399 | impl HirDisplay for Static { | ||
400 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
401 | write_visibility(self.module(f.db).id, self.visibility(f.db), f)?; | ||
402 | let data = f.db.static_data(self.id); | ||
403 | write!(f, "static ")?; | ||
404 | if data.mutable { | ||
405 | write!(f, "mut ")?; | ||
406 | } | ||
407 | match &data.name { | ||
408 | Some(name) => write!(f, "{}: ", name)?, | ||
409 | None => write!(f, "_: ")?, | ||
410 | } | ||
411 | data.type_ref.hir_fmt(f)?; | ||
412 | Ok(()) | ||
413 | } | ||
414 | } | ||
415 | |||
416 | impl HirDisplay for Trait { | ||
417 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
418 | write_visibility(self.module(f.db).id, self.visibility(f.db), f)?; | ||
419 | let data = f.db.trait_data(self.id); | ||
420 | if data.is_unsafe { | ||
421 | write!(f, "unsafe ")?; | ||
422 | } | ||
423 | if data.is_auto { | ||
424 | write!(f, "auto ")?; | ||
425 | } | ||
426 | write!(f, "trait {}", data.name)?; | ||
427 | let def_id = GenericDefId::TraitId(self.id); | ||
428 | write_generic_params(def_id, f)?; | ||
429 | if !data.bounds.is_empty() { | ||
430 | write!(f, ": ")?; | ||
431 | f.write_joined(&*data.bounds, " + ")?; | ||
432 | } | ||
433 | write_where_clause(def_id, f)?; | ||
434 | Ok(()) | ||
435 | } | ||
436 | } | ||
437 | |||
438 | impl HirDisplay for TypeAlias { | ||
439 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
440 | write_visibility(self.module(f.db).id, self.visibility(f.db), f)?; | ||
441 | let data = f.db.type_alias_data(self.id); | ||
442 | write!(f, "type {}", data.name)?; | ||
443 | if !data.bounds.is_empty() { | ||
444 | write!(f, ": ")?; | ||
445 | f.write_joined(&data.bounds, " + ")?; | ||
446 | } | ||
447 | if let Some(ty) = &data.type_ref { | ||
448 | write!(f, " = ")?; | ||
449 | ty.hir_fmt(f)?; | ||
450 | } | ||
451 | Ok(()) | ||
452 | } | ||
453 | } | ||
454 | |||
455 | impl HirDisplay for Module { | ||
456 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
457 | // FIXME: Module doesn't have visibility saved in data. | ||
458 | match self.name(f.db) { | ||
459 | Some(name) => write!(f, "mod {}", name), | ||
460 | None if self.crate_root(f.db) == *self => match self.krate().display_name(f.db) { | ||
461 | Some(name) => write!(f, "extern crate {}", name), | ||
462 | None => write!(f, "extern crate {{unknown}}"), | ||
463 | }, | ||
464 | None => write!(f, "mod {{unnamed}}"), | ||
465 | } | ||
466 | } | ||
467 | } | ||
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index c5161dadd..12dd5fb38 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -29,6 +29,8 @@ mod has_source; | |||
29 | pub mod diagnostics; | 29 | pub mod diagnostics; |
30 | pub mod db; | 30 | pub mod db; |
31 | 31 | ||
32 | mod display; | ||
33 | |||
32 | use std::{iter, sync::Arc}; | 34 | use std::{iter, sync::Arc}; |
33 | 35 | ||
34 | use arrayvec::ArrayVec; | 36 | use arrayvec::ArrayVec; |
@@ -50,14 +52,15 @@ use hir_def::{ | |||
50 | use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind}; | 52 | use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind}; |
51 | use hir_ty::{ | 53 | use hir_ty::{ |
52 | autoderef, | 54 | autoderef, |
53 | display::{write_bounds_like_dyn_trait_with_prefix, HirDisplayError, HirFormatter}, | ||
54 | method_resolution::{self, TyFingerprint}, | 55 | method_resolution::{self, TyFingerprint}, |
56 | primitive::UintTy, | ||
55 | to_assoc_type_id, | 57 | to_assoc_type_id, |
56 | traits::{FnTrait, Solution, SolutionVariables}, | 58 | traits::{FnTrait, Solution, SolutionVariables}, |
57 | AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate, | 59 | AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate, |
58 | InEnvironment, Interner, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, Ty, | 60 | InEnvironment, Interner, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substitution, |
59 | TyDefId, TyKind, TyVariableKind, | 61 | Ty, TyDefId, TyKind, TyVariableKind, |
60 | }; | 62 | }; |
63 | use itertools::Itertools; | ||
61 | use rustc_hash::FxHashSet; | 64 | use rustc_hash::FxHashSet; |
62 | use stdx::{format_to, impl_from}; | 65 | use stdx::{format_to, impl_from}; |
63 | use syntax::{ | 66 | use syntax::{ |
@@ -139,7 +142,6 @@ impl Crate { | |||
139 | .collect() | 142 | .collect() |
140 | } | 143 | } |
141 | 144 | ||
142 | // FIXME: add `transitive_reverse_dependencies`. | ||
143 | pub fn reverse_dependencies(self, db: &dyn HirDatabase) -> Vec<Crate> { | 145 | pub fn reverse_dependencies(self, db: &dyn HirDatabase) -> Vec<Crate> { |
144 | let crate_graph = db.crate_graph(); | 146 | let crate_graph = db.crate_graph(); |
145 | crate_graph | 147 | crate_graph |
@@ -151,6 +153,14 @@ impl Crate { | |||
151 | .collect() | 153 | .collect() |
152 | } | 154 | } |
153 | 155 | ||
156 | pub fn transitive_reverse_dependencies(self, db: &dyn HirDatabase) -> Vec<Crate> { | ||
157 | db.crate_graph() | ||
158 | .transitive_reverse_dependencies(self.id) | ||
159 | .into_iter() | ||
160 | .map(|id| Crate { id }) | ||
161 | .collect() | ||
162 | } | ||
163 | |||
154 | pub fn root_module(self, db: &dyn HirDatabase) -> Module { | 164 | pub fn root_module(self, db: &dyn HirDatabase) -> Module { |
155 | let def_map = db.crate_def_map(self.id); | 165 | let def_map = db.crate_def_map(self.id); |
156 | Module { id: def_map.module_id(def_map.root()) } | 166 | Module { id: def_map.module_id(def_map.root()) } |
@@ -508,7 +518,7 @@ impl Field { | |||
508 | VariantDef::Union(it) => it.id.into(), | 518 | VariantDef::Union(it) => it.id.into(), |
509 | VariantDef::Variant(it) => it.parent.id.into(), | 519 | VariantDef::Variant(it) => it.parent.id.into(), |
510 | }; | 520 | }; |
511 | let substs = Substs::type_params(db, generic_def_id); | 521 | let substs = Substitution::type_params(db, generic_def_id); |
512 | let ty = db.field_types(var_id)[self.id].clone().subst(&substs); | 522 | let ty = db.field_types(var_id)[self.id].clone().subst(&substs); |
513 | Type::new(db, self.parent.module(db).id.krate(), var_id, ty) | 523 | Type::new(db, self.parent.module(db).id.krate(), var_id, ty) |
514 | } | 524 | } |
@@ -571,6 +581,12 @@ impl Struct { | |||
571 | } | 581 | } |
572 | } | 582 | } |
573 | 583 | ||
584 | impl HasVisibility for Struct { | ||
585 | fn visibility(&self, db: &dyn HirDatabase) -> Visibility { | ||
586 | db.struct_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast())) | ||
587 | } | ||
588 | } | ||
589 | |||
574 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 590 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
575 | pub struct Union { | 591 | pub struct Union { |
576 | pub(crate) id: UnionId, | 592 | pub(crate) id: UnionId, |
@@ -603,6 +619,12 @@ impl Union { | |||
603 | } | 619 | } |
604 | } | 620 | } |
605 | 621 | ||
622 | impl HasVisibility for Union { | ||
623 | fn visibility(&self, db: &dyn HirDatabase) -> Visibility { | ||
624 | db.union_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast())) | ||
625 | } | ||
626 | } | ||
627 | |||
606 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 628 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
607 | pub struct Enum { | 629 | pub struct Enum { |
608 | pub(crate) id: EnumId, | 630 | pub(crate) id: EnumId, |
@@ -630,6 +652,12 @@ impl Enum { | |||
630 | } | 652 | } |
631 | } | 653 | } |
632 | 654 | ||
655 | impl HasVisibility for Enum { | ||
656 | fn visibility(&self, db: &dyn HirDatabase) -> Visibility { | ||
657 | db.enum_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast())) | ||
658 | } | ||
659 | } | ||
660 | |||
633 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 661 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
634 | pub struct Variant { | 662 | pub struct Variant { |
635 | pub(crate) parent: Enum, | 663 | pub(crate) parent: Enum, |
@@ -821,7 +849,8 @@ impl Function { | |||
821 | db.function_data(self.id) | 849 | db.function_data(self.id) |
822 | .params | 850 | .params |
823 | .iter() | 851 | .iter() |
824 | .map(|type_ref| { | 852 | .enumerate() |
853 | .map(|(idx, type_ref)| { | ||
825 | let ty = Type { | 854 | let ty = Type { |
826 | krate, | 855 | krate, |
827 | ty: InEnvironment { | 856 | ty: InEnvironment { |
@@ -829,7 +858,7 @@ impl Function { | |||
829 | environment: environment.clone(), | 858 | environment: environment.clone(), |
830 | }, | 859 | }, |
831 | }; | 860 | }; |
832 | Param { ty } | 861 | Param { func: self, ty, idx } |
833 | }) | 862 | }) |
834 | .collect() | 863 | .collect() |
835 | } | 864 | } |
@@ -843,7 +872,7 @@ impl Function { | |||
843 | } | 872 | } |
844 | 873 | ||
845 | pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool { | 874 | pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool { |
846 | db.function_data(self.id).is_unsafe | 875 | db.function_data(self.id).qualifier.is_unsafe |
847 | } | 876 | } |
848 | 877 | ||
849 | pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { | 878 | pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { |
@@ -892,6 +921,9 @@ impl From<hir_ty::Mutability> for Access { | |||
892 | 921 | ||
893 | #[derive(Debug)] | 922 | #[derive(Debug)] |
894 | pub struct Param { | 923 | pub struct Param { |
924 | func: Function, | ||
925 | /// The index in parameter list, including self parameter. | ||
926 | idx: usize, | ||
895 | ty: Type, | 927 | ty: Type, |
896 | } | 928 | } |
897 | 929 | ||
@@ -899,6 +931,15 @@ impl Param { | |||
899 | pub fn ty(&self) -> &Type { | 931 | pub fn ty(&self) -> &Type { |
900 | &self.ty | 932 | &self.ty |
901 | } | 933 | } |
934 | |||
935 | pub fn pattern_source(&self, db: &dyn HirDatabase) -> Option<ast::Pat> { | ||
936 | let params = self.func.source(db)?.value.param_list()?; | ||
937 | if params.self_param().is_some() { | ||
938 | params.params().nth(self.idx.checked_sub(1)?)?.pat() | ||
939 | } else { | ||
940 | params.params().nth(self.idx)?.pat() | ||
941 | } | ||
942 | } | ||
902 | } | 943 | } |
903 | 944 | ||
904 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 945 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -921,6 +962,14 @@ impl SelfParam { | |||
921 | }) | 962 | }) |
922 | .unwrap_or(Access::Owned) | 963 | .unwrap_or(Access::Owned) |
923 | } | 964 | } |
965 | |||
966 | pub fn display(self, db: &dyn HirDatabase) -> &'static str { | ||
967 | match self.access(db) { | ||
968 | Access::Shared => "&self", | ||
969 | Access::Exclusive => "&mut self", | ||
970 | Access::Owned => "self", | ||
971 | } | ||
972 | } | ||
924 | } | 973 | } |
925 | 974 | ||
926 | impl HasVisibility for Function { | 975 | impl HasVisibility for Function { |
@@ -948,6 +997,10 @@ impl Const { | |||
948 | pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { | 997 | pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { |
949 | db.const_data(self.id).name.clone() | 998 | db.const_data(self.id).name.clone() |
950 | } | 999 | } |
1000 | |||
1001 | pub fn type_ref(self, db: &dyn HirDatabase) -> TypeRef { | ||
1002 | db.const_data(self.id).type_ref.clone() | ||
1003 | } | ||
951 | } | 1004 | } |
952 | 1005 | ||
953 | impl HasVisibility for Const { | 1006 | impl HasVisibility for Const { |
@@ -981,6 +1034,12 @@ impl Static { | |||
981 | } | 1034 | } |
982 | } | 1035 | } |
983 | 1036 | ||
1037 | impl HasVisibility for Static { | ||
1038 | fn visibility(&self, db: &dyn HirDatabase) -> Visibility { | ||
1039 | db.static_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast())) | ||
1040 | } | ||
1041 | } | ||
1042 | |||
984 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 1043 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
985 | pub struct Trait { | 1044 | pub struct Trait { |
986 | pub(crate) id: TraitId, | 1045 | pub(crate) id: TraitId, |
@@ -1000,7 +1059,13 @@ impl Trait { | |||
1000 | } | 1059 | } |
1001 | 1060 | ||
1002 | pub fn is_auto(self, db: &dyn HirDatabase) -> bool { | 1061 | pub fn is_auto(self, db: &dyn HirDatabase) -> bool { |
1003 | db.trait_data(self.id).auto | 1062 | db.trait_data(self.id).is_auto |
1063 | } | ||
1064 | } | ||
1065 | |||
1066 | impl HasVisibility for Trait { | ||
1067 | fn visibility(&self, db: &dyn HirDatabase) -> Visibility { | ||
1068 | db.trait_data(self.id).visibility.resolve(db.upcast(), &self.id.resolver(db.upcast())) | ||
1004 | } | 1069 | } |
1005 | } | 1070 | } |
1006 | 1071 | ||
@@ -1406,25 +1471,12 @@ impl TypeParam { | |||
1406 | let resolver = self.id.parent.resolver(db.upcast()); | 1471 | let resolver = self.id.parent.resolver(db.upcast()); |
1407 | let krate = self.id.parent.module(db.upcast()).krate(); | 1472 | let krate = self.id.parent.module(db.upcast()).krate(); |
1408 | let ty = params.get(local_idx)?.clone(); | 1473 | let ty = params.get(local_idx)?.clone(); |
1409 | let subst = Substs::type_params(db, self.id.parent); | 1474 | let subst = Substitution::type_params(db, self.id.parent); |
1410 | let ty = ty.subst(&subst.prefix(local_idx)); | 1475 | let ty = ty.subst(&subst.prefix(local_idx)); |
1411 | Some(Type::new_with_resolver_inner(db, krate, &resolver, ty)) | 1476 | Some(Type::new_with_resolver_inner(db, krate, &resolver, ty)) |
1412 | } | 1477 | } |
1413 | } | 1478 | } |
1414 | 1479 | ||
1415 | impl HirDisplay for TypeParam { | ||
1416 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
1417 | write!(f, "{}", self.name(f.db))?; | ||
1418 | let bounds = f.db.generic_predicates_for_param(self.id); | ||
1419 | let substs = Substs::type_params(f.db, self.id.parent); | ||
1420 | let predicates = bounds.iter().cloned().map(|b| b.subst(&substs)).collect::<Vec<_>>(); | ||
1421 | if !(predicates.is_empty() || f.omit_verbose_types()) { | ||
1422 | write_bounds_like_dyn_trait_with_prefix(":", &predicates, f)?; | ||
1423 | } | ||
1424 | Ok(()) | ||
1425 | } | ||
1426 | } | ||
1427 | |||
1428 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 1480 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
1429 | pub struct LifetimeParam { | 1481 | pub struct LifetimeParam { |
1430 | pub(crate) id: LifetimeParamId, | 1482 | pub(crate) id: LifetimeParamId, |
@@ -1497,11 +1549,17 @@ impl Impl { | |||
1497 | }; | 1549 | }; |
1498 | 1550 | ||
1499 | let mut all = Vec::new(); | 1551 | let mut all = Vec::new(); |
1500 | def_crates.into_iter().for_each(|id| { | 1552 | def_crates.iter().for_each(|&id| { |
1501 | all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter)) | 1553 | all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter)) |
1502 | }); | 1554 | }); |
1503 | let fp = TyFingerprint::for_impl(&ty.value); | 1555 | let fp = TyFingerprint::for_impl(&ty.value); |
1504 | for id in db.crate_graph().iter() { | 1556 | for id in def_crates |
1557 | .iter() | ||
1558 | .flat_map(|&id| Crate { id }.transitive_reverse_dependencies(db)) | ||
1559 | .map(|Crate { id }| id) | ||
1560 | .chain(def_crates.iter().copied()) | ||
1561 | .unique() | ||
1562 | { | ||
1505 | match fp { | 1563 | match fp { |
1506 | Some(fp) => all.extend( | 1564 | Some(fp) => all.extend( |
1507 | db.trait_impls_in_crate(id).for_self_ty(fp).map(Self::from).filter(filter), | 1565 | db.trait_impls_in_crate(id).for_self_ty(fp).map(Self::from).filter(filter), |
@@ -1516,7 +1574,8 @@ impl Impl { | |||
1516 | pub fn all_for_trait(db: &dyn HirDatabase, trait_: Trait) -> Vec<Impl> { | 1574 | pub fn all_for_trait(db: &dyn HirDatabase, trait_: Trait) -> Vec<Impl> { |
1517 | let krate = trait_.module(db).krate(); | 1575 | let krate = trait_.module(db).krate(); |
1518 | let mut all = Vec::new(); | 1576 | let mut all = Vec::new(); |
1519 | for Crate { id } in krate.reverse_dependencies(db).into_iter().chain(Some(krate)) { | 1577 | for Crate { id } in krate.transitive_reverse_dependencies(db).into_iter().chain(Some(krate)) |
1578 | { | ||
1520 | let impls = db.trait_impls_in_crate(id); | 1579 | let impls = db.trait_impls_in_crate(id); |
1521 | all.extend(impls.for_trait(trait_.id).map(Self::from)) | 1580 | all.extend(impls.for_trait(trait_.id).map(Self::from)) |
1522 | } | 1581 | } |
@@ -1615,7 +1674,7 @@ impl Type { | |||
1615 | krate: CrateId, | 1674 | krate: CrateId, |
1616 | def: impl HasResolver + Into<TyDefId> + Into<GenericDefId>, | 1675 | def: impl HasResolver + Into<TyDefId> + Into<GenericDefId>, |
1617 | ) -> Type { | 1676 | ) -> Type { |
1618 | let substs = Substs::build_for_def(db, def).fill_with_unknown().build(); | 1677 | let substs = Substitution::build_for_def(db, def).fill_with_unknown().build(); |
1619 | let ty = db.ty(def.into()).subst(&substs); | 1678 | let ty = db.ty(def.into()).subst(&substs); |
1620 | Type::new(db, krate, def, ty) | 1679 | Type::new(db, krate, def, ty) |
1621 | } | 1680 | } |
@@ -1631,6 +1690,10 @@ impl Type { | |||
1631 | matches!(self.ty.value.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..)) | 1690 | matches!(self.ty.value.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..)) |
1632 | } | 1691 | } |
1633 | 1692 | ||
1693 | pub fn is_usize(&self) -> bool { | ||
1694 | matches!(self.ty.value.interned(&Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize))) | ||
1695 | } | ||
1696 | |||
1634 | pub fn remove_ref(&self) -> Option<Type> { | 1697 | pub fn remove_ref(&self) -> Option<Type> { |
1635 | match &self.ty.value.interned(&Interner) { | 1698 | match &self.ty.value.interned(&Interner) { |
1636 | TyKind::Ref(.., ty) => Some(self.derived(ty.clone())), | 1699 | TyKind::Ref(.., ty) => Some(self.derived(ty.clone())), |
@@ -1691,7 +1754,7 @@ impl Type { | |||
1691 | pub fn impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool { | 1754 | pub fn impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool { |
1692 | let trait_ref = hir_ty::TraitRef { | 1755 | let trait_ref = hir_ty::TraitRef { |
1693 | trait_: trait_.id, | 1756 | trait_: trait_.id, |
1694 | substs: Substs::build_for_def(db, trait_.id) | 1757 | substs: Substitution::build_for_def(db, trait_.id) |
1695 | .push(self.ty.value.clone()) | 1758 | .push(self.ty.value.clone()) |
1696 | .fill(args.iter().map(|t| t.ty.value.clone())) | 1759 | .fill(args.iter().map(|t| t.ty.value.clone())) |
1697 | .build(), | 1760 | .build(), |
@@ -1715,7 +1778,7 @@ impl Type { | |||
1715 | args: &[Type], | 1778 | args: &[Type], |
1716 | alias: TypeAlias, | 1779 | alias: TypeAlias, |
1717 | ) -> Option<Type> { | 1780 | ) -> Option<Type> { |
1718 | let subst = Substs::build_for_def(db, trait_.id) | 1781 | let subst = Substitution::build_for_def(db, trait_.id) |
1719 | .push(self.ty.value.clone()) | 1782 | .push(self.ty.value.clone()) |
1720 | .fill(args.iter().map(|t| t.ty.value.clone())) | 1783 | .fill(args.iter().map(|t| t.ty.value.clone())) |
1721 | .build(); | 1784 | .build(); |
@@ -1982,7 +2045,7 @@ impl Type { | |||
1982 | fn walk_substs( | 2045 | fn walk_substs( |
1983 | db: &dyn HirDatabase, | 2046 | db: &dyn HirDatabase, |
1984 | type_: &Type, | 2047 | type_: &Type, |
1985 | substs: &Substs, | 2048 | substs: &Substitution, |
1986 | cb: &mut impl FnMut(Type), | 2049 | cb: &mut impl FnMut(Type), |
1987 | ) { | 2050 | ) { |
1988 | for ty in substs.iter() { | 2051 | for ty in substs.iter() { |
@@ -2054,12 +2117,6 @@ impl Type { | |||
2054 | } | 2117 | } |
2055 | } | 2118 | } |
2056 | 2119 | ||
2057 | impl HirDisplay for Type { | ||
2058 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
2059 | self.ty.value.hir_fmt(f) | ||
2060 | } | ||
2061 | } | ||
2062 | |||
2063 | // FIXME: closures | 2120 | // FIXME: closures |
2064 | #[derive(Debug)] | 2121 | #[derive(Debug)] |
2065 | pub struct Callable { | 2122 | pub struct Callable { |
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 519339c0c..03c9371b5 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs | |||
@@ -143,6 +143,12 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { | |||
143 | self.imp.diagnostics_display_range(diagnostics) | 143 | self.imp.diagnostics_display_range(diagnostics) |
144 | } | 144 | } |
145 | 145 | ||
146 | pub fn token_ancestors_with_macros( | ||
147 | &self, | ||
148 | token: SyntaxToken, | ||
149 | ) -> impl Iterator<Item = SyntaxNode> + '_ { | ||
150 | token.parent().into_iter().flat_map(move |it| self.ancestors_with_macros(it)) | ||
151 | } | ||
146 | pub fn ancestors_with_macros(&self, node: SyntaxNode) -> impl Iterator<Item = SyntaxNode> + '_ { | 152 | pub fn ancestors_with_macros(&self, node: SyntaxNode) -> impl Iterator<Item = SyntaxNode> + '_ { |
147 | self.imp.ancestors_with_macros(node) | 153 | self.imp.ancestors_with_macros(node) |
148 | } | 154 | } |
@@ -270,8 +276,8 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { | |||
270 | self.imp.scope(node) | 276 | self.imp.scope(node) |
271 | } | 277 | } |
272 | 278 | ||
273 | pub fn scope_at_offset(&self, node: &SyntaxNode, offset: TextSize) -> SemanticsScope<'db> { | 279 | pub fn scope_at_offset(&self, token: &SyntaxToken, offset: TextSize) -> SemanticsScope<'db> { |
274 | self.imp.scope_at_offset(node, offset) | 280 | self.imp.scope_at_offset(&token.parent().unwrap(), offset) |
275 | } | 281 | } |
276 | 282 | ||
277 | pub fn scope_for_def(&self, def: Trait) -> SemanticsScope<'db> { | 283 | pub fn scope_for_def(&self, def: Trait) -> SemanticsScope<'db> { |
@@ -341,7 +347,10 @@ impl<'db> SemanticsImpl<'db> { | |||
341 | 347 | ||
342 | fn descend_into_macros(&self, token: SyntaxToken) -> SyntaxToken { | 348 | fn descend_into_macros(&self, token: SyntaxToken) -> SyntaxToken { |
343 | let _p = profile::span("descend_into_macros"); | 349 | let _p = profile::span("descend_into_macros"); |
344 | let parent = token.parent(); | 350 | let parent = match token.parent() { |
351 | Some(it) => it, | ||
352 | None => return token, | ||
353 | }; | ||
345 | let sa = self.analyze(&parent); | 354 | let sa = self.analyze(&parent); |
346 | 355 | ||
347 | let token = successors(Some(InFile::new(sa.file_id, token)), |token| { | 356 | let token = successors(Some(InFile::new(sa.file_id, token)), |token| { |
@@ -360,7 +369,9 @@ impl<'db> SemanticsImpl<'db> { | |||
360 | .as_ref()? | 369 | .as_ref()? |
361 | .map_token_down(token.as_ref())?; | 370 | .map_token_down(token.as_ref())?; |
362 | 371 | ||
363 | self.cache(find_root(&token.value.parent()), token.file_id); | 372 | if let Some(parent) = token.value.parent() { |
373 | self.cache(find_root(&parent), token.file_id); | ||
374 | } | ||
364 | 375 | ||
365 | Some(token) | 376 | Some(token) |
366 | }) | 377 | }) |
@@ -378,7 +389,7 @@ impl<'db> SemanticsImpl<'db> { | |||
378 | // Handle macro token cases | 389 | // Handle macro token cases |
379 | node.token_at_offset(offset) | 390 | node.token_at_offset(offset) |
380 | .map(|token| self.descend_into_macros(token)) | 391 | .map(|token| self.descend_into_macros(token)) |
381 | .map(|it| self.ancestors_with_macros(it.parent())) | 392 | .map(|it| self.token_ancestors_with_macros(it)) |
382 | .flatten() | 393 | .flatten() |
383 | } | 394 | } |
384 | 395 | ||
@@ -394,6 +405,13 @@ impl<'db> SemanticsImpl<'db> { | |||
394 | src.with_value(&node).original_file_range(self.db.upcast()) | 405 | src.with_value(&node).original_file_range(self.db.upcast()) |
395 | } | 406 | } |
396 | 407 | ||
408 | fn token_ancestors_with_macros( | ||
409 | &self, | ||
410 | token: SyntaxToken, | ||
411 | ) -> impl Iterator<Item = SyntaxNode> + '_ { | ||
412 | token.parent().into_iter().flat_map(move |parent| self.ancestors_with_macros(parent)) | ||
413 | } | ||
414 | |||
397 | fn ancestors_with_macros(&self, node: SyntaxNode) -> impl Iterator<Item = SyntaxNode> + '_ { | 415 | fn ancestors_with_macros(&self, node: SyntaxNode) -> impl Iterator<Item = SyntaxNode> + '_ { |
398 | let node = self.find_file(node); | 416 | let node = self.find_file(node); |
399 | node.ancestors_with_macros(self.db.upcast()).map(|it| it.value) | 417 | node.ancestors_with_macros(self.db.upcast()).map(|it| it.value) |
@@ -405,7 +423,7 @@ impl<'db> SemanticsImpl<'db> { | |||
405 | offset: TextSize, | 423 | offset: TextSize, |
406 | ) -> impl Iterator<Item = SyntaxNode> + '_ { | 424 | ) -> impl Iterator<Item = SyntaxNode> + '_ { |
407 | node.token_at_offset(offset) | 425 | node.token_at_offset(offset) |
408 | .map(|token| self.ancestors_with_macros(token.parent())) | 426 | .map(|token| self.token_ancestors_with_macros(token)) |
409 | .kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len()) | 427 | .kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len()) |
410 | } | 428 | } |
411 | 429 | ||
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index 4d59293e9..117f32a9e 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, Substs, | 23 | InferenceResult, Substitution, |
24 | }; | 24 | }; |
25 | use syntax::{ | 25 | use syntax::{ |
26 | ast::{self, AstNode}, | 26 | ast::{self, AstNode}, |
@@ -329,7 +329,7 @@ impl SourceAnalyzer { | |||
329 | &self, | 329 | &self, |
330 | db: &dyn HirDatabase, | 330 | db: &dyn HirDatabase, |
331 | krate: CrateId, | 331 | krate: CrateId, |
332 | substs: &Substs, | 332 | substs: &Substitution, |
333 | variant: VariantId, | 333 | variant: VariantId, |
334 | missing_fields: Vec<LocalFieldId>, | 334 | missing_fields: Vec<LocalFieldId>, |
335 | ) -> Vec<(Field, Type)> { | 335 | ) -> Vec<(Field, Type)> { |