rustc: remove PrintCx from ty::Print and rely on printers carrying TyCtxt.

This commit is contained in:
Eduard-Mihai Burtescu 2019-01-25 12:11:50 +02:00
parent 2a656828ac
commit 52b4f2daa0
11 changed files with 849 additions and 906 deletions

View File

@ -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<String>;
@ -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<Self::Region, Self::Error> {
Err(NonTrivialPath)
}
fn print_type<'tcx>(
self: PrintCx<'_, '_, 'tcx, Self>,
fn print_type(
self,
_ty: Ty<'tcx>,
) -> Result<Self::Type, Self::Error> {
Err(NonTrivialPath)
}
fn print_dyn_existential<'tcx>(
self: PrintCx<'_, '_, 'tcx, Self>,
fn print_dyn_existential(
self,
_predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
) -> Result<Self::DynExistential, Self::Error> {
Err(NonTrivialPath)
}
fn path_crate(
self: PrintCx<'_, '_, '_, Self>,
self,
cnum: CrateNum,
) -> Result<Self::Path, Self::Error> {
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<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> {
Err(NonTrivialPath)
}
fn path_append_impl<'gcx, 'tcx>(
self: PrintCx<'_, 'gcx, 'tcx, Self>,
_print_prefix: impl FnOnce(
PrintCx<'_, 'gcx, 'tcx, Self>,
) -> Result<Self::Path, Self::Error>,
fn path_append_impl(
self,
_print_prefix: impl FnOnce(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>,
fn path_append(
self,
print_prefix: impl FnOnce(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<'gcx, 'tcx>(
self: PrintCx<'_, 'gcx, 'tcx, Self>,
print_prefix: impl FnOnce(
PrintCx<'_, 'gcx, 'tcx, Self>,
) -> Result<Self::Path, Self::Error>,
fn path_generic_args(
self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
_args: &[Kind<'tcx>],
) -> Result<Self::Path, Self::Error> {
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)
};

View File

@ -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
}

View File

@ -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(())
}
}

View File

@ -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(())
})?;

View File

@ -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(())
})?;

View File

@ -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<P> Deref for PrintCx<'_, '_, '_, P> {
type Target = P;
fn deref(&self) -> &P {
&self.inner
}
}
impl<P> 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<R>(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<E>(self) -> Result<P, E> {
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<Self::Output, Self::Error>;
fn print(&self, cx: P) -> Result<Self::Output, Self::Error>;
}
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<SubstsRef<'tcx>>,
) -> Result<Self::Path, Self::Error> {
self.default_print_def_path(def_id, substs)
}
fn print_impl_path(
self: PrintCx<'_, '_, 'tcx, Self>,
self,
impl_def_id: DefId,
substs: Option<SubstsRef<'tcx>>,
self_ty: Ty<'tcx>,
@ -83,62 +44,56 @@ pub trait Printer: Sized {
}
fn print_region(
self: PrintCx<'_, '_, '_, Self>,
self,
region: ty::Region<'_>,
) -> Result<Self::Region, Self::Error>;
fn print_type(
self: PrintCx<'_, '_, 'tcx, Self>,
self,
ty: Ty<'tcx>,
) -> Result<Self::Type, Self::Error>;
fn print_dyn_existential(
self: PrintCx<'_, '_, 'tcx, Self>,
self,
predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
) -> Result<Self::DynExistential, Self::Error>;
fn path_crate(
self: PrintCx<'_, '_, '_, Self>,
self,
cnum: CrateNum,
) -> Result<Self::Path, Self::Error>;
fn path_qualified(
self: PrintCx<'_, '_, 'tcx, Self>,
self,
self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error>;
fn path_append_impl<'gcx, 'tcx>(
self: PrintCx<'_, 'gcx, 'tcx, Self>,
print_prefix: impl FnOnce(
PrintCx<'_, 'gcx, 'tcx, Self>,
) -> Result<Self::Path, Self::Error>,
fn path_append_impl(
self,
print_prefix: impl FnOnce(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>,
fn path_append(
self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
text: &str,
) -> Result<Self::Path, Self::Error>;
fn path_generic_args<'gcx, 'tcx>(
self: PrintCx<'_, 'gcx, 'tcx, Self>,
print_prefix: impl FnOnce(
PrintCx<'_, 'gcx, 'tcx, Self>,
) -> Result<Self::Path, Self::Error>,
fn path_generic_args(
self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
args: &[Kind<'tcx>],
) -> Result<Self::Path, Self::Error>;
}
impl<P: Printer> 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<SubstsRef<'tcx>>,
) -> Result<P::Path, P::Error> {
) -> Result<Self::Path, Self::Error> {
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<P: Printer> 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<P: Printer> 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<P: Printer> 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<P: Printer> 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<P: Printer> PrintCx<'_, 'gcx, 'tcx, P> {
_substs: Option<SubstsRef<'tcx>>,
self_ty: Ty<'tcx>,
impl_trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<P::Path, P::Error> {
) -> Result<Self::Path, Self::Error> {
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<P: Printer> 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<DefId> {
}
}
impl<P: Printer> 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<Self::Output, Self::Error> {
fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
cx.print_region(self)
}
}
impl<P: Printer> 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<Self::Output, Self::Error> {
fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
cx.print_region(self)
}
}
impl<P: Printer> 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<Self::Output, Self::Error> {
fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
cx.print_type(self)
}
}
impl<P: Printer> Print<'tcx, P> for &'tcx ty::List<ty::ExistentialPredicate<'tcx>> {
impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P>
for &'tcx ty::List<ty::ExistentialPredicate<'tcx>>
{
type Output = P::DynExistential;
type Error = P::Error;
fn print(&self, cx: PrintCx<'_, '_, 'tcx, P>) -> Result<Self::Output, Self::Error> {
fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
cx.print_dyn_existential(self)
}
}

File diff suppressed because it is too large Load Diff

View File

@ -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<Self::Lifted> {
@ -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<Self::Lifted> {
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>)

View File

@ -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::Region, Self::Error> {
self.ok()
Ok(self)
}
fn print_type(
self: PrintCx<'_, '_, 'tcx, Self>,
self,
ty: Ty<'tcx>,
) -> Result<Self::Type, Self::Error> {
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<ty::ExistentialPredicate<'tcx>>,
) -> Result<Self::DynExistential, Self::Error> {
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::Path, Self::Error> {
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<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> {
@ -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<Self::Path, Self::Error>,
fn path_append_impl(
self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> {
@ -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<Self::Path, Self::Error>,
fn path_append(
mut self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
text: &str,
) -> Result<Self::Path, Self::Error> {
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<Self::Path, Self::Error>,
fn path_generic_args(
mut self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
args: &[Kind<'tcx>],
) -> Result<Self::Path, Self::Error> {
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<T>(
mut self: PrintCx<'_, '_, 'tcx, Self>,
mut self,
mut elems: impl Iterator<Item = T>,
) -> Result<Self, Self::Error>
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<Self, Self::Error>,
fn generic_delimiters(
mut self,
f: impl FnOnce(Self) -> Result<Self, Self::Error>,
) -> Result<Self, Self::Error> {
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$"),
'@' => 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.strict_naming => {
'-' | ':' | '.' 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),
}
}
}

View File

@ -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
}
}

View File

@ -4223,13 +4223,18 @@ pub fn path_to_def(tcx: &TyCtxt<'_, '_, '_>, path: &[&str]) -> Option<DefId> {
}
}
pub fn get_path_for_type<F>(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<String>;
@ -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<Self::Region, Self::Error> {
Ok(())
}
fn print_type(
self: PrintCx<'_, '_, 'tcx, Self>,
self,
_ty: Ty<'tcx>,
) -> Result<Self::Type, Self::Error> {
Ok(())
}
fn print_dyn_existential<'tcx>(
self: PrintCx<'_, '_, 'tcx, Self>,
fn print_dyn_existential(
self,
_predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
) -> Result<Self::DynExistential, Self::Error> {
Ok(())
}
fn path_crate(
self: PrintCx<'_, '_, '_, Self>,
self,
cnum: CrateNum,
) -> Result<Self::Path, Self::Error> {
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<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> {
@ -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<Self::Path, Self::Error>,
fn path_append_impl(
self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Result<Self::Path, Self::Error> {
@ -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<Self::Path, Self::Error>,
fn path_append(
self,
print_prefix: impl FnOnce(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<'gcx, 'tcx>(
self: PrintCx<'_, 'gcx, 'tcx, Self>,
print_prefix: impl FnOnce(
PrintCx<'_, 'gcx, 'tcx, Self>,
) -> Result<Self::Path, Self::Error>,
fn path_generic_args(
self,
print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
_args: &[Kind<'tcx>],
) -> Result<Self::Path, Self::Error> {
print_prefix(self)
}
}
let names = PrintCx::new(tcx, AbsolutePathPrinter)
let names = AbsolutePathPrinter { tcx: tcx.global_tcx() }
.print_def_path(def_id, None)
.unwrap();