about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-06-22 21:46:08 +0000
committerbors <bors@rust-lang.org>2017-06-22 21:46:08 +0000
commitbd62230fbdcaf6508dec02a59818f732bd4c1759 (patch)
tree0e546986ce54804d446f749f5800cbf3142d9b2a
parentab5bec25530aac43dfd64384b405c909b6e405e3 (diff)
parentee600642db3034743d3f8ae19abd639139d743dd (diff)
downloadrust-bd62230fbdcaf6508dec02a59818f732bd4c1759.tar.gz
rust-bd62230fbdcaf6508dec02a59818f732bd4c1759.zip
Auto merge of #42614 - GuillaumeGomez:new-error-codes, r=pnkfelix
New error codes

Part of #42229.

cc @Susurrus @frewsxcv @QuietMisdreavus
-rw-r--r--src/librustc_typeck/check/mod.rs76
-rw-r--r--src/librustc_typeck/diagnostics.rs247
-rw-r--r--src/test/compile-fail/E0611.rs22
-rw-r--r--src/test/compile-fail/E0612.rs16
-rw-r--r--src/test/compile-fail/E0613.rs16
-rw-r--r--src/test/compile-fail/E0614.rs14
-rw-r--r--src/test/compile-fail/E0615.rs22
-rw-r--r--src/test/compile-fail/E0616.rs24
-rw-r--r--src/test/compile-fail/struct-field-privacy.rs2
-rw-r--r--src/test/compile-fail/tuple-index-not-tuple.rs4
-rw-r--r--src/test/ui/macros/macro-backtrace-invalid-internals.stderr4
11 files changed, 401 insertions, 46 deletions
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index f7e23d28987..2bf24d5b350 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2950,8 +2950,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
         if let Some((did, field_ty)) = private_candidate {
             let struct_path = self.tcx().item_path_str(did);
-            let msg = format!("field `{}` of struct `{}` is private", field.node, struct_path);
-            let mut err = self.tcx().sess.struct_span_err(expr.span, &msg);
+            let mut err = struct_span_err!(self.tcx().sess, expr.span, E0616,
+                                           "field `{}` of struct `{}` is private",
+                                           field.node, struct_path);
             // Also check if an accessible method exists, which is often what is meant.
             if self.method_exists(field.span, field.node, expr_t, expr.id, false) {
                 err.note(&format!("a method `{}` also exists, perhaps you wish to call it",
@@ -2962,10 +2963,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         } else if field.node == keywords::Invalid.name() {
             self.tcx().types.err
         } else if self.method_exists(field.span, field.node, expr_t, expr.id, true) {
-            self.type_error_struct(field.span, |actual| {
-                format!("attempted to take value of method `{}` on type \
-                         `{}`", field.node, actual)
-            }, expr_t)
+            type_error_struct!(self.tcx().sess, field.span, expr_t, E0615,
+                              "attempted to take value of method `{}` on type `{}`",
+                              field.node, expr_t)
                 .help("maybe a `()` to call it is missing? \
                        If not, try an anonymous function")
                 .emit();
@@ -3080,27 +3080,22 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
         if let Some((did, field_ty)) = private_candidate {
             let struct_path = self.tcx().item_path_str(did);
-            let msg = format!("field `{}` of struct `{}` is private", idx.node, struct_path);
-            self.tcx().sess.span_err(expr.span, &msg);
+            struct_span_err!(self.tcx().sess, expr.span, E0611,
+                             "field `{}` of tuple-struct `{}` is private",
+                             idx.node, struct_path).emit();
             return field_ty;
         }
 
-        self.type_error_message(
-            expr.span,
-            |actual| {
-                if tuple_like {
-                    format!("attempted out-of-bounds tuple index `{}` on \
-                                    type `{}`",
-                                   idx.node,
-                                   actual)
-                } else {
-                    format!("attempted tuple index `{}` on type `{}`, but the \
-                                     type was not a tuple or tuple struct",
-                                    idx.node,
-                                    actual)
-                }
-            },
-            expr_t);
+        if tuple_like {
+            type_error_struct!(self.tcx().sess, expr.span, expr_t, E0612,
+                               "attempted out-of-bounds tuple index `{}` on type `{}`",
+                               idx.node, expr_t).emit();
+        } else {
+            type_error_struct!(self.tcx().sess, expr.span, expr_t, E0613,
+                               "attempted to access tuple index `{}` on type `{}`, but the type \
+                                was not a tuple or tuple struct",
+                               idx.node, expr_t).emit();
+        }
 
         self.tcx().types.err
     }
@@ -3201,10 +3196,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 field_type_hint = tcx.types.err;
                 if let Some(_) = variant.find_field_named(field.name.node) {
                     let mut err = struct_span_err!(self.tcx.sess,
-                                                field.name.span,
-                                                E0062,
-                                                "field `{}` specified more than once",
-                                                field.name.node);
+                                                   field.name.span,
+                                                   E0062,
+                                                   "field `{}` specified more than once",
+                                                   field.name.node);
 
                     err.span_label(field.name.span, "used more than once");
 
@@ -3251,15 +3246,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                         .join(", ");
 
             struct_span_err!(tcx.sess, span, E0063,
-                        "missing field{} {}{} in initializer of `{}`",
-                        if remaining_fields.len() == 1 {""} else {"s"},
-                        remaining_fields_names,
-                        truncated_fields_error,
-                        adt_ty)
-                        .span_label(span, format!("missing {}{}",
-                            remaining_fields_names,
-                            truncated_fields_error))
-                        .emit();
+                             "missing field{} {}{} in initializer of `{}`",
+                             if remaining_fields.len() == 1 { "" } else { "s" },
+                             remaining_fields_names,
+                             truncated_fields_error,
+                             adt_ty)
+                            .span_label(span, format!("missing {}{}",
+                                        remaining_fields_names,
+                                        truncated_fields_error))
+                            .emit();
         }
     }
 
@@ -3492,10 +3487,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                             oprnd_t = self.make_overloaded_lvalue_return_type(method).ty;
                             self.write_method_call(expr.id, method);
                         } else {
-                            self.type_error_message(expr.span, |actual| {
-                                format!("type `{}` cannot be \
-                                        dereferenced", actual)
-                            }, oprnd_t);
+                            type_error_struct!(tcx.sess, expr.span, oprnd_t, E0614,
+                                               "type `{}` cannot be dereferenced",
+                                               oprnd_t).emit();
                             oprnd_t = tcx.types.err;
                         }
                     }
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index f72af2084f0..a898a75d0c9 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -4174,6 +4174,253 @@ println!("x: {}, y: {}", variable.x, variable.y);
 For more information see The Rust Book: https://doc.rust-lang.org/book/
 "##,
 
+E0611: r##"
+Attempted to access a private field on a tuple-struct.
+
+Erroneous code example:
+
+```compile_fail,E0611
+mod some_module {
+    pub struct Foo(u32);
+
+    impl Foo {
+        pub fn new() -> Foo { Foo(0) }
+    }
+}
+
+let y = some_module::Foo::new();
+println!("{}", y.0); // error: field `0` of tuple-struct `some_module::Foo`
+                     //        is private
+```
+
+Since the field is private, you have two solutions:
+
+1) Make the field public:
+
+```
+mod some_module {
+    pub struct Foo(pub u32); // The field is now public.
+
+    impl Foo {
+        pub fn new() -> Foo { Foo(0) }
+    }
+}
+
+let y = some_module::Foo::new();
+println!("{}", y.0); // So we can access it directly.
+```
+
+2) Add a getter function to keep the field private but allow for accessing its
+value:
+
+```
+mod some_module {
+    pub struct Foo(u32);
+
+    impl Foo {
+        pub fn new() -> Foo { Foo(0) }
+
+        // We add the getter function.
+        pub fn get(&self) -> &u32 { &self.0 }
+    }
+}
+
+let y = some_module::Foo::new();
+println!("{}", y.get()); // So we can get the value through the function.
+```
+"##,
+
+E0612: r##"
+Attempted out-of-bounds tuple index.
+
+Erroneous code example:
+
+```compile_fail,E0612
+struct Foo(u32);
+
+let y = Foo(0);
+println!("{}", y.1); // error: attempted out-of-bounds tuple index `1`
+                     //        on type `Foo`
+```
+
+If a tuple/tuple-struct type has n fields, you can only try to access these n
+fields from 0 to (n - 1). So in this case, you can only index `0`. Example:
+
+```
+struct Foo(u32);
+
+let y = Foo(0);
+println!("{}", y.0); // ok!
+```
+"##,
+
+E0613: r##"
+Attempted tuple index on a type which isn't a tuple nor a tuple-struct.
+
+Erroneous code example:
+
+```compile_fail,E0613
+struct Foo;
+
+let y = Foo;
+println!("{}", y.1); // error: attempted to access tuple index `1` on type
+                     //        `Foo`, but the type was not a tuple or tuple
+                     //        struct
+```
+
+Only tuple and tuple-struct types can be indexed this way. Example:
+
+```
+// Let's create a tuple first:
+let x: (u32, u32, u32, u32) = (0, 1, 1, 2);
+// You can index its fields this way:
+println!("({}, {}, {}, {})", x.0, x.1, x.2, x.3);
+
+// Now let's declare a tuple-struct:
+struct TupleStruct(u32, u32, u32, u32);
+// Let's instantiate it:
+let x = TupleStruct(0, 1, 1, 2);
+// And just like the tuple:
+println!("({}, {}, {}, {})", x.0, x.1, x.2, x.3);
+```
+
+If you want to index into an array, use `[]` instead:
+
+```
+let x = &[0, 1, 1, 2];
+println!("[{}, {}, {}, {}]", x[0], x[1], x[2], x[3]);
+```
+
+If you want to access a field of a struct, check the field's name wasn't
+misspelled:
+
+```
+struct SomeStruct {
+    x: u32,
+    y: i32,
+}
+
+let s = SomeStruct {
+    x: 0,
+    y: -1,
+};
+println!("x: {} y: {}", s.x, s.y);
+```
+"##,
+
+E0614: r##"
+Attempted to dereference a variable which cannot be dereferenced.
+
+Erroneous code example:
+
+```compile_fail,E0614
+let y = 0u32;
+*y; // error: type `u32` cannot be dereferenced
+```
+
+Only types implementing `std::ops::Deref` can be dereferenced (such as `&T`).
+Example:
+
+```
+let y = 0u32;
+let x = &y;
+// So here, `x` is a `&u32`, so we can dereference it:
+*x; // ok!
+```
+"##,
+
+E0615: r##"
+Attempted to access a method like a field.
+
+Erroneous code example:
+
+```compile_fail,E0615
+struct Foo {
+    x: u32,
+}
+
+impl Foo {
+    fn method(&self) {}
+}
+
+let f = Foo { x: 0 };
+f.method; // error: attempted to take value of method `method` on type `Foo`
+```
+
+If you want to use a method, add `()` after it:
+
+```ignore
+f.method();
+```
+
+However, if you wanted to access a field of a struct check that the field name
+is spelled correctly. Example:
+
+```ignore
+println!("{}", f.x);
+```
+"##,
+
+E0616: r##"
+Attempted to access a private field on a struct.
+
+Erroneous code example:
+
+```compile_fail,E0616
+mod some_module {
+    pub struct Foo {
+        x: u32, // So `x` is private in here.
+    }
+
+    impl Foo {
+        pub fn new() -> Foo { Foo { x: 0 } }
+    }
+}
+
+let f = some_module::Foo::new();
+println!("{}", f.x); // error: field `x` of struct `some_module::Foo` is private
+```
+
+If you want to access this field, you have two options:
+
+1) Set the field public:
+
+```
+mod some_module {
+    pub struct Foo {
+        pub x: u32, // `x` is now public.
+    }
+
+    impl Foo {
+        pub fn new() -> Foo { Foo { x: 0 } }
+    }
+}
+
+let f = some_module::Foo::new();
+println!("{}", f.x); // ok!
+```
+
+2) Add a getter function:
+
+```
+mod some_module {
+    pub struct Foo {
+        x: u32, // So `x` is still private in here.
+    }
+
+    impl Foo {
+        pub fn new() -> Foo { Foo { x: 0 } }
+
+        // We create the getter function here:
+        pub fn get_x(&self) -> &u32 { &self.x }
+    }
+}
+
+let f = some_module::Foo::new();
+println!("{}", f.get_x()); // ok!
+```
+"##,
+
 E0617: r##"
 Attempted to pass an invalid type of variable into a variadic function.
 
diff --git a/src/test/compile-fail/E0611.rs b/src/test/compile-fail/E0611.rs
new file mode 100644
index 00000000000..1e392d194b1
--- /dev/null
+++ b/src/test/compile-fail/E0611.rs
@@ -0,0 +1,22 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+mod a {
+    pub struct Foo(u32);
+
+    impl Foo {
+        pub fn new() -> Foo { Foo(0) }
+    }
+}
+
+fn main() {
+   let y = a::Foo::new();
+   y.0; //~ ERROR E0611
+}
diff --git a/src/test/compile-fail/E0612.rs b/src/test/compile-fail/E0612.rs
new file mode 100644
index 00000000000..429a8bb7eb7
--- /dev/null
+++ b/src/test/compile-fail/E0612.rs
@@ -0,0 +1,16 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Foo(u32);
+
+fn main() {
+   let y = Foo(0);
+   y.1; //~ ERROR E0612
+}
diff --git a/src/test/compile-fail/E0613.rs b/src/test/compile-fail/E0613.rs
new file mode 100644
index 00000000000..189d1b1d3ba
--- /dev/null
+++ b/src/test/compile-fail/E0613.rs
@@ -0,0 +1,16 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Foo;
+
+fn main() {
+   let y = Foo;
+   y.1; //~ ERROR E0613
+}
diff --git a/src/test/compile-fail/E0614.rs b/src/test/compile-fail/E0614.rs
new file mode 100644
index 00000000000..909f0eb8285
--- /dev/null
+++ b/src/test/compile-fail/E0614.rs
@@ -0,0 +1,14 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let y = 0u32;
+    *y; //~ ERROR E0614
+}
diff --git a/src/test/compile-fail/E0615.rs b/src/test/compile-fail/E0615.rs
new file mode 100644
index 00000000000..abfa93d2fd0
--- /dev/null
+++ b/src/test/compile-fail/E0615.rs
@@ -0,0 +1,22 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Foo {
+    x: u32,
+}
+
+impl Foo {
+    fn method(&self) {}
+}
+
+fn main() {
+    let f = Foo { x: 0 };
+    f.method; //~ ERROR E0615
+}
diff --git a/src/test/compile-fail/E0616.rs b/src/test/compile-fail/E0616.rs
new file mode 100644
index 00000000000..2fd9f94763d
--- /dev/null
+++ b/src/test/compile-fail/E0616.rs
@@ -0,0 +1,24 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+mod a {
+    pub struct Foo {
+        x: u32,
+    }
+
+    impl Foo {
+        pub fn new() -> Foo { Foo { x: 0 } }
+    }
+}
+
+fn main() {
+    let f = a::Foo::new();
+    f.x; //~ ERROR E0616
+}
diff --git a/src/test/compile-fail/struct-field-privacy.rs b/src/test/compile-fail/struct-field-privacy.rs
index f487ef62aa4..5b2e04e25a9 100644
--- a/src/test/compile-fail/struct-field-privacy.rs
+++ b/src/test/compile-fail/struct-field-privacy.rs
@@ -42,7 +42,7 @@ fn test(a: A, b: inner::A, c: inner::B, d: xc::A, e: xc::B, z: inner::Z) {
     e.b; //~ ERROR: field `b` of struct `xc::B` is private
 
     z.0;
-    z.1; //~ ERROR: field `1` of struct `inner::Z` is private
+    z.1; //~ ERROR: field `1` of tuple-struct `inner::Z` is private
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/tuple-index-not-tuple.rs b/src/test/compile-fail/tuple-index-not-tuple.rs
index bf2a63abbfd..26decccdcd8 100644
--- a/src/test/compile-fail/tuple-index-not-tuple.rs
+++ b/src/test/compile-fail/tuple-index-not-tuple.rs
@@ -14,7 +14,7 @@ struct Empty;
 fn main() {
     let origin = Point { x: 0, y: 0 };
     origin.0;
-    //~^ ERROR attempted tuple index `0` on type `Point`, but the type was not
+    //~^ ERROR attempted to access tuple index `0` on type `Point`, but the type was not
     Empty.0;
-    //~^ ERROR attempted tuple index `0` on type `Empty`, but the type was not
+    //~^ ERROR attempted to access tuple index `0` on type `Empty`, but the type was not
 }
diff --git a/src/test/ui/macros/macro-backtrace-invalid-internals.stderr b/src/test/ui/macros/macro-backtrace-invalid-internals.stderr
index 95db694a0c6..5ed4ab4552a 100644
--- a/src/test/ui/macros/macro-backtrace-invalid-internals.stderr
+++ b/src/test/ui/macros/macro-backtrace-invalid-internals.stderr
@@ -16,7 +16,7 @@ error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
 51 |     fake_field_stmt!();
    |     ------------------- in this macro invocation
 
-error: attempted tuple index `0` on type `{integer}`, but the type was not a tuple or tuple struct
+error[E0613]: attempted to access tuple index `0` on type `{integer}`, but the type was not a tuple or tuple struct
   --> $DIR/macro-backtrace-invalid-internals.rs:27:11
    |
 27 |           (1).0
@@ -43,7 +43,7 @@ error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
 55 |     let _ = fake_field_expr!();
    |             ------------------ in this macro invocation
 
-error: attempted tuple index `0` on type `{integer}`, but the type was not a tuple or tuple struct
+error[E0613]: attempted to access tuple index `0` on type `{integer}`, but the type was not a tuple or tuple struct
   --> $DIR/macro-backtrace-invalid-internals.rs:45:11
    |
 45 |           (1).0