diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 06495510ede..10c34aaf5b7 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -58,7 +58,7 @@ use crate::traits::{ObligationCause, ObligationCauseCode}; use crate::ty::error::TypeError; use crate::ty::{self, subst::{Subst, SubstsRef}, Region, Ty, TyCtxt, TyKind, TypeFoldable}; use errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString}; -use std::{cmp, fmt, iter}; +use std::{cmp, fmt}; use syntax_pos::{Pos, Span}; mod note; @@ -458,6 +458,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { type Path = Vec; type Region = !; type Type = !; + type DynExistential = !; fn print_region( self: PrintCx<'_, '_, '_, Self>, @@ -473,6 +474,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { Err(NonTrivialPath) } + fn print_dyn_existential<'tcx>( + self: PrintCx<'_, '_, 'tcx, Self>, + _predicates: &'tcx ty::List>, + ) -> Result { + Err(NonTrivialPath) + } + fn path_crate( self: PrintCx<'_, '_, '_, Self>, cnum: CrateNum, @@ -513,8 +521,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { print_prefix: impl FnOnce( PrintCx<'_, 'gcx, 'tcx, Self>, ) -> Result, - _args: impl Iterator> + Clone, - _projections: impl Iterator>, + _args: &[Kind<'tcx>], ) -> Result { print_prefix(self) } @@ -526,7 +533,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { if !(did1.is_local() || did2.is_local()) && did1.krate != did2.krate { let abs_path = |def_id| { PrintCx::new(self.tcx, AbsolutePathPrinter) - .print_def_path(def_id, None, iter::empty()) + .print_def_path(def_id, None) }; // We compare strings because DefPath can be different diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 5e2851e08ec..d1574bb322d 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2409,7 +2409,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { 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), iter::empty())?; + cx.print_def_path(variant_def.did, Some(substs))?; Ok(()) })?; diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index b137d5f69c6..66c99a7c4fc 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -178,7 +178,7 @@ 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), iter::empty())?; + cx.print_def_path(self.def_id(), Some(substs))?; Ok(()) })?; diff --git a/src/librustc/ty/print/mod.rs b/src/librustc/ty/print/mod.rs index d89bd84a349..4e81533589e 100644 --- a/src/librustc/ty/print/mod.rs +++ b/src/librustc/ty/print/mod.rs @@ -5,7 +5,6 @@ use crate::ty::subst::{Kind, Subst, SubstsRef}; use rustc_data_structures::fx::FxHashSet; -use std::iter; use std::ops::{Deref, DerefMut}; // `pretty` is a separate module only for organization. @@ -64,14 +63,14 @@ pub trait Printer: Sized { type Path; type Region; type Type; + type DynExistential; fn print_def_path( self: PrintCx<'_, '_, 'tcx, Self>, def_id: DefId, substs: Option>, - projections: impl Iterator>, ) -> Result { - self.default_print_def_path(def_id, substs, projections) + self.default_print_def_path(def_id, substs) } fn print_impl_path( self: PrintCx<'_, '_, 'tcx, Self>, @@ -93,6 +92,11 @@ pub trait Printer: Sized { ty: Ty<'tcx>, ) -> Result; + fn print_dyn_existential( + self: PrintCx<'_, '_, 'tcx, Self>, + predicates: &'tcx ty::List>, + ) -> Result; + fn path_crate( self: PrintCx<'_, '_, '_, Self>, cnum: CrateNum, @@ -123,8 +127,7 @@ pub trait Printer: Sized { print_prefix: impl FnOnce( PrintCx<'_, 'gcx, 'tcx, Self>, ) -> Result, - args: impl Iterator> + Clone, - projections: impl Iterator>, + args: &[Kind<'tcx>], ) -> Result; } @@ -133,7 +136,6 @@ impl PrintCx<'_, 'gcx, 'tcx, P> { self, def_id: DefId, substs: Option>, - projections: impl Iterator>, ) -> Result { debug!("default_print_def_path: def_id={:?}, substs={:?}", def_id, substs); let key = self.tcx.def_key(def_id); @@ -175,10 +177,10 @@ impl PrintCx<'_, 'gcx, 'tcx, P> { let trait_ref = ty::TraitRef::new(parent_def_id, substs); cx.path_qualified(trait_ref.self_ty(), Some(trait_ref)) } else { - cx.print_def_path(parent_def_id, substs, iter::empty()) + cx.print_def_path(parent_def_id, substs) } } else { - cx.print_def_path(parent_def_id, None, iter::empty()) + cx.print_def_path(parent_def_id, None) } }; let print_path = |cx: PrintCx<'_, 'gcx, 'tcx, P>| { @@ -197,7 +199,7 @@ impl PrintCx<'_, 'gcx, 'tcx, P> { if let (Some(generics), Some(substs)) = (generics, substs) { let args = self.generic_args_to_print(generics, substs); - self.path_generic_args(print_path, args, projections) + self.path_generic_args(print_path, args) } else { print_path(self) } @@ -209,13 +211,16 @@ impl PrintCx<'_, 'gcx, 'tcx, P> { &self, generics: &'tcx ty::Generics, substs: SubstsRef<'tcx>, - ) -> impl Iterator> + Clone { + ) -> &'tcx [Kind<'tcx>] { + let mut own_params = generics.parent_count..generics.count(); + // Don't print args for `Self` parameters (of traits). - let has_own_self = generics.has_self && generics.parent_count == 0; - let params = &generics.params[has_own_self as usize..]; + if generics.has_self && own_params.start == 0 { + own_params.start = 1; + } // Don't print args that are the defaults of their respective parameters. - let num_supplied_defaults = params.iter().rev().take_while(|param| { + own_params.end -= generics.params.iter().rev().take_while(|param| { match param.kind { ty::GenericParamDefKind::Lifetime => false, ty::GenericParamDefKind::Type { has_default, .. } => { @@ -226,9 +231,8 @@ impl PrintCx<'_, 'gcx, 'tcx, P> { ty::GenericParamDefKind::Const => false, // FIXME(const_generics:defaults) } }).count(); - params[..params.len() - num_supplied_defaults].iter().map(move |param| { - substs[param.index as usize] - }) + + &substs[own_params] } fn default_print_impl_path( @@ -261,7 +265,7 @@ impl PrintCx<'_, 'gcx, 'tcx, P> { // trait-type, then fallback to a format that identifies // the module more clearly. self.path_append_impl( - |cx| cx.print_def_path(parent_def_id, None, iter::empty()), + |cx| cx.print_def_path(parent_def_id, None), self_ty, impl_trait_ref, ) @@ -344,3 +348,11 @@ impl Print<'tcx, P> for Ty<'tcx> { cx.print_type(self) } } + +impl Print<'tcx, P> for &'tcx ty::List> { + type Output = P::DynExistential; + type Error = P::Error; + fn print(&self, cx: PrintCx<'_, '_, 'tcx, P>) -> Result { + cx.print_dyn_existential(self) + } +} diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index a1e157685c9..d27e64b27a2 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -14,7 +14,6 @@ use syntax::symbol::InternedString; use std::cell::Cell; use std::fmt::{self, Write as _}; -use std::iter; use std::ops::{Deref, DerefMut}; // `pretty` is a separate module only for organization. @@ -177,6 +176,7 @@ pub trait PrettyPrinter: Path = Self, Region = Self, Type = Self, + DynExistential = Self, > + fmt::Write { @@ -195,7 +195,7 @@ pub trait PrettyPrinter: def_id: DefId, substs: Option>, ) -> Result { - self.print_def_path(def_id, substs, iter::empty()) + self.print_def_path(def_id, substs) } fn in_binder( @@ -211,14 +211,13 @@ pub trait PrettyPrinter: fn comma_sep( mut self: PrintCx<'_, '_, 'tcx, Self>, mut elems: impl Iterator, - comma: &str, ) -> Result 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.write_str(", ")?; self = self.nest(|cx| elem.print(cx))?; } } @@ -272,7 +271,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns); let mut s = String::new(); let _ = PrintCx::new(self, FmtPrinter::new(&mut s, ns)) - .print_def_path(def_id, None, iter::empty()); + .print_def_path(def_id, None); s } } @@ -317,7 +316,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { }) => { debug!("try_print_visible_def_path: def_id={:?}", def_id); return Ok((if !span.is_dummy() { - self.print_def_path(def_id, None, iter::empty())? + self.print_def_path(def_id, None)? } else { self.path_crate(cnum)? }, true)); @@ -485,33 +484,6 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { cx.ok() }) } - - pub fn pretty_path_generic_args( - mut self, - print_prefix: impl FnOnce( - PrintCx<'_, 'gcx, 'tcx, P>, - ) -> Result, - mut args: impl Iterator>, - mut projections: impl Iterator>, - ) -> Result { - self = self.nest(print_prefix)?; - - let arg0 = args.next(); - let projection0 = projections.next(); - if arg0.is_none() && projection0.is_none() { - return self.ok(); - } - let args = arg0.into_iter().chain(args); - let projections = projection0.into_iter().chain(projections); - - self.generic_delimiters(|mut cx| { - cx = cx.nest(|cx| cx.comma_sep(args, ", "))?; - if arg0.is_some() && projection0.is_some() { - write!(cx, ", ")?; - } - cx.comma_sep(projections, ", ") - }) - } } // HACK(eddyb) boxed to avoid moving around a large struct by-value. @@ -570,12 +542,12 @@ impl Printer for FmtPrinter { type Path = Self; type Region = Self; type Type = Self; + type DynExistential = Self; fn print_def_path( mut self: PrintCx<'_, '_, 'tcx, Self>, def_id: DefId, substs: Option>, - projections: impl Iterator>, ) -> Result { // FIXME(eddyb) avoid querying `tcx.generics_of` and `tcx.def_key` // both here and in `default_print_def_path`. @@ -590,7 +562,7 @@ impl Printer for FmtPrinter { if visible_path_success { return if let (Some(generics), Some(substs)) = (generics, substs) { let args = self.generic_args_to_print(generics, substs); - self.path_generic_args(|cx| cx.ok(), args, projections) + self.path_generic_args(|cx| cx.ok(), args) } else { self.ok() }; @@ -615,13 +587,13 @@ impl Printer for FmtPrinter { let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id }; let span = self.tcx.def_span(def_id); return self.path_append( - |cx| cx.print_def_path(parent_def_id, None, iter::empty()), + |cx| cx.print_def_path(parent_def_id, None), &format!("", span), ); } } - self.default_print_def_path(def_id, substs, projections) + self.default_print_def_path(def_id, substs) } fn print_region( @@ -638,6 +610,13 @@ impl Printer for FmtPrinter { self.pretty_print_type(ty) } + fn print_dyn_existential( + self: PrintCx<'_, '_, 'tcx, Self>, + predicates: &'tcx ty::List>, + ) -> Result { + self.pretty_print_dyn_existential(predicates) + } + fn path_crate( mut self: PrintCx<'_, '_, '_, Self>, cnum: CrateNum, @@ -703,27 +682,33 @@ impl Printer for FmtPrinter { Ok(path) } fn path_generic_args<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, + mut self: PrintCx<'_, 'gcx, 'tcx, Self>, print_prefix: impl FnOnce( PrintCx<'_, 'gcx, 'tcx, Self>, ) -> Result, - args: impl Iterator> + Clone, - projections: impl Iterator>, + args: &[Kind<'tcx>], ) -> Result { + self = self.nest(print_prefix)?; + // Don't print `'_` if there's no unerased regions. - let print_regions = args.clone().any(|arg| { + let print_regions = args.iter().any(|arg| { match arg.unpack() { UnpackedKind::Lifetime(r) => *r != ty::ReErased, _ => false, } }); - let args = args.filter(|arg| { + let args = args.iter().cloned().filter(|arg| { match arg.unpack() { UnpackedKind::Lifetime(_) => print_regions, _ => true, } }); - self.pretty_path_generic_args(print_prefix, args, projections) + + if args.clone().next().is_some() { + self.generic_delimiters(|cx| cx.comma_sep(args)) + } else { + self.ok() + } } } @@ -745,7 +730,7 @@ impl PrettyPrinter for FmtPrinter { substs: Option>, ) -> Result { let was_in_value = std::mem::replace(&mut self.in_value, true); - let mut path = self.print_def_path(def_id, substs, iter::empty())?; + let mut path = self.print_def_path(def_id, substs)?; path.in_value = was_in_value; Ok(path) @@ -995,7 +980,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } } ty::Adt(def, substs) => { - nest!(|cx| cx.print_def_path(def.did, Some(substs), iter::empty())); + nest!(|cx| cx.print_def_path(def.did, Some(substs))); } ty::Dynamic(data, r) => { let print_r = self.region_should_not_be_omitted(r); @@ -1008,7 +993,7 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { } } ty::Foreign(def_id) => { - nest!(|cx| cx.print_def_path(def_id, None, iter::empty())); + nest!(|cx| cx.print_def_path(def_id, None)); } ty::Projection(ref data) => p!(print(data)), ty::UnnormalizedProjection(ref data) => { @@ -1184,6 +1169,105 @@ impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> { self.ok() } + fn pretty_print_dyn_existential( + mut self, + predicates: &'tcx ty::List>, + ) -> Result { + define_scoped_cx!(self); + + // Generate the main trait ref, including associated types. + let mut first = true; + + if let Some(principal) = predicates.principal() { + nest!(|cx| cx.print_def_path(principal.def_id, None)); + + let mut resugared = false; + + // Special-case `Fn(...) -> ...` and resugar it. + let fn_trait_kind = self.tcx.lang_items().fn_trait_kind(principal.def_id); + if !self.tcx.sess.verbose() && fn_trait_kind.is_some() { + if let ty::Tuple(ref args) = principal.substs.type_at(0).sty { + let mut projections = predicates.projection_bounds(); + if let (Some(proj), None) = (projections.next(), projections.next()) { + nest!(|cx| cx.pretty_fn_sig(args, false, proj.ty)); + resugared = true; + } + } + } + + // HACK(eddyb) this duplicates `FmtPrinter`'s `path_generic_args`, + // in order to place the projections inside the `<...>`. + if !resugared { + // Use a type that can't appear in defaults of type parameters. + let dummy_self = self.tcx.mk_infer(ty::FreshTy(0)); + let principal = principal.with_self_ty(self.tcx, dummy_self); + + let args = self.generic_args_to_print( + self.tcx.generics_of(principal.def_id), + principal.substs, + ); + + // Don't print `'_` if there's no unerased regions. + let print_regions = args.iter().any(|arg| { + match arg.unpack() { + UnpackedKind::Lifetime(r) => *r != ty::ReErased, + _ => false, + } + }); + let mut args = args.iter().cloned().filter(|arg| { + match arg.unpack() { + UnpackedKind::Lifetime(_) => print_regions, + _ => true, + } + }); + let mut projections = predicates.projection_bounds(); + + let arg0 = args.next(); + let projection0 = projections.next(); + if arg0.is_some() || projection0.is_some() { + let args = arg0.into_iter().chain(args); + let projections = projection0.into_iter().chain(projections); + + nest!(|cx| cx.generic_delimiters(|mut cx| { + cx = cx.nest(|cx| cx.comma_sep(args))?; + if arg0.is_some() && projection0.is_some() { + write!(cx, ", ")?; + } + cx.comma_sep(projections) + })); + } + } + first = false; + } + + // Builtin bounds. + // FIXME(eddyb) avoid printing twice (needed to ensure + // that the auto traits are sorted *and* printed via cx). + let mut auto_traits: Vec<_> = predicates.auto_traits().map(|did| { + (self.tcx.def_path_str(did), did) + }).collect(); + + // The auto traits come ordered by `DefPathHash`. While + // `DefPathHash` is *stable* in the sense that it depends on + // neither the host nor the phase of the moon, it depends + // "pseudorandomly" on the compiler version and the target. + // + // To avoid that causing instabilities in compiletest + // output, sort the auto-traits alphabetically. + auto_traits.sort(); + + for (_, def_id) in auto_traits { + if !first { + p!(write(" + ")); + } + first = false; + + nest!(|cx| cx.print_def_path(def_id, None)); + } + + self.ok() + } + pub fn pretty_fn_sig( mut self, inputs: &[Ty<'tcx>], @@ -1399,6 +1483,7 @@ macro_rules! define_print_and_forward_display { forward_display_to_print!(ty::RegionKind); forward_display_to_print!(Ty<'tcx>); +forward_display_to_print!(&'tcx ty::List>); forward_display_to_print!( ty::Binder); define_print_and_forward_display! { @@ -1412,70 +1497,6 @@ define_print_and_forward_display! { define_print_and_forward_display! { (self, cx): - &'tcx ty::List> { - // Generate the main trait ref, including associated types. - let mut first = true; - - if let Some(principal) = self.principal() { - let mut resugared_principal = false; - - // Special-case `Fn(...) -> ...` and resugar it. - let fn_trait_kind = cx.tcx.lang_items().fn_trait_kind(principal.def_id); - if !cx.tcx.sess.verbose() && fn_trait_kind.is_some() { - 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()) { - nest!(|cx| cx.print_def_path(principal.def_id, None, iter::empty())); - nest!(|cx| cx.pretty_fn_sig(args, false, proj.ty)); - resugared_principal = true; - } - } - } - - if !resugared_principal { - // 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); - nest!(|cx| cx.print_def_path( - principal.def_id, - Some(principal.substs), - self.projection_bounds(), - )); - } - first = false; - } - - // Builtin bounds. - // FIXME(eddyb) avoid printing twice (needed to ensure - // that the auto traits are sorted *and* printed via cx). - let mut auto_traits: Vec<_> = self.auto_traits().map(|did| { - (cx.tcx.def_path_str(did), did) - }).collect(); - - // The auto traits come ordered by `DefPathHash`. While - // `DefPathHash` is *stable* in the sense that it depends on - // neither the host nor the phase of the moon, it depends - // "pseudorandomly" on the compiler version and the target. - // - // To avoid that causing instabilities in compiletest - // output, sort the auto-traits alphabetically. - auto_traits.sort(); - - for (_, def_id) in auto_traits { - if !first { - p!(write(" + ")); - } - first = false; - - nest!(|cx| cx.print_def_path(def_id, None, iter::empty())); - } - } - - ty::ExistentialProjection<'tcx> { - let name = cx.tcx.associated_item(self.item_def_id).ident; - p!(write("{}=", name), print(self.ty)) - } - &'tcx ty::List> { p!(write("{{")); let mut tys = self.iter(); @@ -1494,14 +1515,27 @@ define_print_and_forward_display! { } ty::ExistentialTraitRef<'tcx> { + // Use a type that can't appear in defaults of type parameters. let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0)); - - let trait_ref = *ty::Binder::bind(*self) - .with_self_ty(cx.tcx, dummy_self) - .skip_binder(); + let trait_ref = self.with_self_ty(cx.tcx, dummy_self); p!(print(trait_ref)) } + ty::ExistentialProjection<'tcx> { + let name = cx.tcx.associated_item(self.item_def_id).ident; + p!(write("{}=", name), print(self.ty)) + } + + ty::ExistentialPredicate<'tcx> { + match *self { + ty::ExistentialPredicate::Trait(x) => p!(print(x)), + ty::ExistentialPredicate::Projection(x) => p!(print(x)), + ty::ExistentialPredicate::AutoTrait(def_id) => { + nest!(|cx| cx.print_def_path(def_id, None)) + } + } + } + ty::FnSig<'tcx> { if self.unsafety == hir::Unsafety::Unsafe { p!(write("unsafe ")); @@ -1531,7 +1565,7 @@ define_print_and_forward_display! { } ty::TraitRef<'tcx> { - nest!(|cx| cx.print_def_path(self.def_id, Some(self.substs), iter::empty())); + nest!(|cx| cx.print_def_path(self.def_id, Some(self.substs))); } ConstValue<'tcx> { @@ -1575,7 +1609,7 @@ define_print_and_forward_display! { } ty::ProjectionTy<'tcx> { - nest!(|cx| cx.print_def_path(self.item_def_id, Some(self.substs), iter::empty())); + nest!(|cx| cx.print_def_path(self.item_def_id, Some(self.substs))); } ty::ClosureKind { @@ -1596,7 +1630,7 @@ define_print_and_forward_display! { ty::Predicate::WellFormed(ty) => p!(print(ty), write(" well-formed")), ty::Predicate::ObjectSafe(trait_def_id) => { p!(write("the trait `")); - nest!(|cx| cx.print_def_path(trait_def_id, None, iter::empty())); + nest!(|cx| cx.print_def_path(trait_def_id, None)); p!(write("` is object-safe")) } ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => { diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index dfb7e64d98b..32a39c2eb88 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -14,7 +14,6 @@ use smallvec::SmallVec; use crate::mir::interpret; use std::fmt; -use std::iter; use std::marker::PhantomData; use std::rc::Rc; @@ -36,7 +35,7 @@ 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, iter::empty())?; + cx.print_def_path(self.def_id, None)?; Ok(()) }) } @@ -45,7 +44,7 @@ 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, iter::empty())?; + cx.print_def_path(self.did, None)?; Ok(()) }) } diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 93e7e495d4e..9620c3efda0 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -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}; +use rustc::ty::print::{PrettyPrinter, PrintCx, Printer, Print}; use rustc::ty::query::Providers; use rustc::ty::subst::{Kind, SubstsRef, UnpackedKind}; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; @@ -106,7 +106,6 @@ use syntax_pos::symbol::Symbol; use log::debug; use std::fmt::{self, Write}; -use std::iter; use std::mem::{self, discriminant}; pub fn provide(providers: &mut Providers<'_>) { @@ -225,7 +224,7 @@ 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, iter::empty()) + .print_def_path(def_id, None) .unwrap() .into_interned() } @@ -409,6 +408,7 @@ impl Printer for SymbolPath { type Path = Self; type Region = Self; type Type = Self; + type DynExistential = Self; fn print_region( self: PrintCx<'_, '_, '_, Self>, @@ -429,12 +429,27 @@ impl Printer for SymbolPath { ty::UnnormalizedProjection(ty::ProjectionTy { item_def_id: def_id, substs }) | ty::Closure(def_id, ty::ClosureSubsts { substs }) | ty::Generator(def_id, ty::GeneratorSubsts { substs }, _) => { - self.print_def_path(def_id, Some(substs), iter::empty()) + self.print_def_path(def_id, Some(substs)) } _ => self.pretty_print_type(ty), } } + fn print_dyn_existential( + mut self: PrintCx<'_, '_, 'tcx, Self>, + predicates: &'tcx ty::List>, + ) -> Result { + let mut first = false; + for p in predicates { + if !first { + write!(self, "+")?; + } + first = false; + self = self.nest(|cx| p.print(cx))?; + } + self.ok() + } + fn path_crate( mut self: PrintCx<'_, '_, '_, Self>, cnum: CrateNum, @@ -499,20 +514,26 @@ impl Printer for SymbolPath { Ok(path) } fn path_generic_args<'gcx, 'tcx>( - self: PrintCx<'_, 'gcx, 'tcx, Self>, + mut self: PrintCx<'_, 'gcx, 'tcx, Self>, print_prefix: impl FnOnce( PrintCx<'_, 'gcx, 'tcx, Self>, ) -> Result, - args: impl Iterator> + Clone, - projections: impl Iterator>, + args: &[Kind<'tcx>], ) -> Result { - let args = args.filter(|arg| { + self = self.nest(print_prefix)?; + + let args = args.iter().cloned().filter(|arg| { match arg.unpack() { UnpackedKind::Lifetime(_) => false, _ => true, } }); - self.pretty_path_generic_args(print_prefix, args, projections) + + if args.clone().next().is_some() { + self.generic_delimiters(|cx| cx.comma_sep(args)) + } else { + self.ok() + } } } @@ -523,6 +544,21 @@ impl PrettyPrinter for SymbolPath { ) -> bool { false } + fn comma_sep( + mut self: PrintCx<'_, '_, 'tcx, Self>, + mut elems: impl Iterator, + ) -> Result + 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(",")?; + self = self.nest(|cx| elem.print(cx))?; + } + } + self.ok() + } fn generic_delimiters<'gcx, 'tcx>( mut self: PrintCx<'_, 'gcx, 'tcx, Self>, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 94c954b01b1..6822de2bceb 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -39,7 +39,7 @@ use std::fmt; use std::hash::{Hash, Hasher}; use std::default::Default; use std::{mem, slice, vec}; -use std::iter::{self, FromIterator, once}; +use std::iter::{FromIterator, once}; use std::rc::Rc; use std::str::FromStr; use std::cell::RefCell; @@ -4235,6 +4235,7 @@ where F: Fn(DefId) -> Def { type Path = Vec; type Region = (); type Type = (); + type DynExistential = (); fn print_region( self: PrintCx<'_, '_, '_, Self>, @@ -4250,6 +4251,13 @@ where F: Fn(DefId) -> Def { Ok(()) } + fn print_dyn_existential<'tcx>( + self: PrintCx<'_, '_, 'tcx, Self>, + _predicates: &'tcx ty::List>, + ) -> Result { + Ok(()) + } + fn path_crate( self: PrintCx<'_, '_, '_, Self>, cnum: CrateNum, @@ -4304,15 +4312,14 @@ where F: Fn(DefId) -> Def { print_prefix: impl FnOnce( PrintCx<'_, 'gcx, 'tcx, Self>, ) -> Result, - _args: impl Iterator> + Clone, - _projections: impl Iterator>, + _args: &[Kind<'tcx>], ) -> Result { print_prefix(self) } } let names = PrintCx::new(tcx, AbsolutePathPrinter) - .print_def_path(def_id, None, iter::empty()) + .print_def_path(def_id, None) .unwrap(); hir::Path {