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.rs85
2 files changed, 502 insertions, 24 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 52939e990..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,7 +52,6 @@ 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},
55 primitive::UintTy, 56 primitive::UintTy,
56 to_assoc_type_id, 57 to_assoc_type_id,
@@ -572,6 +573,12 @@ impl Struct {
572 } 573 }
573} 574}
574 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
575#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 582#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
576pub struct Union { 583pub struct Union {
577 pub(crate) id: UnionId, 584 pub(crate) id: UnionId,
@@ -604,6 +611,12 @@ impl Union {
604 } 611 }
605} 612}
606 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
607#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 620#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
608pub struct Enum { 621pub struct Enum {
609 pub(crate) id: EnumId, 622 pub(crate) id: EnumId,
@@ -631,6 +644,12 @@ impl Enum {
631 } 644 }
632} 645}
633 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
634#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 653#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
635pub struct Variant { 654pub struct Variant {
636 pub(crate) parent: Enum, 655 pub(crate) parent: Enum,
@@ -822,7 +841,8 @@ impl Function {
822 db.function_data(self.id) 841 db.function_data(self.id)
823 .params 842 .params
824 .iter() 843 .iter()
825 .map(|type_ref| { 844 .enumerate()
845 .map(|(idx, type_ref)| {
826 let ty = Type { 846 let ty = Type {
827 krate, 847 krate,
828 ty: InEnvironment { 848 ty: InEnvironment {
@@ -830,7 +850,7 @@ impl Function {
830 environment: environment.clone(), 850 environment: environment.clone(),
831 }, 851 },
832 }; 852 };
833 Param { ty } 853 Param { func: self, ty, idx }
834 }) 854 })
835 .collect() 855 .collect()
836 } 856 }
@@ -844,7 +864,7 @@ impl Function {
844 } 864 }
845 865
846 pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool { 866 pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool {
847 db.function_data(self.id).is_unsafe 867 db.function_data(self.id).qualifier.is_unsafe
848 } 868 }
849 869
850 pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { 870 pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) {
@@ -893,6 +913,9 @@ impl From<hir_ty::Mutability> for Access {
893 913
894#[derive(Debug)] 914#[derive(Debug)]
895pub struct Param { 915pub struct Param {
916 func: Function,
917 /// The index in parameter list, including self parameter.
918 idx: usize,
896 ty: Type, 919 ty: Type,
897} 920}
898 921
@@ -900,6 +923,15 @@ impl Param {
900 pub fn ty(&self) -> &Type { 923 pub fn ty(&self) -> &Type {
901 &self.ty 924 &self.ty
902 } 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 }
903} 935}
904 936
905#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 937#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -922,6 +954,14 @@ impl SelfParam {
922 }) 954 })
923 .unwrap_or(Access::Owned) 955 .unwrap_or(Access::Owned)
924 } 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 }
925} 965}
926 966
927impl HasVisibility for Function { 967impl HasVisibility for Function {
@@ -949,6 +989,10 @@ impl Const {
949 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { 989 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
950 db.const_data(self.id).name.clone() 990 db.const_data(self.id).name.clone()
951 } 991 }
992
993 pub fn type_ref(self, db: &dyn HirDatabase) -> TypeRef {
994 db.const_data(self.id).type_ref.clone()
995 }
952} 996}
953 997
954impl HasVisibility for Const { 998impl HasVisibility for Const {
@@ -982,6 +1026,12 @@ impl Static {
982 } 1026 }
983} 1027}
984 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
985#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 1035#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
986pub struct Trait { 1036pub struct Trait {
987 pub(crate) id: TraitId, 1037 pub(crate) id: TraitId,
@@ -1001,7 +1051,13 @@ impl Trait {
1001 } 1051 }
1002 1052
1003 pub fn is_auto(self, db: &dyn HirDatabase) -> bool { 1053 pub fn is_auto(self, db: &dyn HirDatabase) -> bool {
1004 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()))
1005 } 1061 }
1006} 1062}
1007 1063
@@ -1413,19 +1469,6 @@ impl TypeParam {
1413 } 1469 }
1414} 1470}
1415 1471
1416impl HirDisplay for TypeParam {
1417 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
1418 write!(f, "{}", self.name(f.db))?;
1419 let bounds = f.db.generic_predicates_for_param(self.id);
1420 let substs = Substs::type_params(f.db, self.id.parent);
1421 let predicates = bounds.iter().cloned().map(|b| b.subst(&substs)).collect::<Vec<_>>();
1422 if !(predicates.is_empty() || f.omit_verbose_types()) {
1423 write_bounds_like_dyn_trait_with_prefix(":", &predicates, f)?;
1424 }
1425 Ok(())
1426 }
1427}
1428
1429#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 1472#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1430pub struct LifetimeParam { 1473pub struct LifetimeParam {
1431 pub(crate) id: LifetimeParamId, 1474 pub(crate) id: LifetimeParamId,
@@ -2059,12 +2102,6 @@ impl Type {
2059 } 2102 }
2060} 2103}
2061 2104
2062impl HirDisplay for Type {
2063 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
2064 self.ty.value.hir_fmt(f)
2065 }
2066}
2067
2068// FIXME: closures 2105// FIXME: closures
2069#[derive(Debug)] 2106#[derive(Debug)]
2070pub struct Callable { 2107pub struct Callable {