mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-21 17:52:12 +03:00
Bring attention to suggestions when the only difference is capitalization
This commit is contained in:
@@ -49,6 +49,10 @@ fn emit_diagnostic(&mut self, db: &Diagnostic) {
|
||||
&suggestions);
|
||||
}
|
||||
|
||||
fn source_map(&self) -> Option<&Lrc<SourceMapperDyn>> {
|
||||
self.source_map.as_ref()
|
||||
}
|
||||
|
||||
fn should_show_explain(&self) -> bool {
|
||||
!self.short_message
|
||||
}
|
||||
|
||||
@@ -192,6 +192,8 @@ fn should_show_explain(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn source_map(&self) -> Option<&Lrc<SourceMapperDyn>>;
|
||||
|
||||
/// Formats the substitutions of the primary_span
|
||||
///
|
||||
/// The are a lot of conditions to this method, but in short:
|
||||
@@ -204,7 +206,7 @@ fn should_show_explain(&self) -> bool {
|
||||
/// we return the original `primary_span` and the original suggestions.
|
||||
fn primary_span_formatted<'a>(
|
||||
&mut self,
|
||||
db: &'a Diagnostic
|
||||
db: &'a Diagnostic,
|
||||
) -> (MultiSpan, &'a [CodeSuggestion]) {
|
||||
let mut primary_span = db.span.clone();
|
||||
if let Some((sugg, rest)) = db.suggestions.split_first() {
|
||||
@@ -234,7 +236,20 @@ fn primary_span_formatted<'a>(
|
||||
format!("help: {}", sugg.msg)
|
||||
} else {
|
||||
// Show the default suggestion text with the substitution
|
||||
format!("help: {}: `{}`", sugg.msg, substitution)
|
||||
format!(
|
||||
"help: {}{}: `{}`",
|
||||
sugg.msg,
|
||||
if self.source_map().as_ref().map(|sm| substitution.to_lowercase() == sm
|
||||
.span_to_snippet(sugg.substitutions[0].parts[0].span)
|
||||
.unwrap()
|
||||
.to_lowercase()).unwrap_or(false)
|
||||
{
|
||||
" (notice the capitalization)"
|
||||
} else {
|
||||
""
|
||||
},
|
||||
substitution,
|
||||
)
|
||||
};
|
||||
primary_span.push_span_label(sugg.substitutions[0].parts[0].span, msg);
|
||||
|
||||
@@ -382,6 +397,10 @@ fn fix_multispan_in_std_macros(&self,
|
||||
}
|
||||
|
||||
impl Emitter for EmitterWriter {
|
||||
fn source_map(&self) -> Option<&Lrc<SourceMapperDyn>> {
|
||||
self.sm.as_ref()
|
||||
}
|
||||
|
||||
fn emit_diagnostic(&mut self, db: &Diagnostic) {
|
||||
let mut children = db.children.clone();
|
||||
let (mut primary_span, suggestions) = self.primary_span_formatted(&db);
|
||||
@@ -1461,7 +1480,9 @@ fn emit_suggestion_default(
|
||||
let suggestions = suggestion.splice_lines(&**sm);
|
||||
|
||||
let mut row_num = 2;
|
||||
for &(ref complete, ref parts) in suggestions.iter().take(MAX_SUGGESTIONS) {
|
||||
let mut notice_capitalization = false;
|
||||
for (complete, parts, only_capitalization) in suggestions.iter().take(MAX_SUGGESTIONS) {
|
||||
notice_capitalization |= only_capitalization;
|
||||
// Only show underline if the suggestion spans a single line and doesn't cover the
|
||||
// entirety of the code output. If you have multiple replacements in the same line
|
||||
// of code, show the underline.
|
||||
@@ -1552,7 +1573,10 @@ fn emit_suggestion_default(
|
||||
}
|
||||
if suggestions.len() > MAX_SUGGESTIONS {
|
||||
let msg = format!("and {} other candidates", suggestions.len() - MAX_SUGGESTIONS);
|
||||
buffer.puts(row_num, 0, &msg, Style::NoStyle);
|
||||
buffer.puts(row_num, max_line_num_len + 3, &msg, Style::NoStyle);
|
||||
} else if notice_capitalization {
|
||||
let msg = "notice the capitalization difference";
|
||||
buffer.puts(row_num, max_line_num_len + 3, &msg, Style::NoStyle);
|
||||
}
|
||||
emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?;
|
||||
Ok(())
|
||||
|
||||
+21
-11
@@ -37,13 +37,16 @@
|
||||
mod styled_buffer;
|
||||
mod lock;
|
||||
|
||||
use syntax_pos::{BytePos,
|
||||
Loc,
|
||||
FileLinesResult,
|
||||
SourceFile,
|
||||
FileName,
|
||||
MultiSpan,
|
||||
Span};
|
||||
use syntax_pos::{
|
||||
BytePos,
|
||||
FileLinesResult,
|
||||
FileName,
|
||||
Loc,
|
||||
MultiSpan,
|
||||
SourceFile,
|
||||
Span,
|
||||
SpanSnippetError,
|
||||
};
|
||||
|
||||
/// Indicates the confidence in the correctness of a suggestion.
|
||||
///
|
||||
@@ -147,6 +150,7 @@ pub trait SourceMapper {
|
||||
fn lookup_char_pos(&self, pos: BytePos) -> Loc;
|
||||
fn span_to_lines(&self, sp: Span) -> FileLinesResult;
|
||||
fn span_to_string(&self, sp: Span) -> String;
|
||||
fn span_to_snippet(&self, sp: Span) -> Result<String, SpanSnippetError>;
|
||||
fn span_to_filename(&self, sp: Span) -> FileName;
|
||||
fn merge_spans(&self, sp_lhs: Span, sp_rhs: Span) -> Option<Span>;
|
||||
fn call_span_if_macro(&self, sp: Span) -> Span;
|
||||
@@ -155,9 +159,12 @@ pub trait SourceMapper {
|
||||
}
|
||||
|
||||
impl CodeSuggestion {
|
||||
/// Returns the assembled code suggestions and whether they should be shown with an underline.
|
||||
pub fn splice_lines(&self, cm: &SourceMapperDyn)
|
||||
-> Vec<(String, Vec<SubstitutionPart>)> {
|
||||
/// Returns the assembled code suggestions, whether they should be shown with an underline
|
||||
/// and whether the substitution only differs in capitalization.
|
||||
pub fn splice_lines(
|
||||
&self,
|
||||
cm: &SourceMapperDyn,
|
||||
) -> Vec<(String, Vec<SubstitutionPart>, bool)> {
|
||||
use syntax_pos::{CharPos, Pos};
|
||||
|
||||
fn push_trailing(buf: &mut String,
|
||||
@@ -232,6 +239,8 @@ fn push_trailing(buf: &mut String,
|
||||
prev_hi = cm.lookup_char_pos(part.span.hi());
|
||||
prev_line = fm.get_line(prev_hi.line - 1);
|
||||
}
|
||||
let only_capitalization = buf.clone().to_lowercase()
|
||||
== cm.span_to_snippet(bounding_span).unwrap().to_lowercase();
|
||||
// if the replacement already ends with a newline, don't print the next line
|
||||
if !buf.ends_with('\n') {
|
||||
push_trailing(&mut buf, prev_line.as_ref(), &prev_hi, None);
|
||||
@@ -240,7 +249,8 @@ fn push_trailing(buf: &mut String,
|
||||
while buf.ends_with('\n') {
|
||||
buf.pop();
|
||||
}
|
||||
(buf, substitution.parts)
|
||||
(buf, substitution.parts, only_capitalization)
|
||||
|
||||
}).collect()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user