about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2018-01-21 18:18:52 -0800
committerEsteban Küber <esteban@kuber.com.ar>2018-01-22 15:46:49 -0800
commit9adf2b2225af5f4766709b93da463bfb951ca955 (patch)
tree602ee426ece1fbbe99026d25c00e61df5a754d5d
parentae920dcc98c9b18b38aac03367f7f1cd6dce7d2d (diff)
downloadrust-9adf2b2225af5f4766709b93da463bfb951ca955.tar.gz
rust-9adf2b2225af5f4766709b93da463bfb951ca955.zip
Add `--explain` for extended error explanations
-rw-r--r--src/librustc/session/config.rs2
-rw-r--r--src/librustc_typeck/check/mod.rs19
2 files changed, 18 insertions, 3 deletions
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index cd4e3cfed7a..b5e19d6aad8 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -1122,6 +1122,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
           "treat all errors that occur as bugs"),
     external_macro_backtrace: bool = (false, parse_bool, [UNTRACKED],
           "show macro backtraces even for non-local macros"),
+    explain: bool = (false, parse_bool, [TRACKED],
+          "show extended diagnostic help"),
     continue_parse_after_error: bool = (false, parse_bool, [TRACKED],
           "attempt to recover from parse errors (experimental)"),
     incremental: Option<String> = (None, parse_opt_string, [UNTRACKED],
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index cb8ce8d5ac3..67b1a04d54f 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2591,9 +2591,22 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         // arguments which we skipped above.
         if variadic {
             fn variadic_error<'tcx>(s: &Session, span: Span, t: Ty<'tcx>, cast_ty: &str) {
-                type_error_struct!(s, span, t, E0617,
-                                   "can't pass `{}` to variadic function, cast to `{}`",
-                                   t, cast_ty).emit();
+                let mut err = type_error_struct!(
+                    s, span, t, E0617, "can't pass `{}` to variadic function", t);
+                if s.opts.debugging_opts.explain {
+                    err.note(&format!("certain types, like `{}`, must be cast before passing them \
+                                       to a variadic function, because of arcane ABI rules \
+                                       dictated by the C standard",
+                                      t));
+                }
+                if let Ok(snippet) = s.codemap().span_to_snippet(span) {
+                    err.span_suggestion(span,
+                                        &format!("cast the value to `{}`", cast_ty),
+                                        format!("{} as {}", snippet, cast_ty));
+                } else {
+                    err.help(&format!("cast the value to `{}`", cast_ty));
+                }
+                err.emit();
             }
 
             for arg in args.iter().skip(expected_arg_count) {