rustc: uniformize ty::print's error handling by requiring Result.

This commit is contained in:
Eduard-Mihai Burtescu
2019-01-09 16:30:10 +02:00
parent 972af5e808
commit 5616ca857d
6 changed files with 114 additions and 85 deletions

View File

@@ -454,9 +454,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
struct NonTrivialPath; struct NonTrivialPath;
impl Printer for AbsolutePathPrinter { impl Printer for AbsolutePathPrinter {
type Path = Result<Vec<String>, NonTrivialPath>; type Error = NonTrivialPath;
fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path { type Path = Vec<String>;
fn path_crate(
self: &mut PrintCx<'_, '_, '_, Self>,
cnum: CrateNum,
) -> Result<Self::Path, Self::Error> {
Ok(vec![self.tcx.original_crate_name(cnum).to_string()]) Ok(vec![self.tcx.original_crate_name(cnum).to_string()])
} }
fn path_qualified<'tcx>( fn path_qualified<'tcx>(
@@ -465,15 +470,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
_self_ty: Ty<'tcx>, _self_ty: Ty<'tcx>,
_trait_ref: Option<ty::TraitRef<'tcx>>, _trait_ref: Option<ty::TraitRef<'tcx>>,
_ns: Namespace, _ns: Namespace,
) -> Self::Path { ) -> Result<Self::Path, Self::Error> {
Err(NonTrivialPath) Err(NonTrivialPath)
} }
fn path_append( fn path_append(
self: &mut PrintCx<'_, '_, '_, Self>, self: &mut PrintCx<'_, '_, '_, Self>,
path: Self::Path, mut path: Self::Path,
text: &str, text: &str,
) -> Self::Path { ) -> Result<Self::Path, Self::Error> {
let mut path = path?;
path.push(text.to_string()); path.push(text.to_string());
Ok(path) Ok(path)
} }
@@ -484,8 +488,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
_substs: SubstsRef<'tcx>, _substs: SubstsRef<'tcx>,
_ns: Namespace, _ns: Namespace,
_projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>, _projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>,
) -> Self::Path { ) -> Result<Self::Path, Self::Error> {
path Ok(path)
} }
} }

View File

@@ -109,16 +109,20 @@ impl<P> PrintCx<'a, 'gcx, 'tcx, P> {
pub trait Print<'tcx, P> { pub trait Print<'tcx, P> {
type Output; type Output;
type Error;
fn print(&self, cx: &mut PrintCx<'_, '_, 'tcx, P>) -> Self::Output; fn print(&self, cx: &mut PrintCx<'_, '_, 'tcx, P>) -> Result<Self::Output, Self::Error>;
fn print_display(&self, cx: &mut PrintCx<'_, '_, 'tcx, P>) -> Self::Output { fn print_display(
&self,
cx: &mut PrintCx<'_, '_, 'tcx, P>,
) -> Result<Self::Output, Self::Error> {
let old_debug = cx.is_debug; let old_debug = cx.is_debug;
cx.is_debug = false; cx.is_debug = false;
let result = self.print(cx); let result = self.print(cx);
cx.is_debug = old_debug; cx.is_debug = old_debug;
result result
} }
fn print_debug(&self, cx: &mut PrintCx<'_, '_, 'tcx, P>) -> Self::Output { fn print_debug(&self, cx: &mut PrintCx<'_, '_, 'tcx, P>) -> Result<Self::Output, Self::Error> {
let old_debug = cx.is_debug; let old_debug = cx.is_debug;
cx.is_debug = true; cx.is_debug = true;
let result = self.print(cx); let result = self.print(cx);
@@ -128,19 +132,19 @@ pub trait Print<'tcx, P> {
} }
pub trait Printer: Sized { pub trait Printer: Sized {
type Error;
type Path; type Path;
#[must_use]
fn print_def_path( fn print_def_path(
self: &mut PrintCx<'_, '_, 'tcx, Self>, self: &mut PrintCx<'_, '_, 'tcx, Self>,
def_id: DefId, def_id: DefId,
substs: Option<SubstsRef<'tcx>>, substs: Option<SubstsRef<'tcx>>,
ns: Namespace, ns: Namespace,
projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>, projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>,
) -> Self::Path { ) -> Result<Self::Path, Self::Error> {
self.default_print_def_path(def_id, substs, ns, projections) self.default_print_def_path(def_id, substs, ns, projections)
} }
#[must_use]
fn print_impl_path( fn print_impl_path(
self: &mut PrintCx<'_, '_, 'tcx, Self>, self: &mut PrintCx<'_, '_, 'tcx, Self>,
impl_def_id: DefId, impl_def_id: DefId,
@@ -148,27 +152,26 @@ pub trait Printer: Sized {
ns: Namespace, ns: Namespace,
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>, trait_ref: Option<ty::TraitRef<'tcx>>,
) -> Self::Path { ) -> Result<Self::Path, Self::Error> {
self.default_print_impl_path(impl_def_id, substs, ns, self_ty, trait_ref) self.default_print_impl_path(impl_def_id, substs, ns, self_ty, trait_ref)
} }
#[must_use] fn path_crate(
fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path; self: &mut PrintCx<'_, '_, '_, Self>,
#[must_use] cnum: CrateNum,
) -> Result<Self::Path, Self::Error>;
fn path_qualified( fn path_qualified(
self: &mut PrintCx<'_, '_, 'tcx, Self>, self: &mut PrintCx<'_, '_, 'tcx, Self>,
impl_prefix: Option<Self::Path>, impl_prefix: Option<Self::Path>,
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>, trait_ref: Option<ty::TraitRef<'tcx>>,
ns: Namespace, ns: Namespace,
) -> Self::Path; ) -> Result<Self::Path, Self::Error>;
#[must_use]
fn path_append( fn path_append(
self: &mut PrintCx<'_, '_, '_, Self>, self: &mut PrintCx<'_, '_, '_, Self>,
path: Self::Path, path: Self::Path,
text: &str, text: &str,
) -> Self::Path; ) -> Result<Self::Path, Self::Error>;
#[must_use]
fn path_generic_args( fn path_generic_args(
self: &mut PrintCx<'_, '_, 'tcx, Self>, self: &mut PrintCx<'_, '_, 'tcx, Self>,
path: Self::Path, path: Self::Path,
@@ -176,7 +179,7 @@ pub trait Printer: Sized {
substs: SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
ns: Namespace, ns: Namespace,
projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>, projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>,
) -> Self::Path; ) -> Result<Self::Path, Self::Error>;
} }
#[must_use] #[must_use]
@@ -185,7 +188,7 @@ pub struct PrettyPath {
} }
/// Trait for printers that pretty-print using `fmt::Write` to the printer. /// Trait for printers that pretty-print using `fmt::Write` to the printer.
pub trait PrettyPrinter: Printer<Path = Result<PrettyPath, fmt::Error>> + fmt::Write {} pub trait PrettyPrinter: Printer<Error = fmt::Error, Path = PrettyPath> + fmt::Write {}
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
// HACK(eddyb) get rid of `def_path_str` and/or pass `Namespace` explicitly always // HACK(eddyb) get rid of `def_path_str` and/or pass `Namespace` explicitly always
@@ -225,7 +228,7 @@ impl<P: Printer> PrintCx<'a, 'gcx, 'tcx, P> {
substs: Option<SubstsRef<'tcx>>, substs: Option<SubstsRef<'tcx>>,
ns: Namespace, ns: Namespace,
projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>, projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>,
) -> P::Path { ) -> Result<P::Path, P::Error> {
debug!("default_print_def_path: def_id={:?}, substs={:?}, ns={:?}", def_id, substs, ns); debug!("default_print_def_path: def_id={:?}, substs={:?}, ns={:?}", def_id, substs, ns);
let key = self.tcx.def_key(def_id); let key = self.tcx.def_key(def_id);
debug!("default_print_def_path: key={:?}", key); debug!("default_print_def_path: key={:?}", key);
@@ -263,12 +266,12 @@ impl<P: Printer> PrintCx<'a, 'gcx, 'tcx, P> {
parent_generics.has_self && parent_generics.parent_count == 0; parent_generics.has_self && parent_generics.parent_count == 0;
if let (Some(substs), true) = (substs, parent_has_own_self) { if let (Some(substs), true) = (substs, parent_has_own_self) {
let trait_ref = ty::TraitRef::new(parent_def_id, substs); let trait_ref = ty::TraitRef::new(parent_def_id, substs);
self.path_qualified(None, trait_ref.self_ty(), Some(trait_ref), ns) self.path_qualified(None, trait_ref.self_ty(), Some(trait_ref), ns)?
} else { } else {
self.print_def_path(parent_def_id, substs, ns, iter::empty()) self.print_def_path(parent_def_id, substs, ns, iter::empty())?
} }
} else { } else {
self.print_def_path(parent_def_id, None, ns, iter::empty()) self.print_def_path(parent_def_id, None, ns, iter::empty())?
}; };
let path = match key.disambiguated_data.data { let path = match key.disambiguated_data.data {
// Skip `::{{constructor}}` on tuple/unit structs. // Skip `::{{constructor}}` on tuple/unit structs.
@@ -278,7 +281,7 @@ impl<P: Printer> PrintCx<'a, 'gcx, 'tcx, P> {
self.path_append( self.path_append(
path, path,
&key.disambiguated_data.data.as_interned_str().as_str(), &key.disambiguated_data.data.as_interned_str().as_str(),
) )?
} }
}; };
@@ -287,7 +290,7 @@ impl<P: Printer> PrintCx<'a, 'gcx, 'tcx, P> {
let params = &generics.params[has_own_self as usize..]; let params = &generics.params[has_own_self as usize..];
self.path_generic_args(path, params, substs, ns, projections) self.path_generic_args(path, params, substs, ns, projections)
} else { } else {
path Ok(path)
} }
} }
} }
@@ -300,7 +303,7 @@ impl<P: Printer> PrintCx<'a, 'gcx, 'tcx, P> {
ns: Namespace, ns: Namespace,
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
impl_trait_ref: Option<ty::TraitRef<'tcx>>, impl_trait_ref: Option<ty::TraitRef<'tcx>>,
) -> P::Path { ) -> Result<P::Path, P::Error> {
debug!("default_print_impl_path: impl_def_id={:?}, self_ty={}, impl_trait_ref={:?}", debug!("default_print_impl_path: impl_def_id={:?}, self_ty={}, impl_trait_ref={:?}",
impl_def_id, self_ty, impl_trait_ref); impl_def_id, self_ty, impl_trait_ref);
@@ -323,7 +326,7 @@ impl<P: Printer> PrintCx<'a, 'gcx, 'tcx, P> {
// If the impl is not co-located with either self-type or // If the impl is not co-located with either self-type or
// trait-type, then fallback to a format that identifies // trait-type, then fallback to a format that identifies
// the module more clearly. // the module more clearly.
Some(self.print_def_path(parent_def_id, None, ns, iter::empty())) Some(self.print_def_path(parent_def_id, None, ns, iter::empty())?)
} else { } else {
// Otherwise, try to give a good form that would be valid language // Otherwise, try to give a good form that would be valid language
// syntax. Preferably using associated item notation. // syntax. Preferably using associated item notation.
@@ -390,7 +393,7 @@ impl<P: PrettyPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
/// If possible, this returns a global path resolving to `def_id` that is visible /// 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 /// 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`. /// 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) -> Option<P::Path> { fn try_print_visible_def_path(&mut self, def_id: DefId) -> Result<Option<P::Path>, P::Error> {
debug!("try_print_visible_def_path: def_id={:?}", def_id); debug!("try_print_visible_def_path: def_id={:?}", def_id);
// If `def_id` is a direct or injected extern crate, return the // If `def_id` is a direct or injected extern crate, return the
@@ -399,7 +402,7 @@ impl<P: PrettyPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
let cnum = def_id.krate; let cnum = def_id.krate;
if cnum == LOCAL_CRATE { if cnum == LOCAL_CRATE {
return Some(self.path_crate(cnum)); return Ok(Some(self.path_crate(cnum)?));
} }
// In local mode, when we encounter a crate other than // In local mode, when we encounter a crate other than
@@ -421,21 +424,21 @@ impl<P: PrettyPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
}) => { }) => {
debug!("try_print_visible_def_path: def_id={:?}", def_id); debug!("try_print_visible_def_path: def_id={:?}", def_id);
let path = if !span.is_dummy() { let path = if !span.is_dummy() {
self.print_def_path(def_id, None, Namespace::TypeNS, iter::empty()) self.print_def_path(def_id, None, Namespace::TypeNS, iter::empty())?
} else { } else {
self.path_crate(cnum) self.path_crate(cnum)?
}; };
return Some(path); return Ok(Some(path));
} }
None => { None => {
return Some(self.path_crate(cnum)); return Ok(Some(self.path_crate(cnum)?));
} }
_ => {}, _ => {},
} }
} }
if def_id.is_local() { if def_id.is_local() {
return None; return Ok(None);
} }
let visible_parent_map = self.tcx.visible_parent_map(LOCAL_CRATE); let visible_parent_map = self.tcx.visible_parent_map(LOCAL_CRATE);
@@ -453,8 +456,14 @@ impl<P: PrettyPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
cur_def_key = self.tcx.def_key(parent); cur_def_key = self.tcx.def_key(parent);
} }
let visible_parent = visible_parent_map.get(&def_id).cloned()?; let visible_parent = match visible_parent_map.get(&def_id).cloned() {
let path = self.try_print_visible_def_path(visible_parent)?; Some(parent) => parent,
None => return Ok(None),
};
let path = match self.try_print_visible_def_path(visible_parent)? {
Some(path) => path,
None => return Ok(None),
};
let actual_parent = self.tcx.parent(def_id); let actual_parent = self.tcx.parent(def_id);
let data = cur_def_key.disambiguated_data.data; let data = cur_def_key.disambiguated_data.data;
@@ -515,7 +524,7 @@ impl<P: PrettyPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
}, },
}; };
debug!("try_print_visible_def_path: symbol={:?}", symbol); debug!("try_print_visible_def_path: symbol={:?}", symbol);
Some(self.path_append(path, &symbol)) Ok(Some(self.path_append(path, &symbol)?))
} }
pub fn pretty_path_qualified( pub fn pretty_path_qualified(
@@ -524,7 +533,7 @@ impl<P: PrettyPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>, trait_ref: Option<ty::TraitRef<'tcx>>,
ns: Namespace, ns: Namespace,
) -> P::Path { ) -> Result<P::Path, P::Error> {
if let Some(prefix) = impl_prefix { if let Some(prefix) = impl_prefix {
// HACK(eddyb) going through `path_append` means symbol name // HACK(eddyb) going through `path_append` means symbol name
// computation gets to handle its equivalent of `::` correctly. // computation gets to handle its equivalent of `::` correctly.
@@ -582,9 +591,7 @@ impl<P: PrettyPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
substs: SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
ns: Namespace, ns: Namespace,
projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>, projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>,
) -> P::Path { ) -> Result<P::Path, P::Error> {
let path = path?;
let mut empty = true; let mut empty = true;
let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| { let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| {
if empty { if empty {
@@ -671,7 +678,9 @@ impl<F: fmt::Write> fmt::Write for FmtPrinter<F> {
} }
impl<F: fmt::Write> Printer for FmtPrinter<F> { impl<F: fmt::Write> Printer for FmtPrinter<F> {
type Path = Result<PrettyPath, fmt::Error>; type Error = fmt::Error;
type Path = PrettyPath;
fn print_def_path( fn print_def_path(
self: &mut PrintCx<'_, '_, 'tcx, Self>, self: &mut PrintCx<'_, '_, 'tcx, Self>,
@@ -679,20 +688,20 @@ impl<F: fmt::Write> Printer for FmtPrinter<F> {
substs: Option<SubstsRef<'tcx>>, substs: Option<SubstsRef<'tcx>>,
ns: Namespace, ns: Namespace,
projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>, projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>,
) -> Self::Path { ) -> Result<Self::Path, Self::Error> {
// FIXME(eddyb) avoid querying `tcx.generics_of` and `tcx.def_key` // FIXME(eddyb) avoid querying `tcx.generics_of` and `tcx.def_key`
// both here and in `default_print_def_path`. // both here and in `default_print_def_path`.
let generics = substs.map(|_| self.tcx.generics_of(def_id)); let generics = substs.map(|_| self.tcx.generics_of(def_id));
if generics.as_ref().and_then(|g| g.parent).is_none() { if generics.as_ref().and_then(|g| g.parent).is_none() {
if let Some(path) = self.try_print_visible_def_path(def_id) { if let Some(path) = self.try_print_visible_def_path(def_id)? {
let path = if let (Some(generics), Some(substs)) = (generics, substs) { let path = if let (Some(generics), Some(substs)) = (generics, substs) {
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..];
self.path_generic_args(path, params, substs, ns, projections) self.path_generic_args(path, params, substs, ns, projections)?
} else { } else {
path path
}; };
return path; return Ok(path);
} }
} }
@@ -712,7 +721,7 @@ impl<F: fmt::Write> Printer for FmtPrinter<F> {
// pretty printing some span information. This should // pretty printing some span information. This should
// only occur very early in the compiler pipeline. // only occur very early in the compiler pipeline.
let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id }; 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 path = self.print_def_path(parent_def_id, None, ns, iter::empty())?;
let span = self.tcx.def_span(def_id); let span = self.tcx.def_span(def_id);
return self.path_append(path, &format!("<impl at {:?}>", span)); return self.path_append(path, &format!("<impl at {:?}>", span));
} }
@@ -721,7 +730,10 @@ impl<F: fmt::Write> Printer for FmtPrinter<F> {
self.default_print_def_path(def_id, substs, ns, projections) self.default_print_def_path(def_id, substs, ns, projections)
} }
fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path { fn path_crate(
self: &mut PrintCx<'_, '_, '_, Self>,
cnum: CrateNum,
) -> Result<Self::Path, Self::Error> {
if cnum == LOCAL_CRATE { if cnum == LOCAL_CRATE {
if self.tcx.sess.rust_2018() { if self.tcx.sess.rust_2018() {
// We add the `crate::` keyword on Rust 2018, only when desired. // We add the `crate::` keyword on Rust 2018, only when desired.
@@ -742,16 +754,14 @@ impl<F: fmt::Write> Printer for FmtPrinter<F> {
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>, trait_ref: Option<ty::TraitRef<'tcx>>,
ns: Namespace, ns: Namespace,
) -> Self::Path { ) -> Result<Self::Path, Self::Error> {
self.pretty_path_qualified(impl_prefix, self_ty, trait_ref, ns) self.pretty_path_qualified(impl_prefix, self_ty, trait_ref, ns)
} }
fn path_append( fn path_append(
self: &mut PrintCx<'_, '_, '_, Self>, self: &mut PrintCx<'_, '_, '_, Self>,
path: Self::Path, path: Self::Path,
text: &str, text: &str,
) -> Self::Path { ) -> Result<Self::Path, Self::Error> {
let path = path?;
// FIXME(eddyb) this shouldn't happen, but is currently // FIXME(eddyb) this shouldn't happen, but is currently
// the case for `extern { ... }` "foreign modules". // the case for `extern { ... }` "foreign modules".
if text.is_empty() { if text.is_empty() {
@@ -771,7 +781,7 @@ impl<F: fmt::Write> Printer for FmtPrinter<F> {
substs: SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
ns: Namespace, ns: Namespace,
projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>, projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>,
) -> Self::Path { ) -> Result<Self::Path, Self::Error> {
self.pretty_path_generic_args(path, params, substs, ns, projections) self.pretty_path_generic_args(path, params, substs, ns, projections)
} }
} }

View File

@@ -193,7 +193,8 @@ macro_rules! gen_display_debug {
macro_rules! gen_print_impl { macro_rules! gen_print_impl {
( ($($x:tt)+) $target:ty, ($self:ident, $cx:ident) $disp:block $dbg:block ) => { ( ($($x:tt)+) $target:ty, ($self:ident, $cx:ident) $disp:block $dbg:block ) => {
impl<$($x)+, P: PrettyPrinter> Print<'tcx, P> for $target { impl<$($x)+, P: PrettyPrinter> Print<'tcx, P> for $target {
type Output = fmt::Result; type Output = ();
type Error = fmt::Error;
fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, P>) -> fmt::Result { fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, P>) -> fmt::Result {
define_scoped_cx!($cx); define_scoped_cx!($cx);
if $cx.is_debug $dbg if $cx.is_debug $dbg
@@ -203,7 +204,8 @@ macro_rules! gen_print_impl {
}; };
( () $target:ty, ($self:ident, $cx:ident) $disp:block $dbg:block ) => { ( () $target:ty, ($self:ident, $cx:ident) $disp:block $dbg:block ) => {
impl<P: PrettyPrinter> Print<'tcx, P> for $target { impl<P: PrettyPrinter> Print<'tcx, P> for $target {
type Output = fmt::Result; type Output = ();
type Error = fmt::Error;
fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, P>) -> fmt::Result { fn print(&$self, $cx: &mut PrintCx<'_, '_, 'tcx, P>) -> fmt::Result {
define_scoped_cx!($cx); define_scoped_cx!($cx);
if $cx.is_debug $dbg if $cx.is_debug $dbg
@@ -298,8 +300,8 @@ impl<P: PrettyPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
Ok(()) Ok(())
} }
fn in_binder<T>(&mut self, value: &ty::Binder<T>) -> fmt::Result fn in_binder<T>(&mut self, value: &ty::Binder<T>) -> Result<T::Output, fmt::Error>
where T: Print<'tcx, P, Output = fmt::Result> + TypeFoldable<'tcx> where T: Print<'tcx, P, Error = fmt::Error> + TypeFoldable<'tcx>
{ {
fn name_by_region_index(index: usize) -> InternedString { fn name_by_region_index(index: usize) -> InternedString {
match index { match index {

View File

@@ -404,9 +404,14 @@ impl SymbolPath {
// symbol names should have their own printing machinery. // symbol names should have their own printing machinery.
impl Printer for SymbolPath { impl Printer for SymbolPath {
type Path = Result<PrettyPath, fmt::Error>; type Error = fmt::Error;
fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path { type Path = PrettyPath;
fn path_crate(
self: &mut PrintCx<'_, '_, '_, Self>,
cnum: CrateNum,
) -> Result<Self::Path, Self::Error> {
self.printer.write_str(&self.tcx.original_crate_name(cnum).as_str())?; self.printer.write_str(&self.tcx.original_crate_name(cnum).as_str())?;
Ok(PrettyPath { empty: false }) Ok(PrettyPath { empty: false })
} }
@@ -416,7 +421,7 @@ impl Printer for SymbolPath {
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>, trait_ref: Option<ty::TraitRef<'tcx>>,
ns: Namespace, ns: Namespace,
) -> Self::Path { ) -> Result<Self::Path, Self::Error> {
// HACK(eddyb) avoid `keep_within_component` for the cases // HACK(eddyb) avoid `keep_within_component` for the cases
// that print without `<...>` around `self_ty`. // that print without `<...>` around `self_ty`.
match self_ty.sty { match self_ty.sty {
@@ -432,14 +437,17 @@ impl Printer for SymbolPath {
// HACK(eddyb) make sure to finalize the last component of the // HACK(eddyb) make sure to finalize the last component of the
// `impl` prefix, to avoid it fusing with the following text. // `impl` prefix, to avoid it fusing with the following text.
let impl_prefix = impl_prefix.map(|prefix| { let impl_prefix = match impl_prefix {
let mut prefix = self.path_append(prefix, "")?; Some(prefix) => {
let mut prefix = self.path_append(prefix, "")?;
// HACK(eddyb) also avoid an unnecessary `::`. // HACK(eddyb) also avoid an unnecessary `::`.
prefix.empty = true; prefix.empty = true;
Ok(prefix) Some(prefix)
}); }
None => None,
};
let kept_within_component = mem::replace(&mut self.printer.keep_within_component, true); 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); let r = self.pretty_path_qualified(impl_prefix, self_ty, trait_ref, ns);
@@ -448,11 +456,9 @@ impl Printer for SymbolPath {
} }
fn path_append( fn path_append(
self: &mut PrintCx<'_, '_, '_, Self>, self: &mut PrintCx<'_, '_, '_, Self>,
path: Self::Path, mut path: Self::Path,
text: &str, text: &str,
) -> Self::Path { ) -> Result<Self::Path, Self::Error> {
let mut path = path?;
if self.keep_within_component { if self.keep_within_component {
// HACK(eddyb) print the path similarly to how `FmtPrinter` prints it. // HACK(eddyb) print the path similarly to how `FmtPrinter` prints it.
if !path.empty { if !path.empty {
@@ -475,7 +481,7 @@ impl Printer for SymbolPath {
substs: SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
ns: Namespace, ns: Namespace,
projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>, projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>,
) -> Self::Path { ) -> Result<Self::Path, Self::Error> {
let kept_within_component = mem::replace(&mut self.printer.keep_within_component, true); 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); let r = self.pretty_path_generic_args(path, params, substs, ns, projections);
self.printer.keep_within_component = kept_within_component; self.printer.keep_within_component = kept_within_component;

View File

@@ -4230,10 +4230,15 @@ where F: Fn(DefId) -> Def {
struct AbsolutePathPrinter; struct AbsolutePathPrinter;
impl Printer for AbsolutePathPrinter { impl Printer for AbsolutePathPrinter {
type Error = !;
type Path = Vec<String>; type Path = Vec<String>;
fn path_crate(self: &mut PrintCx<'_, '_, '_, Self>, cnum: CrateNum) -> Self::Path { fn path_crate(
vec![self.tcx.original_crate_name(cnum).to_string()] self: &mut PrintCx<'_, '_, '_, Self>,
cnum: CrateNum,
) -> Result<Self::Path, Self::Error> {
Ok(vec![self.tcx.original_crate_name(cnum).to_string()])
} }
fn path_qualified( fn path_qualified(
self: &mut PrintCx<'_, '_, 'tcx, Self>, self: &mut PrintCx<'_, '_, 'tcx, Self>,
@@ -4241,7 +4246,7 @@ where F: Fn(DefId) -> Def {
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
trait_ref: Option<ty::TraitRef<'tcx>>, trait_ref: Option<ty::TraitRef<'tcx>>,
_ns: Namespace, _ns: Namespace,
) -> Self::Path { ) -> Result<Self::Path, Self::Error> {
let mut path = impl_prefix.unwrap_or(vec![]); let mut path = impl_prefix.unwrap_or(vec![]);
// This shouldn't ever be needed, but just in case: // This shouldn't ever be needed, but just in case:
@@ -4251,15 +4256,15 @@ where F: Fn(DefId) -> Def {
path.push(format!("<{}>", self_ty)); path.push(format!("<{}>", self_ty));
} }
path Ok(path)
} }
fn path_append( fn path_append(
self: &mut PrintCx<'_, '_, '_, Self>, self: &mut PrintCx<'_, '_, '_, Self>,
mut path: Self::Path, mut path: Self::Path,
text: &str, text: &str,
) -> Self::Path { ) -> Result<Self::Path, Self::Error> {
path.push(text.to_string()); path.push(text.to_string());
path Ok(path)
} }
fn path_generic_args( fn path_generic_args(
self: &mut PrintCx<'_, '_, 'tcx, Self>, self: &mut PrintCx<'_, '_, 'tcx, Self>,
@@ -4268,13 +4273,14 @@ where F: Fn(DefId) -> Def {
_substs: SubstsRef<'tcx>, _substs: SubstsRef<'tcx>,
_ns: Namespace, _ns: Namespace,
_projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>, _projections: impl Iterator<Item = ty::ExistentialProjection<'tcx>>,
) -> Self::Path { ) -> Result<Self::Path, Self::Error> {
path Ok(path)
} }
} }
let names = PrintCx::new(tcx, AbsolutePathPrinter) let names = PrintCx::new(tcx, AbsolutePathPrinter)
.print_def_path(def_id, None, Namespace::TypeNS, iter::empty()); .print_def_path(def_id, None, Namespace::TypeNS, iter::empty())
.unwrap();
hir::Path { hir::Path {
span: DUMMY_SP, span: DUMMY_SP,

View File

@@ -18,6 +18,7 @@
#![feature(const_fn)] #![feature(const_fn)]
#![feature(drain_filter)] #![feature(drain_filter)]
#![feature(inner_deref)] #![feature(inner_deref)]
#![feature(never_type)]
#![recursion_limit="256"] #![recursion_limit="256"]