lang (typesystem | machine | parametricity)
libdebug
Poly
format trait as well as the :?
format specifierIn ancient Rust, one of the primary methods of printing a value was via the %?
format specifier. This would use reflection at runtime to determine how to print
a type. Metadata generated by the compiler (a TyDesc
) would be generated to
guide the runtime in how to print a type. One of the great parts about
reflection was that it was quite easy to print any type. No extra burden was
required from the programmer to print something.
There are, however, a number of cons to this approach:
%?
led
to misleading benchmarks about formatting in Rust.Over time, usage off the ?
formatting has fallen out of fashion for the
following reasons:
deriving
-based infrastructure was improved greatly and has started
seeing much more widespread use, especially for traits like Clone
.{}
(an implementation of Show
), and it is quite common to
see an implementation of Show
on nearly all types (frequently via
deriving
). This form of customizable-per-typformatting largely provides the
gap that the original formatting language did not provide, which was limited
to only primitives and %?
.~[T]
and ~str
have been removed from the
language, and runtime reflection on Vec<T>
and String
are far less useful
(they just print pointers, not contents).As a result, the :?
formatting specifier is quite rarely used today, and
when it is used it's largely for historical purposes and the output is not of
very high quality any more.
The drawbacks and today's current state of affairs motivate this RFC to recommend removing this infrastructure entirely. It's possible to add it back in the future with a more modern design reflecting today's design principles of Rust and the many language changes since the infrastructure was created.
visit_glue
function from TyDesc
.visit_glue
generation.name
field of TyDesc
.core::intrinsics::TyVisitor
core::intrinsics::visit_tydesc
libdebug
std::fmt::Poly
:?
format specifier in the formatting language syntax.The current infrastructure for reflection, although outdated, represents a significant investment of work in the past which could be a shame to lose. While present in the git history, this infrastructure has been updated over time, and it will no longer receive this attention.
Additionally, given an arbitrary type T
, it would now be impossible to print
it in literally any situation. Type parameters will now require some bound, such
as Show
, to allow printing a type.
These two drawbacks are currently not seen as large enough to outweigh the gains
from reducing the surface area of the std::fmt
API and reduction in
maintenance load on the compiler.
The primary alternative to outright removing this infrastructure is to preserve
it, but flag it all as #[experimental]
or feature-gated. The compiler could
require the fmt_poly
feature gate to be enabled to enable formatting via :?
in a crate. This would mean that any backwards-incompatible changes could
continue to be made, and any arbitrary type T
could still be printed.
core::intrinsics::TyDesc
be removed entirely?