about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_typeck/check/mod.rs25
-rw-r--r--src/test/compile-fail/issue-27842.rs24
2 files changed, 48 insertions, 1 deletions
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 385f04b8564..1b35576a0ae 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3687,7 +3687,7 @@ fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                   }
                   None => {
                       check_expr_has_type(fcx, &idx, fcx.tcx().types.err);
-                      fcx.type_error_message(
+                      let mut err = fcx.type_error_struct(
                           expr.span,
                           |actual| {
                               format!("cannot index a value of type `{}`",
@@ -3695,6 +3695,29 @@ fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                           },
                           base_t,
                           None);
+                      // Try to give some advice about indexing tuples.
+                      if let ty::TyTuple(_) = base_t.sty {
+                          let mut needs_note = true;
+                          // If the index is an integer, we can show the actual
+                          // fixed expression:
+                          if let hir::ExprLit(ref lit) = idx.node {
+                              if let ast::LitKind::Int(i, ast::LitIntType::Unsuffixed) = lit.node {
+                                  let snip = fcx.tcx().sess.codemap().span_to_snippet(base.span);
+                                  if let Ok(snip) = snip {
+                                      err.span_suggestion(expr.span,
+                                                          "to access tuple elements, use tuple \
+                                                           indexing syntax as shown",
+                                                          format!("{}.{}", snip, i));
+                                      needs_note = false;
+                                  }
+                              }
+                          }
+                          if needs_note {
+                              err.help("to access tuple elements, use tuple indexing \
+                                        syntax (e.g. `tuple.0`)");
+                          }
+                      }
+                      err.emit();
                       fcx.write_ty(id, fcx.tcx().types.err);
                   }
               }
diff --git a/src/test/compile-fail/issue-27842.rs b/src/test/compile-fail/issue-27842.rs
new file mode 100644
index 00000000000..28050a2ee90
--- /dev/null
+++ b/src/test/compile-fail/issue-27842.rs
@@ -0,0 +1,24 @@
+// Copyright 2016 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 tup = (0, 1, 2);
+    // the case where we show a suggestion
+    let _ = tup[0];
+    //~^ ERROR cannot index a value of type
+    //~| HELP to access tuple elements, use tuple indexing syntax as shown
+    //~| SUGGESTION let _ = tup.0
+
+    // the case where we show just a general hint
+    let i = 0_usize;
+    let _ = tup[i];
+    //~^ ERROR cannot index a value of type
+    //~| HELP to access tuple elements, use tuple indexing syntax (e.g. `tuple.0`)
+}