1
Fork 0

review comments

This commit is contained in:
Esteban Küber 2019-10-03 13:22:18 -07:00
parent f1499a8646
commit 02f57f83a9
7 changed files with 81 additions and 41 deletions

View file

@ -298,9 +298,13 @@ impl Diagnostic {
/// * may contain a name of a function, variable, or type, but not whole expressions /// * may contain a name of a function, variable, or type, but not whole expressions
/// ///
/// See `CodeSuggestion` for more information. /// See `CodeSuggestion` for more information.
pub fn span_suggestion(&mut self, sp: Span, msg: &str, pub fn span_suggestion(
suggestion: String, &mut self,
applicability: Applicability) -> &mut Self { sp: Span,
msg: &str,
suggestion: String,
applicability: Applicability,
) -> &mut Self {
self.suggestions.push(CodeSuggestion { self.suggestions.push(CodeSuggestion {
substitutions: vec![Substitution { substitutions: vec![Substitution {
parts: vec![SubstitutionPart { parts: vec![SubstitutionPart {
@ -315,10 +319,35 @@ impl Diagnostic {
self self
} }
pub fn span_suggestion_verbose(
&mut self,
sp: Span,
msg: &str,
suggestion: String,
applicability: Applicability,
) -> &mut Self {
self.suggestions.push(CodeSuggestion {
substitutions: vec![Substitution {
parts: vec![SubstitutionPart {
snippet: suggestion,
span: sp,
}],
}],
msg: msg.to_owned(),
style: SuggestionStyle::ShowAlways,
applicability,
});
self
}
/// Prints out a message with multiple suggested edits of the code. /// Prints out a message with multiple suggested edits of the code.
pub fn span_suggestions(&mut self, sp: Span, msg: &str, pub fn span_suggestions(
suggestions: impl Iterator<Item = String>, applicability: Applicability) -> &mut Self &mut self,
{ sp: Span,
msg: &str,
suggestions: impl Iterator<Item = String>,
applicability: Applicability,
) -> &mut Self {
self.suggestions.push(CodeSuggestion { self.suggestions.push(CodeSuggestion {
substitutions: suggestions.map(|snippet| Substitution { substitutions: suggestions.map(|snippet| Substitution {
parts: vec![SubstitutionPart { parts: vec![SubstitutionPart {

View file

@ -221,7 +221,9 @@ pub trait Emitter {
// when this style is set we want the suggestion to be a message, not inline // when this style is set we want the suggestion to be a message, not inline
sugg.style != SuggestionStyle::HideCodeAlways && sugg.style != SuggestionStyle::HideCodeAlways &&
// trivial suggestion for tooling's sake, never shown // trivial suggestion for tooling's sake, never shown
sugg.style != SuggestionStyle::CompletelyHidden sugg.style != SuggestionStyle::CompletelyHidden &&
// subtle suggestion, never shown inline
sugg.style != SuggestionStyle::ShowAlways
{ {
let substitution = &sugg.substitutions[0].parts[0].snippet.trim(); let substitution = &sugg.substitutions[0].parts[0].snippet.trim();
let msg = if substitution.len() == 0 || sugg.style.hide_inline() { let msg = if substitution.len() == 0 || sugg.style.hide_inline() {

View file

@ -81,6 +81,8 @@ pub enum SuggestionStyle {
/// This will *not* show the code if the suggestion is inline *and* the suggested code is /// This will *not* show the code if the suggestion is inline *and* the suggested code is
/// empty. /// empty.
ShowCode, ShowCode,
/// Always show the suggested code independently.
ShowAlways,
} }
impl SuggestionStyle { impl SuggestionStyle {

View file

@ -17,8 +17,7 @@ use syntax_pos::{Span, DUMMY_SP, MultiSpan, SpanSnippetError};
use log::{debug, trace}; use log::{debug, trace};
use std::mem; use std::mem;
const TURBOFISH: &'static str = "use the \"turbofish\" `::<...>` instead of `<...>` to specify \ const TURBOFISH: &'static str = "use `::<...>` instead of `<...>` to specify type arguments";
type arguments";
/// Creates a placeholder argument. /// Creates a placeholder argument.
crate fn dummy_arg(ident: Ident) -> Param { crate fn dummy_arg(ident: Ident) -> Param {
let pat = P(Pat { let pat = P(Pat {
@ -585,7 +584,7 @@ impl<'a> Parser<'a> {
); );
let suggest = |err: &mut DiagnosticBuilder<'_>| { let suggest = |err: &mut DiagnosticBuilder<'_>| {
err.span_suggestion( err.span_suggestion_verbose(
op_span.shrink_to_lo(), op_span.shrink_to_lo(),
TURBOFISH, TURBOFISH,
"::".to_string(), "::".to_string(),
@ -647,29 +646,16 @@ impl<'a> Parser<'a> {
// We have high certainty that this was a bad turbofish at this point. // We have high certainty that this was a bad turbofish at this point.
// `foo< bar >(` // `foo< bar >(`
suggest(&mut err); suggest(&mut err);
let snapshot = self.clone();
self.bump(); // `(`
// Consume the fn call arguments. // Consume the fn call arguments.
let modifiers = [ match self.consume_fn_args() {
(token::OpenDelim(token::Paren), 1), Err(()) => Err(err),
(token::CloseDelim(token::Paren), -1), Ok(()) => {
]; err.emit();
self.consume_tts(1, &modifiers[..]); // FIXME: actually check that the two expressions in the binop are
// paths and resynthesize new fn call expression instead of using
if self.token.kind == token::Eof { // `ExprKind::Err` placeholder.
// Not entirely sure now, but we bubble the error up with the mk_err_expr(self, lhs.span.to(self.prev_span))
// suggestion. }
mem::replace(self, snapshot);
Err(err)
} else {
// 99% certain that the suggestion is correct, continue parsing.
err.emit();
// FIXME: actually check that the two expressions in the binop are
// paths and resynthesize new fn call expression instead of using
// `ExprKind::Err` placeholder.
mk_err_expr(self, lhs.span.to(self.prev_span))
} }
} else { } else {
// All we know is that this is `foo < bar >` and *nothing* else. Try to // All we know is that this is `foo < bar >` and *nothing* else. Try to
@ -687,6 +673,27 @@ impl<'a> Parser<'a> {
Ok(None) Ok(None)
} }
fn consume_fn_args(&mut self) -> Result<(), ()> {
let snapshot = self.clone();
self.bump(); // `(`
// Consume the fn call arguments.
let modifiers = [
(token::OpenDelim(token::Paren), 1),
(token::CloseDelim(token::Paren), -1),
];
self.consume_tts(1, &modifiers[..]);
if self.token.kind == token::Eof {
// Not entirely sure that what we consumed were fn arguments, rollback.
mem::replace(self, snapshot);
Err(())
} else {
// 99% certain that the suggestion is correct, continue parsing.
Ok(())
}
}
crate fn maybe_report_ambiguous_plus( crate fn maybe_report_ambiguous_plus(
&mut self, &mut self,
allow_plus: bool, allow_plus: bool,

View file

@ -3,7 +3,7 @@ error: chained comparison operators require parentheses
| |
LL | (0..13).collect<Vec<i32>>(); LL | (0..13).collect<Vec<i32>>();
| ^^^^^ | ^^^^^
help: use the "turbofish" `::<...>` instead of `<...>` to specify type arguments help: use `::<...>` instead of `<...>` to specify type arguments
| |
LL | (0..13).collect::<Vec<i32>>(); LL | (0..13).collect::<Vec<i32>>();
| ^^ | ^^
@ -13,7 +13,7 @@ error: chained comparison operators require parentheses
| |
LL | Vec<i32>::new(); LL | Vec<i32>::new();
| ^^^^^ | ^^^^^
help: use the "turbofish" `::<...>` instead of `<...>` to specify type arguments help: use `::<...>` instead of `<...>` to specify type arguments
| |
LL | Vec::<i32>::new(); LL | Vec::<i32>::new();
| ^^ | ^^
@ -23,7 +23,7 @@ error: chained comparison operators require parentheses
| |
LL | (0..13).collect<Vec<i32>(); LL | (0..13).collect<Vec<i32>();
| ^^^^^ | ^^^^^
help: use the "turbofish" `::<...>` instead of `<...>` to specify type arguments help: use `::<...>` instead of `<...>` to specify type arguments
| |
LL | (0..13).collect::<Vec<i32>(); LL | (0..13).collect::<Vec<i32>();
| ^^ | ^^

View file

@ -12,15 +12,15 @@ fn main() {
f<X>(); f<X>();
//~^ ERROR chained comparison operators require parentheses //~^ ERROR chained comparison operators require parentheses
//~| HELP use the "turbofish" `::<...>` instead of `<...>` to specify type arguments //~| HELP use `::<...>` instead of `<...>` to specify type arguments
f<Result<Option<X>, Option<Option<X>>>(1, 2); f<Result<Option<X>, Option<Option<X>>>(1, 2);
//~^ ERROR chained comparison operators require parentheses //~^ ERROR chained comparison operators require parentheses
//~| HELP use the "turbofish" `::<...>` instead of `<...>` to specify type arguments //~| HELP use `::<...>` instead of `<...>` to specify type arguments
use std::convert::identity; use std::convert::identity;
let _ = identity<u8>; let _ = identity<u8>;
//~^ ERROR chained comparison operators require parentheses //~^ ERROR chained comparison operators require parentheses
//~| HELP use the "turbofish" `::<...>` instead of `<...>` to specify type arguments //~| HELP use `::<...>` instead of `<...>` to specify type arguments
//~| HELP or use `(...)` if you meant to specify fn arguments //~| HELP or use `(...)` if you meant to specify fn arguments
} }

View file

@ -15,7 +15,7 @@ error: chained comparison operators require parentheses
| |
LL | f<X>(); LL | f<X>();
| ^^^ | ^^^
help: use the "turbofish" `::<...>` instead of `<...>` to specify type arguments help: use `::<...>` instead of `<...>` to specify type arguments
| |
LL | f::<X>(); LL | f::<X>();
| ^^ | ^^
@ -25,7 +25,7 @@ error: chained comparison operators require parentheses
| |
LL | f<Result<Option<X>, Option<Option<X>>>(1, 2); LL | f<Result<Option<X>, Option<Option<X>>>(1, 2);
| ^^^^^^^^ | ^^^^^^^^
help: use the "turbofish" `::<...>` instead of `<...>` to specify type arguments help: use `::<...>` instead of `<...>` to specify type arguments
| |
LL | f::<Result<Option<X>, Option<Option<X>>>(1, 2); LL | f::<Result<Option<X>, Option<Option<X>>>(1, 2);
| ^^ | ^^
@ -36,7 +36,7 @@ error: chained comparison operators require parentheses
LL | let _ = identity<u8>; LL | let _ = identity<u8>;
| ^^^^ | ^^^^
| |
= help: use the "turbofish" `::<...>` instead of `<...>` to specify type arguments = help: use `::<...>` instead of `<...>` to specify type arguments
= help: or use `(...)` if you meant to specify fn arguments = help: or use `(...)` if you meant to specify fn arguments
error[E0308]: mismatched types error[E0308]: mismatched types