Skip to content

Commit 9c3ec4b

Browse files
committed
rustc: introduce a ty::print::PrettyPrinter helper for printing "<...>".
1 parent ca976f0 commit 9c3ec4b

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
@@ -338,7 +338,7 @@ pub trait PrettyPrinter:
338338
/// nested components in some larger context.
339339
fn nest<'a, 'gcx, 'tcx, E>(
340340
self: PrintCx<'a, 'gcx, 'tcx, Self>,
341-
f: impl for<'b> FnOnce(PrintCx<'b, 'gcx, 'tcx, Self>) -> Result<Self, E>,
341+
f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result<Self, E>,
342342
) -> Result<PrintCx<'a, 'gcx, 'tcx, Self>, E> {
343343
let printer = f(PrintCx {
344344
tcx: self.tcx,
@@ -352,6 +352,17 @@ pub trait PrettyPrinter:
352352
})
353353
}
354354

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

752763
pub fn pretty_path_qualified(
753-
mut self,
764+
self,
754765
self_ty: Ty<'tcx>,
755766
trait_ref: Option<ty::TraitRef<'tcx>>,
756767
ns: Namespace,
@@ -776,20 +787,19 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> {
776787
}
777788
}
778789

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

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

813-
Ok(self.printer)
815+
self.generic_delimiters(|mut cx| {
816+
write!(cx.printer, "impl ")?;
817+
if let Some(trait_ref) = trait_ref {
818+
nest!(cx, |cx| trait_ref.print_display(cx));
819+
write!(cx.printer, " for ")?;
820+
}
821+
nest!(cx, |cx| self_ty.print_display(cx));
822+
823+
Ok(cx.printer)
824+
})
814825
}
815826

816827
pub fn pretty_path_generic_args(
@@ -825,18 +836,6 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> {
825836
) -> Result<P::Path, P::Error> {
826837
nest!(self, |cx| print_prefix(cx));
827838

828-
let mut empty = true;
829-
let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| {
830-
write!(cx.printer, "{}", if empty {
831-
empty = false;
832-
start
833-
} else {
834-
cont
835-
})
836-
};
837-
838-
let start = if ns == Namespace::ValueNS { "::<" } else { "<" };
839-
840839
// Don't print `'_` if there's no printed region.
841840
let print_regions = params.iter().any(|param| {
842841
match substs[param.index as usize].unpack() {
@@ -864,41 +863,72 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> {
864863
}).count()
865864
};
866865

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

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

899-
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+
}
900929

901-
Ok(self.printer)
930+
Ok(cx.printer)
931+
})
902932
}
903933
}
904934

@@ -1086,7 +1116,15 @@ impl<F: fmt::Write> Printer for FmtPrinter<F> {
10861116
self_ty: Ty<'tcx>,
10871117
trait_ref: Option<ty::TraitRef<'tcx>>,
10881118
) -> Result<Self::Path, Self::Error> {
1089-
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)
10901128
}
10911129
fn path_append<'gcx, 'tcx>(
10921130
self: PrintCx<'_, 'gcx, 'tcx, Self>,
@@ -1125,7 +1163,7 @@ impl<F: fmt::Write> Printer for FmtPrinter<F> {
11251163
impl<F: fmt::Write> PrettyPrinter for FmtPrinter<F> {
11261164
fn nest<'a, 'gcx, 'tcx, E>(
11271165
mut self: PrintCx<'a, 'gcx, 'tcx, Self>,
1128-
f: impl for<'b> FnOnce(PrintCx<'b, 'gcx, 'tcx, Self>) -> Result<Self, E>,
1166+
f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result<Self, E>,
11291167
) -> Result<PrintCx<'a, 'gcx, 'tcx, Self>, E> {
11301168
let was_empty = std::mem::replace(&mut self.printer.empty, true);
11311169
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)