use crate::hir::map::DefPathData;
use crate::hir::def_id::{CrateNum, DefId};
-use crate::ty::{self, DefIdTree, Ty, TyCtxt, TypeFoldable};
+use crate::ty::{self, DefIdTree, Ty, TyCtxt};
use crate::ty::subst::{Subst, SubstsRef};
use rustc_data_structures::fx::FxHashSet;
// FIXME(eddyb) this module uses `pub(crate)` for things used only
// from `ppaux` - when that is removed, they can be re-privatized.
-struct LateBoundRegionNameCollector(FxHashSet<InternedString>);
-impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector {
- fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
- match *r {
- ty::ReLateBound(_, ty::BrNamed(_, name)) => {
- self.0.insert(name);
- },
- _ => {},
- }
- r.super_visit_with(self)
- }
-}
-
#[derive(Default)]
pub(crate) struct PrintConfig {
used_region_names: Option<FxHashSet<InternedString>>,
pub(crate) fn with_tls_tcx<R>(printer: P, f: impl FnOnce(PrintCx<'_, '_, '_, P>) -> R) -> R {
ty::tls::with(|tcx| PrintCx::with(tcx, printer, f))
}
- fn prepare_late_bound_region_info<T>(&mut self, value: &ty::Binder<T>)
- where T: TypeFoldable<'tcx>
- {
- let mut collector = LateBoundRegionNameCollector(Default::default());
- value.visit_with(&mut collector);
- self.config.used_region_names = Some(collector.0);
- self.config.region_index = 0;
- }
}
pub trait Print<'tcx, P> {
ty::Float(_) => None,
}
}
+
+impl<P: Printer> Print<'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> {
+ cx.print_region(self)
+ }
+}
+
+impl<P: Printer> Print<'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> {
+ cx.print_region(self)
+ }
+}
+
+impl<P: Printer> Print<'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> {
+ cx.print_type(self)
+ }
+}
self.print_def_path(def_id, substs, iter::empty())
}
+ fn in_binder<T>(
+ self: PrintCx<'_, '_, 'tcx, Self>,
+ value: &ty::Binder<T>,
+ ) -> Result<Self, Self::Error>
+ where T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>
+ {
+ value.skip_binder().print(self)
+ }
+
/// Print `<...>` around what `f` prints.
fn generic_delimiters<'gcx, 'tcx>(
self: PrintCx<'_, 'gcx, 'tcx, Self>,
Ok(printer)
}
+ fn in_binder<T>(
+ self: PrintCx<'_, '_, 'tcx, Self>,
+ value: &ty::Binder<T>,
+ ) -> Result<Self, Self::Error>
+ 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<Self, Self::Error>,
p!(write(" "), print(witness), write("]"))
},
ty::GeneratorWitness(types) => {
- nest!(|cx| cx.pretty_in_binder(&types))
+ nest!(|cx| cx.in_binder(&types))
}
ty::Closure(did, substs) => {
let upvar_tys = substs.upvar_tys(did, self.tcx);
})
};
- // NOTE(eddyb) this must be below `start_or_continue`'s definition
- // as that also has a `define_scoped_cx` and that kind of shadowing
- // is disallowed (name resolution thinks `scoped_cx!` is ambiguous).
define_scoped_cx!(self);
let old_region_index = self.config.region_index;
result
}
+ fn prepare_late_bound_region_info<T>(&mut self, value: &ty::Binder<T>)
+ where T: TypeFoldable<'tcx>
+ {
+
+ struct LateBoundRegionNameCollector(FxHashSet<InternedString>);
+ impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector {
+ fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
+ match *r {
+ ty::ReLateBound(_, ty::BrNamed(_, name)) => {
+ self.0.insert(name);
+ },
+ _ => {},
+ }
+ r.super_visit_with(self)
+ }
+ }
+
+ let mut collector = LateBoundRegionNameCollector(Default::default());
+ value.visit_with(&mut collector);
+ self.config.used_region_names = Some(collector.0);
+ self.config.region_index = 0;
+ }
+
fn is_name_used(&self, name: &InternedString) -> bool {
match self.config.used_region_names {
Some(ref names) => names.contains(name),
}
}
}
+
+impl<T, P: PrettyPrinter> Print<'tcx, P> for ty::Binder<T>
+ where T: Print<'tcx, P, Output = P, Error = P::Error> + TypeFoldable<'tcx>
+{
+ type Output = P;
+ type Error = P::Error;
+ fn print(&self, cx: PrintCx<'_, '_, 'tcx, P>) -> Result<Self::Output, Self::Error> {
+ cx.in_binder(self)
+ }
+}
}
}
-// FIXME(eddyb) this is like what some of the macros above generate,
-// except that macros *also* generate a foldable impl, which we don't
-// want (with it we'd risk bypassing `fold_region` / `fold_const`).
-impl<'tcx> Lift<'tcx> for ty::RegionKind {
- type Lifted = ty::RegionKind;
- fn lift_to_tcx<'b, 'gcx>(&self, _: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
- Some(self.clone())
- }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ty::LazyConst<'a> {
- type Lifted = ty::LazyConst<'tcx>;
- fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
- match self {
- ty::LazyConst::Evaluated(v) => Some(ty::LazyConst::Evaluated(tcx.lift(v)?)),
- ty::LazyConst::Unevaluated(def_id, substs) => {
- Some(ty::LazyConst::Unevaluated(*def_id, tcx.lift(substs)?))
- }
- }
- }
-}
-
BraceStructLiftImpl! {
impl<'a, 'tcx> Lift<'tcx> for ty::Const<'a> {
type Lifted = ty::Const<'tcx>;
use crate::hir;
use crate::hir::def::Namespace;
use crate::ty::subst::{Kind, UnpackedKind};
-use crate::ty::{self, ParamConst, Ty};
+use crate::ty::{self, ParamConst, Ty, TyCtxt};
use crate::ty::print::{FmtPrinter, PrettyPrinter, PrintCx, Print};
use crate::mir::interpret::ConstValue;
use rustc_target::spec::abi::Abi;
+pub trait LiftAndPrintToFmt<'tcx> {
+ fn lift_and_print_to_fmt(
+ &self,
+ tcx: TyCtxt<'_, '_, 'tcx>,
+ f: &mut fmt::Formatter<'_>,
+ ) -> fmt::Result;
+}
+
+impl<T> LiftAndPrintToFmt<'tcx> for T
+ where T: ty::Lift<'tcx>,
+ for<'a, 'b> <T as ty::Lift<'tcx>>::Lifted:
+ Print<'tcx, FmtPrinter<&'a mut fmt::Formatter<'b>>, Error = fmt::Error>
+{
+ fn lift_and_print_to_fmt(
+ &self,
+ tcx: TyCtxt<'_, '_, 'tcx>,
+ f: &mut fmt::Formatter<'_>,
+ ) -> fmt::Result {
+ PrintCx::with(tcx, FmtPrinter::new(f, Namespace::TypeNS), |cx| {
+ cx.tcx.lift(self).expect("could not lift for printing").print(cx)?;
+ 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 {
+ PrintCx::with(tcx, FmtPrinter::new(f, Namespace::TypeNS), |cx| {
+ self.print(cx)?;
+ Ok(())
+ })
+ }
+}
+
macro_rules! define_print {
- ([$($target:ty),+] $vars:tt $def:tt) => {
- $(define_print!($target, $vars $def);)+
+ (<$($T:ident),*> $target:ty) => {
+ impl<$($T),*> fmt::Display for $target
+ where Self: for<'a> LiftAndPrintToFmt<'a>
+ {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ ty::tls::with(|tcx| self.lift_and_print_to_fmt(tcx, f))
+ }
+ }
};
- ($target:ty, ($self:ident, $cx:ident) { display $disp:block }) => {
- impl<P: PrettyPrinter> Print<'tcx, P> for $target {
+ (<$($T:ident),*> $target:ty, ($self:ident, $cx:ident) { display $disp:block }) => {
+ impl<$($T,)* P: PrettyPrinter> Print<'tcx, P> for $target
+ where $($T: Print<'tcx, P, Output = P, Error = P::Error>),*
+ {
type Output = P;
type Error = fmt::Error;
fn print(&$self, $cx: PrintCx<'_, '_, 'tcx, P>) -> Result<Self::Output, Self::Error> {
}
}
- impl fmt::Display for $target {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::TypeNS), |cx| {
- cx.tcx.lift(self).expect("could not lift for printing").print(cx)?;
- Ok(())
- })
- }
- }
+ define_print!(<$($T),*> $target);
+ };
+
+ ($target:ty) => {
+ define_print!(<> $target);
+ };
+
+ ($target:ty, ($self:ident, $cx:ident) { display $disp:block }) => {
+ define_print!(<> $target, ($self, $cx) { display $disp });
};
}
}
define_print! {
- ty::RegionKind, (self, cx) {
- display {
- return cx.print_region(self);
- }
- }
+ ty::RegionKind
}
define_print! {
}
}
-// The generic impl doesn't work yet because projections are not
-// normalized under HRTB.
-/*impl<T> fmt::Display for ty::Binder<T>
- where T: fmt::Display + for<'a> ty::Lift<'a>,
- for<'a> <T as ty::Lift<'a>>::Lifted: fmt::Display + TypeFoldable<'a>
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- PrintCx::with_tls_tcx(|cx| cx.pretty_in_binder(cx.tcx.lift(self)
- .expect("could not lift for printing")))
- }
-}*/
-
define_print! {
- [
- ty::Binder<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>,
- ty::Binder<ty::TraitRef<'tcx>>,
- ty::Binder<ty::FnSig<'tcx>>,
- ty::Binder<ty::TraitPredicate<'tcx>>,
- ty::Binder<ty::SubtypePredicate<'tcx>>,
- ty::Binder<ty::ProjectionPredicate<'tcx>>,
- ty::Binder<ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>>,
- ty::Binder<ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>>
- ]
- (self, cx) {
- display {
- nest!(|cx| cx.pretty_in_binder(self))
- }
- }
+ <T> ty::Binder<T>
}
define_print! {
}
define_print! {
- Ty<'tcx>, (self, cx) {
- display {
- return cx.print_type(self);
- }
- }
+ Ty<'tcx>
}
define_print! {
}
}
-// Similar problem to `Binder<T>`, can't define a generic impl.
define_print! {
- [
- ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>,
- ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>
- ]
- (self, cx) {
+ <T, U> ty::OutlivesPredicate<T, U>, (self, cx) {
display {
p!(print(self.0), write(" : "), print(self.1))
}