Skip to content

Commit f2e635d

Browse files
committed
rustc: introduce a ty::print::PrettyPrinter helper for printing "<...>".
1 parent 4f608ab commit f2e635d

File tree

2 files changed

+129
-113
lines changed

2 files changed

+129
-113
lines changed

src/librustc/ty/print.rs

Lines changed: 106 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ pub trait PrettyPrinter:
337337
/// nested components in some larger context.
338338
fn nest<'a, 'gcx, 'tcx, E>(
339339
self: PrintCx<'a, 'gcx, 'tcx, Self>,
340-
f: impl for<'b> FnOnce(PrintCx<'b, 'gcx, 'tcx, Self>) -> Result<Self, E>,
340+
f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result<Self, E>,
341341
) -> Result<PrintCx<'a, 'gcx, 'tcx, Self>, E> {
342342
let printer = f(PrintCx {
343343
tcx: self.tcx,
@@ -351,6 +351,17 @@ pub trait PrettyPrinter:
351351
})
352352
}
353353

354+
/// Print `<...>` around what `f` prints.
355+
fn generic_delimiters<'gcx, 'tcx>(
356+
mut self: PrintCx<'_, 'gcx, 'tcx, Self>,
357+
f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result<Self, Self::Error>,
358+
) -> Result<Self, Self::Error> {
359+
write!(self.printer, "<")?;
360+
let mut printer = f(self)?;
361+
write!(printer, ">")?;
362+
Ok(printer)
363+
}
364+
354365
/// Return `true` if the region should be printed in path generic args
355366
/// even when it's `'_`, such as in e.g. `Foo<'_, '_, '_>`.
356367
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() {
@@ -860,41 +859,72 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> {
860859
}).count()
861860
};
862861

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

888-
for projection in projections {
889-
start_or_continue(&mut self, start, ", ")?;
890-
write!(self.printer, "{}=",
891-
self.tcx.associated_item(projection.item_def_id).ident)?;
892-
nest!(self, |cx| projection.ty.print_display(cx));
893-
}
918+
for projection in projection0.into_iter().chain(projections) {
919+
maybe_comma(&mut cx)?;
894920

895-
start_or_continue(&mut self, "", ">")?;
921+
write!(cx.printer, "{}=",
922+
cx.tcx.associated_item(projection.item_def_id).ident)?;
923+
nest!(cx, |cx| projection.ty.print_display(cx));
924+
}
896925

897-
Ok(self.printer)
926+
Ok(cx.printer)
927+
})
898928
}
899929
}
900930

@@ -1082,7 +1112,15 @@ impl<F: fmt::Write> Printer for FmtPrinter<F> {
10821112
self_ty: Ty<'tcx>,
10831113
trait_ref: Option<ty::TraitRef<'tcx>>,
10841114
) -> Result<Self::Path, Self::Error> {
1085-
self.pretty_path_append_impl(print_prefix, self_ty, trait_ref)
1115+
self.pretty_path_append_impl(|cx| {
1116+
let mut printer = print_prefix(cx)?;
1117+
1118+
if !printer.empty {
1119+
write!(printer, "::")?;
1120+
}
1121+
1122+
Ok(printer)
1123+
}, self_ty, trait_ref)
10861124
}
10871125
fn path_append<'gcx, 'tcx>(
10881126
self: PrintCx<'_, 'gcx, 'tcx, Self>,
@@ -1121,7 +1159,7 @@ impl<F: fmt::Write> Printer for FmtPrinter<F> {
11211159
impl<F: fmt::Write> PrettyPrinter for FmtPrinter<F> {
11221160
fn nest<'a, 'gcx, 'tcx, E>(
11231161
mut self: PrintCx<'a, 'gcx, 'tcx, Self>,
1124-
f: impl for<'b> FnOnce(PrintCx<'b, 'gcx, 'tcx, Self>) -> Result<Self, E>,
1162+
f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result<Self, E>,
11251163
) -> Result<PrintCx<'a, 'gcx, 'tcx, Self>, E> {
11261164
let was_empty = std::mem::replace(&mut self.printer.empty, true);
11271165
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
@@ -435,28 +435,12 @@ impl Printer for SymbolPath {
435435
Ok(self.printer)
436436
}
437437
fn path_qualified(
438-
mut self: PrintCx<'_, '_, 'tcx, Self>,
438+
self: PrintCx<'_, '_, 'tcx, Self>,
439439
self_ty: Ty<'tcx>,
440440
trait_ref: Option<ty::TraitRef<'tcx>>,
441441
ns: Namespace,
442442
) -> Result<Self::Path, Self::Error> {
443-
// HACK(eddyb) avoid `keep_within_component` for the cases
444-
// that print without `<...>` around `self_ty`.
445-
match self_ty.sty {
446-
ty::Adt(..) | ty::Foreign(_) |
447-
ty::Bool | ty::Char | ty::Str |
448-
ty::Int(_) | ty::Uint(_) | ty::Float(_)
449-
if trait_ref.is_none() =>
450-
{
451-
return self.pretty_path_qualified(self_ty, trait_ref, ns);
452-
}
453-
_ => {}
454-
}
455-
456-
let kept_within_component = mem::replace(&mut self.printer.keep_within_component, true);
457-
let mut path = self.pretty_path_qualified(self_ty, trait_ref, ns)?;
458-
path.keep_within_component = kept_within_component;
459-
Ok(path)
443+
self.pretty_path_qualified(self_ty, trait_ref, ns)
460444
}
461445

462446
fn path_append_impl<'gcx, 'tcx>(
@@ -467,18 +451,11 @@ impl Printer for SymbolPath {
467451
self_ty: Ty<'tcx>,
468452
trait_ref: Option<ty::TraitRef<'tcx>>,
469453
) -> Result<Self::Path, Self::Error> {
470-
let kept_within_component = self.printer.keep_within_component;
471-
let mut path = self.pretty_path_append_impl(
472-
|cx| {
473-
let mut path = print_prefix(cx)?;
474-
path.keep_within_component = true;
475-
Ok(path)
476-
},
454+
self.pretty_path_append_impl(
455+
|cx| cx.path_append(print_prefix, ""),
477456
self_ty,
478457
trait_ref,
479-
)?;
480-
path.keep_within_component = kept_within_component;
481-
Ok(path)
458+
)
482459
}
483460
fn path_append<'gcx, 'tcx>(
484461
self: PrintCx<'_, 'gcx, 'tcx, Self>,
@@ -487,11 +464,9 @@ impl Printer for SymbolPath {
487464
) -> Result<Self::Path, Self::Error>,
488465
text: &str,
489466
) -> Result<Self::Path, Self::Error> {
490-
let keep_within_component = self.printer.keep_within_component;
491-
492467
let mut path = print_prefix(self)?;
493468

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

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

540518
// Name sanitation. LLVM will happily accept identifiers with weird names, but

0 commit comments

Comments
 (0)