about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/ty/mod.rs18
-rw-r--r--src/librustc_typeck/check/mod.rs49
-rw-r--r--src/librustc_typeck/diagnostics.rs36
-rw-r--r--src/test/compile-fail/E0610.rs14
-rw-r--r--src/test/compile-fail/attempted-access-non-fatal.rs4
-rw-r--r--src/test/compile-fail/issue-24363.rs2
-rw-r--r--src/test/compile-fail/parse-error-correct.rs2
-rw-r--r--src/test/ui/macros/macro-backtrace-invalid-internals.stderr4
8 files changed, 98 insertions, 31 deletions
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index afa2da3d561..eea767cd868 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -465,6 +465,24 @@ impl<'tcx> Hash for TyS<'tcx> {
     }
 }
 
+impl<'tcx> TyS<'tcx> {
+    pub fn is_primitive_ty(&self) -> bool {
+        match self.sty {
+            TypeVariants::TyBool |
+                TypeVariants::TyChar |
+                TypeVariants::TyInt(_) |
+                TypeVariants::TyUint(_) |
+                TypeVariants::TyFloat(_) |
+                TypeVariants::TyInfer(InferTy::IntVar(_)) |
+                TypeVariants::TyInfer(InferTy::FloatVar(_)) |
+                TypeVariants::TyInfer(InferTy::FreshIntTy(_)) |
+                TypeVariants::TyInfer(InferTy::FreshFloatTy(_)) => true,
+            TypeVariants::TyRef(_, x) => x.ty.is_primitive_ty(),
+            _ => false,
+        }
+    }
+}
+
 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::TyS<'tcx> {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 9f0ee92930d..60bf321277c 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2921,29 +2921,34 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 .emit();
             self.tcx().types.err
         } else {
-            let mut err = type_error_struct!(self.tcx().sess, field.span, expr_t, E0609,
-                                             "no field `{}` on type `{}`",
-                                             field.node, expr_t);
-            match expr_t.sty {
-                ty::TyAdt(def, _) if !def.is_enum() => {
-                    if let Some(suggested_field_name) =
-                        Self::suggest_field_name(def.struct_variant(), field, vec![]) {
-                            err.span_label(field.span,
-                                           format!("did you mean `{}`?", suggested_field_name));
-                        } else {
-                            err.span_label(field.span,
-                                           "unknown field");
-                        };
-                }
-                ty::TyRawPtr(..) => {
-                    err.note(&format!("`{0}` is a native pointer; perhaps you need to deref with \
-                                      `(*{0}).{1}`",
-                                      self.tcx.hir.node_to_pretty_string(base.id),
-                                      field.node));
+            if !expr_t.is_primitive_ty() {
+                let mut err = type_error_struct!(self.tcx().sess, field.span, expr_t, E0609,
+                                                 "no field `{}` on type `{}`",
+                                                 field.node, expr_t);
+                match expr_t.sty {
+                    ty::TyAdt(def, _) if !def.is_enum() => {
+                        if let Some(suggested_field_name) =
+                            Self::suggest_field_name(def.struct_variant(), field, vec![]) {
+                                err.span_label(field.span,
+                                               format!("did you mean `{}`?", suggested_field_name));
+                            } else {
+                                err.span_label(field.span, "unknown field");
+                            };
+                    }
+                    ty::TyRawPtr(..) => {
+                        err.note(&format!("`{0}` is a native pointer; perhaps you need to deref \
+                                           with `(*{0}).{1}`",
+                                          self.tcx.hir.node_to_pretty_string(base.id),
+                                          field.node));
+                    }
+                    _ => {}
                 }
-                _ => {}
-            }
-            err.emit();
+                err
+            } else {
+                type_error_struct!(self.tcx().sess, field.span, expr_t, E0610,
+                                   "`{}` is a primitive type and therefore doesn't have fields",
+                                   expr_t)
+            }.emit();
             self.tcx().types.err
         }
     }
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index 4f1eb929b8e..6ccfab0a324 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -4096,7 +4096,7 @@ assert_eq!(!Question::No, true);
 "##,
 
 E0609: r##"
-An attempt to access a non-existent field in a struct was performed.
+Attempted to access a non-existent field in a struct.
 
 Erroneous code example:
 
@@ -4109,8 +4109,8 @@ let s = StructWithFields { x: 0 };
 println!("{}", s.foo); // error: no field `foo` on type `StructWithFields`
 ```
 
-To fix this error, check if you didn't misspell the field's name or that the
-field actually exist. Example:
+To fix this error, check that you didn't misspell the field's name or that the
+field actually exists. Example:
 
 ```
 struct StructWithFields {
@@ -4122,6 +4122,36 @@ println!("{}", s.x); // ok!
 ```
 "##,
 
+E0610: r##"
+Attempted to access a field on a primitive type.
+
+Erroneous code example:
+
+```compile_fail,E0610
+let x: u32 = 0;
+println!("{}", x.foo); // error: `{integer}` is a primitive type, therefore
+                       //        doesn't have fields
+```
+
+Primitive types are the most basic types available in Rust and don't have
+fields. To access data via named fields, struct types are used. Example:
+
+```
+// We declare struct called `Foo` containing two fields:
+struct Foo {
+    x: u32,
+    y: i64,
+}
+
+// We create an instance of this struct:
+let variable = Foo { x: 0, y: -12 };
+// And we can now access its fields:
+println!("x: {}, y: {}", variable.x, variable.y);
+```
+
+For more information see The Rust Book: https://doc.rust-lang.org/book/
+"##,
+
 }
 
 register_diagnostics! {
diff --git a/src/test/compile-fail/E0610.rs b/src/test/compile-fail/E0610.rs
new file mode 100644
index 00000000000..522d8b0b943
--- /dev/null
+++ b/src/test/compile-fail/E0610.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 x = 0;
+    let _ = x.foo; //~ ERROR E0610
+}
diff --git a/src/test/compile-fail/attempted-access-non-fatal.rs b/src/test/compile-fail/attempted-access-non-fatal.rs
index fe8e793ed78..3d6c46f5ce3 100644
--- a/src/test/compile-fail/attempted-access-non-fatal.rs
+++ b/src/test/compile-fail/attempted-access-non-fatal.rs
@@ -11,6 +11,6 @@
 // Check that bogus field access is non-fatal
 fn main() {
     let x = 0;
-    let _ = x.foo; //~ no field `foo` on type `{integer}`
-    let _ = x.bar; //~ no field `bar` on type `{integer}`
+    let _ = x.foo; //~ `{integer}` is a primitive type and therefore doesn't have fields [E0610]
+    let _ = x.bar; //~ `{integer}` is a primitive type and therefore doesn't have fields [E0610]
 }
diff --git a/src/test/compile-fail/issue-24363.rs b/src/test/compile-fail/issue-24363.rs
index 03cae6e64ef..619ad74ad00 100644
--- a/src/test/compile-fail/issue-24363.rs
+++ b/src/test/compile-fail/issue-24363.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 fn main() {
-    1.create_a_type_error[ //~ no field `create_a_type_error` on type `{integer}`
+    1.create_a_type_error[ //~ `{integer}` is a primitive type and therefore doesn't have fields
         ()+() //~ ERROR binary operation `+` cannot be applied
               //   ^ ensure that we typeck the inner expression ^
     ];
diff --git a/src/test/compile-fail/parse-error-correct.rs b/src/test/compile-fail/parse-error-correct.rs
index 17b58a9f7c2..7dedfcf2727 100644
--- a/src/test/compile-fail/parse-error-correct.rs
+++ b/src/test/compile-fail/parse-error-correct.rs
@@ -17,5 +17,5 @@ fn main() {
     let y = 42;
     let x = y.;  //~ ERROR unexpected token
     let x = y.();  //~ ERROR unexpected token
-    let x = y.foo; //~ ERROR no field
+    let x = y.foo; //~ ERROR `{integer}` is a primitive type and therefore doesn't have fields [E061
 }
diff --git a/src/test/ui/macros/macro-backtrace-invalid-internals.stderr b/src/test/ui/macros/macro-backtrace-invalid-internals.stderr
index 9694783b08b..95db694a0c6 100644
--- a/src/test/ui/macros/macro-backtrace-invalid-internals.stderr
+++ b/src/test/ui/macros/macro-backtrace-invalid-internals.stderr
@@ -7,7 +7,7 @@ error[E0599]: no method named `fake` found for type `{integer}` in the current s
 50 |     fake_method_stmt!();
    |     -------------------- in this macro invocation
 
-error[E0609]: no field `fake` on type `{integer}`
+error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
   --> $DIR/macro-backtrace-invalid-internals.rs:21:13
    |
 21 |           1.fake
@@ -34,7 +34,7 @@ error[E0599]: no method named `fake` found for type `{integer}` in the current s
 54 |     let _ = fake_method_expr!();
    |             ------------------- in this macro invocation
 
-error[E0609]: no field `fake` on type `{integer}`
+error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
   --> $DIR/macro-backtrace-invalid-internals.rs:39:13
    |
 39 |           1.fake