Skip to content

Commit 5c2c4c4

Browse files
committed
Merge remote-tracking branch 'upstream/master' into slice_copy_set
2 parents da75c9b + ee281d7 commit 5c2c4c4

11 files changed

+3073
-70
lines changed

active/0243-trait-based-exception-handling.md

Lines changed: 698 additions & 0 deletions
Large diffs are not rendered by default.

text/0000-restrict-constants-in-patterns.md

Lines changed: 621 additions & 0 deletions
Large diffs are not rendered by default.

text/0131-target-specification.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,7 @@ deciding how to build for a given target. The process would look like:
6565
1. Look up the target triple in an internal map, and load that configuration
6666
if it exists. If that fails, check if the target name exists as a file, and
6767
try loading that. If the file does not exist, look up `<target>.json` in
68-
the `RUST_TARGET_PATH`, which is a colon-separated list of directories
69-
defaulting to `/etc/rustc`.
68+
the `RUST_TARGET_PATH`, which is a colon-separated list of directories.
7069
2. If `-C linker` is specified, use that instead of the target-specified
7170
linker.
7271
3. If `-C link-args` is given, add those to the ones specified by the target.

text/0550-macro-future-proofing.md

Lines changed: 539 additions & 47 deletions
Large diffs are not rendered by default.

text/1192-inclusive-ranges.md

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,26 @@ more dots means more elements.
2626
`std::ops` defines
2727

2828
```rust
29-
pub struct RangeInclusive<T> {
30-
pub start: T,
31-
pub end: T,
32-
pub finished: bool,
29+
pub enum RangeInclusive<T> {
30+
Empty {
31+
at: T,
32+
},
33+
NonEmpty {
34+
start: T,
35+
end: T,
36+
}
3337
}
3438

3539
pub struct RangeToInclusive<T> {
3640
pub end: T,
3741
}
3842
```
3943

40-
Writing `a...b` in an expression desugars to `std::ops::RangeInclusive
41-
{ start: a, end: b, finished: false }`. Writing `...b` in an
44+
Writing `a...b` in an expression desugars to `std::ops::RangeInclusive::NonEmpty { start: a, end: b }`. Writing `...b` in an
4245
expression desugars to `std::ops::RangeToInclusive { end: b }`.
4346

4447
`RangeInclusive` implements the standard traits (`Clone`, `Debug`
45-
etc.), and implements `Iterator`. The `finished` field is to allow the
48+
etc.), and implements `Iterator`. The `Empty` variant is to allow the
4649
`Iterator` implementation to work without hacks (see Alternatives).
4750

4851
The use of `...` in a pattern remains as testing for inclusion
@@ -79,11 +82,12 @@ winner.
7982
This RFC doesn't propose non-double-ended syntax, like `a...`, `...b`
8083
or `...` since it isn't clear that this is so useful. Maybe it is.
8184

82-
The `finished` field could be omitted, leaving two options:
85+
The `Empty` variant could be omitted, leaving two options:
8386

87+
- `RangeInclusive` could be a struct including a `finished` field.
8488
- `a...b` only implements `IntoIterator`, not `Iterator`, by
8589
converting to a different type that does have the field. However,
86-
this means that `a...b` behaves differently to `a..b`, so
90+
this means that `a.. .b` behaves differently to `a..b`, so
8791
`(a...b).map(|x| ...)` doesn't work (the `..` version of that is
8892
used reasonably often, in the author's experience)
8993
- `a...b` can implement `Iterator` for types that can be stepped
@@ -104,3 +108,8 @@ The `finished` field could be omitted, leaving two options:
104108
# Unresolved questions
105109

106110
None so far.
111+
112+
# Amendments
113+
114+
* In rust-lang/rfcs#1320, this RFC was amended to change the `RangeInclusive`
115+
type from a struct with a `finished` field to an enum.

text/1270-deprecation.md

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# Summary
77

88
This RFC proposes to allow library authors to use a `#[deprecated]` attribute,
9-
with optional `since = "`*version*`"` and `reason = "`*free text*`"`fields. The
9+
with optional `since = "`*version*`"` and `note = "`*free text*`"`fields. The
1010
compiler can then warn on deprecated items, while `rustdoc` can document their
1111
deprecation accordingly.
1212

@@ -32,12 +32,11 @@ possible fields are optional:
3232
deprecating the item, following the semver scheme. Rustc does not know about
3333
versions, thus the content of this field is not checked (but will be by external
3434
lints, e.g. [rust-clippy](https://github.com/Manishearth/rust-clippy).
35-
* `reason` should contain a human-readable string outlining the reason for
36-
deprecating the item. While this field is not required, library authors are
37-
strongly advised to make use of it to convey the reason for the deprecation to
38-
users of their library. The string is interpreted as plain unformatted text
39-
(for now) so that rustdoc can include it in the item's documentation without
40-
messing up the formatting.
35+
* `note` should contain a human-readable string outlining the reason for
36+
deprecating the item and/or what to use instead. While this field is not required,
37+
library authors are strongly advised to make use of it. The string is interpreted
38+
as plain unformatted text (for now) so that rustdoc can include it in the item's
39+
documentation without messing up the formatting.
4140

4241
On use of a *deprecated* item, `rustc` will `warn` of the deprecation. Note
4342
that during Cargo builds, warnings on dependencies get silenced. While this has
@@ -51,7 +50,7 @@ to warn on use of deprecated items in library crates, however this is outside
5150
the scope of this RFC.
5251

5352
`rustdoc` will show deprecation on items, with a `[deprecated]` box that may
54-
optionally show the version and reason where available.
53+
optionally show the version and note where available.
5554

5655
The language reference will be extended to describe this feature as outlined
5756
in this RFC. Authors shall be advised to leave their users enough time to react
@@ -74,16 +73,16 @@ prefix to the `Foo` type:
7473
```
7574
extern crate rust_foo;
7675
77-
#[deprecated(since = "0.2.1", use="rust_foo::Foo",
78-
reason="The rust_foo version is more advanced, and this crates' will likely be discontinued")]
76+
#[deprecated(since = "0.2.1",
77+
note="The rust_foo version is more advanced, and this crate's will likely be discontinued")]
7978
struct Foo { .. }
8079
```
8180

8281
Users of her crate will see the following once they `cargo update` and `build`:
8382

8483
```
8584
src/foo_use.rs:27:5: 27:8 warning: Foo is marked deprecated as of version 0.2.1
86-
src/foo_use.rs:27:5: 27:8 note: The rust_foo version is more advanced, and this crates' will likely be discontinued
85+
src/foo_use.rs:27:5: 27:8 note: The rust_foo version is more advanced, and this crate's will likely be discontinued
8786
```
8887

8988
Rust-clippy will likely gain more sophisticated checks for deprecation:
@@ -108,7 +107,7 @@ deprecation checks.
108107
* make the `since` field required and check that it's a single version
109108
* require either `reason` or `use` be present
110109
* `reason` could include markdown formatting
111-
* rename the `reason` field to `note` to clarify it's broader usage.
110+
* rename the `reason` field to `note` to clarify its broader usage. (**done!**)
112111
* add a `note` field and make `reason` a field with specific meaning, perhaps
113112
even predefine a number of valid reason strings, as JEP277 currently does
114113
* Add a `use` field containing a plain text of what to use instead

text/1328-global-panic-handler.md

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
- Feature Name: `panic_handler`
2+
- Start Date: 2015-10-08
3+
- RFC PR: [rust-lang/rfcs#1328](https://github.com/rust-lang/rfcs/pull/1328)
4+
- Rust Issue: [rust-lang/rust#30449](https://github.com/rust-lang/rust/issues/30449)
5+
6+
# Summary
7+
8+
When a thread panics in Rust, the unwinding runtime currently prints a message
9+
to standard error containing the panic argument as well as the filename and
10+
line number corresponding to the location from which the panic originated.
11+
This RFC proposes a mechanism to allow user code to replace this logic with
12+
custom handlers that will run before unwinding begins.
13+
14+
# Motivation
15+
16+
The default behavior is not always ideal for all programs:
17+
18+
* Programs with command line interfaces do not want their output polluted by
19+
random panic messages.
20+
* Programs using a logging framework may want panic messages to be routed into
21+
that system so that they can be processed like other events.
22+
* Programs with graphical user interfaces may not have standard error attached
23+
at all and want to be notified of thread panics to potentially display an
24+
internal error dialog to the user.
25+
26+
The standard library [previously
27+
supported](https://doc.rust-lang.org/1.3.0/std/rt/unwind/fn.register.html) (in
28+
unstable code) the registration of a set of panic handlers. This API had
29+
several issues:
30+
31+
* The system supported a fixed but unspecified number of handlers, and a
32+
handler could never be unregistered once added.
33+
* The callbacks were raw function pointers rather than closures.
34+
* Handlers would be invoked on nested panics, which would result in a stack
35+
overflow if a handler itself panicked.
36+
* The callbacks were specified to take the panic message, file name and line
37+
number directly. This would prevent us from adding more functionality in
38+
the future, such as access to backtrace information. In addition, the
39+
presence of file names and line numbers for all panics causes some amount of
40+
binary bloat and we may want to add some avenue to allow for the omission of
41+
those values in the future.
42+
43+
# Detailed design
44+
45+
A new module, `std::panic`, will be created with a panic handling API:
46+
47+
```rust
48+
/// Unregisters the current panic handler, returning it.
49+
///
50+
/// If no custom handler is registered, the default handler will be returned.
51+
///
52+
/// # Panics
53+
///
54+
/// Panics if called from a panicking thread. Note that this will be a nested
55+
/// panic and therefore abort the process.
56+
pub fn take_handler() -> Box<Fn(&PanicInfo) + 'static + Sync + Send> { ... }
57+
58+
/// Registers a custom panic handler, replacing any that was previously
59+
/// registered.
60+
///
61+
/// # Panics
62+
///
63+
/// Panics if called from a panicking thread. Note that this will be a nested
64+
/// panic and therefore abort the process.
65+
pub fn set_handler<F>(handler: F) where F: Fn(&PanicInfo) + 'static + Sync + Send { ... }
66+
67+
/// A struct providing information about a panic.
68+
pub struct PanicInfo { ... }
69+
70+
impl PanicInfo {
71+
/// Returns the payload associated with the panic.
72+
///
73+
/// This will commonly, but not always, be a `&'static str` or `String`.
74+
pub fn payload(&self) -> &Any + Send { ... }
75+
76+
/// Returns information about the location from which the panic originated,
77+
/// if available.
78+
pub fn location(&self) -> Option<Location> { ... }
79+
}
80+
81+
/// A struct containing information about the location of a panic.
82+
pub struct Location<'a> { ... }
83+
84+
impl<'a> Location<'a> {
85+
/// Returns the name of the source file from which the panic originated.
86+
pub fn file(&self) -> &str { ... }
87+
88+
/// Returns the line number from which the panic originated.
89+
pub fn line(&self) -> u32 { ... }
90+
}
91+
```
92+
93+
When a panic occurs, but before unwinding begins, the runtime will call the
94+
registered panic handler. After the handler returns, the runtime will then
95+
unwind the thread. If a thread panics while panicking (a "double panic"), the
96+
panic handler will *not* be invoked and the process will abort. Note that the
97+
thread is considered to be panicking while the panic handler is running, so a
98+
panic originating from the panic handler will result in a double panic.
99+
100+
The `take_handler` method exists to allow for handlers to "chain" by closing
101+
over the previous handler and calling into it:
102+
103+
```rust
104+
let old_handler = panic::take_handler();
105+
panic::set_handler(move |info| {
106+
println!("uh oh!");
107+
old_handler(info);
108+
});
109+
```
110+
111+
This is obviously a racy operation, but as a single global resource, the global
112+
panic handler should only be adjusted by applications rather than libraries,
113+
most likely early in the startup process.
114+
115+
The implementation of `set_handler` and `take_handler` will have to be
116+
carefully synchronized to ensure that a handler is not replaced while executing
117+
in another thread. This can be accomplished in a manner similar to [that used
118+
by the `log`
119+
crate](https://github.com/rust-lang-nursery/log/blob/aa8618c840dd88b27c487c9fc9571d89751583f3/src/lib.rs).
120+
`take_handler` and `set_handler` will wait until no other threads are currently
121+
running the panic handler, at which point they will atomically swap the handler
122+
out as appropriate.
123+
124+
Note that `location` will always return `Some` in the current implementation.
125+
It returns an `Option` to hedge against possible future changes to the panic
126+
system that would allow a crate to be compiled with location metadata removed
127+
to minimize binary size.
128+
129+
## Prior Art
130+
131+
C++ has a
132+
[`std::set_terminate`](http://www.cplusplus.com/reference/exception/set_terminate/)
133+
function which registers a handler for uncaught exceptions, returning the old
134+
one. The handler takes no arguments.
135+
136+
Python passes uncaught exceptions to the global handler
137+
[`sys.excepthook`](https://docs.python.org/2/library/sys.html#sys.excepthook)
138+
which can be set by user code.
139+
140+
In Java, uncaught exceptions [can be
141+
handled](http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#setUncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler))
142+
by handlers registered on an individual `Thread`, by the `Thread`'s,
143+
`ThreadGroup`, and by a handler registered globally. The handlers are provided
144+
with the `Throwable` that triggered the handler.
145+
146+
# Drawbacks
147+
148+
The more infrastructure we add to interact with panics, the more attractive it
149+
becomes to use them as a more normal part of control flow.
150+
151+
# Alternatives
152+
153+
Panic handlers could be run after a panicking thread has unwound rather than
154+
before. This is perhaps a more intuitive arrangement, and allows `catch_panic`
155+
to prevent panic handlers from running. However, running handlers before
156+
unwinding allows them access to more context, for example, the ability to take
157+
a stack trace.
158+
159+
`PanicInfo::location` could be split into `PanicInfo::file` and
160+
`PanicInfo::line` to cut down on the API size, though that would require
161+
handlers to deal with weird cases like a line number but no file being
162+
available.
163+
164+
[RFC 1100](https://github.com/rust-lang/rfcs/pull/1100) proposed an API based
165+
around thread-local handlers. While there are reasonable use cases for the
166+
registration of custom handlers on a per-thread basis, most of the common uses
167+
for custom handlers want to have a single set of behavior cover all threads in
168+
the process. Being forced to remember to register a handler in every thread
169+
spawned in a program is tedious and error prone, and not even possible in many
170+
cases for threads spawned in libraries the author has no control over.
171+
172+
While out of scope for this RFC, a future extension could add thread-local
173+
handlers on top of the global one proposed here in a straightforward manner.
174+
175+
The implementation could be simplified by altering the API to store, and
176+
`take_logger` to return, an `Arc<Fn(&PanicInfo) + 'static + Sync + Send>` or
177+
a bare function pointer. This seems like a somewhat weirder API, however, and
178+
the implementation proposed above should not end up complex enough to justify
179+
the change.
180+
181+
# Unresolved questions
182+
183+
None at the moment.

0 commit comments

Comments
 (0)