aboutsummaryrefslogtreecommitdiff
path: root/crates/hir
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir')
-rw-r--r--crates/hir/src/display.rs441
-rw-r--r--crates/hir/src/lib.rs90
-rw-r--r--crates/hir/src/semantics.rs30
3 files changed, 531 insertions, 30 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 c5161dadd..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,8 +52,8 @@ 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},
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,
@@ -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,
@@ -821,7 +841,8 @@ impl Function {
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 {
@@ -829,7 +850,7 @@ impl Function {
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)]
@@ -921,6 +954,14 @@ impl SelfParam {
921 }) 954 })
922 .unwrap_or(Access::Owned) 955 .unwrap_or(Access::Owned)
923 } 956 }
957
958 pub fn display(self, db: &dyn HirDatabase) -> &'static str {
959 match self.access(db) {
960 Access::Shared => "&self",
961 Access::Exclusive => "&mut self",
962 Access::Owned => "self",
963 }
964 }
924} 965}
925 966
926impl HasVisibility for Function { 967impl HasVisibility for Function {
@@ -948,6 +989,10 @@ impl Const {
948 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { 989 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
949 db.const_data(self.id).name.clone() 990 db.const_data(self.id).name.clone()
950 } 991 }
992
993 pub fn type_ref(self, db: &dyn HirDatabase) -> TypeRef {
994 db.const_data(self.id).type_ref.clone()
995 }
951} 996}
952 997
953impl HasVisibility for Const { 998impl HasVisibility for Const {
@@ -981,6 +1026,12 @@ impl Static {
981 } 1026 }
982} 1027}
983 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
984#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 1035#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
985pub struct Trait { 1036pub struct Trait {
986 pub(crate) id: TraitId, 1037 pub(crate) id: TraitId,
@@ -1000,7 +1051,13 @@ impl Trait {
1000 } 1051 }
1001 1052
1002 pub fn is_auto(self, db: &dyn HirDatabase) -> bool { 1053 pub fn is_auto(self, db: &dyn HirDatabase) -> bool {
1003 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()))
1004 } 1061 }
1005} 1062}
1006 1063
@@ -1412,19 +1469,6 @@ impl TypeParam {
1412 } 1469 }
1413} 1470}
1414 1471
1415impl 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)] 1472#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1429pub struct LifetimeParam { 1473pub struct LifetimeParam {
1430 pub(crate) id: LifetimeParamId, 1474 pub(crate) id: LifetimeParamId,
@@ -1631,6 +1675,10 @@ impl Type {
1631 matches!(self.ty.value.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..)) 1675 matches!(self.ty.value.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..))
1632 } 1676 }
1633 1677
1678 pub fn is_usize(&self) -> bool {
1679 matches!(self.ty.value.interned(&Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize)))
1680 }
1681
1634 pub fn remove_ref(&self) -> Option<Type> { 1682 pub fn remove_ref(&self) -> Option<Type> {
1635 match &self.ty.value.interned(&Interner) { 1683 match &self.ty.value.interned(&Interner) {
1636 TyKind::Ref(.., ty) => Some(self.derived(ty.clone())), 1684 TyKind::Ref(.., ty) => Some(self.derived(ty.clone())),
@@ -2054,12 +2102,6 @@ impl Type {
2054 } 2102 }
2055} 2103}
2056 2104
2057impl 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 2105// FIXME: closures
2064#[derive(Debug)] 2106#[derive(Debug)]
2065pub struct Callable { 2107pub 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