diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 10c34aaf5b780..52b4288103813 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -445,14 +445,16 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { sp: Span, ) { use hir::def_id::CrateNum; - use ty::print::{PrintCx, Printer}; + use ty::print::Printer; use ty::subst::Kind; - struct AbsolutePathPrinter; + struct AbsolutePathPrinter<'a, 'gcx, 'tcx> { + tcx: TyCtxt<'a, 'gcx, 'tcx>, + } struct NonTrivialPath; - impl Printer for AbsolutePathPrinter { + impl<'gcx, 'tcx> Printer<'gcx, 'tcx> for AbsolutePathPrinter<'_, 'gcx, 'tcx> { type Error = NonTrivialPath; type Path = Vec; @@ -460,67 +462,65 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { type Type = !; type DynExistential = !; + fn tcx<'a>(&'a self) -> TyCtxt<'a, 'gcx, 'tcx> { + self.tcx + } + fn print_region( - self: PrintCx<'_, '_, '_, Self>, + self, _region: ty::Region<'_>, ) -> Result { Err(NonTrivialPath) } - fn print_type<'tcx>( - self: PrintCx<'_, '_, 'tcx, Self>, + fn print_type( + self, _ty: Ty<'tcx>, ) -> Result { Err(NonTrivialPath) } - fn print_dyn_existential<'tcx>( - self: PrintCx<'_, '_, 'tcx, Self>, + fn print_dyn_existential( + self, _predicates: &'tcx ty::List>, ) -> Result { Err(NonTrivialPath) } fn path_crate( - self: PrintCx<'_, '_, '_, Self>, + self, cnum: CrateNum, ) -> Result { Ok(vec![self.tcx.original_crate_name(cnum).to_string()]) } - fn path_qualified<'tcx>( - self: PrintCx<'_, '_, 'tcx, Self>, + fn path_qualified( + self, _self_ty: Ty<'tcx>, _trait_ref: Option>, ) -> Result { Err(NonTrivialPath) } - fn path_append_impl<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - _print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, + fn path_append_impl( + self, + _print_prefix: impl FnOnce(Self) -> Result, _self_ty: Ty<'tcx>, _trait_ref: Option>, ) -> Result { Err(NonTrivialPath) } - fn path_append<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, + fn path_append( + self, + print_prefix: impl FnOnce(Self) -> Result, text: &str, ) -> Result { let mut path = print_prefix(self)?; path.push(text.to_string()); Ok(path) } - fn path_generic_args<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, + fn path_generic_args( + self, + print_prefix: impl FnOnce(Self) -> Result, _args: &[Kind<'tcx>], ) -> Result { print_prefix(self) @@ -532,7 +532,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // module we could have false positives if !(did1.is_local() || did2.is_local()) && did1.krate != did2.krate { let abs_path = |def_id| { - PrintCx::new(self.tcx, AbsolutePathPrinter) + AbsolutePathPrinter { tcx: self.tcx } .print_def_path(def_id, None) }; diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs index f649309004bfc..0a83b839201ed 100644 --- a/src/librustc/infer/error_reporting/need_type_info.rs +++ b/src/librustc/infer/error_reporting/need_type_info.rs @@ -80,11 +80,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } let mut s = String::new(); - let mut printer = ty::print::FmtPrinter::new(&mut s, Namespace::TypeNS); + let mut printer = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS); if let Some(highlight) = highlight { printer.region_highlight_mode = highlight; } - let _ = ty.print(ty::print::PrintCx::new(self.tcx, printer)); + let _ = ty.print(printer); s } diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs index fd01ed85ef721..e708454b5b672 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -337,17 +337,17 @@ impl NiceRegionError<'me, 'gcx, 'tcx> { } } - impl<'tcx, T> fmt::Display for Highlighted<'_, '_, 'tcx, T> - where T: for<'a, 'b> Print<'tcx, - FmtPrinter<&'a mut fmt::Formatter<'b>>, + impl<'a, 'gcx, 'tcx, T> fmt::Display for Highlighted<'a, 'gcx, 'tcx, T> + where T: for<'b, 'c> Print<'gcx, 'tcx, + FmtPrinter<'a, 'gcx, 'tcx, &'b mut fmt::Formatter<'c>>, Error = fmt::Error, >, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut printer = ty::print::FmtPrinter::new(f, Namespace::TypeNS); + let mut printer = ty::print::FmtPrinter::new(self.tcx, f, Namespace::TypeNS); printer.region_highlight_mode = self.highlight; - self.value.print(ty::print::PrintCx::new(self.tcx, printer))?; + self.value.print(printer)?; Ok(()) } } diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index d1574bb322dd3..3218f8ea5de48 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -34,7 +34,7 @@ use crate::ty::{ self, AdtDef, CanonicalUserTypeAnnotations, ClosureSubsts, GeneratorSubsts, Region, Ty, TyCtxt, UserTypeAnnotationIndex, }; -use crate::ty::print::{FmtPrinter, Printer, PrintCx}; +use crate::ty::print::{FmtPrinter, Printer}; pub use crate::mir::interpret::AssertMessage; @@ -2407,9 +2407,10 @@ impl<'tcx> Debug for Rvalue<'tcx> { let variant_def = &adt_def.variants[variant]; let f = &mut *fmt; - PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::ValueNS), |cx| { - let substs = cx.tcx.lift(&substs).expect("could not lift for printing"); - cx.print_def_path(variant_def.did, Some(substs))?; + ty::tls::with(|tcx| { + let substs = tcx.lift(&substs).expect("could not lift for printing"); + FmtPrinter::new(tcx, f, Namespace::ValueNS) + .print_def_path(variant_def.did, Some(substs))?; Ok(()) })?; diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 66c99a7c4fc09..89d956c8bfae3 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -2,7 +2,7 @@ use crate::hir::Unsafety; use crate::hir::def::Namespace; use crate::hir::def_id::DefId; use crate::ty::{self, Ty, PolyFnSig, TypeFoldable, SubstsRef, TyCtxt}; -use crate::ty::print::{FmtPrinter, Printer, PrintCx}; +use crate::ty::print::{FmtPrinter, Printer}; use crate::traits; use rustc_target::spec::abi::Abi; use rustc_macros::HashStable; @@ -176,9 +176,10 @@ impl<'tcx> InstanceDef<'tcx> { impl<'tcx> fmt::Display for Instance<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with_tls_tcx(FmtPrinter::new(&mut *f, Namespace::ValueNS), |cx| { - let substs = cx.tcx.lift(&self.substs).expect("could not lift for printing"); - cx.print_def_path(self.def_id(), Some(substs))?; + ty::tls::with(|tcx| { + let substs = tcx.lift(&self.substs).expect("could not lift for printing"); + FmtPrinter::new(tcx, &mut *f, Namespace::ValueNS) + .print_def_path(self.def_id(), Some(substs))?; Ok(()) })?; diff --git a/src/librustc/ty/print/mod.rs b/src/librustc/ty/print/mod.rs index 4e81533589e59..ad17a8114cabf 100644 --- a/src/librustc/ty/print/mod.rs +++ b/src/librustc/ty/print/mod.rs @@ -5,59 +5,18 @@ use crate::ty::subst::{Kind, Subst, SubstsRef}; use rustc_data_structures::fx::FxHashSet; -use std::ops::{Deref, DerefMut}; - // `pretty` is a separate module only for organization. mod pretty; pub use self::pretty::*; -pub struct PrintCx<'a, 'gcx, 'tcx, P> { - pub tcx: TyCtxt<'a, 'gcx, 'tcx>, - inner: P, -} - -impl

Deref for PrintCx<'_, '_, '_, P> { - type Target = P; - fn deref(&self) -> &P { - &self.inner - } -} - -impl

DerefMut for PrintCx<'_, '_, '_, P> { - fn deref_mut(&mut self) -> &mut P { - &mut self.inner - } -} - -impl<'a, 'gcx, 'tcx, P> PrintCx<'a, 'gcx, 'tcx, P> { - pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, inner: P) -> Self { - PrintCx { - tcx, - inner, - } - } - - pub fn with_tls_tcx(inner: P, f: impl FnOnce(PrintCx<'_, '_, '_, P>) -> R) -> R { - ty::tls::with(|tcx| f(PrintCx::new(tcx, inner))) - } - - pub fn into_inner(self) -> P { - self.inner - } - - pub fn ok(self) -> Result { - Ok(self.into_inner()) - } -} - -pub trait Print<'tcx, P> { +pub trait Print<'gcx, 'tcx, P> { type Output; type Error; - fn print(&self, cx: PrintCx<'_, '_, 'tcx, P>) -> Result; + fn print(&self, cx: P) -> Result; } -pub trait Printer: Sized { +pub trait Printer<'gcx: 'tcx, 'tcx>: Sized { type Error; type Path; @@ -65,15 +24,17 @@ pub trait Printer: Sized { type Type; type DynExistential; + fn tcx(&'a self) -> TyCtxt<'a, 'gcx, 'tcx>; + fn print_def_path( - self: PrintCx<'_, '_, 'tcx, Self>, + self, def_id: DefId, substs: Option>, ) -> Result { self.default_print_def_path(def_id, substs) } fn print_impl_path( - self: PrintCx<'_, '_, 'tcx, Self>, + self, impl_def_id: DefId, substs: Option>, self_ty: Ty<'tcx>, @@ -83,62 +44,56 @@ pub trait Printer: Sized { } fn print_region( - self: PrintCx<'_, '_, '_, Self>, + self, region: ty::Region<'_>, ) -> Result; fn print_type( - self: PrintCx<'_, '_, 'tcx, Self>, + self, ty: Ty<'tcx>, ) -> Result; fn print_dyn_existential( - self: PrintCx<'_, '_, 'tcx, Self>, + self, predicates: &'tcx ty::List>, ) -> Result; fn path_crate( - self: PrintCx<'_, '_, '_, Self>, + self, cnum: CrateNum, ) -> Result; fn path_qualified( - self: PrintCx<'_, '_, 'tcx, Self>, + self, self_ty: Ty<'tcx>, trait_ref: Option>, ) -> Result; - fn path_append_impl<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, + fn path_append_impl( + self, + print_prefix: impl FnOnce(Self) -> Result, self_ty: Ty<'tcx>, trait_ref: Option>, ) -> Result; - fn path_append<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, + fn path_append( + self, + print_prefix: impl FnOnce(Self) -> Result, text: &str, ) -> Result; - fn path_generic_args<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, + fn path_generic_args( + self, + print_prefix: impl FnOnce(Self) -> Result, args: &[Kind<'tcx>], ) -> Result; -} -impl PrintCx<'_, 'gcx, 'tcx, P> { - pub fn default_print_def_path( + // Defaults (should not be overriden): + + fn default_print_def_path( self, def_id: DefId, substs: Option>, - ) -> Result { + ) -> Result { debug!("default_print_def_path: def_id={:?}, substs={:?}", def_id, substs); - let key = self.tcx.def_key(def_id); + let key = self.tcx().def_key(def_id); debug!("default_print_def_path: key={:?}", key); match key.disambiguated_data.data { @@ -148,29 +103,29 @@ impl PrintCx<'_, 'gcx, 'tcx, P> { } DefPathData::Impl => { - let mut self_ty = self.tcx.type_of(def_id); + let mut self_ty = self.tcx().type_of(def_id); if let Some(substs) = substs { - self_ty = self_ty.subst(self.tcx, substs); + self_ty = self_ty.subst(self.tcx(), substs); } - let mut impl_trait_ref = self.tcx.impl_trait_ref(def_id); + let mut impl_trait_ref = self.tcx().impl_trait_ref(def_id); if let Some(substs) = substs { - impl_trait_ref = impl_trait_ref.subst(self.tcx, substs); + impl_trait_ref = impl_trait_ref.subst(self.tcx(), substs); } self.print_impl_path(def_id, substs, self_ty, impl_trait_ref) } _ => { - let generics = substs.map(|_| self.tcx.generics_of(def_id)); + let generics = substs.map(|_| self.tcx().generics_of(def_id)); let generics_parent = generics.as_ref().and_then(|g| g.parent); let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id }; - let print_parent_path = |cx: PrintCx<'_, 'gcx, 'tcx, P>| { + let print_parent_path = |cx: Self| { if let Some(generics_parent_def_id) = generics_parent { assert_eq!(parent_def_id, generics_parent_def_id); // FIXME(eddyb) try to move this into the parent's printing // logic, instead of doing it when printing the child. - let parent_generics = cx.tcx.generics_of(parent_def_id); + let parent_generics = cx.tcx().generics_of(parent_def_id); let parent_has_own_self = parent_generics.has_self && parent_generics.parent_count == 0; if let (Some(substs), true) = (substs, parent_has_own_self) { @@ -183,7 +138,7 @@ impl PrintCx<'_, 'gcx, 'tcx, P> { cx.print_def_path(parent_def_id, None) } }; - let print_path = |cx: PrintCx<'_, 'gcx, 'tcx, P>| { + let print_path = |cx: Self| { match key.disambiguated_data.data { // Skip `::{{constructor}}` on tuple/unit structs. DefPathData::StructCtor => print_parent_path(cx), @@ -207,7 +162,7 @@ impl PrintCx<'_, 'gcx, 'tcx, P> { } } - pub fn generic_args_to_print( + fn generic_args_to_print( &self, generics: &'tcx ty::Generics, substs: SubstsRef<'tcx>, @@ -225,7 +180,7 @@ impl PrintCx<'_, 'gcx, 'tcx, P> { ty::GenericParamDefKind::Lifetime => false, ty::GenericParamDefKind::Type { has_default, .. } => { has_default && substs[param.index as usize] == Kind::from( - self.tcx.type_of(param.def_id).subst(self.tcx, substs) + self.tcx().type_of(param.def_id).subst(self.tcx(), substs) ) } ty::GenericParamDefKind::Const => false, // FIXME(const_generics:defaults) @@ -241,7 +196,7 @@ impl PrintCx<'_, 'gcx, 'tcx, P> { _substs: Option>, self_ty: Ty<'tcx>, impl_trait_ref: Option>, - ) -> Result { + ) -> Result { debug!("default_print_impl_path: impl_def_id={:?}, self_ty={}, impl_trait_ref={:?}", impl_def_id, self_ty, impl_trait_ref); @@ -250,14 +205,14 @@ impl PrintCx<'_, 'gcx, 'tcx, P> { // users may find it useful. Currently, we omit the parent if // the impl is either in the same module as the self-type or // as the trait. - let parent_def_id = self.tcx.parent(impl_def_id).unwrap(); + let parent_def_id = self.tcx().parent(impl_def_id).unwrap(); let in_self_mod = match characteristic_def_id_of_type(self_ty) { None => false, - Some(ty_def_id) => self.tcx.parent(ty_def_id) == Some(parent_def_id), + Some(ty_def_id) => self.tcx().parent(ty_def_id) == Some(parent_def_id), }; let in_trait_mod = match impl_trait_ref { None => false, - Some(trait_ref) => self.tcx.parent(trait_ref.def_id) == Some(parent_def_id), + Some(trait_ref) => self.tcx().parent(trait_ref.def_id) == Some(parent_def_id), }; if !in_self_mod && !in_trait_mod { @@ -325,34 +280,36 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option { } } -impl Print<'tcx, P> for ty::RegionKind { +impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P> for ty::RegionKind { type Output = P::Region; type Error = P::Error; - fn print(&self, cx: PrintCx<'_, '_, 'tcx, P>) -> Result { + fn print(&self, cx: P) -> Result { cx.print_region(self) } } -impl Print<'tcx, P> for ty::Region<'_> { +impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P> for ty::Region<'_> { type Output = P::Region; type Error = P::Error; - fn print(&self, cx: PrintCx<'_, '_, 'tcx, P>) -> Result { + fn print(&self, cx: P) -> Result { cx.print_region(self) } } -impl Print<'tcx, P> for Ty<'tcx> { +impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P> for Ty<'tcx> { type Output = P::Type; type Error = P::Error; - fn print(&self, cx: PrintCx<'_, '_, 'tcx, P>) -> Result { + fn print(&self, cx: P) -> Result { cx.print_type(self) } } -impl Print<'tcx, P> for &'tcx ty::List> { +impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P> + for &'tcx ty::List> +{ type Output = P::DynExistential; type Error = P::Error; - fn print(&self, cx: PrintCx<'_, '_, 'tcx, P>) -> Result { + fn print(&self, cx: P) -> Result { cx.print_dyn_existential(self) } } diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index da01fd11a3f88..fff4ca822d20e 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -19,17 +19,12 @@ use std::ops::{Deref, DerefMut}; // `pretty` is a separate module only for organization. use super::*; -macro_rules! nest { - ($e:expr) => { - scoped_cx!() = PrintCx::new(scoped_cx!().tcx, $e?) - } -} macro_rules! print_inner { (write ($($data:expr),+)) => { write!(scoped_cx!(), $($data),+)? }; ($kind:ident ($data:expr)) => { - nest!($data.$kind(scoped_cx!())) + scoped_cx!() = $data.$kind(scoped_cx!())? }; } macro_rules! p { @@ -170,8 +165,8 @@ impl RegionHighlightMode { } /// Trait for printers that pretty-print using `fmt::Write` to the printer. -pub trait PrettyPrinter: - Printer< +pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>: + Printer<'gcx, 'tcx, Error = fmt::Error, Path = Self, Region = Self, @@ -182,7 +177,7 @@ pub trait PrettyPrinter: { /// Like `print_def_path` but for value paths. fn print_value_path( - self: PrintCx<'_, '_, 'tcx, Self>, + self, def_id: DefId, substs: Option>, ) -> Result { @@ -190,93 +185,54 @@ pub trait PrettyPrinter: } fn in_binder( - self: PrintCx<'_, '_, 'tcx, Self>, + self, value: &ty::Binder, ) -> Result - where T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx> + where T: Print<'gcx, 'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx> { value.skip_binder().print(self) } /// Print comma-separated elements. fn comma_sep( - mut self: PrintCx<'_, '_, 'tcx, Self>, + mut self, mut elems: impl Iterator, ) -> Result - where T: Print<'tcx, Self, Output = Self, Error = Self::Error> + where T: Print<'gcx, 'tcx, Self, Output = Self, Error = Self::Error> { - define_scoped_cx!(self); - if let Some(first) = elems.next() { - nest!(first.print(self)); + self = first.print(self)?; for elem in elems { self.write_str(", ")?; - nest!(elem.print(self)); + self = elem.print(self)?; } } - self.ok() + Ok(self) } /// Print `<...>` around what `f` prints. - fn generic_delimiters<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, + fn generic_delimiters( + self, + f: impl FnOnce(Self) -> Result, ) -> Result; /// Return `true` if the region should be printed in /// optional positions, e.g. `&'a T` or `dyn Tr + 'b`. /// This is typically the case for all non-`'_` regions. fn region_should_not_be_omitted( - self: &PrintCx<'_, '_, '_, Self>, + &self, region: ty::Region<'_>, ) -> bool; -} - -impl fmt::Write for PrintCx<'_, '_, '_, P> { - fn write_str(&mut self, s: &str) -> fmt::Result { - (**self).write_str(s) - } -} - -impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { - // HACK(eddyb) get rid of `def_path_str` and/or pass `Namespace` explicitly always - // (but also some things just print a `DefId` generally so maybe we need this?) - fn guess_def_namespace(self, def_id: DefId) -> Namespace { - match self.def_key(def_id).disambiguated_data.data { - DefPathData::ValueNs(..) | - DefPathData::EnumVariant(..) | - DefPathData::Field(..) | - DefPathData::AnonConst | - DefPathData::ConstParam(..) | - DefPathData::ClosureExpr | - DefPathData::StructCtor => Namespace::ValueNS, - - DefPathData::MacroDef(..) => Namespace::MacroNS, - - _ => Namespace::TypeNS, - } - } - /// Returns a string identifying this `DefId. This string is - /// suitable for user output. - pub fn def_path_str(self, def_id: DefId) -> String { - 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::new(&mut s, ns)) - .print_def_path(def_id, None); - s - } -} + // Defaults (should not be overriden): -impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { /// If possible, this returns a global path resolving to `def_id` that is visible /// from at least one local module and returns true. If the crate defining `def_id` is /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`. fn try_print_visible_def_path( mut self, def_id: DefId, - ) -> Result<(P, bool), P::Error> { + ) -> Result<(Self, bool), Self::Error> { define_scoped_cx!(self); debug!("try_print_visible_def_path: def_id={:?}", def_id); @@ -300,7 +256,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { // 2. for an extern inferred from a path or an indirect crate, // where there is no explicit `extern crate`, we just prepend // the crate name. - match *self.tcx.extern_crate(def_id) { + match *self.tcx().extern_crate(def_id) { Some(ExternCrate { src: ExternCrateSource::Extern(def_id), direct: true, @@ -322,12 +278,12 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } if def_id.is_local() { - return self.ok().map(|path| (path, false)); + return Ok((self, false)); } - let visible_parent_map = self.tcx.visible_parent_map(LOCAL_CRATE); + let visible_parent_map = self.tcx().visible_parent_map(LOCAL_CRATE); - let mut cur_def_key = self.tcx.def_key(def_id); + let mut cur_def_key = self.tcx().def_key(def_id); debug!("try_print_visible_def_path: cur_def_key={:?}", cur_def_key); // For a UnitStruct or TupleStruct we want the name of its parent rather than . @@ -337,27 +293,22 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { index: cur_def_key.parent.expect("DefPathData::StructCtor missing a parent"), }; - cur_def_key = self.tcx.def_key(parent); + cur_def_key = self.tcx().def_key(parent); } let visible_parent = match visible_parent_map.get(&def_id).cloned() { Some(parent) => parent, - None => return self.ok().map(|path| (path, false)), - }; - // HACK(eddyb) this uses `nest` to avoid knowing ahead of time whether - // the entire path will succeed or not. To support printers that do not - // implement `PrettyPrinter`, a `Vec` or linked list on the stack would - // need to be built, before starting to print anything. - let prefix_success; - nest!({ - let (path, success) = self.try_print_visible_def_path(visible_parent)?; - prefix_success = success; - Ok(path) - }); - if !prefix_success { - return self.ok().map(|path| (path, false)); + None => return Ok((self, false)), }; - let actual_parent = self.tcx.parent(def_id); + // HACK(eddyb) this bypasses `path_append`'s prefix printing to avoid + // knowing ahead of time whether the entire path will succeed or not. + // To support printers that do not implement `PrettyPrinter`, a `Vec` or + // linked list on the stack would need to be built, before any printing. + match self.try_print_visible_def_path(visible_parent)? { + (cx, false) => return Ok((cx, false)), + (cx, true) => self = cx, + } + let actual_parent = self.tcx().parent(def_id); debug!( "try_print_visible_def_path: visible_parent={:?} actual_parent={:?}", visible_parent, actual_parent, @@ -403,7 +354,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { // have access to the re-exported name. DefPathData::Module(actual_name) | DefPathData::TypeNs(actual_name) if Some(visible_parent) != actual_parent => { - self.tcx.item_children(visible_parent) + self.tcx().item_children(visible_parent) .iter() .find(|child| child.def.def_id() == def_id) .map(|child| child.ident.as_str()) @@ -413,7 +364,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { data.get_opt_name().map(|n| n.as_str()).unwrap_or_else(|| { // Re-exported `extern crate` (#43189). if let DefPathData::CrateRoot = data { - self.tcx.original_crate_name(def_id.krate).as_str() + self.tcx().original_crate_name(def_id.krate).as_str() } else { Symbol::intern("").as_str() } @@ -421,14 +372,14 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { }, }; debug!("try_print_visible_def_path: symbol={:?}", symbol); - Ok((self.path_append(|cx| cx.ok(), &symbol)?, true)) + Ok((self.path_append(Ok, &symbol)?, true)) } - pub fn pretty_path_qualified( + fn pretty_path_qualified( self, self_ty: Ty<'tcx>, trait_ref: Option>, - ) -> Result { + ) -> Result { if trait_ref.is_none() { // Inherent impls. Try to print `Foo::bar` for an inherent // impl on `Foo`, but fallback to `::bar` if self-type is @@ -451,19 +402,17 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { if let Some(trait_ref) = trait_ref { p!(write(" as "), print(trait_ref)); } - cx.ok() + Ok(cx) }) } - pub fn pretty_path_append_impl( + fn pretty_path_append_impl( mut self, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, P>, - ) -> Result, + print_prefix: impl FnOnce(Self) -> Result, self_ty: Ty<'tcx>, trait_ref: Option>, - ) -> Result { - self = PrintCx::new(self.tcx, print_prefix(self)?); + ) -> Result { + self = print_prefix(self)?; self.generic_delimiters(|mut cx| { define_scoped_cx!(cx); @@ -474,502 +423,78 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } p!(print(self_ty)); - cx.ok() + Ok(cx) }) } -} - -// HACK(eddyb) boxed to avoid moving around a large struct by-value. -pub struct FmtPrinter(Box>); - -pub struct FmtPrinterData { - fmt: F, - - empty_path: bool, - in_value: bool, - - used_region_names: FxHashSet, - region_index: usize, - binder_depth: usize, - - pub region_highlight_mode: RegionHighlightMode, -} - -impl Deref for FmtPrinter { - type Target = FmtPrinterData; - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl DerefMut for FmtPrinter { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - -impl FmtPrinter { - pub fn new(fmt: F, ns: Namespace) -> Self { - FmtPrinter(Box::new(FmtPrinterData { - fmt, - empty_path: false, - in_value: ns == Namespace::ValueNS, - used_region_names: Default::default(), - region_index: 0, - binder_depth: 0, - region_highlight_mode: RegionHighlightMode::default(), - })) - } -} - -impl fmt::Write for FmtPrinter { - fn write_str(&mut self, s: &str) -> fmt::Result { - self.fmt.write_str(s) - } -} -impl Printer for FmtPrinter { - type Error = fmt::Error; - - type Path = Self; - type Region = Self; - type Type = Self; - type DynExistential = Self; - - fn print_def_path( - mut self: PrintCx<'_, '_, 'tcx, Self>, - def_id: DefId, - substs: Option>, - ) -> Result { + fn pretty_print_type( + mut self, + ty: Ty<'tcx>, + ) -> Result { define_scoped_cx!(self); - // FIXME(eddyb) avoid querying `tcx.generics_of` and `tcx.def_key` - // both here and in `default_print_def_path`. - let generics = substs.map(|_| self.tcx.generics_of(def_id)); - if generics.as_ref().and_then(|g| g.parent).is_none() { - let visible_path_success; - nest!({ - let (path, success) = self.try_print_visible_def_path(def_id)?; - visible_path_success = success; - Ok(path) - }); - if visible_path_success { - return if let (Some(generics), Some(substs)) = (generics, substs) { - let args = self.generic_args_to_print(generics, substs); - self.path_generic_args(|cx| cx.ok(), args) - } else { - self.ok() - }; + match ty.sty { + ty::Bool => p!(write("bool")), + ty::Char => p!(write("char")), + ty::Int(t) => p!(write("{}", t.ty_to_string())), + ty::Uint(t) => p!(write("{}", t.ty_to_string())), + ty::Float(t) => p!(write("{}", t.ty_to_string())), + ty::RawPtr(ref tm) => { + p!(write("*{} ", match tm.mutbl { + hir::MutMutable => "mut", + hir::MutImmutable => "const", + })); + p!(print(tm.ty)) } - } - - let key = self.tcx.def_key(def_id); - if let DefPathData::Impl = key.disambiguated_data.data { - // Always use types for non-local impls, where types are always - // available, and filename/line-number is mostly uninteresting. - let use_types = - !def_id.is_local() || { - // Otherwise, use filename/line-number if forced. - let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get()); - !force_no_types - }; - - if !use_types { - // If no type info is available, fall back to - // pretty printing some span information. This should - // only occur very early in the compiler pipeline. - let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id }; - let span = self.tcx.def_span(def_id); - return self.path_append( - |cx| cx.print_def_path(parent_def_id, None), - &format!("", span), - ); + ty::Ref(r, ty, mutbl) => { + p!(write("&")); + if self.region_should_not_be_omitted(r) { + p!(print(r), write(" ")); + } + p!(print(ty::TypeAndMut { ty, mutbl })) } - } - - self.default_print_def_path(def_id, substs) - } - - fn print_region( - self: PrintCx<'_, '_, '_, Self>, - region: ty::Region<'_>, - ) -> Result { - self.pretty_print_region(region) - } - - fn print_type( - self: PrintCx<'_, '_, 'tcx, Self>, - ty: Ty<'tcx>, - ) -> Result { - self.pretty_print_type(ty) - } - - fn print_dyn_existential( - self: PrintCx<'_, '_, 'tcx, Self>, - predicates: &'tcx ty::List>, - ) -> Result { - self.pretty_print_dyn_existential(predicates) - } - - fn path_crate( - mut self: PrintCx<'_, '_, '_, Self>, - cnum: CrateNum, - ) -> Result { - self.empty_path = true; - if cnum == LOCAL_CRATE { - if self.tcx.sess.rust_2018() { - // We add the `crate::` keyword on Rust 2018, only when desired. - if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) { - write!(self, "{}", keywords::Crate.name())?; - self.empty_path = false; + ty::Never => p!(write("!")), + ty::Tuple(ref tys) => { + p!(write("(")); + let mut tys = tys.iter(); + if let Some(&ty) = tys.next() { + p!(print(ty), write(",")); + if let Some(&ty) = tys.next() { + p!(write(" "), print(ty)); + for &ty in tys { + p!(write(", "), print(ty)); + } + } } + p!(write(")")) } - } else { - write!(self, "{}", self.tcx.crate_name(cnum))?; - self.empty_path = false; - } - self.ok() - } - fn path_qualified( - self: PrintCx<'_, '_, 'tcx, Self>, - self_ty: Ty<'tcx>, - trait_ref: Option>, - ) -> Result { - let mut path = self.pretty_path_qualified(self_ty, trait_ref)?; - path.empty_path = false; - Ok(path) - } - - fn path_append_impl<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, - self_ty: Ty<'tcx>, - trait_ref: Option>, - ) -> Result { - let mut path = self.pretty_path_append_impl(|cx| { - let mut path = print_prefix(cx)?; - if !path.empty_path { - write!(path, "::")?; + ty::FnDef(def_id, substs) => { + let sig = self.tcx().fn_sig(def_id).subst(self.tcx(), substs); + p!(print(sig), write(" {{")); + self = self.print_value_path(def_id, Some(substs))?; + p!(write("}}")) } - - Ok(path) - }, self_ty, trait_ref)?; - path.empty_path = false; - Ok(path) - } - fn path_append<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, - text: &str, - ) -> Result { - let mut path = print_prefix(self)?; - - // FIXME(eddyb) `text` should never be empty, but it - // currently is for `extern { ... }` "foreign modules". - if !text.is_empty() { - if !path.empty_path { - write!(path, "::")?; + ty::FnPtr(ref bare_fn) => { + p!(print(bare_fn)) } - write!(path, "{}", text)?; - path.empty_path = false; - } - - Ok(path) - } - fn path_generic_args<'gcx, 'tcx>( - mut self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, - args: &[Kind<'tcx>], - ) -> Result { - define_scoped_cx!(self); - - nest!(print_prefix(self)); + ty::Infer(infer_ty) => p!(write("{}", infer_ty)), + ty::Error => p!(write("[type error]")), + ty::Param(ref param_ty) => p!(write("{}", param_ty)), + ty::Bound(debruijn, bound_ty) => { + match bound_ty.kind { + ty::BoundTyKind::Anon => { + if debruijn == ty::INNERMOST { + p!(write("^{}", bound_ty.var.index())) + } else { + p!(write("^{}_{}", debruijn.index(), bound_ty.var.index())) + } + } - // Don't print `'_` if there's no unerased regions. - let print_regions = args.iter().any(|arg| { - match arg.unpack() { - UnpackedKind::Lifetime(r) => *r != ty::ReErased, - _ => false, + ty::BoundTyKind::Param(p) => p!(write("{}", p)), + } } - }); - let args = args.iter().cloned().filter(|arg| { - match arg.unpack() { - UnpackedKind::Lifetime(_) => print_regions, - _ => true, - } - }); - - if args.clone().next().is_some() { - if self.in_value { - write!(self, "::")?; - } - self.generic_delimiters(|cx| cx.comma_sep(args)) - } else { - self.ok() - } - } -} - -impl PrettyPrinter for FmtPrinter { - fn print_value_path( - mut self: PrintCx<'_, '_, 'tcx, Self>, - def_id: DefId, - substs: Option>, - ) -> Result { - let was_in_value = std::mem::replace(&mut self.in_value, true); - let mut path = self.print_def_path(def_id, substs)?; - path.in_value = was_in_value; - - Ok(path) - } - - fn in_binder( - self: PrintCx<'_, '_, 'tcx, Self>, - value: &ty::Binder, - ) -> Result - where T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx> - { - self.pretty_in_binder(value) - } - - fn generic_delimiters<'gcx, 'tcx>( - mut self: PrintCx<'_, 'gcx, 'tcx, Self>, - f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, - ) -> Result { - write!(self, "<")?; - - let was_in_value = std::mem::replace(&mut self.in_value, false); - let mut inner = f(self)?; - inner.in_value = was_in_value; - - write!(inner, ">")?; - Ok(inner) - } - - fn region_should_not_be_omitted( - self: &PrintCx<'_, '_, '_, Self>, - region: ty::Region<'_>, - ) -> bool { - let highlight = self.region_highlight_mode; - if highlight.region_highlighted(region).is_some() { - return true; - } - - if self.tcx.sess.verbose() { - return true; - } - - let identify_regions = self.tcx.sess.opts.debugging_opts.identify_regions; - - match *region { - ty::ReEarlyBound(ref data) => { - data.name != "" && data.name != "'_" - } - - ty::ReLateBound(_, br) | - ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | - ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { - if let ty::BrNamed(_, name) = br { - if name != "" && name != "'_" { - return true; - } - } - - if let Some((region, _)) = highlight.highlight_bound_region { - if br == region { - return true; - } - } - - false - } - - ty::ReScope(_) | - ty::ReVar(_) if identify_regions => true, - - ty::ReVar(_) | - ty::ReScope(_) | - ty::ReErased => false, - - ty::ReStatic | - ty::ReEmpty | - ty::ReClosureBound(_) => true, - } - } -} - -// HACK(eddyb) limited to `FmtPrinter` because of `region_highlight_mode`. -impl FmtPrinter { - pub fn pretty_print_region( - mut self: PrintCx<'_, '_, '_, Self>, - region: ty::Region<'_>, - ) -> Result { - define_scoped_cx!(self); - - // Watch out for region highlights. - let highlight = self.region_highlight_mode; - if let Some(n) = highlight.region_highlighted(region) { - p!(write("'{}", n)); - return self.ok(); - } - - if self.tcx.sess.verbose() { - p!(write("{:?}", region)); - return self.ok(); - } - - let identify_regions = self.tcx.sess.opts.debugging_opts.identify_regions; - - // These printouts are concise. They do not contain all the information - // the user might want to diagnose an error, but there is basically no way - // to fit that into a short string. Hence the recommendation to use - // `explain_region()` or `note_and_explain_region()`. - match *region { - ty::ReEarlyBound(ref data) => { - if data.name != "" { - p!(write("{}", data.name)); - return self.ok(); - } - } - ty::ReLateBound(_, br) | - ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | - ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { - if let ty::BrNamed(_, name) = br { - if name != "" && name != "'_" { - p!(write("{}", name)); - return self.ok(); - } - } - - if let Some((region, counter)) = highlight.highlight_bound_region { - if br == region { - p!(write("'{}", counter)); - return self.ok(); - } - } - } - ty::ReScope(scope) if identify_regions => { - match scope.data { - region::ScopeData::Node => - p!(write("'{}s", scope.item_local_id().as_usize())), - region::ScopeData::CallSite => - p!(write("'{}cs", scope.item_local_id().as_usize())), - region::ScopeData::Arguments => - p!(write("'{}as", scope.item_local_id().as_usize())), - region::ScopeData::Destruction => - p!(write("'{}ds", scope.item_local_id().as_usize())), - region::ScopeData::Remainder(first_statement_index) => p!(write( - "'{}_{}rs", - scope.item_local_id().as_usize(), - first_statement_index.index() - )), - } - return self.ok(); - } - ty::ReVar(region_vid) if identify_regions => { - p!(write("{:?}", region_vid)); - return self.ok(); - } - ty::ReVar(_) => {} - ty::ReScope(_) | - ty::ReErased => {} - ty::ReStatic => { - p!(write("'static")); - return self.ok(); - } - ty::ReEmpty => { - p!(write("'")); - return self.ok(); - } - - // The user should never encounter these in unsubstituted form. - ty::ReClosureBound(vid) => { - p!(write("{:?}", vid)); - return self.ok(); - } - } - - p!(write("'_")); - - self.ok() - } -} - -impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { - pub fn pretty_print_type( - mut self, - ty: Ty<'tcx>, - ) -> Result { - define_scoped_cx!(self); - - match ty.sty { - ty::Bool => p!(write("bool")), - ty::Char => p!(write("char")), - ty::Int(t) => p!(write("{}", t.ty_to_string())), - ty::Uint(t) => p!(write("{}", t.ty_to_string())), - ty::Float(t) => p!(write("{}", t.ty_to_string())), - ty::RawPtr(ref tm) => { - p!(write("*{} ", match tm.mutbl { - hir::MutMutable => "mut", - hir::MutImmutable => "const", - })); - p!(print(tm.ty)) - } - ty::Ref(r, ty, mutbl) => { - p!(write("&")); - if self.region_should_not_be_omitted(r) { - p!(print(r), write(" ")); - } - p!(print(ty::TypeAndMut { ty, mutbl })) - } - ty::Never => p!(write("!")), - ty::Tuple(ref tys) => { - p!(write("(")); - let mut tys = tys.iter(); - if let Some(&ty) = tys.next() { - p!(print(ty), write(",")); - if let Some(&ty) = tys.next() { - p!(write(" "), print(ty)); - for &ty in tys { - p!(write(", "), print(ty)); - } - } - } - p!(write(")")) - } - ty::FnDef(def_id, substs) => { - let sig = self.tcx.fn_sig(def_id).subst(self.tcx, substs); - p!(print(sig), write(" {{")); - nest!(self.print_value_path(def_id, Some(substs))); - p!(write("}}")) - } - ty::FnPtr(ref bare_fn) => { - p!(print(bare_fn)) - } - ty::Infer(infer_ty) => p!(write("{}", infer_ty)), - ty::Error => p!(write("[type error]")), - ty::Param(ref param_ty) => p!(write("{}", param_ty)), - ty::Bound(debruijn, bound_ty) => { - match bound_ty.kind { - ty::BoundTyKind::Anon => { - if debruijn == ty::INNERMOST { - p!(write("^{}", bound_ty.var.index())) - } else { - p!(write("^{}_{}", debruijn.index(), bound_ty.var.index())) - } - } - - ty::BoundTyKind::Param(p) => p!(write("{}", p)), - } - } - ty::Adt(def, substs) => { - nest!(self.print_def_path(def.did, Some(substs))); + ty::Adt(def, substs) => { + self = self.print_def_path(def.did, Some(substs))?; } ty::Dynamic(data, r) => { let print_r = self.region_should_not_be_omitted(r); @@ -982,7 +507,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } } ty::Foreign(def_id) => { - nest!(self.print_def_path(def_id, None)); + self = self.print_def_path(def_id, None)?; } ty::Projection(ref data) => p!(print(data)), ty::UnnormalizedProjection(ref data) => { @@ -993,12 +518,12 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } ty::Opaque(def_id, substs) => { // FIXME(eddyb) print this with `print_def_path`. - if self.tcx.sess.verbose() { + if self.tcx().sess.verbose() { p!(write("Opaque({:?}, {:?})", def_id, substs)); - return self.ok(); + return Ok(self); } - let def_key = self.tcx.def_key(def_id); + let def_key = self.tcx().def_key(def_id); if let Some(name) = def_key.disambiguated_data.data.get_opt_name() { p!(write("{}", name)); let mut substs = substs.iter(); @@ -1011,11 +536,11 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } p!(write(">")); } - return self.ok(); + return Ok(self); } // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, // by looking up the projections associated with the def_id. - let bounds = self.tcx.predicates_of(def_id).instantiate(self.tcx, substs); + let bounds = self.tcx().predicates_of(def_id).instantiate(self.tcx(), substs); let mut first = true; let mut is_sized = false; @@ -1023,7 +548,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { for predicate in bounds.predicates { if let Some(trait_ref) = predicate.to_opt_poly_trait_ref() { // Don't print +Sized, but rather +?Sized if absent. - if Some(trait_ref.def_id()) == self.tcx.lang_items().sized_trait() { + if Some(trait_ref.def_id()) == self.tcx().lang_items().sized_trait() { is_sized = true; continue; } @@ -1042,8 +567,8 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } ty::Str => p!(write("str")), ty::Generator(did, substs, movability) => { - let upvar_tys = substs.upvar_tys(did, self.tcx); - let witness = substs.witness(did, self.tcx); + let upvar_tys = substs.upvar_tys(did, self.tcx()); + let witness = substs.witness(did, self.tcx()); if movability == hir::GeneratorMovability::Movable { p!(write("[generator")); } else { @@ -1051,10 +576,10 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } // FIXME(eddyb) should use `def_span`. - if let Some(hir_id) = self.tcx.hir().as_local_hir_id(did) { - p!(write("@{:?}", self.tcx.hir().span_by_hir_id(hir_id))); + if let Some(hir_id) = self.tcx().hir().as_local_hir_id(did) { + p!(write("@{:?}", self.tcx().hir().span_by_hir_id(hir_id))); let mut sep = " "; - for (freevar, upvar_ty) in self.tcx.freevars(did) + for (freevar, upvar_ty) in self.tcx().freevars(did) .as_ref() .map_or(&[][..], |fv| &fv[..]) .iter() @@ -1063,7 +588,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { p!( write("{}{}:", sep, - self.tcx.hir().name(freevar.var_id())), + self.tcx().hir().name(freevar.var_id())), print(upvar_ty)); sep = ", "; } @@ -1083,21 +608,21 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { p!(write(" "), print(witness), write("]")) }, ty::GeneratorWitness(types) => { - nest!(self.in_binder(&types)) + self = self.in_binder(&types)?; } ty::Closure(did, substs) => { - let upvar_tys = substs.upvar_tys(did, self.tcx); + let upvar_tys = substs.upvar_tys(did, self.tcx()); p!(write("[closure")); // FIXME(eddyb) should use `def_span`. - if let Some(hir_id) = self.tcx.hir().as_local_hir_id(did) { - if self.tcx.sess.opts.debugging_opts.span_free_formats { + if let Some(hir_id) = self.tcx().hir().as_local_hir_id(did) { + if self.tcx().sess.opts.debugging_opts.span_free_formats { p!(write("@{:?}", hir_id)); } else { - p!(write("@{:?}", self.tcx.hir().span_by_hir_id(hir_id))); + p!(write("@{:?}", self.tcx().hir().span_by_hir_id(hir_id))); } let mut sep = " "; - for (freevar, upvar_ty) in self.tcx.freevars(did) + for (freevar, upvar_ty) in self.tcx().freevars(did) .as_ref() .map_or(&[][..], |fv| &fv[..]) .iter() @@ -1106,7 +631,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { p!( write("{}{}:", sep, - self.tcx.hir().name(freevar.var_id())), + self.tcx().hir().name(freevar.var_id())), print(upvar_ty)); sep = ", "; } @@ -1123,11 +648,11 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } } - if self.tcx.sess.verbose() { + if self.tcx().sess.verbose() { p!(write( " closure_kind_ty={:?} closure_sig_ty={:?}", - substs.closure_kind_ty(did, self.tcx), - substs.closure_sig_ty(did, self.tcx) + substs.closure_kind_ty(did, self.tcx()), + substs.closure_sig_ty(did, self.tcx()) )); } @@ -1144,7 +669,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { ConstValue::Infer(..) => p!(write("_")), ConstValue::Param(ParamConst { name, .. }) => p!(write("{}", name)), - _ => p!(write("{}", c.unwrap_usize(self.tcx))), + _ => p!(write("{}", c.unwrap_usize(self.tcx()))), } } } @@ -1155,30 +680,30 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } } - self.ok() + Ok(self) } fn pretty_print_dyn_existential( mut self, predicates: &'tcx ty::List>, - ) -> Result { + ) -> Result { define_scoped_cx!(self); // Generate the main trait ref, including associated types. let mut first = true; if let Some(principal) = predicates.principal() { - nest!(self.print_def_path(principal.def_id, None)); + self = self.print_def_path(principal.def_id, None)?; let mut resugared = false; // Special-case `Fn(...) -> ...` and resugar it. - let fn_trait_kind = self.tcx.lang_items().fn_trait_kind(principal.def_id); - if !self.tcx.sess.verbose() && fn_trait_kind.is_some() { + let fn_trait_kind = self.tcx().lang_items().fn_trait_kind(principal.def_id); + if !self.tcx().sess.verbose() && fn_trait_kind.is_some() { if let ty::Tuple(ref args) = principal.substs.type_at(0).sty { let mut projections = predicates.projection_bounds(); if let (Some(proj), None) = (projections.next(), projections.next()) { - nest!(self.pretty_fn_sig(args, false, proj.ty)); + self = self.pretty_fn_sig(args, false, proj.ty)?; resugared = true; } } @@ -1188,11 +713,11 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { // in order to place the projections inside the `<...>`. if !resugared { // Use a type that can't appear in defaults of type parameters. - let dummy_self = self.tcx.mk_infer(ty::FreshTy(0)); - let principal = principal.with_self_ty(self.tcx, dummy_self); + let dummy_self = self.tcx().mk_infer(ty::FreshTy(0)); + let principal = principal.with_self_ty(self.tcx(), dummy_self); let args = self.generic_args_to_print( - self.tcx.generics_of(principal.def_id), + self.tcx().generics_of(principal.def_id), principal.substs, ); @@ -1217,13 +742,13 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { let args = arg0.into_iter().chain(args); let projections = projection0.into_iter().chain(projections); - nest!(self.generic_delimiters(|mut cx| { - cx = PrintCx::new(cx.tcx, cx.comma_sep(args)?); + self = self.generic_delimiters(|mut cx| { + cx = cx.comma_sep(args)?; if arg0.is_some() && projection0.is_some() { write!(cx, ", ")?; } cx.comma_sep(projections) - })); + })?; } } first = false; @@ -1233,7 +758,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { // FIXME(eddyb) avoid printing twice (needed to ensure // that the auto traits are sorted *and* printed via cx). let mut auto_traits: Vec<_> = predicates.auto_traits().map(|did| { - (self.tcx.def_path_str(did), did) + (self.tcx().def_path_str(did), did) }).collect(); // The auto traits come ordered by `DefPathHash`. While @@ -1251,18 +776,18 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } first = false; - nest!(self.print_def_path(def_id, None)); + self = self.print_def_path(def_id, None)?; } - self.ok() + Ok(self) } - pub fn pretty_fn_sig( + fn pretty_fn_sig( mut self, inputs: &[Ty<'tcx>], c_variadic: bool, output: Ty<'tcx>, - ) -> Result { + ) -> Result { define_scoped_cx!(self); p!(write("(")); @@ -1281,30 +806,476 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { p!(write(" -> "), print(output)); } - self.ok() + Ok(self) } } -// HACK(eddyb) limited to `FmtPrinter` because of `binder_depth`, -// `region_index` and `used_region_names`. -impl FmtPrinter { - pub fn pretty_in_binder( - mut self: PrintCx<'_, '_, 'tcx, Self>, - value: &ty::Binder, - ) -> Result - where T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx> - { - fn name_by_region_index(index: usize) -> InternedString { - match index { - 0 => Symbol::intern("'r"), - 1 => Symbol::intern("'s"), - i => Symbol::intern(&format!("'t{}", i-2)), - }.as_interned_str() - } +// HACK(eddyb) boxed to avoid moving around a large struct by-value. +pub struct FmtPrinter<'a, 'gcx, 'tcx, F>(Box>); - // Replace any anonymous late-bound regions with named - // variants, using gensym'd identifiers, so that we can - // clearly differentiate between named and unnamed regions in +pub struct FmtPrinterData<'a, 'gcx, 'tcx, F> { + tcx: TyCtxt<'a, 'gcx, 'tcx>, + fmt: F, + + empty_path: bool, + in_value: bool, + + used_region_names: FxHashSet, + region_index: usize, + binder_depth: usize, + + pub region_highlight_mode: RegionHighlightMode, +} + +impl Deref for FmtPrinter<'a, 'gcx, 'tcx, F> { + type Target = FmtPrinterData<'a, 'gcx, 'tcx, F>; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for FmtPrinter<'_, '_, '_, F> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl FmtPrinter<'a, 'gcx, 'tcx, F> { + pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, fmt: F, ns: Namespace) -> Self { + FmtPrinter(Box::new(FmtPrinterData { + tcx, + fmt, + empty_path: false, + in_value: ns == Namespace::ValueNS, + used_region_names: Default::default(), + region_index: 0, + binder_depth: 0, + region_highlight_mode: RegionHighlightMode::default(), + })) + } +} + +impl TyCtxt<'_, '_, '_> { + // HACK(eddyb) get rid of `def_path_str` and/or pass `Namespace` explicitly always + // (but also some things just print a `DefId` generally so maybe we need this?) + fn guess_def_namespace(self, def_id: DefId) -> Namespace { + match self.def_key(def_id).disambiguated_data.data { + DefPathData::ValueNs(..) | + DefPathData::EnumVariant(..) | + DefPathData::Field(..) | + DefPathData::AnonConst | + DefPathData::ConstParam(..) | + DefPathData::ClosureExpr | + DefPathData::StructCtor => Namespace::ValueNS, + + DefPathData::MacroDef(..) => Namespace::MacroNS, + + _ => Namespace::TypeNS, + } + } + + /// Returns a string identifying this `DefId`. This string is + /// suitable for user output. + pub fn def_path_str(self, def_id: DefId) -> String { + let ns = self.guess_def_namespace(def_id); + debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns); + let mut s = String::new(); + let _ = FmtPrinter::new(self, &mut s, ns) + .print_def_path(def_id, None); + s + } +} + +impl fmt::Write for FmtPrinter<'_, '_, '_, F> { + fn write_str(&mut self, s: &str) -> fmt::Result { + self.fmt.write_str(s) + } +} + +impl Printer<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F> { + type Error = fmt::Error; + + type Path = Self; + type Region = Self; + type Type = Self; + type DynExistential = Self; + + fn tcx(&'a self) -> TyCtxt<'a, 'gcx, 'tcx> { + self.tcx + } + + fn print_def_path( + mut self, + def_id: DefId, + substs: Option>, + ) -> Result { + define_scoped_cx!(self); + + // FIXME(eddyb) avoid querying `tcx.generics_of` and `tcx.def_key` + // both here and in `default_print_def_path`. + let generics = substs.map(|_| self.tcx.generics_of(def_id)); + if generics.as_ref().and_then(|g| g.parent).is_none() { + match self.try_print_visible_def_path(def_id)? { + (cx, true) => return if let (Some(generics), Some(substs)) = (generics, substs) { + let args = cx.generic_args_to_print(generics, substs); + cx.path_generic_args(Ok, args) + } else { + Ok(cx) + }, + (cx, false) => self = cx, + } + } + + let key = self.tcx.def_key(def_id); + if let DefPathData::Impl = key.disambiguated_data.data { + // Always use types for non-local impls, where types are always + // available, and filename/line-number is mostly uninteresting. + let use_types = + !def_id.is_local() || { + // Otherwise, use filename/line-number if forced. + let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get()); + !force_no_types + }; + + if !use_types { + // If no type info is available, fall back to + // pretty printing some span information. This should + // only occur very early in the compiler pipeline. + let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id }; + let span = self.tcx.def_span(def_id); + return self.path_append( + |cx| cx.print_def_path(parent_def_id, None), + &format!("", span), + ); + } + } + + self.default_print_def_path(def_id, substs) + } + + fn print_region( + self, + region: ty::Region<'_>, + ) -> Result { + self.pretty_print_region(region) + } + + fn print_type( + self, + ty: Ty<'tcx>, + ) -> Result { + self.pretty_print_type(ty) + } + + fn print_dyn_existential( + self, + predicates: &'tcx ty::List>, + ) -> Result { + self.pretty_print_dyn_existential(predicates) + } + + fn path_crate( + mut self, + cnum: CrateNum, + ) -> Result { + self.empty_path = true; + if cnum == LOCAL_CRATE { + if self.tcx.sess.rust_2018() { + // We add the `crate::` keyword on Rust 2018, only when desired. + if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) { + write!(self, "{}", keywords::Crate.name())?; + self.empty_path = false; + } + } + } else { + write!(self, "{}", self.tcx.crate_name(cnum))?; + self.empty_path = false; + } + Ok(self) + } + fn path_qualified( + mut self, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Result { + self = self.pretty_path_qualified(self_ty, trait_ref)?; + self.empty_path = false; + Ok(self) + } + + fn path_append_impl( + mut self, + print_prefix: impl FnOnce(Self) -> Result, + self_ty: Ty<'tcx>, + trait_ref: Option>, + ) -> Result { + self = self.pretty_path_append_impl(|mut cx| { + cx = print_prefix(cx)?; + if !cx.empty_path { + write!(cx, "::")?; + } + + Ok(cx) + }, self_ty, trait_ref)?; + self.empty_path = false; + Ok(self) + } + fn path_append( + mut self, + print_prefix: impl FnOnce(Self) -> Result, + text: &str, + ) -> Result { + self = print_prefix(self)?; + + // FIXME(eddyb) `text` should never be empty, but it + // currently is for `extern { ... }` "foreign modules". + if !text.is_empty() { + if !self.empty_path { + write!(self, "::")?; + } + write!(self, "{}", text)?; + self.empty_path = false; + } + + Ok(self) + } + fn path_generic_args( + mut self, + print_prefix: impl FnOnce(Self) -> Result, + args: &[Kind<'tcx>], + ) -> Result { + self = print_prefix(self)?; + + // Don't print `'_` if there's no unerased regions. + let print_regions = args.iter().any(|arg| { + match arg.unpack() { + UnpackedKind::Lifetime(r) => *r != ty::ReErased, + _ => false, + } + }); + let args = args.iter().cloned().filter(|arg| { + match arg.unpack() { + UnpackedKind::Lifetime(_) => print_regions, + _ => true, + } + }); + + if args.clone().next().is_some() { + if self.in_value { + write!(self, "::")?; + } + self.generic_delimiters(|cx| cx.comma_sep(args)) + } else { + Ok(self) + } + } +} + +impl PrettyPrinter<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F> { + fn print_value_path( + mut self, + def_id: DefId, + substs: Option>, + ) -> Result { + let was_in_value = std::mem::replace(&mut self.in_value, true); + self = self.print_def_path(def_id, substs)?; + self.in_value = was_in_value; + + Ok(self) + } + + fn in_binder( + self, + value: &ty::Binder, + ) -> Result + where T: Print<'gcx, 'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx> + { + self.pretty_in_binder(value) + } + + fn generic_delimiters( + mut self, + f: impl FnOnce(Self) -> Result, + ) -> Result { + write!(self, "<")?; + + let was_in_value = std::mem::replace(&mut self.in_value, false); + let mut inner = f(self)?; + inner.in_value = was_in_value; + + write!(inner, ">")?; + Ok(inner) + } + + fn region_should_not_be_omitted( + &self, + region: ty::Region<'_>, + ) -> bool { + let highlight = self.region_highlight_mode; + if highlight.region_highlighted(region).is_some() { + return true; + } + + if self.tcx.sess.verbose() { + return true; + } + + let identify_regions = self.tcx.sess.opts.debugging_opts.identify_regions; + + match *region { + ty::ReEarlyBound(ref data) => { + data.name != "" && data.name != "'_" + } + + ty::ReLateBound(_, br) | + ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | + ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { + if let ty::BrNamed(_, name) = br { + if name != "" && name != "'_" { + return true; + } + } + + if let Some((region, _)) = highlight.highlight_bound_region { + if br == region { + return true; + } + } + + false + } + + ty::ReScope(_) | + ty::ReVar(_) if identify_regions => true, + + ty::ReVar(_) | + ty::ReScope(_) | + ty::ReErased => false, + + ty::ReStatic | + ty::ReEmpty | + ty::ReClosureBound(_) => true, + } + } +} + +// HACK(eddyb) limited to `FmtPrinter` because of `region_highlight_mode`. +impl FmtPrinter<'_, '_, '_, F> { + pub fn pretty_print_region( + mut self, + region: ty::Region<'_>, + ) -> Result { + define_scoped_cx!(self); + + // Watch out for region highlights. + let highlight = self.region_highlight_mode; + if let Some(n) = highlight.region_highlighted(region) { + p!(write("'{}", n)); + return Ok(self); + } + + if self.tcx.sess.verbose() { + p!(write("{:?}", region)); + return Ok(self); + } + + let identify_regions = self.tcx.sess.opts.debugging_opts.identify_regions; + + // These printouts are concise. They do not contain all the information + // the user might want to diagnose an error, but there is basically no way + // to fit that into a short string. Hence the recommendation to use + // `explain_region()` or `note_and_explain_region()`. + match *region { + ty::ReEarlyBound(ref data) => { + if data.name != "" { + p!(write("{}", data.name)); + return Ok(self); + } + } + ty::ReLateBound(_, br) | + ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | + ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { + if let ty::BrNamed(_, name) = br { + if name != "" && name != "'_" { + p!(write("{}", name)); + return Ok(self); + } + } + + if let Some((region, counter)) = highlight.highlight_bound_region { + if br == region { + p!(write("'{}", counter)); + return Ok(self); + } + } + } + ty::ReScope(scope) if identify_regions => { + match scope.data { + region::ScopeData::Node => + p!(write("'{}s", scope.item_local_id().as_usize())), + region::ScopeData::CallSite => + p!(write("'{}cs", scope.item_local_id().as_usize())), + region::ScopeData::Arguments => + p!(write("'{}as", scope.item_local_id().as_usize())), + region::ScopeData::Destruction => + p!(write("'{}ds", scope.item_local_id().as_usize())), + region::ScopeData::Remainder(first_statement_index) => p!(write( + "'{}_{}rs", + scope.item_local_id().as_usize(), + first_statement_index.index() + )), + } + return Ok(self); + } + ty::ReVar(region_vid) if identify_regions => { + p!(write("{:?}", region_vid)); + return Ok(self); + } + ty::ReVar(_) => {} + ty::ReScope(_) | + ty::ReErased => {} + ty::ReStatic => { + p!(write("'static")); + return Ok(self); + } + ty::ReEmpty => { + p!(write("'")); + return Ok(self); + } + + // The user should never encounter these in unsubstituted form. + ty::ReClosureBound(vid) => { + p!(write("{:?}", vid)); + return Ok(self); + } + } + + p!(write("'_")); + + Ok(self) + } +} + +// HACK(eddyb) limited to `FmtPrinter` because of `binder_depth`, +// `region_index` and `used_region_names`. +impl FmtPrinter<'_, 'gcx, 'tcx, F> { + pub fn pretty_in_binder( + mut self, + value: &ty::Binder, + ) -> Result + where T: Print<'gcx, 'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx> + { + fn name_by_region_index(index: usize) -> InternedString { + match index { + 0 => Symbol::intern("'r"), + 1 => Symbol::intern("'s"), + i => Symbol::intern(&format!("'t{}", i-2)), + }.as_interned_str() + } + + // Replace any anonymous late-bound regions with named + // variants, using gensym'd identifiers, so that we can + // 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 { @@ -1382,107 +1353,94 @@ impl FmtPrinter { } } -impl Print<'tcx, P> for ty::Binder - where T: Print<'tcx, P, Output = P, Error = P::Error> + TypeFoldable<'tcx> +impl<'gcx: 'tcx, 'tcx, T, P: PrettyPrinter<'gcx, 'tcx>> Print<'gcx, 'tcx, P> + for ty::Binder + where T: Print<'gcx, 'tcx, P, Output = P, Error = P::Error> + TypeFoldable<'tcx> { type Output = P; type Error = P::Error; - fn print(&self, cx: PrintCx<'_, '_, 'tcx, P>) -> Result { + fn print(&self, cx: P) -> Result { cx.in_binder(self) } } -pub trait LiftAndPrintToFmt<'tcx> { - fn lift_and_print_to_fmt( - &self, - tcx: TyCtxt<'_, '_, 'tcx>, - f: &mut fmt::Formatter<'_>, - ) -> fmt::Result; -} - -impl LiftAndPrintToFmt<'tcx> for T - where T: ty::Lift<'tcx>, - for<'a, 'b> >::Lifted: - Print<'tcx, FmtPrinter<&'a mut fmt::Formatter<'b>>, Error = fmt::Error> +impl<'gcx: 'tcx, 'tcx, T, U, P: PrettyPrinter<'gcx, 'tcx>> Print<'gcx, 'tcx, P> + for ty::OutlivesPredicate + where T: Print<'gcx, 'tcx, P, Output = P, Error = P::Error>, + U: Print<'gcx, 'tcx, P, Output = P, Error = P::Error>, { - fn lift_and_print_to_fmt( - &self, - tcx: TyCtxt<'_, '_, 'tcx>, - f: &mut fmt::Formatter<'_>, - ) -> fmt::Result { - tcx.lift(self) - .expect("could not lift for printing") - .print(PrintCx::new(tcx, FmtPrinter::new(f, Namespace::TypeNS)))?; - Ok(()) - } -} - -// HACK(eddyb) this is separate because `ty::RegionKind` doesn't need lifting. -impl LiftAndPrintToFmt<'tcx> for ty::RegionKind { - fn lift_and_print_to_fmt( - &self, - tcx: TyCtxt<'_, '_, 'tcx>, - f: &mut fmt::Formatter<'_>, - ) -> fmt::Result { - self.print(PrintCx::new(tcx, FmtPrinter::new(f, Namespace::TypeNS)))?; - Ok(()) + type Output = P; + type Error = P::Error; + fn print(&self, mut cx: P) -> Result { + define_scoped_cx!(cx); + p!(print(self.0), write(" : "), print(self.1)); + Ok(cx) } } macro_rules! forward_display_to_print { - (<$($T:ident),*> $ty:ty) => { - impl<$($T),*> fmt::Display for $ty - where Self: for<'a> LiftAndPrintToFmt<'a> - { + ($($ty:ty),+) => { + $(impl fmt::Display for $ty { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - ty::tls::with(|tcx| self.lift_and_print_to_fmt(tcx, f)) + ty::tls::with(|tcx| { + tcx.lift(self) + .expect("could not lift for printing") + .print(FmtPrinter::new(tcx, f, Namespace::TypeNS))?; + Ok(()) + }) } - } - }; - - ($ty:ty) => { - forward_display_to_print!(<> $ty); + })+ }; } macro_rules! define_print_and_forward_display { - (($self:ident, $cx:ident): <$($T:ident),*> $ty:ty $print:block) => { - impl<$($T,)* P: PrettyPrinter> Print<'tcx, P> for $ty - where $($T: Print<'tcx, P, Output = P, Error = P::Error>),* - { + (($self:ident, $cx:ident): $($ty:ty $print:block)+) => { + $(impl<'gcx: 'tcx, 'tcx, P: PrettyPrinter<'gcx, 'tcx>> Print<'gcx, 'tcx, P> for $ty { type Output = P; type Error = fmt::Error; - fn print(&$self, $cx: PrintCx<'_, '_, 'tcx, P>) -> Result { + fn print(&$self, $cx: P) -> Result { #[allow(unused_mut)] let mut $cx = $cx; define_scoped_cx!($cx); let _: () = $print; #[allow(unreachable_code)] - $cx.ok() + Ok($cx) } - } + })+ - forward_display_to_print!(<$($T),*> $ty); - }; - - (($self:ident, $cx:ident): $($ty:ty $print:block)+) => { - $(define_print_and_forward_display!(($self, $cx): <> $ty $print);)+ + forward_display_to_print!($($ty),+); }; } -forward_display_to_print!(ty::RegionKind); -forward_display_to_print!(Ty<'tcx>); -forward_display_to_print!(&'tcx ty::List>); -forward_display_to_print!( ty::Binder); - -define_print_and_forward_display! { - (self, cx): - - ty::OutlivesPredicate { - p!(print(self.0), write(" : "), print(self.1)) +// HACK(eddyb) this is separate because `ty::RegionKind` doesn't need lifting. +impl fmt::Display for ty::RegionKind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + ty::tls::with(|tcx| { + self.print(FmtPrinter::new(tcx, f, Namespace::TypeNS))?; + Ok(()) + }) } } +forward_display_to_print! { + Ty<'tcx>, + &'tcx ty::List>, + + // HACK(eddyb) these are exhaustive instead of generic, + // because `for<'gcx: 'tcx, 'tcx>` isn't possible yet. + ty::Binder<&'tcx ty::List>>, + ty::Binder>, + ty::Binder>, + ty::Binder>, + ty::Binder>, + ty::Binder>, + ty::Binder, ty::Region<'tcx>>>, + ty::Binder, ty::Region<'tcx>>>, + + ty::OutlivesPredicate, ty::Region<'tcx>>, + ty::OutlivesPredicate, ty::Region<'tcx>> +} + define_print_and_forward_display! { (self, cx): @@ -1505,13 +1463,13 @@ define_print_and_forward_display! { ty::ExistentialTraitRef<'tcx> { // Use a type that can't appear in defaults of type parameters. - let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0)); - let trait_ref = self.with_self_ty(cx.tcx, dummy_self); + let dummy_self = cx.tcx().mk_infer(ty::FreshTy(0)); + let trait_ref = self.with_self_ty(cx.tcx(), dummy_self); p!(print(trait_ref)) } ty::ExistentialProjection<'tcx> { - let name = cx.tcx.associated_item(self.item_def_id).ident; + let name = cx.tcx().associated_item(self.item_def_id).ident; p!(write("{}=", name), print(self.ty)) } @@ -1520,7 +1478,7 @@ define_print_and_forward_display! { ty::ExistentialPredicate::Trait(x) => p!(print(x)), ty::ExistentialPredicate::Projection(x) => p!(print(x)), ty::ExistentialPredicate::AutoTrait(def_id) => { - nest!(cx.print_def_path(def_id, None)) + cx = cx.print_def_path(def_id, None)?; } } } @@ -1535,13 +1493,13 @@ define_print_and_forward_display! { } p!(write("fn")); - nest!(cx.pretty_fn_sig(self.inputs(), self.c_variadic, self.output())); + cx = cx.pretty_fn_sig(self.inputs(), self.c_variadic, self.output())?; } ty::InferTy { - if cx.tcx.sess.verbose() { + if cx.tcx().sess.verbose() { p!(write("{:?}", self)); - return cx.ok(); + return Ok(cx); } match *self { ty::TyVar(_) => p!(write("_")), @@ -1554,7 +1512,7 @@ define_print_and_forward_display! { } ty::TraitRef<'tcx> { - nest!(cx.print_def_path(self.def_id, Some(self.substs))); + cx = cx.print_def_path(self.def_id, Some(self.substs))?; } ConstValue<'tcx> { @@ -1569,7 +1527,7 @@ define_print_and_forward_display! { p!(write("{} : {}", self.val, self.ty)) } - ty::LazyConst<'tcx> { + &'tcx ty::LazyConst<'tcx> { match self { // FIXME(const_generics) this should print at least the type. ty::LazyConst::Unevaluated(..) => p!(write("_ : _")), @@ -1598,7 +1556,7 @@ define_print_and_forward_display! { } ty::ProjectionTy<'tcx> { - nest!(cx.print_def_path(self.item_def_id, Some(self.substs))); + cx = cx.print_def_path(self.item_def_id, Some(self.substs))?; } ty::ClosureKind { @@ -1619,17 +1577,17 @@ define_print_and_forward_display! { ty::Predicate::WellFormed(ty) => p!(print(ty), write(" well-formed")), ty::Predicate::ObjectSafe(trait_def_id) => { p!(write("the trait `")); - nest!(cx.print_def_path(trait_def_id, None)); + cx = cx.print_def_path(trait_def_id, None)?; p!(write("` is object-safe")) } ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => { p!(write("the closure `")); - nest!(cx.print_value_path(closure_def_id, None)); + cx = cx.print_value_path(closure_def_id, None)?; p!(write("` implements the trait `{}`", kind)) } ty::Predicate::ConstEvaluatable(def_id, substs) => { p!(write("the constant `")); - nest!(cx.print_value_path(def_id, Some(substs))); + cx = cx.print_value_path(def_id, Some(substs))?; p!(write("` can be evaluated")) } } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 32a39c2eb883d..4cbb315cefadb 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -8,7 +8,7 @@ use crate::mir::ProjectionKind; use crate::mir::interpret::ConstValue; use crate::ty::{self, Lift, Ty, TyCtxt, ConstVid, InferConst}; use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; -use crate::ty::print::{FmtPrinter, PrintCx, Printer}; +use crate::ty::print::{FmtPrinter, Printer}; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; use smallvec::SmallVec; use crate::mir::interpret; @@ -34,8 +34,9 @@ impl fmt::Debug for ty::GenericParamDef { impl fmt::Debug for ty::TraitDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::TypeNS), |cx| { - cx.print_def_path(self.def_id, None)?; + ty::tls::with(|tcx| { + FmtPrinter::new(tcx, f, Namespace::TypeNS) + .print_def_path(self.def_id, None)?; Ok(()) }) } @@ -43,8 +44,9 @@ impl fmt::Debug for ty::TraitDef { impl fmt::Debug for ty::AdtDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::TypeNS), |cx| { - cx.print_def_path(self.did, None)?; + ty::tls::with(|tcx| { + FmtPrinter::new(tcx, f, Namespace::TypeNS) + .print_def_path(self.did, None)?; Ok(()) }) } @@ -333,6 +335,7 @@ CloneTypeFoldableAndLiftImpls! { /////////////////////////////////////////////////////////////////////////// // Lift implementations +// FIXME(eddyb) replace all the uses of `Option::map` with `?`. impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>> Lift<'tcx> for (A, B) { type Lifted = (A::Lifted, B::Lifted); fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option { @@ -429,6 +432,23 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialTraitRef<'a> { } } +impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialPredicate<'a> { + type Lifted = ty::ExistentialPredicate<'tcx>; + fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option { + match self { + ty::ExistentialPredicate::Trait(x) => { + tcx.lift(x).map(ty::ExistentialPredicate::Trait) + } + ty::ExistentialPredicate::Projection(x) => { + tcx.lift(x).map(ty::ExistentialPredicate::Projection) + } + ty::ExistentialPredicate::AutoTrait(def_id) => { + Some(ty::ExistentialPredicate::AutoTrait(*def_id)) + } + } + } +} + impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> { type Lifted = ty::TraitPredicate<'tcx>; fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 084b86b1eb424..d1fcc88e59900 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -92,7 +92,7 @@ use rustc::hir::Node; use rustc::hir::CodegenFnAttrFlags; use rustc::hir::map::definitions::DefPathData; use rustc::ich::NodeIdHashingMode; -use rustc::ty::print::{PrettyPrinter, PrintCx, Printer, Print}; +use rustc::ty::print::{PrettyPrinter, Printer, Print}; use rustc::ty::query::Providers; use rustc::ty::subst::{Kind, SubstsRef, UnpackedKind}; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; @@ -223,10 +223,11 @@ fn get_symbol_hash<'a, 'tcx>( } fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName { - PrintCx::new(tcx, SymbolPath::new(tcx)) - .print_def_path(def_id, None) - .unwrap() - .into_interned() + SymbolPrinter { + tcx, + path: SymbolPath::new(), + keep_within_component: false, + }.print_def_path(def_id, None).unwrap().path.into_interned() } fn symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>) -> ty::SymbolName { @@ -318,13 +319,17 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance let hash = get_symbol_hash(tcx, def_id, instance, instance_ty, substs); - let mut buf = SymbolPath::from_interned(tcx.def_symbol_name(def_id), tcx); + let mut printer = SymbolPrinter { + tcx, + path: SymbolPath::from_interned(tcx.def_symbol_name(def_id)), + keep_within_component: false, + }; if instance.is_vtable_shim() { - let _ = buf.write_str("{{vtable-shim}}"); + let _ = printer.write_str("{{vtable-shim}}"); } - buf.finish(hash) + printer.path.finish(hash) } // Follow C++ namespace-mangling style, see @@ -344,33 +349,22 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance struct SymbolPath { result: String, temp_buf: String, - strict_naming: bool, - - // When `true`, `finalize_pending_component` isn't used. - // This is needed when recursing into `path_qualified`, - // or `path_generic_args`, as any nested paths are - // logically within one component. - keep_within_component: bool, } impl SymbolPath { - fn new(tcx: TyCtxt<'_, '_, '_>) -> Self { + fn new() -> Self { let mut result = SymbolPath { result: String::with_capacity(64), temp_buf: String::with_capacity(16), - strict_naming: tcx.has_strict_asm_symbol_naming(), - keep_within_component: false, }; result.result.push_str("_ZN"); // _Z == Begin name-sequence, N == nested result } - fn from_interned(symbol: ty::SymbolName, tcx: TyCtxt<'_, '_, '_>) -> Self { + fn from_interned(symbol: ty::SymbolName) -> Self { let mut result = SymbolPath { result: String::with_capacity(64), temp_buf: String::with_capacity(16), - strict_naming: tcx.has_strict_asm_symbol_naming(), - keep_within_component: false, }; result.result.push_str(&symbol.as_str()); result @@ -398,11 +392,22 @@ impl SymbolPath { } } +struct SymbolPrinter<'a, 'tcx> { + tcx: TyCtxt<'a, 'tcx, 'tcx>, + path: SymbolPath, + + // When `true`, `finalize_pending_component` isn't used. + // This is needed when recursing into `path_qualified`, + // or `path_generic_args`, as any nested paths are + // logically within one component. + keep_within_component: bool, +} + // HACK(eddyb) this relies on using the `fmt` interface to get // `PrettyPrinter` aka pretty printing of e.g. types in paths, // symbol names should have their own printing machinery. -impl Printer for SymbolPath { +impl Printer<'tcx, 'tcx> for SymbolPrinter<'_, 'tcx> { type Error = fmt::Error; type Path = Self; @@ -410,15 +415,19 @@ impl Printer for SymbolPath { type Type = Self; type DynExistential = Self; + fn tcx(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> { + self.tcx + } + fn print_region( - self: PrintCx<'_, '_, '_, Self>, + self, _region: ty::Region<'_>, ) -> Result { - self.ok() + Ok(self) } fn print_type( - self: PrintCx<'_, '_, 'tcx, Self>, + self, ty: Ty<'tcx>, ) -> Result { match ty.sty { @@ -436,7 +445,7 @@ impl Printer for SymbolPath { } fn print_dyn_existential( - mut self: PrintCx<'_, '_, 'tcx, Self>, + mut self, predicates: &'tcx ty::List>, ) -> Result { let mut first = false; @@ -445,20 +454,20 @@ impl Printer for SymbolPath { write!(self, "+")?; } first = false; - self = PrintCx::new(self.tcx, p.print(self)?); + self = p.print(self)?; } - self.ok() + Ok(self) } fn path_crate( - mut self: PrintCx<'_, '_, '_, Self>, + mut self, cnum: CrateNum, ) -> Result { self.write_str(&self.tcx.original_crate_name(cnum).as_str())?; - self.ok() + Ok(self) } fn path_qualified( - self: PrintCx<'_, '_, 'tcx, Self>, + self, self_ty: Ty<'tcx>, trait_ref: Option>, ) -> Result { @@ -480,11 +489,9 @@ impl Printer for SymbolPath { } } - fn path_append_impl<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, + fn path_append_impl( + self, + print_prefix: impl FnOnce(Self) -> Result, self_ty: Ty<'tcx>, trait_ref: Option>, ) -> Result { @@ -494,33 +501,29 @@ impl Printer for SymbolPath { trait_ref, ) } - fn path_append<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, + fn path_append( + mut self, + print_prefix: impl FnOnce(Self) -> Result, text: &str, ) -> Result { - let mut path = print_prefix(self)?; + self = print_prefix(self)?; - if path.keep_within_component { + if self.keep_within_component { // HACK(eddyb) print the path similarly to how `FmtPrinter` prints it. - path.write_str("::")?; + self.write_str("::")?; } else { - path.finalize_pending_component(); + self.path.finalize_pending_component(); } - path.write_str(text)?; - Ok(path) + self.write_str(text)?; + Ok(self) } - fn path_generic_args<'gcx, 'tcx>( - mut self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, + fn path_generic_args( + mut self, + print_prefix: impl FnOnce(Self) -> Result, args: &[Kind<'tcx>], ) -> Result { - self = PrintCx::new(self.tcx, print_prefix(self)?); + self = print_prefix(self)?; let args = args.iter().cloned().filter(|arg| { match arg.unpack() { @@ -532,52 +535,52 @@ impl Printer for SymbolPath { if args.clone().next().is_some() { self.generic_delimiters(|cx| cx.comma_sep(args)) } else { - self.ok() + Ok(self) } } } -impl PrettyPrinter for SymbolPath { +impl PrettyPrinter<'tcx, 'tcx> for SymbolPrinter<'_, 'tcx> { fn region_should_not_be_omitted( - self: &PrintCx<'_, '_, '_, Self>, + &self, _region: ty::Region<'_>, ) -> bool { false } fn comma_sep( - mut self: PrintCx<'_, '_, 'tcx, Self>, + mut self, mut elems: impl Iterator, ) -> Result - where T: Print<'tcx, Self, Output = Self, Error = Self::Error> + where T: Print<'tcx, 'tcx, Self, Output = Self, Error = Self::Error> { if let Some(first) = elems.next() { - self = PrintCx::new(self.tcx, first.print(self)?); + self = first.print(self)?; for elem in elems { self.write_str(",")?; - self = PrintCx::new(self.tcx, elem.print(self)?); + self = elem.print(self)?; } } - self.ok() + Ok(self) } - fn generic_delimiters<'gcx, 'tcx>( - mut self: PrintCx<'_, 'gcx, 'tcx, Self>, - f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result, + fn generic_delimiters( + mut self, + f: impl FnOnce(Self) -> Result, ) -> Result { write!(self, "<")?; let kept_within_component = mem::replace(&mut self.keep_within_component, true); - let mut path = f(self)?; - path.keep_within_component = kept_within_component; + self = f(self)?; + self.keep_within_component = kept_within_component; - write!(path, ">")?; + write!(self, ">")?; - Ok(path) + Ok(self) } } -impl fmt::Write for SymbolPath { +impl fmt::Write for SymbolPrinter<'_, '_> { fn write_str(&mut self, s: &str) -> fmt::Result { // Name sanitation. LLVM will happily accept identifiers with weird names, but // gas doesn't! @@ -586,45 +589,45 @@ impl fmt::Write for SymbolPath { // are replaced with '$' there. for c in s.chars() { - if self.temp_buf.is_empty() { + if self.path.temp_buf.is_empty() { match c { 'a'..='z' | 'A'..='Z' | '_' => {} _ => { // Underscore-qualify anything that didn't start as an ident. - self.temp_buf.push('_'); + self.path.temp_buf.push('_'); } } } match c { // Escape these with $ sequences - '@' => self.temp_buf.push_str("$SP$"), - '*' => self.temp_buf.push_str("$BP$"), - '&' => self.temp_buf.push_str("$RF$"), - '<' => self.temp_buf.push_str("$LT$"), - '>' => self.temp_buf.push_str("$GT$"), - '(' => self.temp_buf.push_str("$LP$"), - ')' => self.temp_buf.push_str("$RP$"), - ',' => self.temp_buf.push_str("$C$"), - - '-' | ':' | '.' if self.strict_naming => { + '@' => self.path.temp_buf.push_str("$SP$"), + '*' => self.path.temp_buf.push_str("$BP$"), + '&' => self.path.temp_buf.push_str("$RF$"), + '<' => self.path.temp_buf.push_str("$LT$"), + '>' => self.path.temp_buf.push_str("$GT$"), + '(' => self.path.temp_buf.push_str("$LP$"), + ')' => self.path.temp_buf.push_str("$RP$"), + ',' => self.path.temp_buf.push_str("$C$"), + + '-' | ':' | '.' if self.tcx.has_strict_asm_symbol_naming() => { // NVPTX doesn't support these characters in symbol names. - self.temp_buf.push('$') + self.path.temp_buf.push('$') } // '.' doesn't occur in types and functions, so reuse it // for ':' and '-' - '-' | ':' => self.temp_buf.push('.'), + '-' | ':' => self.path.temp_buf.push('.'), // These are legal symbols - 'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '.' | '$' => self.temp_buf.push(c), + 'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '.' | '$' => self.path.temp_buf.push(c), _ => { - self.temp_buf.push('$'); + self.path.temp_buf.push('$'); for c in c.escape_unicode().skip(1) { match c { '{' => {} - '}' => self.temp_buf.push('$'), - c => self.temp_buf.push(c), + '}' => self.path.temp_buf.push('$'), + c => self.path.temp_buf.push(c), } } } diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index d7dd0313e9487..8613464732457 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -2326,7 +2326,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { /// name where required. fn get_name_for_ty(&self, ty: ty::Ty<'tcx>, counter: usize) -> String { let mut s = String::new(); - let mut printer = ty::print::FmtPrinter::new(&mut s, Namespace::TypeNS); + let mut printer = ty::print::FmtPrinter::new(self.infcx.tcx, &mut s, Namespace::TypeNS); // We need to add synthesized lifetimes where appropriate. We do // this by hooking into the pretty printer and telling it to label the @@ -2341,7 +2341,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { _ => {} } - let _ = ty.print(ty::print::PrintCx::new(self.infcx.tcx, printer)); + let _ = ty.print(printer); s } @@ -2349,7 +2349,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { /// synthesized lifetime name where required. fn get_region_name_for_ty(&self, ty: ty::Ty<'tcx>, counter: usize) -> String { let mut s = String::new(); - let mut printer = ty::print::FmtPrinter::new(&mut s, Namespace::TypeNS); + let mut printer = ty::print::FmtPrinter::new(self.infcx.tcx, &mut s, Namespace::TypeNS); let region = match ty.sty { ty::TyKind::Ref(region, _, _) => { @@ -2366,7 +2366,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { _ => bug!("ty for annotation of borrow region is not a reference"), }; - let _ = region.print(ty::print::PrintCx::new(self.infcx.tcx, printer)); + let _ = region.print(printer); s } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 6822de2bcebae..53087eb1b1aba 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -4223,13 +4223,18 @@ pub fn path_to_def(tcx: &TyCtxt<'_, '_, '_>, path: &[&str]) -> Option { } } -pub fn get_path_for_type(tcx: TyCtxt<'_, '_, '_>, def_id: DefId, def_ctor: F) -> hir::Path -where F: Fn(DefId) -> Def { - use rustc::ty::print::{PrintCx, Printer}; +pub fn get_path_for_type( + tcx: TyCtxt<'_, '_, '_>, + def_id: DefId, + def_ctor: impl Fn(DefId) -> Def, +) -> hir::Path { + use rustc::ty::print::Printer; - struct AbsolutePathPrinter; + struct AbsolutePathPrinter<'a, 'tcx> { + tcx: TyCtxt<'a, 'tcx, 'tcx>, + } - impl Printer for AbsolutePathPrinter { + impl Printer<'tcx, 'tcx> for AbsolutePathPrinter<'_, 'tcx> { type Error = !; type Path = Vec; @@ -4237,35 +4242,39 @@ where F: Fn(DefId) -> Def { type Type = (); type DynExistential = (); + fn tcx(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> { + self.tcx + } + fn print_region( - self: PrintCx<'_, '_, '_, Self>, + self, _region: ty::Region<'_>, ) -> Result { Ok(()) } fn print_type( - self: PrintCx<'_, '_, 'tcx, Self>, + self, _ty: Ty<'tcx>, ) -> Result { Ok(()) } - fn print_dyn_existential<'tcx>( - self: PrintCx<'_, '_, 'tcx, Self>, + fn print_dyn_existential( + self, _predicates: &'tcx ty::List>, ) -> Result { Ok(()) } fn path_crate( - self: PrintCx<'_, '_, '_, Self>, + self, cnum: CrateNum, ) -> Result { Ok(vec![self.tcx.original_crate_name(cnum).to_string()]) } fn path_qualified( - self: PrintCx<'_, '_, 'tcx, Self>, + self, self_ty: Ty<'tcx>, trait_ref: Option>, ) -> Result { @@ -4276,11 +4285,9 @@ where F: Fn(DefId) -> Def { }]) } - fn path_append_impl<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, + fn path_append_impl( + self, + print_prefix: impl FnOnce(Self) -> Result, self_ty: Ty<'tcx>, trait_ref: Option>, ) -> Result { @@ -4296,29 +4303,25 @@ where F: Fn(DefId) -> Def { Ok(path) } - fn path_append<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, + fn path_append( + self, + print_prefix: impl FnOnce(Self) -> Result, text: &str, ) -> Result { let mut path = print_prefix(self)?; path.push(text.to_string()); Ok(path) } - fn path_generic_args<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, Self>, - ) -> Result, + fn path_generic_args( + self, + print_prefix: impl FnOnce(Self) -> Result, _args: &[Kind<'tcx>], ) -> Result { print_prefix(self) } } - let names = PrintCx::new(tcx, AbsolutePathPrinter) + let names = AbsolutePathPrinter { tcx: tcx.global_tcx() } .print_def_path(def_id, None) .unwrap();