rustc: pass ty::print::PrintCx by value.
This commit is contained in:
parent
ab5d6fb302
commit
7c4eecef0b
@ -459,37 +459,52 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
type Path = Vec<String>;
|
||||
|
||||
fn path_crate(
|
||||
self: &mut PrintCx<'_, '_, '_, Self>,
|
||||
self: PrintCx<'_, '_, '_, Self>,
|
||||
cnum: CrateNum,
|
||||
) -> Result<Self::Path, Self::Error> {
|
||||
Ok(vec![self.tcx.original_crate_name(cnum).to_string()])
|
||||
}
|
||||
fn path_qualified<'tcx>(
|
||||
self: &mut PrintCx<'_, '_, 'tcx, Self>,
|
||||
_impl_prefix: Option<Self::Path>,
|
||||
self: PrintCx<'_, '_, 'tcx, Self>,
|
||||
_self_ty: Ty<'tcx>,
|
||||
_trait_ref: Option<ty::TraitRef<'tcx>>,
|
||||
_ns: Namespace,
|
||||
) -> Result<Self::Path, Self::Error> {
|
||||
Err(NonTrivialPath)
|
||||
}
|
||||
fn path_append(
|
||||
self: &mut PrintCx<'_, '_, '_, Self>,
|
||||
mut path: Self::Path,
|
||||
|
||||
fn path_append_impl<'gcx, 'tcx>(
|
||||
self: PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
_print_prefix: impl FnOnce(
|
||||
PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
) -> Result<Self::Path, Self::Error>,
|
||||
_self_ty: Ty<'tcx>,
|
||||
_trait_ref: Option<ty::TraitRef<'tcx>>,
|
||||
) -> Result<Self::Path, Self::Error> {
|
||||
Err(NonTrivialPath)
|
||||
}
|
||||
fn path_append<'gcx, 'tcx>(
|
||||
self: PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
print_prefix: impl FnOnce(
|
||||
PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
) -> Result<Self::Path, Self::Error>,
|
||||
text: &str,
|
||||
) -> Result<Self::Path, Self::Error> {
|
||||
let mut path = print_prefix(self)?;
|
||||
path.push(text.to_string());
|
||||
Ok(path)
|
||||
}
|
||||
fn path_generic_args<'tcx>(
|
||||
self: &mut PrintCx<'_, '_, 'tcx, Self>,
|
||||
path: Self::Path,
|
||||
fn path_generic_args<'gcx, 'tcx>(
|
||||
self: PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
print_prefix: impl FnOnce(
|
||||
PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
) -> Result<Self::Path, Self::Error>,
|
||||
_params: &[ty::GenericParamDef],
|
||||
_substs: SubstsRef<'tcx>,
|
||||
_ns: Namespace,
|
||||
_projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>,
|
||||
) -> Result<Self::Path, Self::Error> {
|
||||
Ok(path)
|
||||
print_prefix(self)
|
||||
}
|
||||
}
|
||||
|
||||
@ -498,7 +513,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::with(self.tcx, AbsolutePathPrinter, |mut cx| {
|
||||
PrintCx::with(self.tcx, AbsolutePathPrinter, |cx| {
|
||||
cx.print_def_path(def_id, None, Namespace::TypeNS, iter::empty())
|
||||
})
|
||||
};
|
||||
|
@ -2369,7 +2369,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
|
||||
};
|
||||
|
||||
// When printing regions, add trailing space if necessary.
|
||||
ty::print::PrintCx::with_tls_tcx(ty::print::FmtPrinter { fmt }, |cx| {
|
||||
ty::print::PrintCx::with_tls_tcx(ty::print::FmtPrinter::new(fmt), |cx| {
|
||||
let region = if cx.config.is_verbose || cx.config.identify_regions {
|
||||
let mut region = region.to_string();
|
||||
if region.len() > 0 {
|
||||
|
@ -88,7 +88,7 @@ pub struct PrintCx<'a, 'gcx, 'tcx, P> {
|
||||
pub(crate) config: &'a mut PrintConfig,
|
||||
}
|
||||
|
||||
// HACK(eddyb) this is solely for `self: &mut PrintCx<Self>`, e.g. to
|
||||
// HACK(eddyb) this is solely for `self: PrintCx<Self>`, e.g. to
|
||||
// implement traits on the printer and call the methods on the context.
|
||||
impl<P> Deref for PrintCx<'_, '_, '_, P> {
|
||||
type Target = P;
|
||||
@ -127,21 +127,29 @@ pub trait Print<'tcx, P> {
|
||||
type Output;
|
||||
type Error;
|
||||
|
||||
fn print(&self, cx: &mut PrintCx<'_, '_, 'tcx, P>) -> Result<Self::Output, Self::Error>;
|
||||
fn print(&self, cx: PrintCx<'_, '_, 'tcx, P>) -> Result<Self::Output, Self::Error>;
|
||||
fn print_display(
|
||||
&self,
|
||||
cx: &mut PrintCx<'_, '_, 'tcx, P>,
|
||||
cx: PrintCx<'_, '_, 'tcx, P>,
|
||||
) -> Result<Self::Output, Self::Error> {
|
||||
let old_debug = cx.config.is_debug;
|
||||
cx.config.is_debug = false;
|
||||
let result = self.print(cx);
|
||||
let result = self.print(PrintCx {
|
||||
tcx: cx.tcx,
|
||||
printer: cx.printer,
|
||||
config: cx.config,
|
||||
});
|
||||
cx.config.is_debug = old_debug;
|
||||
result
|
||||
}
|
||||
fn print_debug(&self, cx: &mut PrintCx<'_, '_, 'tcx, P>) -> Result<Self::Output, Self::Error> {
|
||||
fn print_debug(&self, cx: PrintCx<'_, '_, 'tcx, P>) -> Result<Self::Output, Self::Error> {
|
||||
let old_debug = cx.config.is_debug;
|
||||
cx.config.is_debug = true;
|
||||
let result = self.print(cx);
|
||||
let result = self.print(PrintCx {
|
||||
tcx: cx.tcx,
|
||||
printer: cx.printer,
|
||||
config: cx.config,
|
||||
});
|
||||
cx.config.is_debug = old_debug;
|
||||
result
|
||||
}
|
||||
@ -153,7 +161,7 @@ pub trait Printer: Sized {
|
||||
type Path;
|
||||
|
||||
fn print_def_path(
|
||||
self: &mut PrintCx<'_, '_, 'tcx, Self>,
|
||||
self: PrintCx<'_, '_, 'tcx, Self>,
|
||||
def_id: DefId,
|
||||
substs: Option<SubstsRef<'tcx>>,
|
||||
ns: Namespace,
|
||||
@ -162,7 +170,7 @@ pub trait Printer: Sized {
|
||||
self.default_print_def_path(def_id, substs, ns, projections)
|
||||
}
|
||||
fn print_impl_path(
|
||||
self: &mut PrintCx<'_, '_, 'tcx, Self>,
|
||||
self: PrintCx<'_, '_, 'tcx, Self>,
|
||||
impl_def_id: DefId,
|
||||
substs: Option<SubstsRef<'tcx>>,
|
||||
ns: Namespace,
|
||||
@ -173,24 +181,36 @@ pub trait Printer: Sized {
|
||||
}
|
||||
|
||||
fn path_crate(
|
||||
self: &mut PrintCx<'_, '_, '_, Self>,
|
||||
self: PrintCx<'_, '_, '_, Self>,
|
||||
cnum: CrateNum,
|
||||
) -> Result<Self::Path, Self::Error>;
|
||||
fn path_qualified(
|
||||
self: &mut PrintCx<'_, '_, 'tcx, Self>,
|
||||
impl_prefix: Option<Self::Path>,
|
||||
self: PrintCx<'_, '_, 'tcx, Self>,
|
||||
self_ty: Ty<'tcx>,
|
||||
trait_ref: Option<ty::TraitRef<'tcx>>,
|
||||
ns: Namespace,
|
||||
) -> Result<Self::Path, Self::Error>;
|
||||
fn path_append(
|
||||
self: &mut PrintCx<'_, '_, '_, Self>,
|
||||
path: Self::Path,
|
||||
|
||||
fn path_append_impl<'gcx, 'tcx>(
|
||||
self: PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
print_prefix: impl FnOnce(
|
||||
PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
) -> Result<Self::Path, Self::Error>,
|
||||
self_ty: Ty<'tcx>,
|
||||
trait_ref: Option<ty::TraitRef<'tcx>>,
|
||||
) -> Result<Self::Path, Self::Error>;
|
||||
fn path_append<'gcx, 'tcx>(
|
||||
self: PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
print_prefix: impl FnOnce(
|
||||
PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
) -> Result<Self::Path, Self::Error>,
|
||||
text: &str,
|
||||
) -> Result<Self::Path, Self::Error>;
|
||||
fn path_generic_args(
|
||||
self: &mut PrintCx<'_, '_, 'tcx, Self>,
|
||||
path: Self::Path,
|
||||
fn path_generic_args<'gcx, 'tcx>(
|
||||
self: PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
print_prefix: impl FnOnce(
|
||||
PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
) -> Result<Self::Path, Self::Error>,
|
||||
params: &[ty::GenericParamDef],
|
||||
substs: SubstsRef<'tcx>,
|
||||
ns: Namespace,
|
||||
@ -198,13 +218,32 @@ pub trait Printer: Sized {
|
||||
) -> Result<Self::Path, Self::Error>;
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub struct PrettyPath {
|
||||
pub empty: bool,
|
||||
/// Trait for printers that pretty-print using `fmt::Write` to the printer.
|
||||
pub trait PrettyPrinter: Printer<Error = fmt::Error, Path = Self> + fmt::Write {
|
||||
/// Enter a nested print context, for pretty-printing
|
||||
/// nested components in some larger context.
|
||||
fn nest<'a, 'gcx, 'tcx, E>(
|
||||
self: PrintCx<'a, 'gcx, 'tcx, Self>,
|
||||
f: impl for<'b> FnOnce(PrintCx<'b, 'gcx, 'tcx, Self>) -> Result<Self, E>,
|
||||
) -> Result<PrintCx<'a, 'gcx, 'tcx, Self>, E> {
|
||||
let printer = f(PrintCx {
|
||||
tcx: self.tcx,
|
||||
printer: self.printer,
|
||||
config: self.config,
|
||||
})?;
|
||||
Ok(PrintCx {
|
||||
tcx: self.tcx,
|
||||
printer,
|
||||
config: self.config,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait for printers that pretty-print using `fmt::Write` to the printer.
|
||||
pub trait PrettyPrinter: Printer<Error = fmt::Error, Path = PrettyPath> + fmt::Write {}
|
||||
macro_rules! nest {
|
||||
($cx:ident, $closure:expr) => {
|
||||
$cx = $cx.nest($closure)?
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
// HACK(eddyb) get rid of `def_path_str` and/or pass `Namespace` explicitly always
|
||||
@ -231,7 +270,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
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::with(self, FmtPrinter { fmt: &mut s }, |mut cx| {
|
||||
let _ = PrintCx::with(self, FmtPrinter::new(&mut s), |cx| {
|
||||
cx.print_def_path(def_id, None, ns, iter::empty())
|
||||
});
|
||||
s
|
||||
@ -240,7 +279,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
impl<P: Printer> PrintCx<'a, 'gcx, 'tcx, P> {
|
||||
pub fn default_print_def_path(
|
||||
&mut self,
|
||||
self,
|
||||
def_id: DefId,
|
||||
substs: Option<SubstsRef<'tcx>>,
|
||||
ns: Namespace,
|
||||
@ -273,48 +312,52 @@ impl<P: Printer> PrintCx<'a, 'gcx, 'tcx, P> {
|
||||
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 path = if let Some(generics_parent_def_id) = generics_parent {
|
||||
assert_eq!(parent_def_id, generics_parent_def_id);
|
||||
let print_parent_path = |cx: PrintCx<'_, 'gcx, 'tcx, P>| {
|
||||
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 = self.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) {
|
||||
let trait_ref = ty::TraitRef::new(parent_def_id, substs);
|
||||
self.path_qualified(None, trait_ref.self_ty(), Some(trait_ref), ns)?
|
||||
// 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_has_own_self =
|
||||
parent_generics.has_self && parent_generics.parent_count == 0;
|
||||
if let (Some(substs), true) = (substs, parent_has_own_self) {
|
||||
let trait_ref = ty::TraitRef::new(parent_def_id, substs);
|
||||
cx.path_qualified(trait_ref.self_ty(), Some(trait_ref), ns)
|
||||
} else {
|
||||
cx.print_def_path(parent_def_id, substs, ns, iter::empty())
|
||||
}
|
||||
} else {
|
||||
self.print_def_path(parent_def_id, substs, ns, iter::empty())?
|
||||
cx.print_def_path(parent_def_id, None, ns, iter::empty())
|
||||
}
|
||||
} else {
|
||||
self.print_def_path(parent_def_id, None, ns, iter::empty())?
|
||||
};
|
||||
let path = match key.disambiguated_data.data {
|
||||
// Skip `::{{constructor}}` on tuple/unit structs.
|
||||
DefPathData::StructCtor => path,
|
||||
let print_path = |cx: PrintCx<'_, 'gcx, 'tcx, P>| {
|
||||
match key.disambiguated_data.data {
|
||||
// Skip `::{{constructor}}` on tuple/unit structs.
|
||||
DefPathData::StructCtor => print_parent_path(cx),
|
||||
|
||||
_ => {
|
||||
self.path_append(
|
||||
path,
|
||||
&key.disambiguated_data.data.as_interned_str().as_str(),
|
||||
)?
|
||||
_ => {
|
||||
cx.path_append(
|
||||
print_parent_path,
|
||||
&key.disambiguated_data.data.as_interned_str().as_str(),
|
||||
)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if let (Some(generics), Some(substs)) = (generics, substs) {
|
||||
let has_own_self = generics.has_self && generics.parent_count == 0;
|
||||
let params = &generics.params[has_own_self as usize..];
|
||||
self.path_generic_args(path, params, substs, ns, projections)
|
||||
self.path_generic_args(print_path, params, substs, ns, projections)
|
||||
} else {
|
||||
Ok(path)
|
||||
print_path(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn default_print_impl_path(
|
||||
&mut self,
|
||||
self,
|
||||
impl_def_id: DefId,
|
||||
_substs: Option<SubstsRef<'tcx>>,
|
||||
ns: Namespace,
|
||||
@ -339,18 +382,20 @@ impl<P: Printer> PrintCx<'a, 'gcx, 'tcx, P> {
|
||||
Some(trait_ref) => self.tcx.parent(trait_ref.def_id) == Some(parent_def_id),
|
||||
};
|
||||
|
||||
let prefix_path = if !in_self_mod && !in_trait_mod {
|
||||
if !in_self_mod && !in_trait_mod {
|
||||
// If the impl is not co-located with either self-type or
|
||||
// trait-type, then fallback to a format that identifies
|
||||
// the module more clearly.
|
||||
Some(self.print_def_path(parent_def_id, None, ns, iter::empty())?)
|
||||
self.path_append_impl(
|
||||
|cx| cx.print_def_path(parent_def_id, None, ns, iter::empty()),
|
||||
self_ty,
|
||||
impl_trait_ref,
|
||||
)
|
||||
} else {
|
||||
// Otherwise, try to give a good form that would be valid language
|
||||
// syntax. Preferably using associated item notation.
|
||||
None
|
||||
};
|
||||
|
||||
self.path_qualified(prefix_path, self_ty, impl_trait_ref, ns)
|
||||
self.path_qualified(self_ty, impl_trait_ref, ns)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -403,14 +448,27 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
|
||||
}
|
||||
|
||||
pub struct FmtPrinter<F: fmt::Write> {
|
||||
pub fmt: F,
|
||||
pub(crate) fmt: F,
|
||||
empty: bool,
|
||||
}
|
||||
|
||||
impl<P: PrettyPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
|
||||
impl<F: fmt::Write> FmtPrinter<F> {
|
||||
pub fn new(fmt: F) -> Self {
|
||||
FmtPrinter {
|
||||
fmt,
|
||||
empty: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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<Option<P::Path>, P::Error> {
|
||||
fn try_print_visible_def_path(
|
||||
mut self,
|
||||
def_id: DefId,
|
||||
) -> Result<(P, bool), P::Error> {
|
||||
debug!("try_print_visible_def_path: def_id={:?}", def_id);
|
||||
|
||||
// If `def_id` is a direct or injected extern crate, return the
|
||||
@ -419,7 +477,7 @@ impl<P: PrettyPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
|
||||
let cnum = def_id.krate;
|
||||
|
||||
if cnum == LOCAL_CRATE {
|
||||
return Ok(Some(self.path_crate(cnum)?));
|
||||
return Ok((self.path_crate(cnum)?, true));
|
||||
}
|
||||
|
||||
// In local mode, when we encounter a crate other than
|
||||
@ -440,22 +498,21 @@ impl<P: PrettyPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
|
||||
..
|
||||
}) => {
|
||||
debug!("try_print_visible_def_path: def_id={:?}", def_id);
|
||||
let path = if !span.is_dummy() {
|
||||
return Ok((if !span.is_dummy() {
|
||||
self.print_def_path(def_id, None, Namespace::TypeNS, iter::empty())?
|
||||
} else {
|
||||
self.path_crate(cnum)?
|
||||
};
|
||||
return Ok(Some(path));
|
||||
}, true));
|
||||
}
|
||||
None => {
|
||||
return Ok(Some(self.path_crate(cnum)?));
|
||||
return Ok((self.path_crate(cnum)?, true));
|
||||
}
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
if def_id.is_local() {
|
||||
return Ok(None);
|
||||
return Ok((self.printer, false));
|
||||
}
|
||||
|
||||
let visible_parent_map = self.tcx.visible_parent_map(LOCAL_CRATE);
|
||||
@ -475,11 +532,20 @@ impl<P: PrettyPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
|
||||
|
||||
let visible_parent = match visible_parent_map.get(&def_id).cloned() {
|
||||
Some(parent) => parent,
|
||||
None => return Ok(None),
|
||||
None => return Ok((self.printer, false)),
|
||||
};
|
||||
let path = match self.try_print_visible_def_path(visible_parent)? {
|
||||
Some(path) => path,
|
||||
None => return Ok(None),
|
||||
// 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 mut prefix_success = false;
|
||||
nest!(self, |cx| {
|
||||
let (printer, success) = cx.try_print_visible_def_path(visible_parent)?;
|
||||
prefix_success = success;
|
||||
Ok(printer)
|
||||
});
|
||||
if !prefix_success {
|
||||
return Ok((self.printer, false));
|
||||
};
|
||||
let actual_parent = self.tcx.parent(def_id);
|
||||
|
||||
@ -541,29 +607,15 @@ impl<P: PrettyPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
|
||||
},
|
||||
};
|
||||
debug!("try_print_visible_def_path: symbol={:?}", symbol);
|
||||
Ok(Some(self.path_append(path, &symbol)?))
|
||||
Ok((self.path_append(|cx| Ok(cx.printer), &symbol)?, true))
|
||||
}
|
||||
|
||||
pub fn pretty_path_qualified(
|
||||
&mut self,
|
||||
impl_prefix: Option<P::Path>,
|
||||
mut self,
|
||||
self_ty: Ty<'tcx>,
|
||||
trait_ref: Option<ty::TraitRef<'tcx>>,
|
||||
ns: Namespace,
|
||||
) -> Result<P::Path, P::Error> {
|
||||
if let Some(prefix) = impl_prefix {
|
||||
// HACK(eddyb) going through `path_append` means symbol name
|
||||
// computation gets to handle its equivalent of `::` correctly.
|
||||
let _ = self.path_append(prefix, "<impl ")?;
|
||||
if let Some(trait_ref) = trait_ref {
|
||||
trait_ref.print_display(self)?;
|
||||
write!(self.printer, " for ")?;
|
||||
}
|
||||
self_ty.print_display(self)?;
|
||||
write!(self.printer, ">")?;
|
||||
return Ok(PrettyPath { empty: false });
|
||||
}
|
||||
|
||||
if trait_ref.is_none() {
|
||||
// Inherent impls. Try to print `Foo::bar` for an inherent
|
||||
// impl on `Foo`, but fallback to `<Foo>::bar` if self-type is
|
||||
@ -578,8 +630,7 @@ impl<P: PrettyPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
|
||||
|
||||
ty::Bool | ty::Char | ty::Str |
|
||||
ty::Int(_) | ty::Uint(_) | ty::Float(_) => {
|
||||
self_ty.print_display(self)?;
|
||||
return Ok(PrettyPath { empty: false });
|
||||
return self_ty.print_display(self);
|
||||
}
|
||||
|
||||
_ => {}
|
||||
@ -587,28 +638,54 @@ impl<P: PrettyPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
|
||||
}
|
||||
|
||||
write!(self.printer, "<")?;
|
||||
self_ty.print_display(self)?;
|
||||
nest!(self, |cx| self_ty.print_display(cx));
|
||||
if let Some(trait_ref) = trait_ref {
|
||||
write!(self.printer, " as ")?;
|
||||
let _ = self.print_def_path(
|
||||
nest!(self, |cx| cx.print_def_path(
|
||||
trait_ref.def_id,
|
||||
Some(trait_ref.substs),
|
||||
Namespace::TypeNS,
|
||||
iter::empty(),
|
||||
)?;
|
||||
));
|
||||
}
|
||||
write!(self.printer, ">")?;
|
||||
Ok(PrettyPath { empty: false })
|
||||
|
||||
Ok(self.printer)
|
||||
}
|
||||
|
||||
pub fn pretty_path_append_impl(
|
||||
mut self,
|
||||
print_prefix: impl FnOnce(
|
||||
PrintCx<'_, 'gcx, 'tcx, P>,
|
||||
) -> Result<P::Path, P::Error>,
|
||||
self_ty: Ty<'tcx>,
|
||||
trait_ref: Option<ty::TraitRef<'tcx>>,
|
||||
) -> Result<P::Path, P::Error> {
|
||||
// HACK(eddyb) going through `path_append` means symbol name
|
||||
// computation gets to handle its equivalent of `::` correctly.
|
||||
nest!(self, |cx| cx.path_append(print_prefix, "<impl "));
|
||||
if let Some(trait_ref) = trait_ref {
|
||||
nest!(self, |cx| trait_ref.print_display(cx));
|
||||
write!(self.printer, " for ")?;
|
||||
}
|
||||
nest!(self, |cx| self_ty.print_display(cx));
|
||||
write!(self.printer, ">")?;
|
||||
|
||||
Ok(self.printer)
|
||||
}
|
||||
|
||||
pub fn pretty_path_generic_args(
|
||||
&mut self,
|
||||
path: P::Path,
|
||||
mut self,
|
||||
print_prefix: impl FnOnce(
|
||||
PrintCx<'_, 'gcx, 'tcx, P>,
|
||||
) -> Result<P::Path, P::Error>,
|
||||
params: &[ty::GenericParamDef],
|
||||
substs: SubstsRef<'tcx>,
|
||||
ns: Namespace,
|
||||
projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>,
|
||||
) -> Result<P::Path, P::Error> {
|
||||
nest!(self, |cx| print_prefix(cx));
|
||||
|
||||
let mut empty = true;
|
||||
let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| {
|
||||
write!(cx.printer, "{}", if empty {
|
||||
@ -652,8 +729,8 @@ impl<P: PrettyPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
|
||||
if !print_regions {
|
||||
continue;
|
||||
}
|
||||
start_or_continue(self, start, ", ")?;
|
||||
if !region.display_outputs_anything(self) {
|
||||
start_or_continue(&mut self, start, ", ")?;
|
||||
if !region.display_outputs_anything(&self) {
|
||||
// This happens when the value of the region
|
||||
// parameter is not easily serialized. This may be
|
||||
// because the user omitted it in the first place,
|
||||
@ -661,12 +738,12 @@ impl<P: PrettyPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
|
||||
// etc. I'm not sure how best to serialize this.
|
||||
write!(self.printer, "'_")?;
|
||||
} else {
|
||||
region.print_display(self)?;
|
||||
nest!(self, |cx| region.print_display(cx));
|
||||
}
|
||||
}
|
||||
UnpackedKind::Type(ty) => {
|
||||
start_or_continue(self, start, ", ")?;
|
||||
ty.print_display(self)?;
|
||||
start_or_continue(&mut self, start, ", ")?;
|
||||
nest!(self, |cx| ty.print_display(cx));
|
||||
}
|
||||
UnpackedKind::Const(ct) => {
|
||||
start_or_continue(self, start, ", ")?;
|
||||
@ -676,20 +753,21 @@ impl<P: PrettyPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
|
||||
}
|
||||
|
||||
for projection in projections {
|
||||
start_or_continue(self, start, ", ")?;
|
||||
start_or_continue(&mut self, start, ", ")?;
|
||||
write!(self.printer, "{}=",
|
||||
self.tcx.associated_item(projection.item_def_id).ident)?;
|
||||
projection.ty.print_display(self)?;
|
||||
nest!(self, |cx| projection.ty.print_display(cx));
|
||||
}
|
||||
|
||||
start_or_continue(self, "", ">")?;
|
||||
start_or_continue(&mut self, "", ">")?;
|
||||
|
||||
Ok(path)
|
||||
Ok(self.printer)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: fmt::Write> fmt::Write for FmtPrinter<F> {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
self.empty &= s.is_empty();
|
||||
self.fmt.write_str(s)
|
||||
}
|
||||
}
|
||||
@ -697,10 +775,10 @@ impl<F: fmt::Write> fmt::Write for FmtPrinter<F> {
|
||||
impl<F: fmt::Write> Printer for FmtPrinter<F> {
|
||||
type Error = fmt::Error;
|
||||
|
||||
type Path = PrettyPath;
|
||||
type Path = Self;
|
||||
|
||||
fn print_def_path(
|
||||
self: &mut PrintCx<'_, '_, 'tcx, Self>,
|
||||
mut self: PrintCx<'_, '_, 'tcx, Self>,
|
||||
def_id: DefId,
|
||||
substs: Option<SubstsRef<'tcx>>,
|
||||
ns: Namespace,
|
||||
@ -710,15 +788,20 @@ impl<F: fmt::Write> Printer for FmtPrinter<F> {
|
||||
// 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() {
|
||||
if let Some(path) = self.try_print_visible_def_path(def_id)? {
|
||||
let path = if let (Some(generics), Some(substs)) = (generics, substs) {
|
||||
let mut visible_path_success = false;
|
||||
nest!(self, |cx| {
|
||||
let (printer, success) = cx.try_print_visible_def_path(def_id)?;
|
||||
visible_path_success = success;
|
||||
Ok(printer)
|
||||
});
|
||||
if visible_path_success {
|
||||
return if let (Some(generics), Some(substs)) = (generics, substs) {
|
||||
let has_own_self = generics.has_self && generics.parent_count == 0;
|
||||
let params = &generics.params[has_own_self as usize..];
|
||||
self.path_generic_args(path, params, substs, ns, projections)?
|
||||
self.path_generic_args(|cx| Ok(cx.printer), params, substs, ns, projections)
|
||||
} else {
|
||||
path
|
||||
Ok(self.printer)
|
||||
};
|
||||
return Ok(path);
|
||||
}
|
||||
}
|
||||
|
||||
@ -738,9 +821,11 @@ impl<F: fmt::Write> Printer for FmtPrinter<F> {
|
||||
// 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 path = self.print_def_path(parent_def_id, None, ns, iter::empty())?;
|
||||
let span = self.tcx.def_span(def_id);
|
||||
return self.path_append(path, &format!("<impl at {:?}>", span));
|
||||
return self.path_append(
|
||||
|cx| cx.print_def_path(parent_def_id, None, ns, iter::empty()),
|
||||
&format!("<impl at {:?}>", span),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -748,7 +833,7 @@ impl<F: fmt::Write> Printer for FmtPrinter<F> {
|
||||
}
|
||||
|
||||
fn path_crate(
|
||||
self: &mut PrintCx<'_, '_, '_, Self>,
|
||||
mut self: PrintCx<'_, '_, '_, Self>,
|
||||
cnum: CrateNum,
|
||||
) -> Result<Self::Path, Self::Error> {
|
||||
if cnum == LOCAL_CRATE {
|
||||
@ -756,51 +841,83 @@ impl<F: fmt::Write> Printer for FmtPrinter<F> {
|
||||
// We add the `crate::` keyword on Rust 2018, only when desired.
|
||||
if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) {
|
||||
write!(self.printer, "{}", keywords::Crate.name())?;
|
||||
return Ok(PrettyPath { empty: false });
|
||||
}
|
||||
}
|
||||
Ok(PrettyPath { empty: true })
|
||||
Ok(self.printer)
|
||||
} else {
|
||||
write!(self.printer, "{}", self.tcx.crate_name(cnum))?;
|
||||
Ok(PrettyPath { empty: false })
|
||||
Ok(self.printer)
|
||||
}
|
||||
}
|
||||
fn path_qualified(
|
||||
self: &mut PrintCx<'_, '_, 'tcx, Self>,
|
||||
impl_prefix: Option<Self::Path>,
|
||||
self: PrintCx<'_, '_, 'tcx, Self>,
|
||||
self_ty: Ty<'tcx>,
|
||||
trait_ref: Option<ty::TraitRef<'tcx>>,
|
||||
ns: Namespace,
|
||||
) -> Result<Self::Path, Self::Error> {
|
||||
self.pretty_path_qualified(impl_prefix, self_ty, trait_ref, ns)
|
||||
self.pretty_path_qualified(self_ty, trait_ref, ns)
|
||||
}
|
||||
fn path_append(
|
||||
self: &mut PrintCx<'_, '_, '_, Self>,
|
||||
path: Self::Path,
|
||||
|
||||
fn path_append_impl<'gcx, 'tcx>(
|
||||
self: PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
print_prefix: impl FnOnce(
|
||||
PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
) -> Result<Self::Path, Self::Error>,
|
||||
self_ty: Ty<'tcx>,
|
||||
trait_ref: Option<ty::TraitRef<'tcx>>,
|
||||
) -> Result<Self::Path, Self::Error> {
|
||||
self.pretty_path_append_impl(print_prefix, self_ty, trait_ref)
|
||||
}
|
||||
fn path_append<'gcx, 'tcx>(
|
||||
self: PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
print_prefix: impl FnOnce(
|
||||
PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
) -> Result<Self::Path, Self::Error>,
|
||||
text: &str,
|
||||
) -> Result<Self::Path, Self::Error> {
|
||||
// FIXME(eddyb) this shouldn't happen, but is currently
|
||||
// the case for `extern { ... }` "foreign modules".
|
||||
if text.is_empty() {
|
||||
return Ok(path);
|
||||
let mut printer = print_prefix(self)?;
|
||||
|
||||
// FIXME(eddyb) `text` should never be empty, but it
|
||||
// currently is for `extern { ... }` "foreign modules".
|
||||
if !text.is_empty() {
|
||||
if !printer.empty {
|
||||
write!(printer, "::")?;
|
||||
}
|
||||
write!(printer, "{}", text)?;
|
||||
}
|
||||
|
||||
if !path.empty {
|
||||
write!(self.printer, "::")?;
|
||||
}
|
||||
write!(self.printer, "{}", text)?;
|
||||
Ok(PrettyPath { empty: false })
|
||||
Ok(printer)
|
||||
}
|
||||
fn path_generic_args(
|
||||
self: &mut PrintCx<'_, '_, 'tcx, Self>,
|
||||
path: Self::Path,
|
||||
fn path_generic_args<'gcx, 'tcx>(
|
||||
self: PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
print_prefix: impl FnOnce(
|
||||
PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
) -> Result<Self::Path, Self::Error>,
|
||||
params: &[ty::GenericParamDef],
|
||||
substs: SubstsRef<'tcx>,
|
||||
ns: Namespace,
|
||||
projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>,
|
||||
) -> Result<Self::Path, Self::Error> {
|
||||
self.pretty_path_generic_args(path, params, substs, ns, projections)
|
||||
self.pretty_path_generic_args(print_prefix, params, substs, ns, projections)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: fmt::Write> PrettyPrinter for FmtPrinter<F> {}
|
||||
impl<F: fmt::Write> PrettyPrinter for FmtPrinter<F> {
|
||||
fn nest<'a, 'gcx, 'tcx, E>(
|
||||
mut self: PrintCx<'a, 'gcx, 'tcx, Self>,
|
||||
f: impl for<'b> FnOnce(PrintCx<'b, 'gcx, 'tcx, Self>) -> Result<Self, E>,
|
||||
) -> Result<PrintCx<'a, 'gcx, 'tcx, Self>, E> {
|
||||
let was_empty = std::mem::replace(&mut self.printer.empty, true);
|
||||
let mut printer = f(PrintCx {
|
||||
tcx: self.tcx,
|
||||
printer: self.printer,
|
||||
config: self.config,
|
||||
})?;
|
||||
printer.empty &= was_empty;
|
||||
Ok(PrintCx {
|
||||
tcx: self.tcx,
|
||||
printer,
|
||||
config: self.config,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -161,8 +161,9 @@ impl RegionHighlightMode {
|
||||
macro_rules! gen_display_debug_body {
|
||||
( $with:path ) => {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
PrintCx::with_tls_tcx(FmtPrinter { fmt: f }, |mut cx| {
|
||||
$with(&cx.tcx.lift(self).expect("could not lift for printing"), &mut cx)
|
||||
PrintCx::with_tls_tcx(FmtPrinter::new(f), |cx| {
|
||||
$with(&cx.tcx.lift(self).expect("could not lift for printing"), cx)?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
};
|
||||
@ -193,27 +194,35 @@ macro_rules! gen_display_debug {
|
||||
macro_rules! gen_print_impl {
|
||||
( ($($x:tt)+) $target:ty, ($self:ident, $cx:ident) $disp:block $dbg:block ) => {
|
||||
impl<$($x)+, P: PrettyPrinter> Print<'tcx, P> for $target {
|
||||
type Output = ();
|
||||
type Output = P;
|
||||
type Error = fmt::Error;
|
||||
fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, P>) -> fmt::Result {
|
||||
Ok({
|
||||
fn print(&$self, $cx: PrintCx<'_, '_, 'tcx, P>) -> Result<Self::Output, Self::Error> {
|
||||
#[allow(unused_mut)]
|
||||
let mut $cx = $cx;
|
||||
let _: () = {
|
||||
define_scoped_cx!($cx);
|
||||
|
||||
if $cx.config.is_debug $dbg
|
||||
else $disp
|
||||
})
|
||||
};
|
||||
Ok($cx.printer)
|
||||
}
|
||||
}
|
||||
};
|
||||
( () $target:ty, ($self:ident, $cx:ident) $disp:block $dbg:block ) => {
|
||||
impl<P: PrettyPrinter> Print<'tcx, P> for $target {
|
||||
type Output = ();
|
||||
type Output = P;
|
||||
type Error = fmt::Error;
|
||||
fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, P>) -> fmt::Result {
|
||||
Ok({
|
||||
fn print(&$self, $cx: PrintCx<'_, '_, 'tcx, P>) -> Result<Self::Output, Self::Error> {
|
||||
#[allow(unused_mut)]
|
||||
let mut $cx = $cx;
|
||||
let _: () = {
|
||||
define_scoped_cx!($cx);
|
||||
|
||||
if $cx.config.is_debug $dbg
|
||||
else $disp
|
||||
})
|
||||
};
|
||||
Ok($cx.printer)
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -251,18 +260,23 @@ macro_rules! define_print_multi {
|
||||
$(define_print! { $generic $target, $vars $def })*
|
||||
};
|
||||
}
|
||||
macro_rules! nest {
|
||||
($closure:expr) => {
|
||||
scoped_cx!() = scoped_cx!().nest($closure)?
|
||||
}
|
||||
}
|
||||
macro_rules! print_inner {
|
||||
(write ($($data:expr),+)) => {
|
||||
write!(scoped_cx!().printer, $($data),+)
|
||||
write!(scoped_cx!().printer, $($data),+)?
|
||||
};
|
||||
($kind:ident ($data:expr)) => {
|
||||
$data.$kind(scoped_cx!())
|
||||
nest!(|cx| $data.$kind(cx))
|
||||
};
|
||||
}
|
||||
macro_rules! p {
|
||||
($($kind:ident $data:tt),+) => {
|
||||
{
|
||||
$(print_inner!($kind $data)?);+
|
||||
$(print_inner!($kind $data));+
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -277,11 +291,11 @@ macro_rules! define_scoped_cx {
|
||||
|
||||
impl<P: PrettyPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
|
||||
fn fn_sig(
|
||||
&mut self,
|
||||
mut self,
|
||||
inputs: &[Ty<'tcx>],
|
||||
c_variadic: bool,
|
||||
output: Ty<'tcx>,
|
||||
) -> fmt::Result {
|
||||
) -> Result<P, fmt::Error> {
|
||||
define_scoped_cx!(self);
|
||||
|
||||
p!(write("("));
|
||||
@ -300,11 +314,11 @@ impl<P: PrettyPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
|
||||
p!(write(" -> "), print_display(output));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(self.printer)
|
||||
}
|
||||
|
||||
fn in_binder<T>(&mut self, value: &ty::Binder<T>) -> Result<T::Output, fmt::Error>
|
||||
where T: Print<'tcx, P, Error = fmt::Error> + TypeFoldable<'tcx>
|
||||
fn in_binder<T>(mut self, value: &ty::Binder<T>) -> Result<P, fmt::Error>
|
||||
where T: Print<'tcx, P, Output = P, Error = fmt::Error> + TypeFoldable<'tcx>
|
||||
{
|
||||
fn name_by_region_index(index: usize) -> InternedString {
|
||||
match index {
|
||||
@ -341,7 +355,7 @@ impl<P: PrettyPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
|
||||
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<", ", ");
|
||||
let _ = start_or_continue(&mut self, "for<", ", ");
|
||||
let br = match br {
|
||||
ty::BrNamed(_, name) => {
|
||||
let _ = write!(self.printer, "{}", name);
|
||||
@ -363,12 +377,16 @@ impl<P: PrettyPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
|
||||
};
|
||||
self.tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br))
|
||||
}).0;
|
||||
start_or_continue(self, "", "> ")?;
|
||||
start_or_continue(&mut self, "", "> ")?;
|
||||
|
||||
// Push current state to gcx, and restore after writing new_value.
|
||||
self.config.binder_depth += 1;
|
||||
self.config.region_index = region_index;
|
||||
let result = new_value.print_display(self);
|
||||
let result = new_value.print_display(PrintCx {
|
||||
tcx: self.tcx,
|
||||
printer: self.printer,
|
||||
config: self.config,
|
||||
});
|
||||
self.config.region_index = old_region_index;
|
||||
self.config.binder_depth -= 1;
|
||||
result
|
||||
@ -388,9 +406,9 @@ pub fn parameterized<F: fmt::Write>(
|
||||
substs: SubstsRef<'_>,
|
||||
ns: Namespace,
|
||||
) -> fmt::Result {
|
||||
PrintCx::with_tls_tcx(FmtPrinter { fmt: f }, |mut cx| {
|
||||
PrintCx::with_tls_tcx(FmtPrinter::new(f), |cx| {
|
||||
let substs = cx.tcx.lift(&substs).expect("could not lift for printing");
|
||||
let _ = cx.print_def_path(did, Some(substs), ns, iter::empty())?;
|
||||
cx.print_def_path(did, Some(substs), ns, iter::empty())?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
@ -410,13 +428,13 @@ define_print! {
|
||||
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(
|
||||
nest!(|cx| cx.print_def_path(
|
||||
principal.def_id,
|
||||
None,
|
||||
Namespace::TypeNS,
|
||||
iter::empty(),
|
||||
)?;
|
||||
cx.fn_sig(args, false, proj.ty)?;
|
||||
));
|
||||
nest!(|cx| cx.fn_sig(args, false, proj.ty));
|
||||
resugared_principal = true;
|
||||
}
|
||||
}
|
||||
@ -426,12 +444,12 @@ define_print! {
|
||||
// Use a type that can't appear in defaults of type parameters.
|
||||
let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0));
|
||||
let principal = principal.with_self_ty(cx.tcx, dummy_self);
|
||||
let _ = cx.print_def_path(
|
||||
nest!(|cx| cx.print_def_path(
|
||||
principal.def_id,
|
||||
Some(principal.substs),
|
||||
Namespace::TypeNS,
|
||||
self.projection_bounds(),
|
||||
)?;
|
||||
));
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
@ -458,12 +476,12 @@ define_print! {
|
||||
}
|
||||
first = false;
|
||||
|
||||
let _ = cx.print_def_path(
|
||||
nest!(|cx| cx.print_def_path(
|
||||
def_id,
|
||||
None,
|
||||
Namespace::TypeNS,
|
||||
iter::empty(),
|
||||
)?;
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -486,8 +504,8 @@ 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 { fmt: f }, |mut cx| {
|
||||
let _ = cx.print_def_path(
|
||||
PrintCx::with_tls_tcx(FmtPrinter::new(f), |cx| {
|
||||
cx.print_def_path(
|
||||
self.def_id,
|
||||
None,
|
||||
Namespace::TypeNS,
|
||||
@ -500,8 +518,8 @@ 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 { fmt: f }, |mut cx| {
|
||||
let _ = cx.print_def_path(
|
||||
PrintCx::with_tls_tcx(FmtPrinter::new(f), |cx| {
|
||||
cx.print_def_path(
|
||||
self.did,
|
||||
None,
|
||||
Namespace::TypeNS,
|
||||
@ -522,7 +540,7 @@ impl<'tcx> fmt::Debug for ty::ClosureUpvar<'tcx> {
|
||||
|
||||
impl fmt::Debug for ty::UpvarId {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
PrintCx::with_tls_tcx(FmtPrinter { fmt: f }, |mut cx| {
|
||||
PrintCx::with_tls_tcx(FmtPrinter::new(f), |mut cx| {
|
||||
define_scoped_cx!(cx);
|
||||
p!(write("UpvarId({:?};`{}`;{:?})",
|
||||
self.var_path.hir_id,
|
||||
@ -571,9 +589,10 @@ define_print! {
|
||||
display {
|
||||
let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0));
|
||||
|
||||
p!(print_display(ty::Binder::bind(*self)
|
||||
let trait_ref = *ty::Binder::bind(*self)
|
||||
.with_self_ty(cx.tcx, dummy_self)
|
||||
.skip_binder()))
|
||||
.skip_binder();
|
||||
p!(print_display(trait_ref))
|
||||
}
|
||||
debug {
|
||||
p!(print_display(self))
|
||||
@ -599,7 +618,7 @@ define_print! {
|
||||
if let BrNamed(_, name) = *self {
|
||||
if name != "" && name != "'_" {
|
||||
p!(write("{}", name));
|
||||
return Ok(());
|
||||
return Ok(cx.printer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -628,7 +647,7 @@ define_print! {
|
||||
//
|
||||
// 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 {
|
||||
fn display_outputs_anything<P>(&self, cx: &PrintCx<'_, '_, '_, P>) -> bool {
|
||||
if cx.config.is_verbose {
|
||||
return true;
|
||||
}
|
||||
@ -671,7 +690,7 @@ define_print! {
|
||||
//
|
||||
// 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 {
|
||||
fn display_outputs_anything<P>(&self, cx: &PrintCx<'_, '_, '_, P>) -> bool {
|
||||
if cx.config.is_verbose {
|
||||
return true;
|
||||
}
|
||||
@ -695,7 +714,7 @@ define_print! {
|
||||
// Watch out for region highlights.
|
||||
if let Some(n) = RegionHighlightMode::get().region_highlighted(self) {
|
||||
p!(write("'{:?}", n));
|
||||
return Ok(());
|
||||
return Ok(cx.printer);
|
||||
}
|
||||
|
||||
// These printouts are concise. They do not contain all the information
|
||||
@ -798,7 +817,7 @@ define_print! {
|
||||
// NB: this must be kept in sync with the printing logic above.
|
||||
impl ty::RegionKind {
|
||||
// HACK(eddyb) `pub(crate)` only for `ty::print`.
|
||||
pub(crate) fn display_outputs_anything<P>(&self, cx: &mut PrintCx<'_, '_, '_, P>) -> bool {
|
||||
pub(crate) fn display_outputs_anything<P>(&self, cx: &PrintCx<'_, '_, '_, P>) -> bool {
|
||||
if cx.config.is_verbose {
|
||||
return true;
|
||||
}
|
||||
@ -867,7 +886,7 @@ define_print! {
|
||||
}
|
||||
|
||||
p!(write("fn"));
|
||||
cx.fn_sig(self.inputs(), self.c_variadic, self.output())?
|
||||
nest!(|cx| cx.fn_sig(self.inputs(), self.c_variadic, self.output()));
|
||||
}
|
||||
debug {
|
||||
p!(write("({:?}; c_variadic: {})->{:?}",
|
||||
@ -929,7 +948,7 @@ define_print! {
|
||||
//
|
||||
// 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 {
|
||||
fn display_outputs_anything<P>(&self, cx: &PrintCx<'_, '_, '_, P>) -> bool {
|
||||
if cx.config.is_verbose {
|
||||
return true;
|
||||
}
|
||||
@ -1011,7 +1030,7 @@ define_print_multi! {
|
||||
]
|
||||
(self, cx) {
|
||||
display {
|
||||
cx.in_binder(self)?
|
||||
nest!(|cx| cx.in_binder(self))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1019,15 +1038,15 @@ define_print_multi! {
|
||||
define_print! {
|
||||
('tcx) ty::TraitRef<'tcx>, (self, cx) {
|
||||
display {
|
||||
let _ = cx.print_def_path(
|
||||
nest!(|cx| cx.print_def_path(
|
||||
self.def_id,
|
||||
Some(self.substs),
|
||||
Namespace::TypeNS,
|
||||
iter::empty(),
|
||||
)?;
|
||||
));
|
||||
}
|
||||
debug {
|
||||
let _ = cx.path_qualified(None, self.self_ty(), Some(*self), Namespace::TypeNS)?;
|
||||
nest!(|cx| cx.path_qualified(self.self_ty(), Some(*self), Namespace::TypeNS));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1050,7 +1069,7 @@ define_print! {
|
||||
}
|
||||
Ref(r, ty, mutbl) => {
|
||||
p!(write("&"));
|
||||
if r.display_outputs_anything(cx) {
|
||||
if r.display_outputs_anything(&cx) {
|
||||
p!(print_display(r), write(" "));
|
||||
}
|
||||
p!(print(ty::TypeAndMut { ty, mutbl }))
|
||||
@ -1073,12 +1092,12 @@ define_print! {
|
||||
FnDef(def_id, substs) => {
|
||||
let sig = cx.tcx.fn_sig(def_id).subst(cx.tcx, substs);
|
||||
p!(print(sig), write(" {{"));
|
||||
let _ = cx.print_def_path(
|
||||
nest!(|cx| cx.print_def_path(
|
||||
def_id,
|
||||
Some(substs),
|
||||
Namespace::ValueNS,
|
||||
iter::empty(),
|
||||
)?;
|
||||
));
|
||||
p!(write("}}"))
|
||||
}
|
||||
FnPtr(ref bare_fn) => {
|
||||
@ -1101,15 +1120,15 @@ define_print! {
|
||||
}
|
||||
}
|
||||
Adt(def, substs) => {
|
||||
let _ = cx.print_def_path(
|
||||
nest!(|cx| cx.print_def_path(
|
||||
def.did,
|
||||
Some(substs),
|
||||
Namespace::TypeNS,
|
||||
iter::empty(),
|
||||
)?;
|
||||
));
|
||||
}
|
||||
Dynamic(data, r) => {
|
||||
let print_r = r.display_outputs_anything(cx);
|
||||
let print_r = r.display_outputs_anything(&cx);
|
||||
if print_r {
|
||||
p!(write("("));
|
||||
}
|
||||
@ -1119,18 +1138,16 @@ define_print! {
|
||||
}
|
||||
}
|
||||
Foreign(def_id) => {
|
||||
let _ = cx.print_def_path(
|
||||
nest!(|cx| cx.print_def_path(
|
||||
def_id,
|
||||
None,
|
||||
Namespace::TypeNS,
|
||||
iter::empty(),
|
||||
)?;
|
||||
));
|
||||
}
|
||||
Projection(ref data) => p!(print(data)),
|
||||
UnnormalizedProjection(ref data) => {
|
||||
p!(write("Unnormalized("));
|
||||
data.print(cx)?;
|
||||
p!(write(")"))
|
||||
p!(write("Unnormalized("), print(data), write(")"))
|
||||
}
|
||||
Placeholder(placeholder) => {
|
||||
p!(write("Placeholder({:?})", placeholder))
|
||||
@ -1138,7 +1155,7 @@ define_print! {
|
||||
Opaque(def_id, substs) => {
|
||||
if cx.config.is_verbose {
|
||||
p!(write("Opaque({:?}, {:?})", def_id, substs));
|
||||
return Ok(());
|
||||
return Ok(cx.printer);
|
||||
}
|
||||
|
||||
let def_key = cx.tcx.def_key(def_id);
|
||||
@ -1154,7 +1171,7 @@ define_print! {
|
||||
}
|
||||
p!(write(">"));
|
||||
}
|
||||
return Ok(());
|
||||
return Ok(cx.printer);
|
||||
}
|
||||
// Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
|
||||
// by looking up the projections associated with the def_id.
|
||||
@ -1197,17 +1214,19 @@ define_print! {
|
||||
if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(did) {
|
||||
p!(write("@{:?}", cx.tcx.hir().span_by_hir_id(hir_id)));
|
||||
let mut sep = " ";
|
||||
cx.tcx.with_freevars(hir_id, |freevars| {
|
||||
for (freevar, upvar_ty) in freevars.iter().zip(upvar_tys) {
|
||||
p!(
|
||||
write("{}{}:",
|
||||
sep,
|
||||
cx.tcx.hir().name(freevar.var_id())),
|
||||
print(upvar_ty));
|
||||
sep = ", ";
|
||||
}
|
||||
Ok(())
|
||||
})?
|
||||
for (freevar, upvar_ty) in cx.tcx.freevars(did)
|
||||
.as_ref()
|
||||
.map_or(&[][..], |fv| &fv[..])
|
||||
.iter()
|
||||
.zip(upvar_tys)
|
||||
{
|
||||
p!(
|
||||
write("{}{}:",
|
||||
sep,
|
||||
cx.tcx.hir().name(freevar.var_id())),
|
||||
print(upvar_ty));
|
||||
sep = ", ";
|
||||
}
|
||||
} else {
|
||||
// cross-crate closure types should only be
|
||||
// visible in codegen bug reports, I imagine.
|
||||
@ -1224,7 +1243,7 @@ define_print! {
|
||||
p!(write(" "), print(witness), write("]"))
|
||||
},
|
||||
GeneratorWitness(types) => {
|
||||
cx.in_binder(&types)?
|
||||
nest!(|cx| cx.in_binder(&types))
|
||||
}
|
||||
Closure(did, substs) => {
|
||||
let upvar_tys = substs.upvar_tys(did, cx.tcx);
|
||||
@ -1238,17 +1257,19 @@ define_print! {
|
||||
p!(write("@{:?}", cx.tcx.hir().span_by_hir_id(hir_id)));
|
||||
}
|
||||
let mut sep = " ";
|
||||
cx.tcx.with_freevars(hir_id, |freevars| {
|
||||
for (freevar, upvar_ty) in freevars.iter().zip(upvar_tys) {
|
||||
p!(
|
||||
write("{}{}:",
|
||||
sep,
|
||||
cx.tcx.hir().name(freevar.var_id())),
|
||||
print(upvar_ty));
|
||||
sep = ", ";
|
||||
}
|
||||
Ok(())
|
||||
})?
|
||||
for (freevar, upvar_ty) in cx.tcx.freevars(did)
|
||||
.as_ref()
|
||||
.map_or(&[][..], |fv| &fv[..])
|
||||
.iter()
|
||||
.zip(upvar_tys)
|
||||
{
|
||||
p!(
|
||||
write("{}{}:",
|
||||
sep,
|
||||
cx.tcx.hir().name(freevar.var_id())),
|
||||
print(upvar_ty));
|
||||
sep = ", ";
|
||||
}
|
||||
} else {
|
||||
// cross-crate closure types should only be
|
||||
// visible in codegen bug reports, I imagine.
|
||||
@ -1406,12 +1427,12 @@ define_print! {
|
||||
define_print! {
|
||||
('tcx) ty::ProjectionTy<'tcx>, (self, cx) {
|
||||
display {
|
||||
let _ = cx.print_def_path(
|
||||
nest!(|cx| cx.print_def_path(
|
||||
self.item_def_id,
|
||||
Some(self.substs),
|
||||
Namespace::TypeNS,
|
||||
iter::empty(),
|
||||
)?;
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1440,32 +1461,32 @@ define_print! {
|
||||
ty::Predicate::WellFormed(ty) => p!(print(ty), write(" well-formed")),
|
||||
ty::Predicate::ObjectSafe(trait_def_id) => {
|
||||
p!(write("the trait `"));
|
||||
let _ = cx.print_def_path(
|
||||
nest!(|cx| cx.print_def_path(
|
||||
trait_def_id,
|
||||
None,
|
||||
Namespace::TypeNS,
|
||||
iter::empty(),
|
||||
)?;
|
||||
));
|
||||
p!(write("` is object-safe"))
|
||||
}
|
||||
ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => {
|
||||
p!(write("the closure `"));
|
||||
let _ = cx.print_def_path(
|
||||
nest!(|cx| cx.print_def_path(
|
||||
closure_def_id,
|
||||
None,
|
||||
Namespace::ValueNS,
|
||||
iter::empty(),
|
||||
)?;
|
||||
));
|
||||
p!(write("` implements the trait `{}`", kind))
|
||||
}
|
||||
ty::Predicate::ConstEvaluatable(def_id, substs) => {
|
||||
p!(write("the constant `"));
|
||||
let _ = cx.print_def_path(
|
||||
nest!(|cx| cx.print_def_path(
|
||||
def_id,
|
||||
Some(substs),
|
||||
Namespace::ValueNS,
|
||||
iter::empty(),
|
||||
)?;
|
||||
));
|
||||
p!(write("` can be evaluated"))
|
||||
}
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ use rustc::hir::Node;
|
||||
use rustc::hir::CodegenFnAttrFlags;
|
||||
use rustc::hir::map::definitions::DefPathData;
|
||||
use rustc::ich::NodeIdHashingMode;
|
||||
use rustc::ty::print::{PrettyPath, PrettyPrinter, PrintCx, Printer};
|
||||
use rustc::ty::print::{PrettyPrinter, PrintCx, Printer};
|
||||
use rustc::ty::query::Providers;
|
||||
use rustc::ty::subst::SubstsRef;
|
||||
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||
@ -225,9 +225,10 @@ fn get_symbol_hash<'a, 'tcx>(
|
||||
}
|
||||
|
||||
fn def_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::SymbolName {
|
||||
PrintCx::with(tcx, SymbolPath::new(tcx), |mut cx| {
|
||||
let _ = cx.print_def_path(def_id, None, Namespace::ValueNS, iter::empty());
|
||||
cx.printer.into_interned()
|
||||
PrintCx::with(tcx, SymbolPath::new(tcx), |cx| {
|
||||
cx.print_def_path(def_id, None, Namespace::ValueNS, iter::empty())
|
||||
.unwrap()
|
||||
.into_interned()
|
||||
})
|
||||
}
|
||||
|
||||
@ -348,7 +349,7 @@ struct SymbolPath {
|
||||
temp_buf: String,
|
||||
strict_naming: bool,
|
||||
|
||||
// When `true`, `finalize_pending_component` is a noop.
|
||||
// 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.
|
||||
@ -407,18 +408,17 @@ impl SymbolPath {
|
||||
impl Printer for SymbolPath {
|
||||
type Error = fmt::Error;
|
||||
|
||||
type Path = PrettyPath;
|
||||
type Path = Self;
|
||||
|
||||
fn path_crate(
|
||||
self: &mut PrintCx<'_, '_, '_, Self>,
|
||||
mut self: PrintCx<'_, '_, '_, Self>,
|
||||
cnum: CrateNum,
|
||||
) -> Result<Self::Path, Self::Error> {
|
||||
self.printer.write_str(&self.tcx.original_crate_name(cnum).as_str())?;
|
||||
Ok(PrettyPath { empty: false })
|
||||
Ok(self.printer)
|
||||
}
|
||||
fn path_qualified(
|
||||
self: &mut PrintCx<'_, '_, 'tcx, Self>,
|
||||
impl_prefix: Option<Self::Path>,
|
||||
mut self: PrintCx<'_, '_, 'tcx, Self>,
|
||||
self_ty: Ty<'tcx>,
|
||||
trait_ref: Option<ty::TraitRef<'tcx>>,
|
||||
ns: Namespace,
|
||||
@ -429,64 +429,85 @@ impl Printer for SymbolPath {
|
||||
ty::Adt(..) | ty::Foreign(_) |
|
||||
ty::Bool | ty::Char | ty::Str |
|
||||
ty::Int(_) | ty::Uint(_) | ty::Float(_)
|
||||
if impl_prefix.is_none() && trait_ref.is_none() =>
|
||||
if trait_ref.is_none() =>
|
||||
{
|
||||
return self.pretty_path_qualified(None, self_ty, trait_ref, ns);
|
||||
return self.pretty_path_qualified(self_ty, trait_ref, ns);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// HACK(eddyb) make sure to finalize the last component of the
|
||||
// `impl` prefix, to avoid it fusing with the following text.
|
||||
let impl_prefix = match impl_prefix {
|
||||
Some(prefix) => {
|
||||
let mut prefix = self.path_append(prefix, "")?;
|
||||
|
||||
// HACK(eddyb) also avoid an unnecessary `::`.
|
||||
prefix.empty = true;
|
||||
|
||||
Some(prefix)
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
|
||||
let kept_within_component = mem::replace(&mut self.printer.keep_within_component, true);
|
||||
let r = self.pretty_path_qualified(impl_prefix, self_ty, trait_ref, ns);
|
||||
self.printer.keep_within_component = kept_within_component;
|
||||
r
|
||||
}
|
||||
fn path_append(
|
||||
self: &mut PrintCx<'_, '_, '_, Self>,
|
||||
mut path: Self::Path,
|
||||
text: &str,
|
||||
) -> Result<Self::Path, Self::Error> {
|
||||
if self.keep_within_component {
|
||||
// HACK(eddyb) print the path similarly to how `FmtPrinter` prints it.
|
||||
if !path.empty {
|
||||
self.printer.write_str("::")?;
|
||||
} else {
|
||||
path.empty = text.is_empty();
|
||||
}
|
||||
} else {
|
||||
self.printer.finalize_pending_component();
|
||||
path.empty = false;
|
||||
}
|
||||
|
||||
self.printer.write_str(text)?;
|
||||
let mut path = self.pretty_path_qualified(self_ty, trait_ref, ns)?;
|
||||
path.keep_within_component = kept_within_component;
|
||||
Ok(path)
|
||||
}
|
||||
fn path_generic_args(
|
||||
self: &mut PrintCx<'_, '_, 'tcx, Self>,
|
||||
path: Self::Path,
|
||||
|
||||
fn path_append_impl<'gcx, 'tcx>(
|
||||
self: PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
print_prefix: impl FnOnce(
|
||||
PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
) -> Result<Self::Path, Self::Error>,
|
||||
self_ty: Ty<'tcx>,
|
||||
trait_ref: Option<ty::TraitRef<'tcx>>,
|
||||
) -> Result<Self::Path, Self::Error> {
|
||||
let kept_within_component = self.printer.keep_within_component;
|
||||
let mut path = self.pretty_path_append_impl(
|
||||
|cx| {
|
||||
let mut path = print_prefix(cx)?;
|
||||
path.keep_within_component = true;
|
||||
Ok(path)
|
||||
},
|
||||
self_ty,
|
||||
trait_ref,
|
||||
)?;
|
||||
path.keep_within_component = kept_within_component;
|
||||
Ok(path)
|
||||
}
|
||||
fn path_append<'gcx, 'tcx>(
|
||||
self: PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
print_prefix: impl FnOnce(
|
||||
PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
) -> Result<Self::Path, Self::Error>,
|
||||
text: &str,
|
||||
) -> Result<Self::Path, Self::Error> {
|
||||
let keep_within_component = self.printer.keep_within_component;
|
||||
|
||||
let mut path = print_prefix(self)?;
|
||||
|
||||
if keep_within_component {
|
||||
// HACK(eddyb) print the path similarly to how `FmtPrinter` prints it.
|
||||
path.write_str("::")?;
|
||||
} else {
|
||||
path.finalize_pending_component();
|
||||
}
|
||||
|
||||
path.write_str(text)?;
|
||||
Ok(path)
|
||||
}
|
||||
fn path_generic_args<'gcx, 'tcx>(
|
||||
self: PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
print_prefix: impl FnOnce(
|
||||
PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
) -> Result<Self::Path, Self::Error>,
|
||||
params: &[ty::GenericParamDef],
|
||||
substs: SubstsRef<'tcx>,
|
||||
ns: Namespace,
|
||||
projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>,
|
||||
) -> Result<Self::Path, Self::Error> {
|
||||
let kept_within_component = mem::replace(&mut self.printer.keep_within_component, true);
|
||||
let r = self.pretty_path_generic_args(path, params, substs, ns, projections);
|
||||
self.printer.keep_within_component = kept_within_component;
|
||||
r
|
||||
let kept_within_component = self.printer.keep_within_component;
|
||||
let mut path = self.pretty_path_generic_args(
|
||||
|cx| {
|
||||
let mut path = print_prefix(cx)?;
|
||||
path.keep_within_component = true;
|
||||
Ok(path)
|
||||
},
|
||||
params,
|
||||
substs,
|
||||
ns,
|
||||
projections,
|
||||
)?;
|
||||
path.keep_within_component = kept_within_component;
|
||||
Ok(path)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4235,50 +4235,70 @@ where F: Fn(DefId) -> Def {
|
||||
type Path = Vec<String>;
|
||||
|
||||
fn path_crate(
|
||||
self: &mut PrintCx<'_, '_, '_, Self>,
|
||||
self: PrintCx<'_, '_, '_, Self>,
|
||||
cnum: CrateNum,
|
||||
) -> Result<Self::Path, Self::Error> {
|
||||
Ok(vec![self.tcx.original_crate_name(cnum).to_string()])
|
||||
}
|
||||
fn path_qualified(
|
||||
self: &mut PrintCx<'_, '_, 'tcx, Self>,
|
||||
impl_prefix: Option<Self::Path>,
|
||||
self: PrintCx<'_, '_, 'tcx, Self>,
|
||||
self_ty: Ty<'tcx>,
|
||||
trait_ref: Option<ty::TraitRef<'tcx>>,
|
||||
_ns: Namespace,
|
||||
) -> Result<Self::Path, Self::Error> {
|
||||
let mut path = impl_prefix.unwrap_or(vec![]);
|
||||
// This shouldn't ever be needed, but just in case:
|
||||
Ok(vec![match trait_ref {
|
||||
Some(trait_ref) => format!("{:?}", trait_ref),
|
||||
None => format!("<{}>", self_ty),
|
||||
}])
|
||||
}
|
||||
|
||||
fn path_append_impl<'gcx, 'tcx>(
|
||||
self: PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
print_prefix: impl FnOnce(
|
||||
PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
) -> Result<Self::Path, Self::Error>,
|
||||
self_ty: Ty<'tcx>,
|
||||
trait_ref: Option<ty::TraitRef<'tcx>>,
|
||||
) -> Result<Self::Path, Self::Error> {
|
||||
let mut path = print_prefix(self)?;
|
||||
|
||||
// This shouldn't ever be needed, but just in case:
|
||||
if let Some(trait_ref) = trait_ref {
|
||||
path.push(format!("{:?}", trait_ref));
|
||||
} else {
|
||||
path.push(format!("<{}>", self_ty));
|
||||
}
|
||||
path.push(match trait_ref {
|
||||
Some(trait_ref) => {
|
||||
format!("<impl {} for {}>", trait_ref, self_ty)
|
||||
}
|
||||
None => format!("<impl {}>", self_ty),
|
||||
});
|
||||
|
||||
Ok(path)
|
||||
}
|
||||
fn path_append(
|
||||
self: &mut PrintCx<'_, '_, '_, Self>,
|
||||
mut path: Self::Path,
|
||||
fn path_append<'gcx, 'tcx>(
|
||||
self: PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
print_prefix: impl FnOnce(
|
||||
PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
) -> Result<Self::Path, Self::Error>,
|
||||
text: &str,
|
||||
) -> Result<Self::Path, Self::Error> {
|
||||
let mut path = print_prefix(self)?;
|
||||
path.push(text.to_string());
|
||||
Ok(path)
|
||||
}
|
||||
fn path_generic_args(
|
||||
self: &mut PrintCx<'_, '_, 'tcx, Self>,
|
||||
path: Self::Path,
|
||||
fn path_generic_args<'gcx, 'tcx>(
|
||||
self: PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
print_prefix: impl FnOnce(
|
||||
PrintCx<'_, 'gcx, 'tcx, Self>,
|
||||
) -> Result<Self::Path, Self::Error>,
|
||||
_params: &[ty::GenericParamDef],
|
||||
_substs: SubstsRef<'tcx>,
|
||||
_ns: Namespace,
|
||||
_projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>,
|
||||
) -> Result<Self::Path, Self::Error> {
|
||||
Ok(path)
|
||||
print_prefix(self)
|
||||
}
|
||||
}
|
||||
|
||||
let names = PrintCx::with(tcx, AbsolutePathPrinter, |mut cx| {
|
||||
let names = PrintCx::with(tcx, AbsolutePathPrinter, |cx| {
|
||||
cx.print_def_path(def_id, None, Namespace::TypeNS, iter::empty()).unwrap()
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user