aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/item_tree/pretty.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/item_tree/pretty.rs')
-rw-r--r--crates/hir_def/src/item_tree/pretty.rs82
1 files changed, 73 insertions, 9 deletions
diff --git a/crates/hir_def/src/item_tree/pretty.rs b/crates/hir_def/src/item_tree/pretty.rs
index 5ec02d1be..c91f21bbb 100644
--- a/crates/hir_def/src/item_tree/pretty.rs
+++ b/crates/hir_def/src/item_tree/pretty.rs
@@ -2,7 +2,7 @@
2 2
3use std::fmt::{self, Write}; 3use std::fmt::{self, Write};
4 4
5use crate::{attr::RawAttrs, visibility::RawVisibility}; 5use crate::{attr::RawAttrs, path::GenericArg, visibility::RawVisibility};
6 6
7use super::*; 7use super::*;
8 8
@@ -466,7 +466,7 @@ impl<'a> Printer<'a> {
466 TypeRef::Macro(_ast_id) => { 466 TypeRef::Macro(_ast_id) => {
467 w!(self, "<macro>"); 467 w!(self, "<macro>");
468 } 468 }
469 TypeRef::Error => drop(write!(self, "{{unknown}}")), 469 TypeRef::Error => w!(self, "{{unknown}}"),
470 TypeRef::ImplTrait(bounds) => { 470 TypeRef::ImplTrait(bounds) => {
471 w!(self, "impl "); 471 w!(self, "impl ");
472 self.print_type_bounds(bounds); 472 self.print_type_bounds(bounds);
@@ -493,13 +493,77 @@ impl<'a> Printer<'a> {
493 } 493 }
494 494
495 fn print_path(&mut self, path: &Path) { 495 fn print_path(&mut self, path: &Path) {
496 if path.type_anchor().is_none() 496 match path.type_anchor() {
497 && path.segments().iter().all(|seg| seg.args_and_bindings.is_none()) 497 Some(anchor) => {
498 { 498 w!(self, "<");
499 w!(self, "{}", path.mod_path()); 499 self.print_type_ref(anchor);
500 } else { 500 w!(self, ">::");
501 // too complicated, just use `Debug` 501 }
502 w!(self, "{:?}", path); 502 None => match path.kind() {
503 PathKind::Plain => {}
504 PathKind::Super(0) => w!(self, "self::"),
505 PathKind::Super(n) => {
506 for _ in 0..*n {
507 w!(self, "super::");
508 }
509 }
510 PathKind::Crate => w!(self, "crate::"),
511 PathKind::Abs => w!(self, "::"),
512 PathKind::DollarCrate(_) => w!(self, "$crate::"),
513 },
514 }
515
516 for (i, segment) in path.segments().iter().enumerate() {
517 if i != 0 {
518 w!(self, "::");
519 }
520
521 w!(self, "{}", segment.name);
522 if let Some(generics) = segment.args_and_bindings {
523 // NB: these are all in type position, so `::<` turbofish syntax is not necessary
524 w!(self, "<");
525 let mut first = true;
526 let args = if generics.has_self_type {
527 let (self_ty, args) = generics.args.split_first().unwrap();
528 w!(self, "Self=");
529 self.print_generic_arg(self_ty);
530 first = false;
531 args
532 } else {
533 &generics.args
534 };
535 for arg in args {
536 if !first {
537 w!(self, ", ");
538 }
539 first = false;
540 self.print_generic_arg(arg);
541 }
542 for binding in &generics.bindings {
543 if !first {
544 w!(self, ", ");
545 }
546 first = false;
547 w!(self, "{}", binding.name);
548 if !binding.bounds.is_empty() {
549 w!(self, ": ");
550 self.print_type_bounds(&binding.bounds);
551 }
552 if let Some(ty) = &binding.type_ref {
553 w!(self, " = ");
554 self.print_type_ref(ty);
555 }
556 }
557
558 w!(self, ">");
559 }
560 }
561 }
562
563 fn print_generic_arg(&mut self, arg: &GenericArg) {
564 match arg {
565 GenericArg::Type(ty) => self.print_type_ref(ty),
566 GenericArg::Lifetime(lt) => w!(self, "{}", lt.name),
503 } 567 }
504 } 568 }
505} 569}