}
}
-pub struct PrintCx<'a, 'gcx, 'tcx, P> {
- pub tcx: TyCtxt<'a, 'gcx, 'tcx>,
- pub printer: P,
+pub(crate) struct PrintConfig {
pub(crate) is_debug: bool,
pub(crate) is_verbose: bool,
pub(crate) identify_regions: bool,
pub(crate) binder_depth: usize,
}
+impl PrintConfig {
+ pub(crate) fn new(tcx: TyCtxt<'_, '_, '_>) -> Self {
+ PrintConfig {
+ is_debug: false,
+ is_verbose: tcx.sess.verbose(),
+ identify_regions: tcx.sess.opts.debugging_opts.identify_regions,
+ used_region_names: None,
+ region_index: 0,
+ binder_depth: 0,
+ }
+ }
+}
+
+pub struct PrintCx<'a, 'gcx, 'tcx, P> {
+ pub tcx: TyCtxt<'a, 'gcx, 'tcx>,
+ pub printer: P,
+ pub(crate) config: &'a mut PrintConfig,
+}
+
// HACK(eddyb) this is solely for `self: &mut PrintCx<Self>`, e.g. to
// implement traits on the printer and call the methods on the context.
impl<P> Deref for PrintCx<'_, '_, '_, P> {
}
}
-impl<P> PrintCx<'a, 'gcx, 'tcx, P> {
- pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, printer: P) -> Self {
- PrintCx {
+impl<'a, 'gcx, 'tcx, P> PrintCx<'a, 'gcx, 'tcx, P> {
+ pub fn with<R>(
+ tcx: TyCtxt<'a, 'gcx, 'tcx>,
+ printer: P,
+ f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, P>) -> R,
+ ) -> R {
+ f(PrintCx {
tcx,
printer,
- is_debug: false,
- is_verbose: tcx.sess.verbose(),
- identify_regions: tcx.sess.opts.debugging_opts.identify_regions,
- used_region_names: None,
- region_index: 0,
- binder_depth: 0,
- }
+ config: &mut PrintConfig::new(tcx),
+ })
}
- pub(crate) fn with<R>(printer: P, f: impl FnOnce(PrintCx<'_, '_, '_, P>) -> R) -> R {
- ty::tls::with(|tcx| f(PrintCx::new(tcx, printer)))
+ pub(crate) fn with_tls_tcx<R>(printer: P, f: impl FnOnce(PrintCx<'_, '_, '_, P>) -> R) -> R {
+ ty::tls::with(|tcx| PrintCx::with(tcx, printer, f))
}
pub(crate) fn prepare_late_bound_region_info<T>(&mut self, value: &ty::Binder<T>)
where T: TypeFoldable<'tcx>
{
let mut collector = LateBoundRegionNameCollector(Default::default());
value.visit_with(&mut collector);
- self.used_region_names = Some(collector.0);
- self.region_index = 0;
+ self.config.used_region_names = Some(collector.0);
+ self.config.region_index = 0;
}
}
&self,
cx: &mut PrintCx<'_, '_, 'tcx, P>,
) -> Result<Self::Output, Self::Error> {
- let old_debug = cx.is_debug;
- cx.is_debug = false;
+ let old_debug = cx.config.is_debug;
+ cx.config.is_debug = false;
let result = self.print(cx);
- cx.is_debug = old_debug;
+ cx.config.is_debug = old_debug;
result
}
fn print_debug(&self, cx: &mut PrintCx<'_, '_, 'tcx, P>) -> Result<Self::Output, Self::Error> {
- let old_debug = cx.is_debug;
- cx.is_debug = true;
+ let old_debug = cx.config.is_debug;
+ cx.config.is_debug = true;
let result = self.print(cx);
- cx.is_debug = old_debug;
+ cx.config.is_debug = old_debug;
result
}
}
let ns = self.guess_def_namespace(def_id);
debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns);
let mut s = String::new();
- let _ = PrintCx::new(self, FmtPrinter { fmt: &mut s })
- .print_def_path(def_id, None, ns, iter::empty());
+ let _ = PrintCx::with(self, FmtPrinter { fmt: &mut s }, |mut cx| {
+ cx.print_def_path(def_id, None, ns, iter::empty())
+ });
s
}
}
});
// Don't print args that are the defaults of their respective parameters.
- let num_supplied_defaults = if self.is_verbose {
+ let num_supplied_defaults = if self.config.is_verbose {
0
} else {
params.iter().rev().take_while(|param| {
macro_rules! gen_display_debug_body {
( $with:path ) => {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- PrintCx::with(FmtPrinter { fmt: f }, |mut cx| {
+ PrintCx::with_tls_tcx(FmtPrinter { fmt: f }, |mut cx| {
$with(&cx.tcx.lift(self).expect("could not lift for printing"), &mut cx)
})
}
type Error = fmt::Error;
fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, P>) -> fmt::Result {
define_scoped_cx!($cx);
- if $cx.is_debug $dbg
+ if $cx.config.is_debug $dbg
else $disp
}
}
type Error = fmt::Error;
fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, P>) -> fmt::Result {
define_scoped_cx!($cx);
- if $cx.is_debug $dbg
+ if $cx.config.is_debug $dbg
else $disp
}
}
// clearly differentiate between named and unnamed regions in
// the output. We'll probably want to tweak this over time to
// decide just how much information to give.
- if self.binder_depth == 0 {
+ if self.config.binder_depth == 0 {
self.prepare_late_bound_region_info(value);
}
// is disallowed (name resolution thinks `scoped_cx!` is ambiguous).
define_scoped_cx!(self);
- let old_region_index = self.region_index;
+ let old_region_index = self.config.region_index;
let mut region_index = old_region_index;
let new_value = self.tcx.replace_late_bound_regions(value, |br| {
let _ = start_or_continue(self, "for<", ", ");
start_or_continue(self, "", "> ")?;
// Push current state to gcx, and restore after writing new_value.
- self.binder_depth += 1;
- self.region_index = region_index;
+ self.config.binder_depth += 1;
+ self.config.region_index = region_index;
let result = new_value.print_display(self);
- self.region_index = old_region_index;
- self.binder_depth -= 1;
+ self.config.region_index = old_region_index;
+ self.config.binder_depth -= 1;
result
}
fn is_name_used(&self, name: &InternedString) -> bool {
- match self.used_region_names {
+ match self.config.used_region_names {
Some(ref names) => names.contains(name),
None => false,
}
substs: SubstsRef<'_>,
ns: Namespace,
) -> fmt::Result {
- PrintCx::with(FmtPrinter { fmt: f }, |mut cx| {
+ PrintCx::with_tls_tcx(FmtPrinter { fmt: f }, |mut cx| {
let substs = cx.tcx.lift(&substs).expect("could not lift for printing");
let _ = cx.print_def_path(did, Some(substs), ns, iter::empty())?;
Ok(())
let mut resugared_principal = false;
// Special-case `Fn(...) -> ...` and resugar it.
- if !cx.is_verbose && cx.tcx.lang_items().fn_trait_kind(principal.def_id).is_some() {
- if let Tuple(ref args) = principal.substs.type_at(0).sty {
+ let fn_trait_kind = cx.tcx.lang_items().fn_trait_kind(principal.def_id);
+ if !cx.config.is_verbose && fn_trait_kind.is_some() {
+ if let ty::Tuple(ref args) = principal.substs.type_at(0).sty {
let mut projections = self.projection_bounds();
if let (Some(proj), None) = (projections.next(), projections.next()) {
let _ = cx.print_def_path(
impl fmt::Debug for ty::TraitDef {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- PrintCx::with(FmtPrinter { fmt: f }, |mut cx| {
+ PrintCx::with_tls_tcx(FmtPrinter { fmt: f }, |mut cx| {
let _ = cx.print_def_path(
self.def_id,
None,
impl fmt::Debug for ty::AdtDef {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- PrintCx::with(FmtPrinter { fmt: f }, |mut cx| {
+ PrintCx::with_tls_tcx(FmtPrinter { fmt: f }, |mut cx| {
let _ = cx.print_def_path(
self.did,
None,
impl fmt::Debug for ty::UpvarId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- PrintCx::with(FmtPrinter { fmt: f }, |mut cx| {
+ PrintCx::with_tls_tcx(FmtPrinter { fmt: f }, |mut cx| {
define_scoped_cx!(cx);
p!(write("UpvarId({:?};`{}`;{:?})",
self.var_path.hir_id,
define_print! {
() ty::BoundRegion, (self, cx) {
display {
- if cx.is_verbose {
+ if cx.config.is_verbose {
return self.print_debug(cx);
}
// NB: this must be kept in sync with the printing logic above.
impl ty::BoundRegion {
fn display_outputs_anything<P>(&self, cx: &mut PrintCx<'_, '_, '_, P>) -> bool {
- if cx.is_verbose {
+ if cx.config.is_verbose {
return true;
}
define_print! {
() ty::PlaceholderRegion, (self, cx) {
display {
- if cx.is_verbose {
+ if cx.config.is_verbose {
return self.print_debug(cx);
}
// NB: this must be kept in sync with the printing logic above.
impl ty::PlaceholderRegion {
fn display_outputs_anything<P>(&self, cx: &mut PrintCx<'_, '_, '_, P>) -> bool {
- if cx.is_verbose {
+ if cx.config.is_verbose {
return true;
}
define_print! {
() ty::RegionKind, (self, cx) {
display {
- if cx.is_verbose {
+ if cx.config.is_verbose {
return self.print_debug(cx);
}
ty::RePlaceholder(p) => {
p!(print_display(p))
}
- ty::ReScope(scope) if cx.identify_regions => {
+ ty::ReScope(scope) if cx.config.identify_regions => {
match scope.data {
region::ScopeData::Node =>
p!(write("'{}s", scope.item_local_id().as_usize())),
)),
}
}
- ty::ReVar(region_vid) if cx.identify_regions => {
+ ty::ReVar(region_vid) if cx.config.identify_regions => {
p!(print_debug(region_vid))
}
ty::ReVar(region_vid) => {
impl ty::RegionKind {
// HACK(eddyb) `pub(crate)` only for `ty::print`.
pub(crate) fn display_outputs_anything<P>(&self, cx: &mut PrintCx<'_, '_, '_, P>) -> bool {
- if cx.is_verbose {
+ if cx.config.is_verbose {
return true;
}
ty::RePlaceholder(p) => p.display_outputs_anything(cx),
ty::ReScope(_) |
- ty::ReVar(_) if cx.identify_regions => true,
+ ty::ReVar(_) if cx.config.identify_regions => true,
ty::ReVar(region_vid) => region_vid.display_outputs_anything(cx),
define_print! {
() ty::RegionVid, (self, cx) {
display {
- if cx.is_verbose {
+ if cx.config.is_verbose {
return self.print_debug(cx);
}
// NB: this must be kept in sync with the printing logic above.
impl ty::RegionVid {
fn display_outputs_anything<P>(&self, cx: &mut PrintCx<'_, '_, '_, P>) -> bool {
- if cx.is_verbose {
+ if cx.config.is_verbose {
return true;
}
define_print! {
() ty::InferTy, (self, cx) {
display {
- if cx.is_verbose {
+ if cx.config.is_verbose {
return self.print_debug(cx);
}
match *self {
for<'a> <T as ty::Lift<'a>>::Lifted: fmt::Display + TypeFoldable<'a>
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- PrintCx::with(|cx| cx.in_binder(cx.tcx.lift(self)
+ PrintCx::with_tls_tcx(|cx| cx.in_binder(cx.tcx.lift(self)
.expect("could not lift for printing")))
}
}*/
p!(write("Placeholder({:?})", placeholder))
}
Opaque(def_id, substs) => {
- if cx.is_verbose {
+ if cx.config.is_verbose {
return p!(write("Opaque({:?}, {:?})", def_id, substs));
}