about summary refs log tree commit diff
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2015-04-18 23:29:57 +0530
committerManish Goregaokar <manishsmail@gmail.com>2015-04-18 23:29:57 +0530
commitcb7a12757b9f9214c2b5f38437bf6c717f83eca5 (patch)
tree0b00d1548a63cc00d341f6e2cfa22f00944eb743
parent93d8ba29066c8c81185e54a6d686d18165faa6e8 (diff)
parent50f75f3e2a4b8cb5451acb15f8d469a222dafbf4 (diff)
downloadrust-cb7a12757b9f9214c2b5f38437bf6c717f83eca5.tar.gz
rust-cb7a12757b9f9214c2b5f38437bf6c717f83eca5.zip
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.
-rw-r--r--src/librustc/diagnostics.rs115
-rw-r--r--src/libsyntax/diagnostics/plugin.rs21
2 files changed, 117 insertions, 19 deletions
diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs
index e1eb8d74186..306d2cd102f 100644
--- a/src/librustc/diagnostics.rs
+++ b/src/librustc/diagnostics.rs
@@ -55,15 +55,17 @@ underscore `_` wildcard pattern can be added after all other patterns to match
 
 // FIXME: Remove duplication here?
 E0005: r##"
-Patterns used to bind names must be irrefutable, that is, they must guarantee that a
-name will be extracted in all cases. If you encounter this error you probably need
-to use a `match` or `if let` to deal with the possibility of failure.
+Patterns used to bind names must be irrefutable, that is, they must guarantee
+that a name will be extracted in all cases. If you encounter this error you
+probably need to use a `match` or `if let` to deal with the possibility of
+failure.
 "##,
 
 E0006: r##"
-Patterns used to bind names must be irrefutable, that is, they must guarantee that a
-name will be extracted in all cases. If you encounter this error you probably need
-to use a `match` or `if let` to deal with the possibility of failure.
+Patterns used to bind names must be irrefutable, that is, they must guarantee
+that a name will be extracted in all cases. If you encounter this error you
+probably need to use a `match` or `if let` to deal with the possibility of
+failure.
 "##,
 
 E0007: r##"
@@ -112,6 +114,65 @@ reference when using guards or refactor the entire expression, perhaps by
 putting the condition inside the body of the arm.
 "##,
 
+E0009: r##"
+In a pattern, all values that don't implement the `Copy` trait have to be bound
+the same way. The goal here is to avoid binding simultaneously by-move and
+by-ref.
+
+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!()
+}
+```
+
+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!()
+}
+```
+
+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!()
+}
+```
+"##,
+
+E0015: r##"
+The only function calls allowed in static or constant expressions are enum
+variant constructors or struct constructors (for unit or tuple structs). This
+is because Rust currently does not support compile-time function execution.
+"##,
+
+E0020: r##"
+This error indicates that an attempt was made to divide by zero (or take the
+remainder of a zero divisor) in a static or constant expression.
+"##,
+
 E0152: r##"
 Lang items are already implemented in the standard library. Unless you are
 writing a free-standing application (e.g. a kernel), you do not need to provide
@@ -217,6 +278,26 @@ use Method::*;
 enum Method { GET, POST }
 "##,
 
+E0267: r##"
+This error indicates the use of loop keyword (break or continue) inside a
+closure but outside of any loop. Break and continue can be used as normal
+inside closures as long as they are also contained within a loop. To halt the
+execution of a closure you should instead use a return statement.
+"##,
+
+E0268: r##"
+This error indicates the use of loop keyword (break or continue) outside of a
+loop. Without a loop to break out of or continue in, no sensible action can be
+taken.
+"##,
+
+E0296: r##"
+This error indicates that the given recursion limit could not be parsed. Ensure
+that the value provided is a positive integer between quotes, like so:
+
+#![recursion_limit="1000"]
+"##,
+
 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
@@ -277,21 +358,23 @@ 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
 restriction, but for now patterns must be rewritten without sub-bindings.
 
-// Code like this...
-match Some(5) {
-    ref op_num @ Some(num) => ...
+// Before.
+match Some("hi".to_string()) {
+    ref op_string_ref @ Some(ref s) => ...
     None => ...
 }
 
-// ... should be updated to code like this.
-match Some(5) {
-    Some(num) => {
-        let op_num = &Some(num);
+// After.
+match Some("hi".to_string()) {
+    Some(ref s) => {
+        let op_string_ref = &Some(&s);
         ...
     }
     None => ...
 }
 
+The `op_string_ref` binding has type &Option<&String> in both cases.
+
 See also https://github.com/rust-lang/rust/issues/14587
 "##,
 
@@ -308,18 +391,15 @@ a compile-time constant.
 }
 
 register_diagnostics! {
-    E0009,
     E0010,
     E0011,
     E0012,
     E0013,
     E0014,
-    E0015,
     E0016,
     E0017,
     E0018,
     E0019,
-    E0020,
     E0022,
     E0079, // enum variant: expected signed integer constant
     E0080, // enum variant: constant evaluation error
@@ -338,8 +418,6 @@ register_diagnostics! {
     E0264, // unknown external lang item
     E0265, // recursive constant
     E0266, // expected item
-    E0267, // thing inside of a closure
-    E0268, // thing outside of a loop
     E0269, // not all control paths return a value
     E0270, // computation may converge in a function marked as diverging
     E0271, // type mismatch resolving
@@ -357,7 +435,6 @@ register_diagnostics! {
     E0283, // cannot resolve type
     E0284, // cannot resolve type
     E0285, // overflow evaluation builtin bounds
-    E0296, // malformed recursion limit attribute
     E0298, // mismatched types between arms
     E0299, // mismatched types between arms
     E0300, // unexpanded macro
diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs
index 59fe3658437..6fcf39f0b17 100644
--- a/src/libsyntax/diagnostics/plugin.rs
+++ b/src/libsyntax/diagnostics/plugin.rs
@@ -20,6 +20,9 @@ use parse::token;
 use ptr::P;
 use util::small_vector::SmallVector;
 
+// Maximum width of any line in an extended error description (inclusive).
+const MAX_DESCRIPTION_WIDTH: usize = 80;
+
 thread_local! {
     static REGISTERED_DIAGNOSTICS: RefCell<BTreeMap<Name, Option<Name>>> = {
         RefCell::new(BTreeMap::new())
@@ -92,6 +95,24 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt,
         }
         _ => unreachable!()
     };
+    // Check that the description starts and ends with a newline and doesn't
+    // overflow the maximum line width.
+    description.map(|raw_msg| {
+        let msg = raw_msg.as_str();
+        if !msg.starts_with("\n") || !msg.ends_with("\n") {
+            ecx.span_err(span, &format!(
+                "description for error code {} doesn't start and end with a newline",
+                token::get_ident(*code)
+            ));
+        }
+        if msg.lines().any(|line| line.len() > MAX_DESCRIPTION_WIDTH) {
+            ecx.span_err(span, &format!(
+                "description for error code {} contains a line longer than {} characters",
+                token::get_ident(*code), MAX_DESCRIPTION_WIDTH
+            ));
+        }
+        raw_msg
+    });
     with_registered_diagnostics(|diagnostics| {
         if diagnostics.insert(code.name, description).is_some() {
             ecx.span_err(span, &format!(