Set applicability for more suggestions.

This commit is contained in:
Sébastien Duquette 2018-08-19 15:01:33 -04:00
parent d2048b6db3
commit 5a23a0d283
8 changed files with 217 additions and 125 deletions

View File

@ -17,7 +17,7 @@ use rustc::ty;
use rustc_mir::util::borrowck_errors::{BorrowckErrors, Origin};
use syntax::ast;
use syntax_pos;
use errors::DiagnosticBuilder;
use errors::{DiagnosticBuilder, Applicability};
use borrowck::gather_loans::gather_moves::PatternSource;
pub struct MoveErrorCollector<'tcx> {
@ -80,9 +80,12 @@ fn report_move_errors<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, errors: &[MoveErr
let initializer =
e.init.as_ref().expect("should have an initializer to get an error");
if let Ok(snippet) = bccx.tcx.sess.source_map().span_to_snippet(initializer.span) {
err.span_suggestion(initializer.span,
"consider using a reference instead",
format!("&{}", snippet));
err.span_suggestion_with_applicability(
initializer.span,
"consider using a reference instead",
format!("&{}", snippet),
Applicability::MaybeIncorrect // using a reference may not be the right fix
);
}
}
_ => {

View File

@ -25,6 +25,7 @@ use syntax::symbol::keywords;
use syntax::visit::{self, Visitor};
use syntax_pos::Span;
use errors;
use errors::Applicability;
struct AstValidator<'a> {
session: &'a Session,
@ -185,11 +186,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
);
match val.node {
ExprKind::Lit(ref v) if v.node.is_numeric() => {
err.span_suggestion(
err.span_suggestion_with_applicability(
place.span.between(val.span),
"if you meant to write a comparison against a negative value, add a \
space in between `<` and `-`",
"< -".to_string(),
Applicability::MaybeIncorrect
);
}
_ => {}

View File

@ -38,6 +38,7 @@ use syntax::symbol::{Symbol, keywords};
use syntax::tokenstream::{TokenStream, TokenTree, Delimited};
use syntax::util::lev_distance::find_best_match_for_name;
use syntax_pos::{Span, DUMMY_SP};
use errors::Applicability;
use std::cell::Cell;
use std::mem;
@ -1000,9 +1001,19 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
if let Some(suggestion) = suggestion {
if suggestion != name {
if let MacroKind::Bang = kind {
err.span_suggestion(span, "you could try the macro", suggestion.to_string());
err.span_suggestion_with_applicability(
span,
"you could try the macro",
suggestion.to_string(),
Applicability::MaybeIncorrect
);
} else {
err.span_suggestion(span, "try", suggestion.to_string());
err.span_suggestion_with_applicability(
span,
"try",
suggestion.to_string(),
Applicability::MaybeIncorrect
);
}
} else {
err.help("have you added the `#[macro_use]` on the module/import?");
@ -1123,10 +1134,11 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
if let Some(span) = span {
let found_use = if found_use { "" } else { "\n" };
self.session.struct_span_err(err.use_span, err.warn_msg)
.span_suggestion(
.span_suggestion_with_applicability(
span,
"instead, import the procedural macro like any other item",
format!("use {}::{};{}", err.crate_name, err.name, found_use),
Applicability::MachineApplicable
).emit();
} else {
self.session.struct_span_err(err.use_span, err.warn_msg)

View File

@ -20,6 +20,7 @@ use rustc::ty::adjustment::{Adjustment, Adjust, AllowTwoPhase, AutoBorrow, AutoB
use rustc_target::spec::abi;
use syntax::ast::Ident;
use syntax_pos::Span;
use errors::Applicability;
use rustc::hir;
@ -234,10 +235,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
err.span_label(call_expr.span, "not a function");
if let Some(ref path) = unit_variant {
err.span_suggestion(call_expr.span,
&format!("`{}` is a unit variant, you need to write it \
without the parenthesis", path),
path.to_string());
err.span_suggestion_with_applicability(
call_expr.span,
&format!("`{}` is a unit variant, you need to write it \
without the parenthesis", path),
path.to_string(),
Applicability::MachineApplicable
);
}
if let hir::ExprKind::Call(ref expr, _) = call_expr.node {

View File

@ -21,7 +21,7 @@ use rustc::hir::map::{NodeItem, NodeExpr};
use rustc::hir::{Item, ItemKind, print};
use rustc::ty::{self, Ty, AssociatedItem};
use rustc::ty::adjustment::AllowTwoPhase;
use errors::{DiagnosticBuilder, SourceMapper};
use errors::{Applicability, DiagnosticBuilder, SourceMapper};
use super::method::probe;
@ -422,24 +422,31 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
match (found.bit_width(), exp.bit_width()) {
(Some(found), Some(exp)) if found > exp => {
if can_cast {
err.span_suggestion(expr.span,
&format!("{}, which {}", msg, will_truncate),
cast_suggestion);
err.span_suggestion_with_applicability(
expr.span,
&format!("{}, which {}", msg, will_truncate),
cast_suggestion,
Applicability::MaybeIncorrect // lossy conversion
);
}
}
(None, _) | (_, None) => {
if can_cast {
err.span_suggestion(expr.span,
&format!("{}, which {}",
msg,
depending_on_isize),
cast_suggestion);
err.span_suggestion_with_applicability(
expr.span,
&format!("{}, which {}", msg, depending_on_isize),
cast_suggestion,
Applicability::MaybeIncorrect // lossy conversion
);
}
}
_ => {
err.span_suggestion(expr.span,
&format!("{}, which {}", msg, will_sign_extend),
into_suggestion);
err.span_suggestion_with_applicability(
expr.span,
&format!("{}, which {}", msg, will_sign_extend),
into_suggestion,
Applicability::MachineApplicable
);
}
}
true
@ -448,24 +455,31 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
match (found.bit_width(), exp.bit_width()) {
(Some(found), Some(exp)) if found > exp => {
if can_cast {
err.span_suggestion(expr.span,
&format!("{}, which {}", msg, will_truncate),
cast_suggestion);
err.span_suggestion_with_applicability(
expr.span,
&format!("{}, which {}", msg, will_truncate),
cast_suggestion,
Applicability::MaybeIncorrect // lossy conversion
);
}
}
(None, _) | (_, None) => {
if can_cast {
err.span_suggestion(expr.span,
&format!("{}, which {}",
msg,
depending_on_usize),
cast_suggestion);
err.span_suggestion_with_applicability(
expr.span,
&format!("{}, which {}", msg, depending_on_usize),
cast_suggestion,
Applicability::MaybeIncorrect // lossy conversion
);
}
}
_ => {
err.span_suggestion(expr.span,
&format!("{}, which {}", msg, will_zero_extend),
into_suggestion);
err.span_suggestion_with_applicability(
expr.span,
&format!("{}, which {}", msg, will_zero_extend),
into_suggestion,
Applicability::MachineApplicable
);
}
}
true
@ -474,33 +488,44 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
if can_cast {
match (found.bit_width(), exp.bit_width()) {
(Some(found), Some(exp)) if found > exp - 1 => {
err.span_suggestion(expr.span,
&format!("{}, which {}", msg, will_truncate),
cast_suggestion);
err.span_suggestion_with_applicability(
expr.span,
&format!("{}, which {}", msg, will_truncate),
cast_suggestion,
Applicability::MaybeIncorrect // lossy conversion
);
}
(None, None) => {
err.span_suggestion(expr.span,
&format!("{}, which {}", msg, will_truncate),
cast_suggestion);
err.span_suggestion_with_applicability(
expr.span,
&format!("{}, which {}", msg, will_truncate),
cast_suggestion,
Applicability::MaybeIncorrect // lossy conversion
);
}
(None, _) => {
err.span_suggestion(expr.span,
&format!("{}, which {}",
msg,
depending_on_isize),
cast_suggestion);
err.span_suggestion_with_applicability(
expr.span,
&format!("{}, which {}", msg, depending_on_isize),
cast_suggestion,
Applicability::MaybeIncorrect // lossy conversion
);
}
(_, None) => {
err.span_suggestion(expr.span,
&format!("{}, which {}",
msg,
depending_on_usize),
cast_suggestion);
err.span_suggestion_with_applicability(
expr.span,
&format!("{}, which {}", msg, depending_on_usize),
cast_suggestion,
Applicability::MaybeIncorrect // lossy conversion
);
}
_ => {
err.span_suggestion(expr.span,
&format!("{}, which {}", msg, will_zero_extend),
cast_suggestion);
err.span_suggestion_with_applicability(
expr.span,
&format!("{}, which {}", msg, will_zero_extend),
cast_suggestion,
Applicability::MachineApplicable
);
}
}
}
@ -510,33 +535,44 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
if can_cast {
match (found.bit_width(), exp.bit_width()) {
(Some(found), Some(exp)) if found - 1 > exp => {
err.span_suggestion(expr.span,
&format!("{}, which {}", msg, will_truncate),
cast_suggestion);
err.span_suggestion_with_applicability(
expr.span,
&format!("{}, which {}", msg, will_truncate),
cast_suggestion,
Applicability::MaybeIncorrect // lossy conversion
);
}
(None, None) => {
err.span_suggestion(expr.span,
&format!("{}, which {}", msg, will_sign_extend),
cast_suggestion);
err.span_suggestion_with_applicability(
expr.span,
&format!("{}, which {}", msg, will_sign_extend),
cast_suggestion,
Applicability::MachineApplicable // lossy conversion
);
}
(None, _) => {
err.span_suggestion(expr.span,
&format!("{}, which {}",
msg,
depending_on_usize),
cast_suggestion);
err.span_suggestion_with_applicability(
expr.span,
&format!("{}, which {}", msg, depending_on_usize),
cast_suggestion,
Applicability::MaybeIncorrect // lossy conversion
);
}
(_, None) => {
err.span_suggestion(expr.span,
&format!("{}, which {}",
msg,
depending_on_isize),
cast_suggestion);
err.span_suggestion_with_applicability(
expr.span,
&format!("{}, which {}", msg, depending_on_isize),
cast_suggestion,
Applicability::MaybeIncorrect // lossy conversion
);
}
_ => {
err.span_suggestion(expr.span,
&format!("{}, which {}", msg, will_sign_extend),
cast_suggestion);
err.span_suggestion_with_applicability(
expr.span,
&format!("{}, which {}", msg, will_sign_extend),
cast_suggestion,
Applicability::MachineApplicable
);
}
}
}
@ -544,24 +580,30 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
(&ty::TyFloat(ref exp), &ty::TyFloat(ref found)) => {
if found.bit_width() < exp.bit_width() {
err.span_suggestion(expr.span,
&format!("{} in a lossless way",
msg),
into_suggestion);
err.span_suggestion_with_applicability(
expr.span,
&format!("{} in a lossless way", msg),
into_suggestion,
Applicability::MachineApplicable
);
} else if can_cast {
err.span_suggestion(expr.span,
&format!("{}, producing the closest possible value",
msg),
cast_suggestion);
err.span_suggestion_with_applicability(
expr.span,
&format!("{}, producing the closest possible value", msg),
cast_suggestion,
Applicability::MaybeIncorrect // lossy conversion
);
}
true
}
(&ty::TyUint(_), &ty::TyFloat(_)) | (&ty::TyInt(_), &ty::TyFloat(_)) => {
if can_cast {
err.span_suggestion(expr.span,
&format!("{}, rounding the float towards zero",
msg),
cast_suggestion);
err.span_suggestion_with_applicability(
expr.span,
&format!("{}, rounding the float towards zero", msg),
cast_suggestion,
Applicability::MaybeIncorrect // lossy conversion
);
err.warn("casting here will cause undefined behavior if the rounded value \
cannot be represented by the target integer type, including \
`Inf` and `NaN` (this is a bug and will be fixed)");
@ -571,36 +613,45 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
(&ty::TyFloat(ref exp), &ty::TyUint(ref found)) => {
// if `found` is `None` (meaning found is `usize`), don't suggest `.into()`
if exp.bit_width() > found.bit_width().unwrap_or(256) {
err.span_suggestion(expr.span,
&format!("{}, producing the floating point \
representation of the integer",
msg),
into_suggestion);
err.span_suggestion_with_applicability(
expr.span,
&format!("{}, producing the floating point representation of the \
integer",
msg),
into_suggestion,
Applicability::MachineApplicable
);
} else if can_cast {
err.span_suggestion(expr.span,
&format!("{}, producing the floating point \
representation of the integer, rounded if \
necessary",
msg),
cast_suggestion);
err.span_suggestion_with_applicability(expr.span,
&format!("{}, producing the floating point representation of the \
integer, rounded if necessary",
msg),
cast_suggestion,
Applicability::MaybeIncorrect // lossy conversion
);
}
true
}
(&ty::TyFloat(ref exp), &ty::TyInt(ref found)) => {
// if `found` is `None` (meaning found is `isize`), don't suggest `.into()`
if exp.bit_width() > found.bit_width().unwrap_or(256) {
err.span_suggestion(expr.span,
&format!("{}, producing the floating point \
representation of the integer",
msg),
into_suggestion);
err.span_suggestion_with_applicability(
expr.span,
&format!("{}, producing the floating point representation of the \
integer",
msg),
into_suggestion,
Applicability::MachineApplicable
);
} else if can_cast {
err.span_suggestion(expr.span,
&format!("{}, producing the floating point \
representation of the integer, rounded if \
necessary",
msg),
cast_suggestion);
err.span_suggestion_with_applicability(
expr.span,
&format!("{}, producing the floating point representation of the \
integer, rounded if necessary",
msg),
cast_suggestion,
Applicability::MaybeIncorrect // lossy conversion
);
}
true
}

View File

@ -102,7 +102,7 @@ use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoB
use rustc::ty::fold::TypeFoldable;
use rustc::ty::query::Providers;
use rustc::ty::util::{Representability, IntTypeExt, Discr};
use errors::{DiagnosticBuilder, DiagnosticId};
use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
use require_c_abi_if_variadic;
use session::{CompileIncomplete, config, Session};
@ -2675,10 +2675,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let sugg_span = tcx.sess.source_map().end_point(expr_sp);
// remove closing `)` from the span
let sugg_span = sugg_span.shrink_to_lo();
err.span_suggestion(
err.span_suggestion_with_applicability(
sugg_span,
"expected the unit value `()`; create it with empty parentheses",
String::from("()"));
String::from("()"),
Applicability::MachineApplicable);
} else {
err.span_label(sp, format!("expected {}{} parameter{}",
if variadic {"at least "} else {""},
@ -2940,7 +2941,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
self.tcx.sess.source_map().span_to_snippet(lhs.span),
self.tcx.sess.source_map().span_to_snippet(rhs.span))
{
err.span_suggestion(expr.span, msg, format!("{} == {}", left, right));
err.span_suggestion_with_applicability(
expr.span,
msg,
format!("{} == {}", left, right),
Applicability::MaybeIncorrect);
} else {
err.help(msg);
}
@ -4234,9 +4239,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
ast::LitIntType::Unsuffixed) = lit.node {
let snip = tcx.sess.source_map().span_to_snippet(base.span);
if let Ok(snip) = snip {
err.span_suggestion(expr.span,
"to access tuple elements, use",
format!("{}.{}", snip, i));
err.span_suggestion_with_applicability(
expr.span,
"to access tuple elements, use",
format!("{}.{}", snip, i),
Applicability::MachineApplicable);
needs_note = false;
}
}
@ -4674,9 +4681,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
hir::ExprKind::Match(..) |
hir::ExprKind::Block(..) => {
let sp = self.tcx.sess.source_map().next_point(cause_span);
err.span_suggestion(sp,
"try adding a semicolon",
";".to_string());
err.span_suggestion_with_applicability(
sp,
"try adding a semicolon",
";".to_string(),
Applicability::MachineApplicable);
}
_ => (),
}
@ -4705,10 +4714,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// haven't set a return type at all (and aren't `fn main()` or an impl).
match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_nil()) {
(&hir::FunctionRetTy::DefaultReturn(span), true, true, true) => {
err.span_suggestion(span,
"try adding a return type",
format!("-> {} ",
self.resolve_type_vars_with_obligations(found)));
err.span_suggestion_with_applicability(
span,
"try adding a return type",
format!("-> {} ", self.resolve_type_vars_with_obligations(found)),
Applicability::MachineApplicable);
}
(&hir::FunctionRetTy::DefaultReturn(span), false, true, true) => {
err.span_label(span, "possibly return type missing here?");
@ -4767,7 +4777,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
let original_span = original_sp(last_stmt.span, blk.span);
let span_semi = original_span.with_lo(original_span.hi() - BytePos(1));
err.span_suggestion(span_semi, "consider removing this semicolon", "".to_string());
err.span_suggestion_with_applicability(
span_semi,
"consider removing this semicolon",
"".to_string(),
Applicability::MachineApplicable);
}
// Instantiates the given path, which must refer to an item with the given

View File

@ -12,7 +12,7 @@
// http://www.unicode.org/Public/security/10.0.0/confusables.txt
use syntax_pos::{Span, NO_EXPANSION};
use errors::DiagnosticBuilder;
use errors::{Applicability, DiagnosticBuilder};
use super::StringReader;
const UNICODE_ARRAY: &[(char, &str, char)] = &[
@ -346,7 +346,11 @@ crate fn check_for_substitution<'a>(reader: &StringReader<'a>,
let msg =
format!("Unicode character '{}' ({}) looks like '{}' ({}), but it is not",
ch, u_name, ascii_char, ascii_name);
err.span_suggestion(span, &msg, ascii_char.to_string());
err.span_suggestion_with_applicability(
span,
&msg,
ascii_char.to_string(),
Applicability::MaybeIncorrect);
true
},
None => {

View File

@ -22,6 +22,7 @@ use syntax::ptr::P;
use syntax::symbol::Symbol;
use syntax::tokenstream;
use syntax_pos::{MultiSpan, Span, DUMMY_SP};
use errors::Applicability;
use std::borrow::Cow;
use std::collections::hash_map::Entry;
@ -791,10 +792,11 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
0 => "{}".to_string(),
_ => format!("{}{{}}", "{} ".repeat(args.len())),
};
err.span_suggestion(
err.span_suggestion_with_applicability(
fmt_sp.shrink_to_lo(),
"you might be missing a string literal to format with",
format!("\"{}\", ", sugg_fmt),
Applicability::MaybeIncorrect,
);
err.emit();
return DummyResult::raw_expr(sp);