Skip to content

Commit 98a0429

Browse files
committed
suggestion applicabilities for libsyntax and librustc, run-rustfix tests
Consider this a down payment on #50723. To recap, an `Applicability` enum was recently (#50204) added, to convey to Rustfix and other tools whether we think it's OK for them to blindly apply the suggestion, or whether to prompt a human for guidance (because the suggestion might contain placeholders that we can't infer, or because we think it has a sufficiently high probability of being wrong even though it's— presumably—right often enough to be worth emitting in the first place). When a suggestion is marked as `MaybeIncorrect`, we try to use comments to indicate precisely why (although there are a few places where we just say `// speculative` because the present author's subjective judgement balked at the idea that the suggestion has no false positives). The `run-rustfix` directive is opporunistically set on some relevant UI tests (and a couple tests that were in the `test/ui/suggestions` directory, even if the suggestions didn't originate in librustc or libsyntax). This is less trivial than it sounds, because a surprising number of test files aren't equipped to be tested as fixed even when they contain successfully fixable errors, because, e.g., there are more, not-directly-related errors after fixing. Some test files need an attribute or underscore to avoid unused warnings tripping up the "fixed code is still producing diagnostics" check despite the fixes being correct; this is an interesting contrast-to/inconsistency-with the behavior of UI tests (which secretly pass `-A unused`), a behavior which we probably ought to resolve one way or the other (filed issue #50926). A few suggestion labels are reworded (e.g., to avoid phrasing it as a question, which which is discouraged by the style guidelines listed in `.span_suggestion`'s doc-comment).
1 parent 6bb4aad commit 98a0429

33 files changed

+424
-117
lines changed

src/librustc/infer/error_reporting/mod.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ use ty::{self, Region, Ty, TyCtxt, TypeFoldable, TypeVariants};
7070
use ty::error::TypeError;
7171
use syntax::ast::DUMMY_NODE_ID;
7272
use syntax_pos::{Pos, Span};
73-
use errors::{DiagnosticBuilder, DiagnosticStyledString};
73+
use errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
7474

7575
use rustc_data_structures::indexed_vec::Idx;
7676

@@ -1097,7 +1097,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
10971097
if let Some((sp, has_lifetimes)) = type_param_span {
10981098
let tail = if has_lifetimes { " + " } else { "" };
10991099
let suggestion = format!("{}: {}{}", bound_kind, sub, tail);
1100-
err.span_suggestion_short(sp, consider, suggestion);
1100+
err.span_suggestion_short_with_applicability(
1101+
sp, consider, suggestion,
1102+
Applicability::MaybeIncorrect // Issue #41966
1103+
);
11011104
} else {
11021105
err.help(consider);
11031106
}

src/librustc/lint/levels.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
use std::cmp;
1212

13-
use errors::DiagnosticBuilder;
13+
use errors::{Applicability, DiagnosticBuilder};
1414
use hir::HirId;
1515
use ich::StableHashingContext;
1616
use lint::builtin;
@@ -265,10 +265,11 @@ impl<'a> LintLevelsBuilder<'a> {
265265
store.check_lint_name(&name_lower) {
266266
db.emit();
267267
} else {
268-
db.span_suggestion(
268+
db.span_suggestion_with_applicability(
269269
li.span,
270270
"lowercase the lint name",
271-
name_lower
271+
name_lower,
272+
Applicability::MachineApplicable
272273
).emit();
273274
}
274275
} else {

src/librustc/middle/liveness.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ use self::VarKind::*;
109109
use hir::def::*;
110110
use ty::{self, TyCtxt};
111111
use lint;
112+
use errors::Applicability;
112113
use util::nodemap::{NodeMap, NodeSet};
113114

114115
use std::collections::VecDeque;
@@ -1541,11 +1542,15 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
15411542
let mut err = self.ir.tcx
15421543
.struct_span_lint_node(lint::builtin::UNUSED_VARIABLES, id, sp, &msg);
15431544
if self.ir.variable_is_shorthand(var) {
1544-
err.span_suggestion(sp, "try ignoring the field",
1545-
format!("{}: _", name));
1545+
err.span_suggestion_with_applicability(sp, "try ignoring the field",
1546+
format!("{}: _", name),
1547+
Applicability::MachineApplicable);
15461548
} else {
1547-
err.span_suggestion_short(sp, &suggest_underscore_msg,
1548-
format!("_{}", name));
1549+
err.span_suggestion_short_with_applicability(
1550+
sp, &suggest_underscore_msg,
1551+
format!("_{}", name),
1552+
Applicability::MachineApplicable,
1553+
);
15491554
}
15501555
err.emit()
15511556
}

src/librustc/traits/error_reporting.rs

+22-13
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use super::{
2727
Overflow,
2828
};
2929

30-
use errors::DiagnosticBuilder;
30+
use errors::{Applicability, DiagnosticBuilder};
3131
use hir;
3232
use hir::def_id::DefId;
3333
use infer::{self, InferCtxt};
@@ -856,9 +856,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
856856
if let Some(ref expr) = local.init {
857857
if let hir::ExprIndex(_, _) = expr.node {
858858
if let Ok(snippet) = self.tcx.sess.codemap().span_to_snippet(expr.span) {
859-
err.span_suggestion(expr.span,
860-
"consider borrowing here",
861-
format!("&{}", snippet));
859+
err.span_suggestion_with_applicability(
860+
expr.span,
861+
"consider borrowing here",
862+
format!("&{}", snippet),
863+
Applicability::MachineApplicable
864+
);
862865
}
863866
}
864867
}
@@ -901,7 +904,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
901904
let format_str = format!("consider removing {} leading `&`-references",
902905
remove_refs);
903906

904-
err.span_suggestion_short(sp, &format_str, String::from(""));
907+
err.span_suggestion_short_with_applicability(
908+
sp, &format_str, String::from(""), Applicability::MachineApplicable
909+
);
905910
break;
906911
}
907912
} else {
@@ -1046,10 +1051,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
10461051
let sugg = fields.iter()
10471052
.map(|(name, _)| name.to_owned())
10481053
.collect::<Vec<String>>().join(", ");
1049-
err.span_suggestion(found_span,
1050-
"change the closure to take multiple arguments instead of \
1051-
a single tuple",
1052-
format!("|{}|", sugg));
1054+
err.span_suggestion_with_applicability(found_span,
1055+
"change the closure to take multiple \
1056+
arguments instead of a single tuple",
1057+
format!("|{}|", sugg),
1058+
Applicability::MachineApplicable);
10531059
}
10541060
}
10551061
if let &[ArgKind::Tuple(_, ref fields)] = &expected_args[..] {
@@ -1077,10 +1083,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
10771083
"".to_owned()
10781084
},
10791085
);
1080-
err.span_suggestion(found_span,
1081-
"change the closure to accept a tuple instead of \
1082-
individual arguments",
1083-
sugg);
1086+
err.span_suggestion_with_applicability(
1087+
found_span,
1088+
"change the closure to accept a tuple instead of \
1089+
individual arguments",
1090+
sugg,
1091+
Applicability::MachineApplicable
1092+
);
10841093
}
10851094
}
10861095
}

src/libsyntax/attr.rs

+13-7
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use ast::{MetaItem, MetaItemKind, NestedMetaItem, NestedMetaItemKind};
2020
use ast::{Lit, LitKind, Expr, ExprKind, Item, Local, Stmt, StmtKind};
2121
use codemap::{BytePos, Spanned, respan, dummy_spanned};
2222
use syntax_pos::Span;
23-
use errors::Handler;
23+
use errors::{Applicability, Handler};
2424
use feature_gate::{Features, GatedCfg};
2525
use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
2626
use parse::parser::Parser;
@@ -1067,14 +1067,20 @@ pub fn find_repr_attrs(diagnostic: &Handler, attr: &Attribute) -> Vec<ReprAttr>
10671067
"incorrect `repr(align)` attribute format");
10681068
match value.node {
10691069
ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => {
1070-
err.span_suggestion(item.span,
1071-
"use parentheses instead",
1072-
format!("align({})", int));
1070+
err.span_suggestion_with_applicability(
1071+
item.span,
1072+
"use parentheses instead",
1073+
format!("align({})", int),
1074+
Applicability::MachineApplicable
1075+
);
10731076
}
10741077
ast::LitKind::Str(s, _) => {
1075-
err.span_suggestion(item.span,
1076-
"use parentheses instead",
1077-
format!("align({})", s));
1078+
err.span_suggestion_with_applicability(
1079+
item.span,
1080+
"use parentheses instead",
1081+
format!("align({})", s),
1082+
Applicability::MachineApplicable
1083+
);
10781084
}
10791085
_ => {}
10801086
}

src/libsyntax/ext/expand.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use ast::{MacStmtStyle, StmtKind, ItemKind};
1313
use attr::{self, HasAttrs};
1414
use codemap::{ExpnInfo, NameAndSpan, MacroBang, MacroAttribute, dummy_spanned, respan};
1515
use config::{is_test_or_bench, StripUnconfigured};
16-
use errors::FatalError;
16+
use errors::{Applicability, FatalError};
1717
use ext::base::*;
1818
use ext::derive::{add_derived_markers, collect_derives};
1919
use ext::hygiene::{self, Mark, SyntaxContext};
@@ -331,7 +331,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
331331
let trait_list = traits.iter()
332332
.map(|t| format!("{}", t)).collect::<Vec<_>>();
333333
let suggestion = format!("#[derive({})]", trait_list.join(", "));
334-
err.span_suggestion(span, "try an outer attribute", suggestion);
334+
err.span_suggestion_with_applicability(
335+
span, "try an outer attribute", suggestion,
336+
// We don't 𝑘𝑛𝑜𝑤 that the following item is an ADT
337+
Applicability::MaybeIncorrect
338+
);
335339
}
336340
err.emit();
337341
}

src/libsyntax/parse/lexer/mod.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use ast::{self, Ident};
1212
use syntax_pos::{self, BytePos, CharPos, Pos, Span, NO_EXPANSION};
1313
use codemap::{CodeMap, FilePathMapping};
14-
use errors::{FatalError, DiagnosticBuilder};
14+
use errors::{Applicability, FatalError, DiagnosticBuilder};
1515
use parse::{token, ParseSess};
1616
use str::char_at;
1717
use symbol::{Symbol, keywords};
@@ -1345,11 +1345,12 @@ impl<'a> StringReader<'a> {
13451345
self.sess.span_diagnostic
13461346
.struct_span_err(span,
13471347
"character literal may only contain one codepoint")
1348-
.span_suggestion(span,
1349-
"if you meant to write a `str` literal, \
1350-
use double quotes",
1351-
format!("\"{}\"", &self.src[start..end]))
1352-
.emit();
1348+
.span_suggestion_with_applicability(
1349+
span,
1350+
"if you meant to write a `str` literal, use double quotes",
1351+
format!("\"{}\"", &self.src[start..end]),
1352+
Applicability::MachineApplicable
1353+
).emit();
13531354
return Ok(token::Literal(token::Str_(Symbol::intern("??")), None))
13541355
}
13551356
if self.ch_is('\n') || self.is_eof() || self.ch_is('/') {

0 commit comments

Comments
 (0)