Skip to content

Commit bc8aafa

Browse files
committed
rustc: integrate LocalPathPrinter's behavior into FmtPrinter.
1 parent ba106ff commit bc8aafa

File tree

2 files changed

+63
-39
lines changed

2 files changed

+63
-39
lines changed

src/librustc/ty/print.rs

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_data_structures::fx::FxHashSet;
1111
use syntax::symbol::InternedString;
1212

1313
use std::cell::Cell;
14-
use std::fmt;
14+
use std::fmt::{self, Write as _};
1515
use std::ops::Deref;
1616

1717
thread_local! {
@@ -145,6 +145,7 @@ pub trait Print<'tcx, P> {
145145
pub trait Printer: Sized {
146146
type Path;
147147

148+
#[must_use]
148149
fn print_def_path(
149150
self: &mut PrintCx<'_, '_, 'tcx, Self>,
150151
def_id: DefId,
@@ -153,6 +154,7 @@ pub trait Printer: Sized {
153154
) -> Self::Path {
154155
self.default_print_def_path(def_id, substs, ns)
155156
}
157+
#[must_use]
156158
fn print_impl_path(
157159
self: &mut PrintCx<'_, '_, 'tcx, Self>,
158160
impl_def_id: DefId,
@@ -162,15 +164,26 @@ pub trait Printer: Sized {
162164
self.default_print_impl_path(impl_def_id, substs, ns)
163165
}
164166

167+
#[must_use]
165168
fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path;
169+
#[must_use]
166170
fn path_impl(self: &mut PrintCx<'_, '_, '_, Self>, text: &str) -> Self::Path;
171+
#[must_use]
167172
fn path_append(
168173
self: &mut PrintCx<'_, '_, '_, Self>,
169174
path: Self::Path,
170175
text: &str,
171176
) -> Self::Path;
172177
}
173178

179+
#[must_use]
180+
pub struct PrettyPath {
181+
pub empty: bool,
182+
}
183+
184+
/// Trait for printers that pretty-print using `fmt::Write` to the printer.
185+
pub trait PrettyPrinter: Printer<Path = Result<PrettyPath, fmt::Error>> + fmt::Write {}
186+
174187
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
175188
// HACK(eddyb) get rid of `def_path_str` and/or pass `Namespace` explicitly always
176189
// (but also some things just print a `DefId` generally so maybe we need this?)
@@ -202,7 +215,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
202215
if FORCE_ABSOLUTE.with(|force| force.get()) {
203216
PrintCx::new(self, AbsolutePathPrinter).print_def_path(def_id, substs, ns)
204217
} else {
205-
PrintCx::new(self, LocalPathPrinter).print_def_path(def_id, substs, ns)
218+
let mut s = String::new();
219+
let _ = PrintCx::new(self, FmtPrinter { fmt: &mut s })
220+
.print_def_path(def_id, substs, ns);
221+
s
206222
}
207223
}
208224

@@ -441,10 +457,7 @@ pub struct FmtPrinter<F: fmt::Write> {
441457
pub fmt: F,
442458
}
443459

444-
// FIXME(eddyb) integrate into `FmtPrinter`.
445-
struct LocalPathPrinter;
446-
447-
impl LocalPathPrinter {
460+
impl<F: fmt::Write> FmtPrinter<F> {
448461
/// If possible, this returns a global path resolving to `def_id` that is visible
449462
/// from at least one local module and returns true. If the crate defining `def_id` is
450463
/// declared with an `extern crate`, the path is guaranteed to use the `extern crate`.
@@ -581,8 +594,14 @@ impl LocalPathPrinter {
581594
}
582595
}
583596

584-
impl Printer for LocalPathPrinter {
585-
type Path = String;
597+
impl<F: fmt::Write> fmt::Write for FmtPrinter<F> {
598+
fn write_str(&mut self, s: &str) -> fmt::Result {
599+
self.fmt.write_str(s)
600+
}
601+
}
602+
603+
impl<F: fmt::Write> Printer for FmtPrinter<F> {
604+
type Path = Result<PrettyPath, fmt::Error>;
586605

587606
fn print_def_path(
588607
self: &mut PrintCx<'_, '_, 'tcx, Self>,
@@ -611,7 +630,6 @@ impl Printer for LocalPathPrinter {
611630
// If no type info is available, fall back to
612631
// pretty printing some span information. This should
613632
// only occur very early in the compiler pipeline.
614-
// FIXME(eddyb) this should just be using `tcx.def_span(impl_def_id)`
615633
let parent_def_id = self.tcx.parent(impl_def_id).unwrap();
616634
let path = self.print_def_path(parent_def_id, None, ns);
617635
let span = self.tcx.def_span(impl_def_id);
@@ -626,26 +644,39 @@ impl Printer for LocalPathPrinter {
626644
if self.tcx.sess.rust_2018() {
627645
// We add the `crate::` keyword on Rust 2018, only when desired.
628646
if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) {
629-
return keywords::Crate.name().to_string();
647+
write!(self.printer, "{}", keywords::Crate.name())?;
648+
return Ok(PrettyPath { empty: false });
630649
}
631650
}
632-
String::new()
651+
Ok(PrettyPath { empty: true })
633652
} else {
634-
self.tcx.crate_name(cnum).to_string()
653+
write!(self.printer, "{}", self.tcx.crate_name(cnum))?;
654+
Ok(PrettyPath { empty: false })
635655
}
636656
}
637657
fn path_impl(self: &mut PrintCx<'_, '_, '_, Self>, text: &str) -> Self::Path {
638-
text.to_string()
658+
write!(self.printer, "{}", text)?;
659+
Ok(PrettyPath { empty: false })
639660
}
640661
fn path_append(
641662
self: &mut PrintCx<'_, '_, '_, Self>,
642-
mut path: Self::Path,
663+
path: Self::Path,
643664
text: &str,
644665
) -> Self::Path {
645-
if !path.is_empty() {
646-
path.push_str("::");
666+
let path = path?;
667+
668+
// FIXME(eddyb) this shouldn't happen, but is currently
669+
// the case for `extern { ... }` "foreign modules".
670+
if text.is_empty() {
671+
return Ok(path);
647672
}
648-
path.push_str(text);
649-
path
673+
674+
if !path.empty {
675+
write!(self.printer, "::")?;
676+
}
677+
write!(self.printer, "{}", text)?;
678+
Ok(PrettyPath { empty: false })
650679
}
651680
}
681+
682+
impl<F: fmt::Write> PrettyPrinter for FmtPrinter<F> {}

src/librustc/util/ppaux.rs

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ use ty::{Param, Bound, RawPtr, Ref, Never, Tuple};
1010
use ty::{Closure, Generator, GeneratorWitness, Foreign, Projection, Opaque};
1111
use ty::{Placeholder, UnnormalizedProjection, Dynamic, Int, Uint, Infer};
1212
use ty::{self, Ty, TypeFoldable};
13-
use ty::print::{FmtPrinter, PrintCx, Print};
13+
use ty::print::{FmtPrinter, PrettyPrinter, PrintCx, Print};
1414

1515
use std::cell::Cell;
16-
use std::fmt;
16+
use std::fmt::{self, Write as _};
1717
use std::iter;
1818
use std::usize;
1919

@@ -193,18 +193,18 @@ macro_rules! gen_display_debug {
193193
}
194194
macro_rules! gen_print_impl {
195195
( ($($x:tt)+) $target:ty, ($self:ident, $cx:ident) $disp:block $dbg:block ) => {
196-
impl<$($x)+, F: fmt::Write> Print<'tcx, FmtPrinter<F>> for $target {
196+
impl<$($x)+, P: PrettyPrinter> Print<'tcx, P> for $target {
197197
type Output = fmt::Result;
198-
fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, FmtPrinter<F>>) -> fmt::Result {
198+
fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, P>) -> fmt::Result {
199199
if $cx.is_debug $dbg
200200
else $disp
201201
}
202202
}
203203
};
204204
( () $target:ty, ($self:ident, $cx:ident) $disp:block $dbg:block ) => {
205-
impl<F: fmt::Write> Print<'tcx, FmtPrinter<F>> for $target {
205+
impl<P: PrettyPrinter> Print<'tcx, P> for $target {
206206
type Output = fmt::Result;
207-
fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, FmtPrinter<F>>) -> fmt::Result {
207+
fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, P>) -> fmt::Result {
208208
if $cx.is_debug $dbg
209209
else $disp
210210
}
@@ -235,7 +235,7 @@ macro_rules! define_print {
235235
( $generic:tt $target:ty,
236236
($self:ident, $cx:ident) { display $disp:block } ) => {
237237
gen_print_impl! { $generic $target, ($self, $cx) yes $disp no {
238-
write!($cx.printer.fmt, "{:?}", $self)
238+
write!($cx.printer, "{:?}", $self)
239239
} }
240240
};
241241
}
@@ -246,7 +246,7 @@ macro_rules! define_print_multi {
246246
}
247247
macro_rules! print_inner {
248248
( $cx:expr, write ($($data:expr),+) ) => {
249-
write!($cx.printer.fmt, $($data),+)
249+
write!($cx.printer, $($data),+)
250250
};
251251
( $cx:expr, $kind:ident ($data:expr) ) => {
252252
$data.$kind($cx)
@@ -258,7 +258,7 @@ macro_rules! print {
258258
};
259259
}
260260

261-
impl<F: fmt::Write> PrintCx<'a, 'gcx, 'tcx, FmtPrinter<F>> {
261+
impl<P: PrettyPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
262262
fn fn_sig(
263263
&mut self,
264264
inputs: &[Ty<'tcx>],
@@ -404,7 +404,7 @@ impl<F: fmt::Write> PrintCx<'a, 'gcx, 'tcx, FmtPrinter<F>> {
404404
}
405405

406406
fn in_binder<T>(&mut self, value: &ty::Binder<T>) -> fmt::Result
407-
where T: Print<'tcx, FmtPrinter<F>, Output = fmt::Result> + TypeFoldable<'tcx>
407+
where T: Print<'tcx, P, Output = fmt::Result> + TypeFoldable<'tcx>
408408
{
409409
fn name_by_region_index(index: usize) -> InternedString {
410410
match index {
@@ -489,13 +489,6 @@ pub fn parameterized<F: fmt::Write>(
489489
})
490490
}
491491

492-
impl<'a, 'tcx, P, T: Print<'tcx, P>> Print<'tcx, P> for &'a T {
493-
type Output = T::Output;
494-
fn print(&self, cx: &mut PrintCx<'_, '_, 'tcx, P>) -> Self::Output {
495-
(*self).print(cx)
496-
}
497-
}
498-
499492
define_print! {
500493
('tcx) &'tcx ty::List<ty::ExistentialPredicate<'tcx>>, (self, cx) {
501494
display {
@@ -575,15 +568,15 @@ impl fmt::Debug for ty::GenericParamDef {
575568

576569
impl fmt::Debug for ty::TraitDef {
577570
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
578-
PrintCx::with(FmtPrinter { fmt: f }, |cx| {
571+
PrintCx::with(FmtPrinter { fmt: f }, |mut cx| {
579572
print!(cx, write("{}", cx.tcx.def_path_str(self.def_id)))
580573
})
581574
}
582575
}
583576

584577
impl fmt::Debug for ty::AdtDef {
585578
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
586-
PrintCx::with(FmtPrinter { fmt: f }, |cx| {
579+
PrintCx::with(FmtPrinter { fmt: f }, |mut cx| {
587580
print!(cx, write("{}", cx.tcx.def_path_str(self.did)))
588581
})
589582
}
@@ -599,7 +592,7 @@ impl<'tcx> fmt::Debug for ty::ClosureUpvar<'tcx> {
599592

600593
impl fmt::Debug for ty::UpvarId {
601594
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
602-
PrintCx::with(FmtPrinter { fmt: f }, |cx| {
595+
PrintCx::with(FmtPrinter { fmt: f }, |mut cx| {
603596
print!(cx, write("UpvarId({:?};`{}`;{:?})",
604597
self.var_path.hir_id,
605598
cx.tcx.hir().name(cx.tcx.hir().hir_to_node_id(self.var_path.hir_id)),
@@ -922,7 +915,7 @@ define_print! {
922915
define_print! {
923916
() ty::Variance, (self, cx) {
924917
debug {
925-
cx.printer.fmt.write_str(match *self {
918+
cx.printer.write_str(match *self {
926919
ty::Covariant => "+",
927920
ty::Contravariant => "-",
928921
ty::Invariant => "o",

0 commit comments

Comments
 (0)