Skip to content

Commit cb7a127

Browse files
committed
Rollup merge of #24542 - michaelsproul:rollup, r=alexcrichton
I did a manual merge of all the extended error PRs as we were getting merge conflicts yesterday. I think this is preferable to merging separately as I ended up having to manually merge @nham and @GuillaumeGomez's commits. Rollup of #24458, #24482 and #24488. #24482 and #24488 were already re-approved, and would need to be cancelled if this is merged instead.
2 parents 93d8ba2 + 50f75f3 commit cb7a127

File tree

2 files changed

+117
-19
lines changed

2 files changed

+117
-19
lines changed

src/librustc/diagnostics.rs

Lines changed: 96 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,17 @@ underscore `_` wildcard pattern can be added after all other patterns to match
5555

5656
// FIXME: Remove duplication here?
5757
E0005: r##"
58-
Patterns used to bind names must be irrefutable, that is, they must guarantee that a
59-
name will be extracted in all cases. If you encounter this error you probably need
60-
to use a `match` or `if let` to deal with the possibility of failure.
58+
Patterns used to bind names must be irrefutable, that is, they must guarantee
59+
that a name will be extracted in all cases. If you encounter this error you
60+
probably need to use a `match` or `if let` to deal with the possibility of
61+
failure.
6162
"##,
6263

6364
E0006: r##"
64-
Patterns used to bind names must be irrefutable, that is, they must guarantee that a
65-
name will be extracted in all cases. If you encounter this error you probably need
66-
to use a `match` or `if let` to deal with the possibility of failure.
65+
Patterns used to bind names must be irrefutable, that is, they must guarantee
66+
that a name will be extracted in all cases. If you encounter this error you
67+
probably need to use a `match` or `if let` to deal with the possibility of
68+
failure.
6769
"##,
6870

6971
E0007: r##"
@@ -112,6 +114,65 @@ reference when using guards or refactor the entire expression, perhaps by
112114
putting the condition inside the body of the arm.
113115
"##,
114116

117+
E0009: r##"
118+
In a pattern, all values that don't implement the `Copy` trait have to be bound
119+
the same way. The goal here is to avoid binding simultaneously by-move and
120+
by-ref.
121+
122+
This limitation may be removed in a future version of Rust.
123+
124+
Wrong example:
125+
126+
```
127+
struct X { x: (), }
128+
129+
let x = Some((X { x: () }, X { x: () }));
130+
match x {
131+
Some((y, ref z)) => {},
132+
None => panic!()
133+
}
134+
```
135+
136+
You have two solutions:
137+
1. Bind the pattern's values the same way:
138+
139+
```
140+
struct X { x: (), }
141+
142+
let x = Some((X { x: () }, X { x: () }));
143+
match x {
144+
Some((ref y, ref z)) => {},
145+
// or Some((y, z)) => {}
146+
None => panic!()
147+
}
148+
```
149+
150+
2. Implement the `Copy` trait for the X structure (however, please
151+
keep in mind that the first solution should be preferred!):
152+
153+
```
154+
#[derive(Clone, Copy)]
155+
struct X { x: (), }
156+
157+
let x = Some((X { x: () }, X { x: () }));
158+
match x {
159+
Some((y, ref z)) => {},
160+
None => panic!()
161+
}
162+
```
163+
"##,
164+
165+
E0015: r##"
166+
The only function calls allowed in static or constant expressions are enum
167+
variant constructors or struct constructors (for unit or tuple structs). This
168+
is because Rust currently does not support compile-time function execution.
169+
"##,
170+
171+
E0020: r##"
172+
This error indicates that an attempt was made to divide by zero (or take the
173+
remainder of a zero divisor) in a static or constant expression.
174+
"##,
175+
115176
E0152: r##"
116177
Lang items are already implemented in the standard library. Unless you are
117178
writing a free-standing application (e.g. a kernel), you do not need to provide
@@ -217,6 +278,26 @@ use Method::*;
217278
enum Method { GET, POST }
218279
"##,
219280

281+
E0267: r##"
282+
This error indicates the use of loop keyword (break or continue) inside a
283+
closure but outside of any loop. Break and continue can be used as normal
284+
inside closures as long as they are also contained within a loop. To halt the
285+
execution of a closure you should instead use a return statement.
286+
"##,
287+
288+
E0268: r##"
289+
This error indicates the use of loop keyword (break or continue) outside of a
290+
loop. Without a loop to break out of or continue in, no sensible action can be
291+
taken.
292+
"##,
293+
294+
E0296: r##"
295+
This error indicates that the given recursion limit could not be parsed. Ensure
296+
that the value provided is a positive integer between quotes, like so:
297+
298+
#![recursion_limit="1000"]
299+
"##,
300+
220301
E0297: r##"
221302
Patterns used to bind names must be irrefutable. That is, they must guarantee
222303
that a name will be extracted in all cases. Instead of pattern matching the
@@ -277,21 +358,23 @@ In certain cases it is possible for sub-bindings to violate memory safety.
277358
Updates to the borrow checker in a future version of Rust may remove this
278359
restriction, but for now patterns must be rewritten without sub-bindings.
279360
280-
// Code like this...
281-
match Some(5) {
282-
ref op_num @ Some(num) => ...
361+
// Before.
362+
match Some("hi".to_string()) {
363+
ref op_string_ref @ Some(ref s) => ...
283364
None => ...
284365
}
285366
286-
// ... should be updated to code like this.
287-
match Some(5) {
288-
Some(num) => {
289-
let op_num = &Some(num);
367+
// After.
368+
match Some("hi".to_string()) {
369+
Some(ref s) => {
370+
let op_string_ref = &Some(&s);
290371
...
291372
}
292373
None => ...
293374
}
294375
376+
The `op_string_ref` binding has type &Option<&String> in both cases.
377+
295378
See also https://github.com/rust-lang/rust/issues/14587
296379
"##,
297380

@@ -308,18 +391,15 @@ a compile-time constant.
308391
}
309392

310393
register_diagnostics! {
311-
E0009,
312394
E0010,
313395
E0011,
314396
E0012,
315397
E0013,
316398
E0014,
317-
E0015,
318399
E0016,
319400
E0017,
320401
E0018,
321402
E0019,
322-
E0020,
323403
E0022,
324404
E0079, // enum variant: expected signed integer constant
325405
E0080, // enum variant: constant evaluation error
@@ -338,8 +418,6 @@ register_diagnostics! {
338418
E0264, // unknown external lang item
339419
E0265, // recursive constant
340420
E0266, // expected item
341-
E0267, // thing inside of a closure
342-
E0268, // thing outside of a loop
343421
E0269, // not all control paths return a value
344422
E0270, // computation may converge in a function marked as diverging
345423
E0271, // type mismatch resolving
@@ -357,7 +435,6 @@ register_diagnostics! {
357435
E0283, // cannot resolve type
358436
E0284, // cannot resolve type
359437
E0285, // overflow evaluation builtin bounds
360-
E0296, // malformed recursion limit attribute
361438
E0298, // mismatched types between arms
362439
E0299, // mismatched types between arms
363440
E0300, // unexpanded macro

src/libsyntax/diagnostics/plugin.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ use parse::token;
2020
use ptr::P;
2121
use util::small_vector::SmallVector;
2222

23+
// Maximum width of any line in an extended error description (inclusive).
24+
const MAX_DESCRIPTION_WIDTH: usize = 80;
25+
2326
thread_local! {
2427
static REGISTERED_DIAGNOSTICS: RefCell<BTreeMap<Name, Option<Name>>> = {
2528
RefCell::new(BTreeMap::new())
@@ -92,6 +95,24 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt,
9295
}
9396
_ => unreachable!()
9497
};
98+
// Check that the description starts and ends with a newline and doesn't
99+
// overflow the maximum line width.
100+
description.map(|raw_msg| {
101+
let msg = raw_msg.as_str();
102+
if !msg.starts_with("\n") || !msg.ends_with("\n") {
103+
ecx.span_err(span, &format!(
104+
"description for error code {} doesn't start and end with a newline",
105+
token::get_ident(*code)
106+
));
107+
}
108+
if msg.lines().any(|line| line.len() > MAX_DESCRIPTION_WIDTH) {
109+
ecx.span_err(span, &format!(
110+
"description for error code {} contains a line longer than {} characters",
111+
token::get_ident(*code), MAX_DESCRIPTION_WIDTH
112+
));
113+
}
114+
raw_msg
115+
});
95116
with_registered_diagnostics(|diagnostics| {
96117
if diagnostics.insert(code.name, description).is_some() {
97118
ecx.span_err(span, &format!(

0 commit comments

Comments
 (0)