Skip to content

Commit ab26b26

Browse files
committed
rustc: introduce a ty::print::PrettyPrinter helper for printing "<...>".
1 parent 35e5123 commit ab26b26

File tree

2 files changed

+132
-117
lines changed

2 files changed

+132
-117
lines changed

src/librustc/ty/print.rs

Lines changed: 109 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ pub trait PrettyPrinter:
336336
/// nested components in some larger context.
337337
fn nest<'a, 'gcx, 'tcx, E>(
338338
self: PrintCx<'a, 'gcx, 'tcx, Self>,
339-
f: impl for<'b> FnOnce(PrintCx<'b, 'gcx, 'tcx, Self>) -> Result<Self, E>,
339+
f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result<Self, E>,
340340
) -> Result<PrintCx<'a, 'gcx, 'tcx, Self>, E> {
341341
let printer = f(PrintCx {
342342
tcx: self.tcx,
@@ -350,6 +350,17 @@ pub trait PrettyPrinter:
350350
})
351351
}
352352

353+
/// Print `<...>` around what `f` prints.
354+
fn generic_delimiters<'gcx, 'tcx>(
355+
mut self: PrintCx<'_, 'gcx, 'tcx, Self>,
356+
f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result<Self, Self::Error>,
357+
) -> Result<Self, Self::Error> {
358+
write!(self.printer, "<")?;
359+
let mut printer = f(self)?;
360+
write!(printer, ">")?;
361+
Ok(printer)
362+
}
363+
353364
/// Return `true` if the region should be printed in path generic args
354365
/// even when it's `'_`, such as in e.g. `Foo<'_, '_, '_>`.
355366
fn always_print_region_in_paths(
@@ -746,7 +757,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> {
746757
}
747758

748759
pub fn pretty_path_qualified(
749-
mut self,
760+
self,
750761
self_ty: Ty<'tcx>,
751762
trait_ref: Option<ty::TraitRef<'tcx>>,
752763
ns: Namespace,
@@ -772,20 +783,19 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> {
772783
}
773784
}
774785

775-
write!(self.printer, "<")?;
776-
nest!(self, |cx| self_ty.print_display(cx));
777-
if let Some(trait_ref) = trait_ref {
778-
write!(self.printer, " as ")?;
779-
nest!(self, |cx| cx.print_def_path(
780-
trait_ref.def_id,
781-
Some(trait_ref.substs),
782-
Namespace::TypeNS,
783-
iter::empty(),
784-
));
785-
}
786-
write!(self.printer, ">")?;
787-
788-
Ok(self.printer)
786+
self.generic_delimiters(|mut cx| {
787+
nest!(cx, |cx| self_ty.print_display(cx));
788+
if let Some(trait_ref) = trait_ref {
789+
write!(cx.printer, " as ")?;
790+
nest!(cx, |cx| cx.print_def_path(
791+
trait_ref.def_id,
792+
Some(trait_ref.substs),
793+
Namespace::TypeNS,
794+
iter::empty(),
795+
));
796+
}
797+
Ok(cx.printer)
798+
})
789799
}
790800

791801
pub fn pretty_path_append_impl(
@@ -796,17 +806,18 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> {
796806
self_ty: Ty<'tcx>,
797807
trait_ref: Option<ty::TraitRef<'tcx>>,
798808
) -> Result<P::Path, P::Error> {
799-
// HACK(eddyb) going through `path_append` means symbol name
800-
// computation gets to handle its equivalent of `::` correctly.
801-
nest!(self, |cx| cx.path_append(print_prefix, "<impl "));
802-
if let Some(trait_ref) = trait_ref {
803-
nest!(self, |cx| trait_ref.print_display(cx));
804-
write!(self.printer, " for ")?;
805-
}
806-
nest!(self, |cx| self_ty.print_display(cx));
807-
write!(self.printer, ">")?;
809+
nest!(self, print_prefix);
808810

809-
Ok(self.printer)
811+
self.generic_delimiters(|mut cx| {
812+
write!(cx.printer, "impl ")?;
813+
if let Some(trait_ref) = trait_ref {
814+
nest!(cx, |cx| trait_ref.print_display(cx));
815+
write!(cx.printer, " for ")?;
816+
}
817+
nest!(cx, |cx| self_ty.print_display(cx));
818+
819+
Ok(cx.printer)
820+
})
810821
}
811822

812823
pub fn pretty_path_generic_args(
@@ -821,18 +832,6 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> {
821832
) -> Result<P::Path, P::Error> {
822833
nest!(self, |cx| print_prefix(cx));
823834

824-
let mut empty = true;
825-
let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| {
826-
write!(cx.printer, "{}", if empty {
827-
empty = false;
828-
start
829-
} else {
830-
cont
831-
})
832-
};
833-
834-
let start = if ns == Namespace::ValueNS { "::<" } else { "<" };
835-
836835
// Don't print `'_` if there's no printed region.
837836
let print_regions = params.iter().any(|param| {
838837
match substs[param.index as usize].unpack() {
@@ -861,45 +860,75 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> {
861860
}).count()
862861
};
863862

864-
for param in &params[..params.len() - num_supplied_defaults] {
865-
match substs[param.index as usize].unpack() {
866-
UnpackedKind::Lifetime(region) => {
867-
if !print_regions {
868-
continue;
863+
let params = &params[..params.len() - num_supplied_defaults];
864+
let mut args = params.iter().map(|param| {
865+
substs[param.index as usize].unpack()
866+
}).filter(|arg| {
867+
match arg {
868+
UnpackedKind::Lifetime(_) => print_regions,
869+
_ => true,
870+
}
871+
});
872+
let arg0 = args.next();
873+
874+
let mut projections = projections;
875+
let projection0 = projections.next();
876+
877+
if arg0.is_none() && projection0.is_none() {
878+
return Ok(self.printer);
879+
}
880+
881+
// FIXME(eddyb) move this into `generic_delimiters`.
882+
if ns == Namespace::ValueNS {
883+
write!(self.printer, "::")?;
884+
}
885+
886+
self.generic_delimiters(|mut cx| {
887+
let mut empty = true;
888+
let mut maybe_comma = |cx: &mut Self| {
889+
if empty {
890+
empty = false;
891+
Ok(())
892+
} else {
893+
write!(cx.printer, ", ")
894+
}
895+
};
896+
897+
for arg in arg0.into_iter().chain(args) {
898+
maybe_comma(&mut cx)?;
899+
900+
match arg {
901+
UnpackedKind::Lifetime(region) => {
902+
if !cx.print_region_outputs_anything(region) {
903+
// This happens when the value of the region
904+
// parameter is not easily serialized. This may be
905+
// because the user omitted it in the first place,
906+
// or because it refers to some block in the code,
907+
// etc. I'm not sure how best to serialize this.
908+
write!(cx.printer, "'_")?;
909+
} else {
910+
nest!(cx, |cx| region.print_display(cx));
911+
}
869912
}
870-
start_or_continue(&mut self, start, ", ")?;
871-
if !self.print_region_outputs_anything(region) {
872-
// This happens when the value of the region
873-
// parameter is not easily serialized. This may be
874-
// because the user omitted it in the first place,
875-
// or because it refers to some block in the code,
876-
// etc. I'm not sure how best to serialize this.
877-
write!(self.printer, "'_")?;
878-
} else {
879-
nest!(self, |cx| region.print_display(cx));
913+
UnpackedKind::Type(ty) => {
914+
nest!(cx, |cx| ty.print_display(cx));
915+
}
916+
UnpackedKind::Const(ct) => {
917+
nest!(cx, |cx| ct.print_display(cx));
880918
}
881-
}
882-
UnpackedKind::Type(ty) => {
883-
start_or_continue(&mut self, start, ", ")?;
884-
nest!(self, |cx| ty.print_display(cx));
885-
}
886-
UnpackedKind::Const(ct) => {
887-
start_or_continue(&mut self, start, ", ")?;
888-
nest!(self, |cx| ct.print_display(cx));
889919
}
890920
}
891-
}
892921

893-
for projection in projections {
894-
start_or_continue(&mut self, start, ", ")?;
895-
write!(self.printer, "{}=",
896-
self.tcx.associated_item(projection.item_def_id).ident)?;
897-
nest!(self, |cx| projection.ty.print_display(cx));
898-
}
922+
for projection in projection0.into_iter().chain(projections) {
923+
maybe_comma(&mut cx)?;
899924

900-
start_or_continue(&mut self, "", ">")?;
925+
write!(cx.printer, "{}=",
926+
cx.tcx.associated_item(projection.item_def_id).ident)?;
927+
nest!(cx, |cx| projection.ty.print_display(cx));
928+
}
901929

902-
Ok(self.printer)
930+
Ok(cx.printer)
931+
})
903932
}
904933
}
905934

@@ -1087,7 +1116,15 @@ impl<F: fmt::Write> Printer for FmtPrinter<F> {
10871116
self_ty: Ty<'tcx>,
10881117
trait_ref: Option<ty::TraitRef<'tcx>>,
10891118
) -> Result<Self::Path, Self::Error> {
1090-
self.pretty_path_append_impl(print_prefix, self_ty, trait_ref)
1119+
self.pretty_path_append_impl(|cx| {
1120+
let mut printer = print_prefix(cx)?;
1121+
1122+
if !printer.empty {
1123+
write!(printer, "::")?;
1124+
}
1125+
1126+
Ok(printer)
1127+
}, self_ty, trait_ref)
10911128
}
10921129
fn path_append<'gcx, 'tcx>(
10931130
self: PrintCx<'_, 'gcx, 'tcx, Self>,
@@ -1126,7 +1163,7 @@ impl<F: fmt::Write> Printer for FmtPrinter<F> {
11261163
impl<F: fmt::Write> PrettyPrinter for FmtPrinter<F> {
11271164
fn nest<'a, 'gcx, 'tcx, E>(
11281165
mut self: PrintCx<'a, 'gcx, 'tcx, Self>,
1129-
f: impl for<'b> FnOnce(PrintCx<'b, 'gcx, 'tcx, Self>) -> Result<Self, E>,
1166+
f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result<Self, E>,
11301167
) -> Result<PrintCx<'a, 'gcx, 'tcx, Self>, E> {
11311168
let was_empty = std::mem::replace(&mut self.printer.empty, true);
11321169
let mut printer = f(PrintCx {

src/librustc_codegen_utils/symbol_names.rs

Lines changed: 23 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -434,28 +434,12 @@ impl Printer for SymbolPath {
434434
Ok(self.printer)
435435
}
436436
fn path_qualified(
437-
mut self: PrintCx<'_, '_, 'tcx, Self>,
437+
self: PrintCx<'_, '_, 'tcx, Self>,
438438
self_ty: Ty<'tcx>,
439439
trait_ref: Option<ty::TraitRef<'tcx>>,
440440
ns: Namespace,
441441
) -> Result<Self::Path, Self::Error> {
442-
// HACK(eddyb) avoid `keep_within_component` for the cases
443-
// that print without `<...>` around `self_ty`.
444-
match self_ty.sty {
445-
ty::Adt(..) | ty::Foreign(_) |
446-
ty::Bool | ty::Char | ty::Str |
447-
ty::Int(_) | ty::Uint(_) | ty::Float(_)
448-
if trait_ref.is_none() =>
449-
{
450-
return self.pretty_path_qualified(self_ty, trait_ref, ns);
451-
}
452-
_ => {}
453-
}
454-
455-
let kept_within_component = mem::replace(&mut self.printer.keep_within_component, true);
456-
let mut path = self.pretty_path_qualified(self_ty, trait_ref, ns)?;
457-
path.keep_within_component = kept_within_component;
458-
Ok(path)
442+
self.pretty_path_qualified(self_ty, trait_ref, ns)
459443
}
460444

461445
fn path_append_impl<'gcx, 'tcx>(
@@ -466,18 +450,11 @@ impl Printer for SymbolPath {
466450
self_ty: Ty<'tcx>,
467451
trait_ref: Option<ty::TraitRef<'tcx>>,
468452
) -> Result<Self::Path, Self::Error> {
469-
let kept_within_component = self.printer.keep_within_component;
470-
let mut path = self.pretty_path_append_impl(
471-
|cx| {
472-
let mut path = print_prefix(cx)?;
473-
path.keep_within_component = true;
474-
Ok(path)
475-
},
453+
self.pretty_path_append_impl(
454+
|cx| cx.path_append(print_prefix, ""),
476455
self_ty,
477456
trait_ref,
478-
)?;
479-
path.keep_within_component = kept_within_component;
480-
Ok(path)
457+
)
481458
}
482459
fn path_append<'gcx, 'tcx>(
483460
self: PrintCx<'_, 'gcx, 'tcx, Self>,
@@ -486,11 +463,9 @@ impl Printer for SymbolPath {
486463
) -> Result<Self::Path, Self::Error>,
487464
text: &str,
488465
) -> Result<Self::Path, Self::Error> {
489-
let keep_within_component = self.printer.keep_within_component;
490-
491466
let mut path = print_prefix(self)?;
492467

493-
if keep_within_component {
468+
if path.keep_within_component {
494469
// HACK(eddyb) print the path similarly to how `FmtPrinter` prints it.
495470
path.write_str("::")?;
496471
} else {
@@ -510,20 +485,7 @@ impl Printer for SymbolPath {
510485
ns: Namespace,
511486
projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>,
512487
) -> Result<Self::Path, Self::Error> {
513-
let kept_within_component = self.printer.keep_within_component;
514-
let mut path = self.pretty_path_generic_args(
515-
|cx| {
516-
let mut path = print_prefix(cx)?;
517-
path.keep_within_component = true;
518-
Ok(path)
519-
},
520-
params,
521-
substs,
522-
ns,
523-
projections,
524-
)?;
525-
path.keep_within_component = kept_within_component;
526-
Ok(path)
488+
self.pretty_path_generic_args(print_prefix, params, substs, ns, projections)
527489
}
528490
}
529491

@@ -534,6 +496,22 @@ impl PrettyPrinter for SymbolPath {
534496
) -> bool {
535497
false
536498
}
499+
500+
fn generic_delimiters<'gcx, 'tcx>(
501+
mut self: PrintCx<'_, 'gcx, 'tcx, Self>,
502+
f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result<Self, Self::Error>,
503+
) -> Result<Self, Self::Error> {
504+
write!(self.printer, "<")?;
505+
506+
let kept_within_component =
507+
mem::replace(&mut self.printer.keep_within_component, true);
508+
let mut path = f(self)?;
509+
path.keep_within_component = kept_within_component;
510+
511+
write!(path, ">")?;
512+
513+
Ok(path)
514+
}
537515
}
538516

539517
impl fmt::Write for SymbolPath {

0 commit comments

Comments
 (0)