From 5a23a0d283653c79fd623b479b1e8e71d5eea093 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Duquette?= Date: Sun, 19 Aug 2018 15:01:33 -0400 Subject: [PATCH] Set applicability for more suggestions. --- .../borrowck/gather_loans/move_error.rs | 11 +- src/librustc_passes/ast_validation.rs | 4 +- src/librustc_resolve/macros.rs | 18 +- src/librustc_typeck/check/callee.rs | 12 +- src/librustc_typeck/check/demand.rs | 241 +++++++++++------- src/librustc_typeck/check/mod.rs | 44 ++-- src/libsyntax/parse/lexer/unicode_chars.rs | 8 +- src/libsyntax_ext/format.rs | 4 +- 8 files changed, 217 insertions(+), 125 deletions(-) diff --git a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs index e1c3ac839902f..87f2c7576a4e6 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs @@ -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 + ); } } _ => { diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 99ea62e80298c..ca7dcbcc307b8 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -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 ); } _ => {} diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 8f2e76d8866dd..0a33aae076be1 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -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) diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index ec127d26ab307..7f3aaa6792ffe 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -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 { diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 00cc36ecd428c..9ca8686eb226f 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -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 } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index b57967a7aab21..7c46cff890e43 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -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 diff --git a/src/libsyntax/parse/lexer/unicode_chars.rs b/src/libsyntax/parse/lexer/unicode_chars.rs index 88ff8582da801..03bf1b5a4e1ed 100644 --- a/src/libsyntax/parse/lexer/unicode_chars.rs +++ b/src/libsyntax/parse/lexer/unicode_chars.rs @@ -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 => { diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index d97c0b14f797a..a77feae2733f4 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -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);