Skip to content

Commit

Permalink
Update diagnostics.rs
Browse files Browse the repository at this point in the history
  • Loading branch information
GuillaumeGomez committed Apr 23, 2015
1 parent 79a402b commit 264d365
Showing 1 changed file with 98 additions and 76 deletions.
174 changes: 98 additions & 76 deletions src/librustc/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,13 @@ the following is invalid as it requires the entire Option<String> to be moved
into a variable called `op_string` while simultaneously requiring the inner
String to be moved into a variable called `s`.
let x = Some("s".to_string());
match x {
op_string @ Some(s) => ...
None => ...
}
```
let x = Some("s".to_string());
match x {
op_string @ Some(s) => ...
None => ...
}
```
See also Error 303.
"##,
Expand All @@ -90,10 +92,12 @@ name is bound by move in a pattern, it should also be moved to wherever it is
referenced in the pattern guard code. Doing so however would prevent the name
from being available in the body of the match arm. Consider the following:
match Some("hi".to_string()) {
Some(s) if s.len() == 0 => // use s.
...
}
```
match Some("hi".to_string()) {
Some(s) if s.len() == 0 => // use s.
...
}
```
The variable `s` has type String, and its use in the guard is as a variable of
type String. The guard code effectively executes in a separate scope to the body
Expand All @@ -102,11 +106,13 @@ become unavailable in the body of the arm. Although this example seems
innocuous, the problem is most clear when considering functions that take their
argument by value.
match Some("hi".to_string()) {
Some(s) if { drop(s); false } => (),
Some(s) => // use s.
...
}
```
match Some("hi".to_string()) {
Some(s) if { drop(s); false } => (),
Some(s) => // use s.
...
}
```
The value would be dropped in the guard then become unavailable not only in the
body of that arm but also in all subsequent arms! The solution is to bind by
Expand All @@ -123,37 +129,43 @@ This limitation may be removed in a future version of Rust.
Wrong example:
struct X { x: (), }
let x = Some((X { x: () }, X { x: () }));
match x {
Some((y, ref z)) => {},
None => panic!()
}
```
struct X { x: (), }
let x = Some((X { x: () }, X { x: () }));
match x {
Some((y, ref z)) => {},
None => panic!()
}
```
You have two solutions:
1. Bind the pattern's values the same way:
struct X { x: (), }
let x = Some((X { x: () }, X { x: () }));
match x {
Some((ref y, ref z)) => {},
// or Some((y, z)) => {}
None => panic!()
}
```
struct X { x: (), }
let x = Some((X { x: () }, X { x: () }));
match x {
Some((ref y, ref z)) => {},
// or Some((y, z)) => {}
None => panic!()
}
```
2. Implement the `Copy` trait for the X structure (however, please
keep in mind that the first solution should be preferred!):
#[derive(Clone, Copy)]
struct X { x: (), }
let x = Some((X { x: () }, X { x: () }));
match x {
Some((y, ref z)) => {},
None => panic!()
}
```
#[derive(Clone, Copy)]
struct X { x: (), }
let x = Some((X { x: () }, X { x: () }));
match x {
Some((y, ref z)) => {},
None => panic!()
}
```
"##,

E0015: r##"
Expand All @@ -175,8 +187,10 @@ them yourself.
You can build a free-standing crate by adding `#![no_std]` to the crate
attributes:
#![feature(no_std)]
#![no_std]
```
#![feature(no_std)]
#![no_std]
```
See also https://doc.rust-lang.org/book/no-stdlib.html
"##,
Expand All @@ -192,11 +206,13 @@ mutex can be declared `static` as well.
If you want to match against a `static`, consider using a guard instead:
static FORTY_TWO: i32 = 42;
match Some(42) {
Some(x) if x == FORTY_TWO => ...
...
}
```
static FORTY_TWO: i32 = 42;
match Some(42) {
Some(x) if x == FORTY_TWO => ...
...
}
```
"##,

E0161: r##"
Expand All @@ -212,54 +228,60 @@ An if-let pattern attempts to match the pattern, and enters the body if the
match was succesful. If the match is irrefutable (when it cannot fail to match),
use a regular `let`-binding instead. For instance:
struct Irrefutable(i32);
let irr = Irrefutable(0);
// This fails to compile because the match is irrefutable.
if let Irrefutable(x) = irr {
// This body will always be executed.
foo(x);
}
// Try this instead:
let Irrefutable(x) = irr;
```
struct Irrefutable(i32);
let irr = Irrefutable(0);
// This fails to compile because the match is irrefutable.
if let Irrefutable(x) = irr {
// This body will always be executed.
foo(x);
}
// Try this instead:
let Irrefutable(x) = irr;
foo(x);
```
"##,

E0165: r##"
A while-let pattern attempts to match the pattern, and enters the body if the
match was succesful. If the match is irrefutable (when it cannot fail to match),
use a regular `let`-binding inside a `loop` instead. For instance:
struct Irrefutable(i32);
let irr = Irrefutable(0);
// This fails to compile because the match is irrefutable.
while let Irrefutable(x) = irr {
...
}
// Try this instead:
loop {
let Irrefutable(x) = irr;
...
}
```
struct Irrefutable(i32);
let irr = Irrefutable(0);
// This fails to compile because the match is irrefutable.
while let Irrefutable(x) = irr {
...
}
// Try this instead:
loop {
let Irrefutable(x) = irr;
...
}
```
"##,

E0170: r##"
Enum variants are qualified by default. For example, given this type:
enum Method {
GET,
POST
}
```
enum Method {
GET,
POST
}
```
you would match it using:
match m {
Method::GET => ...
Method::POST => ...
}
match m {
Method::GET => ...
Method::POST => ...
}
If you don't qualify the names, the code will bind new variables named "GET" and
"POST" instead. This behavior is likely not what you want, so rustc warns when
Expand Down

0 comments on commit 264d365

Please sign in to comment.