From b48b509d89318bdbe85c6ffb37db63b1eca95c78 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Mon, 2 May 2016 09:27:21 +0200 Subject: [PATCH] typeck: show a note about tuple indexing for erroneous tup[i] Fixes: #27842 --- src/librustc_typeck/check/mod.rs | 25 ++++++++++++++++++++++++- src/test/compile-fail/issue-27842.rs | 24 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 src/test/compile-fail/issue-27842.rs diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 385f04b8564f5..1b35576a0ae3b 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 0000000000000..28050a2ee9083 --- /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 or the MIT license +// , 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`) +}