From 9c6f4b6d1d57ef53886034b91f46e09f892a2851 Mon Sep 17 00:00:00 2001 From: Ruud van Asseldonk Date: Tue, 14 Apr 2015 18:27:41 +0200 Subject: [PATCH 1/5] rustc: Add long diagnostics for E0297 --- src/librustc/diagnostics.rs | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index b15304d6dc5..63d10a83751 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -112,6 +112,33 @@ reference when using guards or refactor the entire expression, perhaps by putting the condition inside the body of the arm. "##, +E0297: r##" +Patterns used to bind names must be irrefutable. That is, they must guarantee +that a name will be extracted in all cases. Instead of pattern matching the +loop variable, consider using a `match` or `if let` inside the loop body. For +instance: + +// This fails because `None` is not covered. +for Some(x) in xs { + ... +} + +// Match inside the loop instead: +for item in xs { + match item { + Some(x) => ... + None => ... + } +} + +// Or use `if let`: +for item in xs { + if let Some(x) = item { + ... + } +} +"##, + E0303: r##" In certain cases it is possible for sub-bindings to violate memory safety. Updates to the borrow checker in a future version of Rust may remove this @@ -194,7 +221,6 @@ register_diagnostics! { E0284, // cannot resolve type E0285, // overflow evaluation builtin bounds E0296, // malformed recursion limit attribute - E0297, // refutable pattern in for loop binding E0298, // mismatched types between arms E0299, // mismatched types between arms E0300, // unexpanded macro From ab1723b6704f31390a55a160955240aef817c8b3 Mon Sep 17 00:00:00 2001 From: Ruud van Asseldonk Date: Tue, 14 Apr 2015 19:31:42 +0200 Subject: [PATCH 2/5] rustc: Add long diagnostics for E0301 --- src/librustc/diagnostics.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 63d10a83751..3495f8eb160 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -139,6 +139,20 @@ for item in xs { } "##, +E0301: r##" +Mutable borrows are not allowed in pattern guards, because matching cannot have +side effects. Side effects could alter the matched object or the environment +on which the match depends in such a way, that the match would not be +exhaustive. For instance, the following would not match any arm if mutable +borrows were allowed: + +match Some(()) { + None => { }, + option if option.take().is_none() => { /* impossible, option is `Some` */ }, + Some(_) => { } // When the previous match failed, the option became `None`. +} +"##, + E0303: r##" In certain cases it is possible for sub-bindings to violate memory safety. Updates to the borrow checker in a future version of Rust may remove this @@ -224,7 +238,6 @@ register_diagnostics! { E0298, // mismatched types between arms E0299, // mismatched types between arms E0300, // unexpanded macro - E0301, // cannot mutable borrow in a pattern guard E0302, // cannot assign in a pattern guard E0304, // expected signed integer constant E0305, // expected constant From 48a376da18b27c787818eec18ad26ba96ebdff67 Mon Sep 17 00:00:00 2001 From: Ruud van Asseldonk Date: Tue, 14 Apr 2015 19:39:58 +0200 Subject: [PATCH 3/5] rustc: Add long diagnostics for E0302 --- src/librustc/diagnostics.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 3495f8eb160..7f77c0fceea 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -153,6 +153,20 @@ match Some(()) { } "##, +E0302: r##" +Assignments are not allowed in pattern guards, because matching cannot have +side effects. Side effects could alter the matched object or the environment +on which the match depends in such a way, that the match would not be +exhaustive. For instance, the following would not match any arm if assignments +were allowed: + +match Some(()) { + None => { }, + option if { option = None; false } { }, + Some(_) => { } // When the previous match failed, the option became `None`. +} +"##, + E0303: r##" In certain cases it is possible for sub-bindings to violate memory safety. Updates to the borrow checker in a future version of Rust may remove this @@ -238,7 +252,6 @@ register_diagnostics! { E0298, // mismatched types between arms E0299, // mismatched types between arms E0300, // unexpanded macro - E0302, // cannot assign in a pattern guard E0304, // expected signed integer constant E0305, // expected constant E0306, // expected positive integer for repeat count From c45eacdbc688708ccd4dd09c8bcfb513e5e5fead Mon Sep 17 00:00:00 2001 From: Ruud van Asseldonk Date: Tue, 14 Apr 2015 20:00:17 +0200 Subject: [PATCH 4/5] rustc: Add long diagnostics for E0162 --- src/librustc/diagnostics.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 7f77c0fceea..d4a1dd26660 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -112,6 +112,25 @@ reference when using guards or refactor the entire expression, perhaps by putting the condition inside the body of the arm. "##, +E0162: r##" +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; +foo(x); +"##, + E0297: r##" Patterns used to bind names must be irrefutable. That is, they must guarantee that a name will be extracted in all cases. Instead of pattern matching the @@ -220,7 +239,6 @@ register_diagnostics! { E0152, E0158, E0161, - E0162, E0165, E0170, E0261, // use of undeclared lifetime name From 33dca5e3ad376e7bd1fd618d5bbd0ed3a27840f8 Mon Sep 17 00:00:00 2001 From: Ruud van Asseldonk Date: Tue, 14 Apr 2015 20:11:04 +0200 Subject: [PATCH 5/5] rustc: Add long diagnostics for E0165 --- src/librustc/diagnostics.rs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index d4a1dd26660..938a74382e2 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -131,6 +131,26 @@ 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; + ... +} +"##, + E0297: r##" Patterns used to bind names must be irrefutable. That is, they must guarantee that a name will be extracted in all cases. Instead of pattern matching the @@ -239,7 +259,6 @@ register_diagnostics! { E0152, E0158, E0161, - E0165, E0170, E0261, // use of undeclared lifetime name E0262, // illegal lifetime parameter name