1
Fork 0

rustc: make pretty_path_generic_args' task as simple as possible.

This commit is contained in:
Eduard-Mihai Burtescu 2019-01-24 19:52:43 +02:00
parent 4deaa69b42
commit ffa00d4628
5 changed files with 70 additions and 88 deletions

View file

@ -446,7 +446,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
) { ) {
use hir::def_id::CrateNum; use hir::def_id::CrateNum;
use ty::print::{PrintCx, Printer}; use ty::print::{PrintCx, Printer};
use ty::subst::SubstsRef; use ty::subst::Kind;
struct AbsolutePathPrinter; struct AbsolutePathPrinter;
@ -513,8 +513,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
print_prefix: impl FnOnce( print_prefix: impl FnOnce(
PrintCx<'_, 'gcx, 'tcx, Self>, PrintCx<'_, 'gcx, 'tcx, Self>,
) -> Result<Self::Path, Self::Error>, ) -> Result<Self::Path, Self::Error>,
_params: &[ty::GenericParamDef], _args: impl Iterator<Item = Kind<'tcx>> + Clone,
_substs: SubstsRef<'tcx>,
_projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>, _projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>,
) -> Result<Self::Path, Self::Error> { ) -> Result<Self::Path, Self::Error> {
print_prefix(self) print_prefix(self)

View file

@ -123,8 +123,7 @@ pub trait Printer: Sized {
print_prefix: impl FnOnce( print_prefix: impl FnOnce(
PrintCx<'_, 'gcx, 'tcx, Self>, PrintCx<'_, 'gcx, 'tcx, Self>,
) -> Result<Self::Path, Self::Error>, ) -> Result<Self::Path, Self::Error>,
params: &[ty::GenericParamDef], args: impl Iterator<Item = Kind<'tcx>> + Clone,
substs: SubstsRef<'tcx>,
projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>, projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>,
) -> Result<Self::Path, Self::Error>; ) -> Result<Self::Path, Self::Error>;
} }
@ -197,8 +196,8 @@ impl<P: Printer> PrintCx<'_, 'gcx, 'tcx, P> {
}; };
if let (Some(generics), Some(substs)) = (generics, substs) { if let (Some(generics), Some(substs)) = (generics, substs) {
let params = self.generic_params_to_print(generics, substs); let args = self.generic_args_to_print(generics, substs);
self.path_generic_args(print_path, params, substs, projections) self.path_generic_args(print_path, args, projections)
} else { } else {
print_path(self) print_path(self)
} }
@ -206,11 +205,11 @@ impl<P: Printer> PrintCx<'_, 'gcx, 'tcx, P> {
} }
} }
pub fn generic_params_to_print( pub fn generic_args_to_print(
&self, &self,
generics: &'a ty::Generics, generics: &'tcx ty::Generics,
substs: SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
) -> &'a [ty::GenericParamDef] { ) -> impl Iterator<Item = Kind<'tcx>> + Clone {
// Don't print args for `Self` parameters (of traits). // Don't print args for `Self` parameters (of traits).
let has_own_self = generics.has_self && generics.parent_count == 0; let has_own_self = generics.has_self && generics.parent_count == 0;
let params = &generics.params[has_own_self as usize..]; let params = &generics.params[has_own_self as usize..];
@ -227,7 +226,9 @@ impl<P: Printer> PrintCx<'_, 'gcx, 'tcx, P> {
ty::GenericParamDefKind::Const => false, // FIXME(const_generics:defaults) ty::GenericParamDefKind::Const => false, // FIXME(const_generics:defaults)
} }
}).count(); }).count();
&params[..params.len() - num_supplied_defaults] params[..params.len() - num_supplied_defaults].iter().map(move |param| {
substs[param.index as usize]
})
} }
fn default_print_impl_path( fn default_print_impl_path(

View file

@ -207,21 +207,30 @@ pub trait PrettyPrinter:
value.skip_binder().print(self) value.skip_binder().print(self)
} }
/// Print comma-separated elements.
fn comma_sep<T>(
mut self: PrintCx<'_, '_, 'tcx, Self>,
mut elems: impl Iterator<Item = T>,
comma: &str,
) -> Result<Self, Self::Error>
where T: Print<'tcx, Self, Output = Self, Error = Self::Error>
{
if let Some(first) = elems.next() {
self = self.nest(|cx| first.print(cx))?;
for elem in elems {
self.write_str(comma)?;
self = self.nest(|cx| elem.print(cx))?;
}
}
self.ok()
}
/// Print `<...>` around what `f` prints. /// Print `<...>` around what `f` prints.
fn generic_delimiters<'gcx, 'tcx>( fn generic_delimiters<'gcx, 'tcx>(
self: PrintCx<'_, 'gcx, 'tcx, Self>, self: PrintCx<'_, 'gcx, 'tcx, Self>,
f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result<Self, Self::Error>, f: impl FnOnce(PrintCx<'_, 'gcx, 'tcx, Self>) -> Result<Self, Self::Error>,
) -> Result<Self, Self::Error>; ) -> Result<Self, Self::Error>;
/// Return `true` if the region should be printed in path generic args
/// even when it's `'_`, such as in e.g. `Foo<'_, '_, '_>`.
fn always_print_region_in_paths(
self: &PrintCx<'_, '_, '_, Self>,
_region: ty::Region<'_>,
) -> bool {
false
}
/// Return `true` if the region should be printed in /// Return `true` if the region should be printed in
/// optional positions, e.g. `&'a T` or `dyn Tr + 'b`. /// optional positions, e.g. `&'a T` or `dyn Tr + 'b`.
/// This is typically the case for all non-`'_` regions. /// This is typically the case for all non-`'_` regions.
@ -482,66 +491,25 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> {
print_prefix: impl FnOnce( print_prefix: impl FnOnce(
PrintCx<'_, 'gcx, 'tcx, P>, PrintCx<'_, 'gcx, 'tcx, P>,
) -> Result<P::Path, P::Error>, ) -> Result<P::Path, P::Error>,
params: &[ty::GenericParamDef], mut args: impl Iterator<Item = Kind<'tcx>>,
substs: SubstsRef<'tcx>, mut projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>,
projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>,
) -> Result<P::Path, P::Error> { ) -> Result<P::Path, P::Error> {
self = self.nest(print_prefix)?; self = self.nest(print_prefix)?;
// Don't print `'_` if there's no printed region.
let print_regions = params.iter().any(|param| {
match substs[param.index as usize].unpack() {
UnpackedKind::Lifetime(r) => {
self.always_print_region_in_paths(r) ||
self.region_should_not_be_omitted(r)
}
_ => false,
}
});
let mut args = params.iter().map(|param| {
substs[param.index as usize]
}).filter(|arg| {
match arg.unpack() {
UnpackedKind::Lifetime(_) => print_regions,
_ => true,
}
});
let arg0 = args.next(); let arg0 = args.next();
let mut projections = projections;
let projection0 = projections.next(); let projection0 = projections.next();
if arg0.is_none() && projection0.is_none() { if arg0.is_none() && projection0.is_none() {
return self.ok(); return self.ok();
} }
let args = arg0.into_iter().chain(args);
let projections = projection0.into_iter().chain(projections);
self.generic_delimiters(|mut cx| { self.generic_delimiters(|mut cx| {
define_scoped_cx!(cx); cx = cx.nest(|cx| cx.comma_sep(args, ", "))?;
if arg0.is_some() && projection0.is_some() {
let mut empty = true; write!(cx, ", ")?;
let mut maybe_comma = |cx: &mut Self| {
if empty {
empty = false;
Ok(())
} else {
write!(cx, ", ")
}
};
for arg in arg0.into_iter().chain(args) {
maybe_comma(&mut cx)?;
p!(print(arg));
} }
cx.comma_sep(projections, ", ")
for projection in projection0.into_iter().chain(projections) {
maybe_comma(&mut cx)?;
p!(write("{}=", cx.tcx.associated_item(projection.item_def_id).ident),
print(projection.ty));
}
cx.ok()
}) })
} }
} }
@ -621,8 +589,8 @@ impl<F: fmt::Write> Printer for FmtPrinter<F> {
})?; })?;
if visible_path_success { if visible_path_success {
return if let (Some(generics), Some(substs)) = (generics, substs) { return if let (Some(generics), Some(substs)) = (generics, substs) {
let params = self.generic_params_to_print(generics, substs); let args = self.generic_args_to_print(generics, substs);
self.path_generic_args(|cx| cx.ok(), params, substs, projections) self.path_generic_args(|cx| cx.ok(), args, projections)
} else { } else {
self.ok() self.ok()
}; };
@ -739,11 +707,23 @@ impl<F: fmt::Write> Printer for FmtPrinter<F> {
print_prefix: impl FnOnce( print_prefix: impl FnOnce(
PrintCx<'_, 'gcx, 'tcx, Self>, PrintCx<'_, 'gcx, 'tcx, Self>,
) -> Result<Self::Path, Self::Error>, ) -> Result<Self::Path, Self::Error>,
params: &[ty::GenericParamDef], args: impl Iterator<Item = Kind<'tcx>> + Clone,
substs: SubstsRef<'tcx>,
projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>, projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>,
) -> Result<Self::Path, Self::Error> { ) -> Result<Self::Path, Self::Error> {
self.pretty_path_generic_args(print_prefix, params, substs, projections) // Don't print `'_` if there's no unerased regions.
let print_regions = args.clone().any(|arg| {
match arg.unpack() {
UnpackedKind::Lifetime(r) => *r != ty::ReErased,
_ => false,
}
});
let args = args.filter(|arg| {
match arg.unpack() {
UnpackedKind::Lifetime(_) => print_regions,
_ => true,
}
});
self.pretty_path_generic_args(print_prefix, args, projections)
} }
} }
@ -798,13 +778,6 @@ impl<F: fmt::Write> PrettyPrinter for FmtPrinter<F> {
Ok(inner) Ok(inner)
} }
fn always_print_region_in_paths(
self: &PrintCx<'_, '_, '_, Self>,
region: ty::Region<'_>,
) -> bool {
*region != ty::ReErased
}
fn region_should_not_be_omitted( fn region_should_not_be_omitted(
self: &PrintCx<'_, '_, '_, Self>, self: &PrintCx<'_, '_, '_, Self>,
region: ty::Region<'_>, region: ty::Region<'_>,
@ -1498,6 +1471,11 @@ define_print_and_forward_display! {
} }
} }
ty::ExistentialProjection<'tcx> {
let name = cx.tcx.associated_item(self.item_def_id).ident;
p!(write("{}=", name), print(self.ty))
}
&'tcx ty::List<Ty<'tcx>> { &'tcx ty::List<Ty<'tcx>> {
p!(write("{{")); p!(write("{{"));
let mut tys = self.iter(); let mut tys = self.iter();

View file

@ -94,7 +94,7 @@ use rustc::hir::map::definitions::DefPathData;
use rustc::ich::NodeIdHashingMode; use rustc::ich::NodeIdHashingMode;
use rustc::ty::print::{PrettyPrinter, PrintCx, Printer}; use rustc::ty::print::{PrettyPrinter, PrintCx, Printer};
use rustc::ty::query::Providers; use rustc::ty::query::Providers;
use rustc::ty::subst::SubstsRef; use rustc::ty::subst::{Kind, SubstsRef, UnpackedKind};
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc::util::common::record_time; use rustc::util::common::record_time;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@ -503,11 +503,16 @@ impl Printer for SymbolPath {
print_prefix: impl FnOnce( print_prefix: impl FnOnce(
PrintCx<'_, 'gcx, 'tcx, Self>, PrintCx<'_, 'gcx, 'tcx, Self>,
) -> Result<Self::Path, Self::Error>, ) -> Result<Self::Path, Self::Error>,
params: &[ty::GenericParamDef], args: impl Iterator<Item = Kind<'tcx>> + Clone,
substs: SubstsRef<'tcx>,
projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>, projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>,
) -> Result<Self::Path, Self::Error> { ) -> Result<Self::Path, Self::Error> {
self.pretty_path_generic_args(print_prefix, params, substs, projections) let args = args.filter(|arg| {
match arg.unpack() {
UnpackedKind::Lifetime(_) => false,
_ => true,
}
});
self.pretty_path_generic_args(print_prefix, args, projections)
} }
} }

View file

@ -20,7 +20,7 @@ use rustc::mir::interpret::GlobalId;
use rustc::hir::{self, GenericArg, HirVec}; use rustc::hir::{self, GenericArg, HirVec};
use rustc::hir::def::{self, Def, CtorKind}; use rustc::hir::def::{self, Def, CtorKind};
use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc::ty::subst::{InternalSubsts, SubstsRef}; use rustc::ty::subst::{Kind, InternalSubsts, SubstsRef};
use rustc::ty::{self, DefIdTree, TyCtxt, Region, RegionVid, Ty, AdtKind}; use rustc::ty::{self, DefIdTree, TyCtxt, Region, RegionVid, Ty, AdtKind};
use rustc::ty::fold::TypeFolder; use rustc::ty::fold::TypeFolder;
use rustc::ty::layout::VariantIdx; use rustc::ty::layout::VariantIdx;
@ -4304,8 +4304,7 @@ where F: Fn(DefId) -> Def {
print_prefix: impl FnOnce( print_prefix: impl FnOnce(
PrintCx<'_, 'gcx, 'tcx, Self>, PrintCx<'_, 'gcx, 'tcx, Self>,
) -> Result<Self::Path, Self::Error>, ) -> Result<Self::Path, Self::Error>,
_params: &[ty::GenericParamDef], _args: impl Iterator<Item = Kind<'tcx>> + Clone,
_substs: SubstsRef<'tcx>,
_projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>, _projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>,
) -> Result<Self::Path, Self::Error> { ) -> Result<Self::Path, Self::Error> {
print_prefix(self) print_prefix(self)