1use either::Either;
4use hir_def::{
5 AdtId, GenericDefId,
6 expr_store::ExpressionStore,
7 hir::generics::{GenericParams, TypeOrConstParamData, TypeParamProvenance, WherePredicate},
8 item_tree::FieldsShape,
9 lang_item::LangItem,
10 signatures::{StaticFlags, TraitFlags},
11 type_ref::{TypeBound, TypeRef, TypeRefId},
12};
13use hir_ty::{
14 AliasEq, AliasTy, Interner, ProjectionTyExt, TraitRefExt, TyKind, WhereClause,
15 db::HirDatabase,
16 display::{
17 HirDisplay, HirDisplayError, HirDisplayWithExpressionStore, HirFormatter, SizedByDefault,
18 hir_display_with_store, write_bounds_like_dyn_trait_with_prefix, write_visibility,
19 },
20};
21use itertools::Itertools;
22
23use crate::{
24 Adt, AsAssocItem, AssocItem, AssocItemContainer, Const, ConstParam, Crate, Enum,
25 ExternCrateDecl, Field, Function, GenericParam, HasCrate, HasVisibility, Impl, LifetimeParam,
26 Macro, Module, SelfParam, Static, Struct, StructKind, Trait, TraitRef, TupleField, TyBuilder,
27 Type, TypeAlias, TypeOrConstParam, TypeParam, Union, Variant,
28};
29
30impl HirDisplay for Function {
31 fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
32 let db = f.db;
33 let data = db.function_signature(self.id);
34 let container = self.as_assoc_item(db).map(|it| it.container(db));
35 let mut module = self.module(db);
36
37 let container_params = match container {
39 Some(AssocItemContainer::Trait(trait_)) => {
40 let (params, params_store) = f.db.generic_params_and_store(trait_.id.into());
41 if f.show_container_bounds() && !params.is_empty() {
42 write_trait_header(&trait_, f)?;
43 f.write_char('\n')?;
44 has_disaplayable_predicates(f.db, ¶ms, ¶ms_store)
45 .then_some((params, params_store))
46 } else {
47 None
48 }
49 }
50 Some(AssocItemContainer::Impl(impl_)) => {
51 let (params, params_store) = f.db.generic_params_and_store(impl_.id.into());
52 if f.show_container_bounds() && !params.is_empty() {
53 write_impl_header(&impl_, f)?;
54 f.write_char('\n')?;
55 has_disaplayable_predicates(f.db, ¶ms, ¶ms_store)
56 .then_some((params, params_store))
57 } else {
58 None
59 }
60 }
61 None => None,
62 };
63
64 if let Some(AssocItemContainer::Impl(_)) = container {
68 module = module.nearest_non_block_module(db);
69 }
70 let module_id = module.id;
71
72 write_visibility(module_id, self.visibility(db), f)?;
73
74 if data.is_default() {
75 f.write_str("default ")?;
76 }
77 if data.is_const() {
78 f.write_str("const ")?;
79 }
80 if data.is_async() {
81 f.write_str("async ")?;
82 }
83 if self.is_unsafe_to_call(db, None, f.edition()) {
86 f.write_str("unsafe ")?;
87 }
88 if let Some(abi) = &data.abi {
89 write!(f, "extern \"{}\" ", abi.as_str())?;
90 }
91 write!(f, "fn {}", data.name.display(f.db, f.edition()))?;
92
93 write_generic_params(GenericDefId::FunctionId(self.id), f)?;
94
95 f.write_char('(')?;
96
97 let mut first = true;
98 let mut skip_self = 0;
99 if let Some(self_param) = self.self_param(db) {
100 self_param.hir_fmt(f)?;
101 first = false;
102 skip_self = 1;
103 }
104
105 let body = db.body(self.id.into());
107 for (type_ref, param) in data.params.iter().zip(self.assoc_fn_params(db)).skip(skip_self) {
108 if !first {
109 f.write_str(", ")?;
110 } else {
111 first = false;
112 }
113
114 let pat_id = body.params[param.idx - body.self_param.is_some() as usize];
115 let pat_str = body.pretty_print_pat(db, self.id.into(), pat_id, true, f.edition());
116 f.write_str(&pat_str)?;
117
118 f.write_str(": ")?;
119 type_ref.hir_fmt(f, &data.store)?;
120 }
121
122 if data.is_varargs() {
123 if !first {
124 f.write_str(", ")?;
125 }
126 f.write_str("...")?;
127 }
128
129 f.write_char(')')?;
130
131 let ret_type = if !data.is_async() {
135 data.ret_type
136 } else if let Some(ret_type) = data.ret_type {
137 match &data.store[ret_type] {
138 TypeRef::ImplTrait(bounds) => match &bounds[0] {
139 &TypeBound::Path(path, _) => Some(
140 *data.store[path]
141 .segments()
142 .iter()
143 .last()
144 .unwrap()
145 .args_and_bindings
146 .unwrap()
147 .bindings[0]
148 .type_ref
149 .as_ref()
150 .unwrap(),
151 ),
152 _ => None,
153 },
154 _ => None,
155 }
156 } else {
157 None
158 };
159
160 if let Some(ret_type) = ret_type {
161 match &data.store[ret_type] {
162 TypeRef::Tuple(tup) if tup.is_empty() => {}
163 _ => {
164 f.write_str(" -> ")?;
165 ret_type.hir_fmt(f, &data.store)?;
166 }
167 }
168 }
169
170 let has_written_where = write_where_clause(GenericDefId::FunctionId(self.id), f)?;
172 if let Some((container_params, container_params_store)) = container_params {
173 if !has_written_where {
174 f.write_str("\nwhere")?;
175 }
176 let container_name = match container.unwrap() {
177 AssocItemContainer::Trait(_) => "trait",
178 AssocItemContainer::Impl(_) => "impl",
179 };
180 write!(f, "\n // Bounds from {container_name}:",)?;
181 write_where_predicates(&container_params, &container_params_store, f)?;
182 }
183 Ok(())
184 }
185}
186
187fn write_impl_header(impl_: &Impl, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
188 let db = f.db;
189
190 f.write_str("impl")?;
191 let def_id = GenericDefId::ImplId(impl_.id);
192 write_generic_params(def_id, f)?;
193
194 if let Some(trait_) = impl_.trait_(db) {
195 let trait_data = db.trait_signature(trait_.id);
196 write!(f, " {} for", trait_data.name.display(db, f.edition()))?;
197 }
198
199 f.write_char(' ')?;
200 impl_.self_ty(db).hir_fmt(f)?;
201
202 Ok(())
203}
204
205impl HirDisplay for SelfParam {
206 fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
207 let data = f.db.function_signature(self.func);
208 let param = *data.params.first().unwrap();
209 match &data.store[param] {
210 TypeRef::Path(p) if p.is_self_type() => f.write_str("self"),
211 TypeRef::Reference(ref_) if matches!(&data.store[ref_.ty], TypeRef::Path(p) if p.is_self_type()) =>
212 {
213 f.write_char('&')?;
214 if let Some(lifetime) = &ref_.lifetime {
215 lifetime.hir_fmt(f, &data.store)?;
216 f.write_char(' ')?;
217 }
218 if let hir_def::type_ref::Mutability::Mut = ref_.mutability {
219 f.write_str("mut ")?;
220 }
221 f.write_str("self")
222 }
223 _ => {
224 f.write_str("self: ")?;
225 param.hir_fmt(f, &data.store)
226 }
227 }
228 }
229}
230
231impl HirDisplay for Adt {
232 fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
233 match self {
234 Adt::Struct(it) => it.hir_fmt(f),
235 Adt::Union(it) => it.hir_fmt(f),
236 Adt::Enum(it) => it.hir_fmt(f),
237 }
238 }
239}
240
241impl HirDisplay for Struct {
242 fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
243 let module_id = self.module(f.db).id;
244 write_visibility(module_id, self.visibility(f.db), f)?;
246 f.write_str("struct ")?;
247 write!(f, "{}", self.name(f.db).display(f.db, f.edition()))?;
248 let def_id = GenericDefId::AdtId(AdtId::StructId(self.id));
249 write_generic_params(def_id, f)?;
250
251 let variant_data = self.variant_fields(f.db);
252 match self.kind(f.db) {
253 StructKind::Tuple => {
254 f.write_char('(')?;
255 let mut it = variant_data.fields().iter().peekable();
256
257 while let Some((id, _)) = it.next() {
258 let field = Field { parent: (*self).into(), id };
259 write_visibility(module_id, field.visibility(f.db), f)?;
260 field.ty(f.db).hir_fmt(f)?;
261 if it.peek().is_some() {
262 f.write_str(", ")?;
263 }
264 }
265
266 f.write_char(')')?;
267 write_where_clause(def_id, f)?;
268 }
269 StructKind::Record => {
270 let has_where_clause = write_where_clause(def_id, f)?;
271 if let Some(limit) = f.entity_limit {
272 write_fields(&self.fields(f.db), has_where_clause, limit, false, f)?;
273 }
274 }
275 StructKind::Unit => _ = write_where_clause(def_id, f)?,
276 }
277
278 Ok(())
279 }
280}
281
282impl HirDisplay for Enum {
283 fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
284 write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
285 f.write_str("enum ")?;
286 write!(f, "{}", self.name(f.db).display(f.db, f.edition()))?;
287 let def_id = GenericDefId::AdtId(AdtId::EnumId(self.id));
288 write_generic_params(def_id, f)?;
289
290 let has_where_clause = write_where_clause(def_id, f)?;
291 if let Some(limit) = f.entity_limit {
292 write_variants(&self.variants(f.db), has_where_clause, limit, f)?;
293 }
294
295 Ok(())
296 }
297}
298
299impl HirDisplay for Union {
300 fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
301 write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
302 f.write_str("union ")?;
303 write!(f, "{}", self.name(f.db).display(f.db, f.edition()))?;
304 let def_id = GenericDefId::AdtId(AdtId::UnionId(self.id));
305 write_generic_params(def_id, f)?;
306
307 let has_where_clause = write_where_clause(def_id, f)?;
308 if let Some(limit) = f.entity_limit {
309 write_fields(&self.fields(f.db), has_where_clause, limit, false, f)?;
310 }
311 Ok(())
312 }
313}
314
315fn write_fields(
316 fields: &[Field],
317 has_where_clause: bool,
318 limit: usize,
319 in_line: bool,
320 f: &mut HirFormatter<'_>,
321) -> Result<(), HirDisplayError> {
322 let count = fields.len().min(limit);
323 let (indent, separator) = if in_line { ("", ' ') } else { (" ", '\n') };
324 f.write_char(if !has_where_clause { ' ' } else { separator })?;
325 if count == 0 {
326 f.write_str(if fields.is_empty() { "{}" } else { "{ /* … */ }" })?;
327 } else {
328 f.write_char('{')?;
329
330 if !fields.is_empty() {
331 f.write_char(separator)?;
332 for field in &fields[..count] {
333 f.write_str(indent)?;
334 field.hir_fmt(f)?;
335 write!(f, ",{separator}")?;
336 }
337
338 if fields.len() > count {
339 write!(f, "{indent}/* … */{separator}")?;
340 }
341 }
342
343 f.write_str("}")?;
344 }
345
346 Ok(())
347}
348
349fn write_variants(
350 variants: &[Variant],
351 has_where_clause: bool,
352 limit: usize,
353 f: &mut HirFormatter<'_>,
354) -> Result<(), HirDisplayError> {
355 let count = variants.len().min(limit);
356 f.write_char(if !has_where_clause { ' ' } else { '\n' })?;
357 if count == 0 {
358 let variants = if variants.is_empty() { "{}" } else { "{ /* … */ }" };
359 f.write_str(variants)?;
360 } else {
361 f.write_str("{\n")?;
362 for variant in &variants[..count] {
363 write!(f, " {}", variant.name(f.db).display(f.db, f.edition()))?;
364 match variant.kind(f.db) {
365 StructKind::Tuple => {
366 let fields_str =
367 if variant.fields(f.db).is_empty() { "()" } else { "( /* … */ )" };
368 f.write_str(fields_str)?;
369 }
370 StructKind::Record => {
371 let fields_str =
372 if variant.fields(f.db).is_empty() { " {}" } else { " { /* … */ }" };
373 f.write_str(fields_str)?;
374 }
375 StructKind::Unit => {}
376 }
377 f.write_str(",\n")?;
378 }
379
380 if variants.len() > count {
381 f.write_str(" /* … */\n")?;
382 }
383 f.write_str("}")?;
384 }
385
386 Ok(())
387}
388
389impl HirDisplay for Field {
390 fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
391 write_visibility(self.parent.module(f.db).id, self.visibility(f.db), f)?;
392 write!(f, "{}: ", self.name(f.db).display(f.db, f.edition()))?;
393 self.ty(f.db).hir_fmt(f)
394 }
395}
396
397impl HirDisplay for TupleField {
398 fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
399 write!(f, "pub {}: ", self.name().display(f.db, f.edition()))?;
400 self.ty(f.db).hir_fmt(f)
401 }
402}
403
404impl HirDisplay for Variant {
405 fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
406 write!(f, "{}", self.name(f.db).display(f.db, f.edition()))?;
407 let data = self.id.fields(f.db);
408 match data.shape {
409 FieldsShape::Unit => {}
410 FieldsShape::Tuple => {
411 f.write_char('(')?;
412 let mut first = true;
413 for (_, field) in data.fields().iter() {
414 if first {
415 first = false;
416 } else {
417 f.write_str(", ")?;
418 }
419 field.type_ref.hir_fmt(f, &data.store)?;
421 }
422 f.write_char(')')?;
423 }
424 FieldsShape::Record => {
425 if let Some(limit) = f.entity_limit {
426 write_fields(&self.fields(f.db), false, limit, true, f)?;
427 }
428 }
429 }
430 Ok(())
431 }
432}
433
434impl HirDisplay for Type<'_> {
435 fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
436 self.ty.hir_fmt(f)
437 }
438}
439
440impl HirDisplay for ExternCrateDecl {
441 fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
442 write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
443 f.write_str("extern crate ")?;
444 write!(f, "{}", self.name(f.db).display(f.db, f.edition()))?;
445 if let Some(alias) = self.alias(f.db) {
446 write!(f, " as {}", alias.display(f.edition()))?;
447 }
448 Ok(())
449 }
450}
451
452impl HirDisplay for GenericParam {
453 fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
454 match self {
455 GenericParam::TypeParam(it) => it.hir_fmt(f),
456 GenericParam::ConstParam(it) => it.hir_fmt(f),
457 GenericParam::LifetimeParam(it) => it.hir_fmt(f),
458 }
459 }
460}
461
462impl HirDisplay for TypeOrConstParam {
463 fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
464 match self.split(f.db) {
465 either::Either::Left(it) => it.hir_fmt(f),
466 either::Either::Right(it) => it.hir_fmt(f),
467 }
468 }
469}
470
471impl HirDisplay for TypeParam {
472 fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
473 let params = f.db.generic_params(self.id.parent());
474 let param_data = ¶ms[self.id.local_id()];
475 let substs = TyBuilder::placeholder_subst(f.db, self.id.parent());
476 let krate = self.id.parent().krate(f.db).id;
477 let ty = TyKind::Placeholder(hir_ty::to_placeholder_idx_no_index(f.db, self.id.into()))
478 .intern(Interner);
479 let predicates = f.db.generic_predicates(self.id.parent());
480 let predicates = predicates
481 .iter()
482 .cloned()
483 .map(|pred| pred.substitute(Interner, &substs))
484 .filter(|wc| match wc.skip_binders() {
485 WhereClause::Implemented(tr) => tr.self_type_parameter(Interner) == ty,
486 WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(proj), ty: _ }) => {
487 proj.self_type_parameter(f.db) == ty
488 }
489 WhereClause::AliasEq(_) => false,
490 WhereClause::TypeOutlives(to) => to.ty == ty,
491 WhereClause::LifetimeOutlives(_) => false,
492 })
493 .collect::<Vec<_>>();
494
495 match param_data {
496 TypeOrConstParamData::TypeParamData(p) => match p.provenance {
497 TypeParamProvenance::TypeParamList | TypeParamProvenance::TraitSelf => {
498 write!(f, "{}", p.name.clone().unwrap().display(f.db, f.edition()))?
499 }
500 TypeParamProvenance::ArgumentImplTrait => {
501 return write_bounds_like_dyn_trait_with_prefix(
502 f,
503 "impl",
504 Either::Left(&ty),
505 &predicates,
506 SizedByDefault::Sized { anchor: krate },
507 );
508 }
509 },
510 TypeOrConstParamData::ConstParamData(p) => {
511 write!(f, "{}", p.name.display(f.db, f.edition()))?;
512 }
513 }
514
515 if f.omit_verbose_types() {
516 return Ok(());
517 }
518
519 let sized_trait = LangItem::Sized.resolve_trait(f.db, krate);
520 let has_only_sized_bound = predicates.iter().all(move |pred| match pred.skip_binders() {
521 WhereClause::Implemented(it) => Some(it.hir_trait_id()) == sized_trait,
522 _ => false,
523 });
524 let has_only_not_sized_bound = predicates.is_empty();
525 if !has_only_sized_bound || has_only_not_sized_bound {
526 let default_sized = SizedByDefault::Sized { anchor: krate };
527 write_bounds_like_dyn_trait_with_prefix(
528 f,
529 ":",
530 Either::Left(
531 &hir_ty::TyKind::Placeholder(hir_ty::to_placeholder_idx_no_index(
532 f.db,
533 self.id.into(),
534 ))
535 .intern(Interner),
536 ),
537 &predicates,
538 default_sized,
539 )?;
540 }
541 Ok(())
542 }
543}
544
545impl HirDisplay for LifetimeParam {
546 fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
547 write!(f, "{}", self.name(f.db).display(f.db, f.edition()))
548 }
549}
550
551impl HirDisplay for ConstParam {
552 fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
553 write!(f, "const {}: ", self.name(f.db).display(f.db, f.edition()))?;
554 self.ty(f.db).hir_fmt(f)
555 }
556}
557
558fn write_generic_params(
559 def: GenericDefId,
560 f: &mut HirFormatter<'_>,
561) -> Result<(), HirDisplayError> {
562 let (params, store) = f.db.generic_params_and_store(def);
563 if params.iter_lt().next().is_none()
564 && params.iter_type_or_consts().all(|it| it.1.const_param().is_none())
565 && params
566 .iter_type_or_consts()
567 .filter_map(|it| it.1.type_param())
568 .all(|param| !matches!(param.provenance, TypeParamProvenance::TypeParamList))
569 {
570 return Ok(());
571 }
572 f.write_char('<')?;
573
574 let mut first = true;
575 let mut delim = |f: &mut HirFormatter<'_>| {
576 if first {
577 first = false;
578 Ok(())
579 } else {
580 f.write_str(", ")
581 }
582 };
583 for (_, lifetime) in params.iter_lt() {
584 delim(f)?;
585 write!(f, "{}", lifetime.name.display(f.db, f.edition()))?;
586 }
587 for (_, ty) in params.iter_type_or_consts() {
588 if let Some(name) = &ty.name() {
589 match ty {
590 TypeOrConstParamData::TypeParamData(ty) => {
591 if ty.provenance != TypeParamProvenance::TypeParamList {
592 continue;
593 }
594 delim(f)?;
595 write!(f, "{}", name.display(f.db, f.edition()))?;
596 if let Some(default) = &ty.default {
597 f.write_str(" = ")?;
598 default.hir_fmt(f, &store)?;
599 }
600 }
601 TypeOrConstParamData::ConstParamData(c) => {
602 delim(f)?;
603 write!(f, "const {}: ", name.display(f.db, f.edition()))?;
604 c.ty.hir_fmt(f, &store)?;
605
606 if let Some(default) = &c.default {
607 f.write_str(" = ")?;
608 default.hir_fmt(f, &store)?;
609 }
610 }
611 }
612 }
613 }
614
615 f.write_char('>')?;
616 Ok(())
617}
618
619fn write_where_clause(
620 def: GenericDefId,
621 f: &mut HirFormatter<'_>,
622) -> Result<bool, HirDisplayError> {
623 let (params, store) = f.db.generic_params_and_store(def);
624 if !has_disaplayable_predicates(f.db, ¶ms, &store) {
625 return Ok(false);
626 }
627
628 f.write_str("\nwhere")?;
629 write_where_predicates(¶ms, &store, f)?;
630
631 Ok(true)
632}
633
634fn has_disaplayable_predicates(
635 db: &dyn HirDatabase,
636 params: &GenericParams,
637 store: &ExpressionStore,
638) -> bool {
639 params.where_predicates().iter().any(|pred| {
640 !matches!(
641 pred,
642 WherePredicate::TypeBound { target, .. }
643 if matches!(store[*target],
644 TypeRef::TypeParam(id) if db.generic_params(id.parent())[id.local_id()].name().is_none()
645 )
646 )
647 })
648}
649
650fn write_where_predicates(
651 params: &GenericParams,
652 store: &ExpressionStore,
653 f: &mut HirFormatter<'_>,
654) -> Result<(), HirDisplayError> {
655 use WherePredicate::*;
656
657 let is_unnamed_type_target = |target: TypeRefId| {
659 matches!(store[target],
660 TypeRef::TypeParam(id) if f.db.generic_params(id.parent())[id.local_id()].name().is_none()
661 )
662 };
663
664 let check_same_target = |pred1: &WherePredicate, pred2: &WherePredicate| match (pred1, pred2) {
665 (TypeBound { target: t1, .. }, TypeBound { target: t2, .. }) => t1 == t2,
666 (Lifetime { target: t1, .. }, Lifetime { target: t2, .. }) => t1 == t2,
667 (
668 ForLifetime { lifetimes: l1, target: t1, .. },
669 ForLifetime { lifetimes: l2, target: t2, .. },
670 ) => l1 == l2 && t1 == t2,
671 _ => false,
672 };
673
674 let mut iter = params.where_predicates().iter().peekable();
675 while let Some(pred) = iter.next() {
676 if matches!(pred, TypeBound { target, .. } if is_unnamed_type_target(*target)) {
677 continue;
678 }
679
680 f.write_str("\n ")?;
681 match pred {
682 TypeBound { target, bound } => {
683 target.hir_fmt(f, store)?;
684 f.write_str(": ")?;
685 bound.hir_fmt(f, store)?;
686 }
687 Lifetime { target, bound } => {
688 target.hir_fmt(f, store)?;
689 write!(f, ": ")?;
690 bound.hir_fmt(f, store)?;
691 }
692 ForLifetime { lifetimes, target, bound } => {
693 let lifetimes = lifetimes.iter().map(|it| it.display(f.db, f.edition())).join(", ");
694 write!(f, "for<{lifetimes}> ")?;
695 target.hir_fmt(f, store)?;
696 f.write_str(": ")?;
697 bound.hir_fmt(f, store)?;
698 }
699 }
700
701 while let Some(nxt) = iter.next_if(|nxt| check_same_target(pred, nxt)) {
702 f.write_str(" + ")?;
703 match nxt {
704 TypeBound { bound, .. } | ForLifetime { bound, .. } => bound.hir_fmt(f, store)?,
705 Lifetime { bound, .. } => bound.hir_fmt(f, store)?,
706 }
707 }
708 f.write_str(",")?;
709 }
710
711 Ok(())
712}
713
714impl HirDisplay for Const {
715 fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
716 let db = f.db;
717 let container = self.as_assoc_item(db).map(|it| it.container(db));
718 let mut module = self.module(db);
719 if let Some(AssocItemContainer::Impl(_)) = container {
720 module = module.nearest_non_block_module(db);
722 }
723 write_visibility(module.id, self.visibility(db), f)?;
724 let data = db.const_signature(self.id);
725 f.write_str("const ")?;
726 match &data.name {
727 Some(name) => write!(f, "{}: ", name.display(f.db, f.edition()))?,
728 None => f.write_str("_: ")?,
729 }
730 data.type_ref.hir_fmt(f, &data.store)?;
731 Ok(())
732 }
733}
734
735impl HirDisplay for Static {
736 fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
737 write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
738 let data = f.db.static_signature(self.id);
739 f.write_str("static ")?;
740 if data.flags.contains(StaticFlags::MUTABLE) {
741 f.write_str("mut ")?;
742 }
743 write!(f, "{}: ", data.name.display(f.db, f.edition()))?;
744 data.type_ref.hir_fmt(f, &data.store)?;
745 Ok(())
746 }
747}
748
749impl HirDisplay for TraitRef<'_> {
750 fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
751 self.trait_ref.hir_fmt(f)
752 }
753}
754
755impl HirDisplay for Trait {
756 fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
757 write_trait_header(self, f)?;
759 let def_id = GenericDefId::TraitId(self.id);
760 let has_where_clause = write_where_clause(def_id, f)?;
761
762 if let Some(limit) = f.entity_limit {
763 let assoc_items = self.items(f.db);
764 let count = assoc_items.len().min(limit);
765 f.write_char(if !has_where_clause { ' ' } else { '\n' })?;
766 if count == 0 {
767 if assoc_items.is_empty() {
768 f.write_str("{}")?;
769 } else {
770 f.write_str("{ /* … */ }")?;
771 }
772 } else {
773 f.write_str("{\n")?;
774 for item in &assoc_items[..count] {
775 f.write_str(" ")?;
776 match item {
777 AssocItem::Function(func) => func.hir_fmt(f),
778 AssocItem::Const(cst) => cst.hir_fmt(f),
779 AssocItem::TypeAlias(type_alias) => type_alias.hir_fmt(f),
780 }?;
781 f.write_str(";\n")?;
782 }
783
784 if assoc_items.len() > count {
785 f.write_str(" /* … */\n")?;
786 }
787 f.write_str("}")?;
788 }
789 }
790
791 Ok(())
792 }
793}
794
795fn write_trait_header(trait_: &Trait, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
796 write_visibility(trait_.module(f.db).id, trait_.visibility(f.db), f)?;
797 let data = f.db.trait_signature(trait_.id);
798 if data.flags.contains(TraitFlags::UNSAFE) {
799 f.write_str("unsafe ")?;
800 }
801 if data.flags.contains(TraitFlags::AUTO) {
802 f.write_str("auto ")?;
803 }
804 write!(f, "trait {}", data.name.display(f.db, f.edition()))?;
805 write_generic_params(GenericDefId::TraitId(trait_.id), f)?;
806 Ok(())
807}
808
809impl HirDisplay for TypeAlias {
810 fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
811 write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
812 let data = f.db.type_alias_signature(self.id);
813 write!(f, "type {}", data.name.display(f.db, f.edition()))?;
814 let def_id = GenericDefId::TypeAliasId(self.id);
815 write_generic_params(def_id, f)?;
816 if !data.bounds.is_empty() {
817 f.write_str(": ")?;
818 f.write_joined(
819 data.bounds.iter().map(|bound| hir_display_with_store(bound, &data.store)),
820 " + ",
821 )?;
822 }
823 if let Some(ty) = data.ty {
824 f.write_str(" = ")?;
825 ty.hir_fmt(f, &data.store)?;
826 }
827 write_where_clause(def_id, f)?;
828 Ok(())
829 }
830}
831
832impl HirDisplay for Module {
833 fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
834 match self.parent(f.db) {
835 Some(m) => write_visibility(m.id, self.visibility(f.db), f)?,
836 None => {
837 return match self.krate(f.db).display_name(f.db) {
838 Some(name) => write!(f, "extern crate {name}"),
839 None => f.write_str("extern crate {unknown}"),
840 };
841 }
842 }
843 match self.name(f.db) {
844 Some(name) => write!(f, "mod {}", name.display(f.db, f.edition())),
845 None => f.write_str("mod {unknown}"),
846 }
847 }
848}
849
850impl HirDisplay for Crate {
851 fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
852 match self.display_name(f.db) {
853 Some(name) => write!(f, "extern crate {name}"),
854 None => f.write_str("extern crate {unknown}"),
855 }
856 }
857}
858
859impl HirDisplay for Macro {
860 fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
861 match self.id {
862 hir_def::MacroId::Macro2Id(_) => f.write_str("macro"),
863 hir_def::MacroId::MacroRulesId(_) => f.write_str("macro_rules!"),
864 hir_def::MacroId::ProcMacroId(_) => f.write_str("proc_macro"),
865 }?;
866 write!(f, " {}", self.name(f.db).display(f.db, f.edition()))
867 }
868}