Skip to content

Commit ecdd086

Browse files
committed
RFC: Remove reflection from the compiler
1 parent c7da23a commit ecdd086

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed

active/0000-remove-reflection.md

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
- Start Date: (fill me in with today's date, YYYY-MM-DD)
2+
- RFC PR: (leave this empty)
3+
- Rust Issue: (leave this empty)
4+
5+
# Summary
6+
7+
* Remove reflection from the compiler
8+
* Remove `libdebug`
9+
* Remove the `Poly` format trait as well as the `:?` format specifier
10+
11+
# Motivation
12+
13+
In ancient Rust, one of the primary methods of printing a value was via the `%?`
14+
format specifier. This would use reflection at runtime to determine how to print
15+
a type. Metadata generated by the compiler (a `TyDesc`) would be generated to
16+
guide the runtime in how to print a type. One of the great parts about
17+
reflection was that it was quite easy to print any type. No extra burden was
18+
required from the programmer to print something.
19+
20+
There are, however, a number of cons to this approach:
21+
22+
* Generating extra metadata for many many types by the compiler can lead to
23+
noticeable increases in compile time and binary size.
24+
* This form of formatting is inherently not speedy. Widespread usage of `%?` led
25+
to misleading benchmarks about formatting in Rust.
26+
* Depending on how metadata is handled, this scheme makes it very difficult to
27+
allow recompiling a library without recompiling downstream dependants.
28+
29+
Over time, usage off the `?` formatting has fallen out of fashion for the
30+
following reasons:
31+
32+
* The `deriving`-based infrastructure was improved greatly and has started
33+
seeing much more widespread use, especially for traits like `Clone`.
34+
* The formatting language implementation and syntax has changed. The most common
35+
formatter is now `{}` (an implementation of `Show`), and it is quite common to
36+
see an implementation of `Show` on nearly all types (frequently via
37+
`deriving`). This form of customizable-per-typformatting largely provides the
38+
gap that the original formatting language did not provide, which was limited
39+
to only primitives and `%?`.
40+
* Compiler built-ins, such as `~[T]` and `~str` have been removed from the
41+
language, and runtime reflection on `Vec<T>` and `String` are far less useful
42+
(they just print pointers, not contents).
43+
44+
As a result, the `:?` formatting specifier is quite rarely used today, and
45+
when it *is* used it's largely for historical purposes and the output is not of
46+
very high quality any more.
47+
48+
The drawbacks and today's current state of affairs motivate this RFC to
49+
recommend removing this infrastructure entirely. It's possible to add it back in
50+
the future with a more modern design reflecting today's design principles of
51+
Rust and the many language changes since the infrastructure was created.
52+
53+
# Detailed design
54+
55+
* Remove all reflection infrastructure from the compiler. I am not personally
56+
super familiar with what exists, but at least these concrete actions will be
57+
taken.
58+
* Remove the `visit_glue` function from `TyDesc`.
59+
* Remove any form of `visit_glue` generation.
60+
* (maybe?) Remove the `name` field of `TyDesc`.
61+
* Remove `core::intrinsics::TyVisitor`
62+
* Remove `core::intrinsics::visit_tydesc`
63+
* Remove `libdebug`
64+
* Remove `std::fmt::Poly`
65+
* Remove the `:?` format specifier in the formatting language syntax.
66+
67+
# Drawbacks
68+
69+
The current infrastructure for reflection, although outdated, represents a
70+
significant investment of work in the past which could be a shame to lose. While
71+
present in the git history, this infrastructure has been updated over time, and
72+
it will no longer receive this attention.
73+
74+
Additionally, given an arbitrary type `T`, it would now be impossible to print
75+
it in literally any situation. Type parameters will now require some bound, such
76+
as `Show`, to allow printing a type.
77+
78+
These two drawbacks are currently not seen as large enough to outweigh the gains
79+
from reducing the surface area of the `std::fmt` API and reduction in
80+
maintenance load on the compiler.
81+
82+
# Alternatives
83+
84+
The primary alternative to outright removing this infrastructure is to preserve
85+
it, but flag it all as `#[experimental]` or feature-gated. The compiler could
86+
require the `fmt_poly` feature gate to be enabled to enable formatting via `:?`
87+
in a crate. This would mean that any backwards-incompatible changes could
88+
continue to be made, and any arbitrary type `T` could still be printed.
89+
90+
# Unresolved questions
91+
92+
* Can `core::intrinsics::TyDesc` be removed entirely?

0 commit comments

Comments
 (0)