Skip to content

Commit 43b10fa

Browse files
committed
Teach diagnostics to have correctly padded lists
Make the suggestion list have a correct padding: ``` error[E0308]: mismatched types --> file.rs:3:20 | 3 | let x: usize = ""; | ^^ expected usize, found reference | = note: expected type `usize` = note: found type `&'static str` = help: here are some functions which might fulfill your needs: - .len() - .foo() - .bar() ```
1 parent 7e38a89 commit 43b10fa

File tree

6 files changed

+49
-17
lines changed

6 files changed

+49
-17
lines changed

src/librustc_errors/diagnostic.rs

+18
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ pub struct SubDiagnostic {
3232
pub message: String,
3333
pub span: MultiSpan,
3434
pub render_span: Option<RenderSpan>,
35+
pub list: Vec<String>,
3536
}
3637

3738
impl Diagnostic {
@@ -132,6 +133,11 @@ impl Diagnostic {
132133
self
133134
}
134135

136+
pub fn help_with_list(&mut self , msg: &str, list: Vec<String>) -> &mut Self {
137+
self.sub_with_list(Level::Help, msg, MultiSpan::new(), None, list);
138+
self
139+
}
140+
135141
pub fn span_help<S: Into<MultiSpan>>(&mut self,
136142
sp: S,
137143
msg: &str)
@@ -191,11 +197,23 @@ impl Diagnostic {
191197
message: &str,
192198
span: MultiSpan,
193199
render_span: Option<RenderSpan>) {
200+
self.sub_with_list(level, message, span, render_span, vec![]);
201+
}
202+
203+
/// Convenience function for internal use, clients should use one of the
204+
/// public methods above.
205+
fn sub_with_list(&mut self,
206+
level: Level,
207+
message: &str,
208+
span: MultiSpan,
209+
render_span: Option<RenderSpan>,
210+
list: Vec<String>) {
194211
let sub = SubDiagnostic {
195212
level: level,
196213
message: message.to_owned(),
197214
span: span,
198215
render_span: render_span,
216+
list: list,
199217
};
200218
self.children.push(sub);
201219
}

src/librustc_errors/diagnostic_builder.rs

+1
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ impl<'a> DiagnosticBuilder<'a> {
135135
forward!(pub fn warn(&mut self, msg: &str) -> &mut Self);
136136
forward!(pub fn span_warn<S: Into<MultiSpan>>(&mut self, sp: S, msg: &str) -> &mut Self);
137137
forward!(pub fn help(&mut self , msg: &str) -> &mut Self);
138+
forward!(pub fn help_with_list(&mut self , msg: &str, list: Vec<String>) -> &mut Self);
138139
forward!(pub fn span_help<S: Into<MultiSpan>>(&mut self,
139140
sp: S,
140141
msg: &str)

src/librustc_errors/emitter.rs

+17-2
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,7 @@ impl EmitterWriter {
699699
.to_string(),
700700
span: MultiSpan::new(),
701701
render_span: None,
702+
list: vec![],
702703
});
703704
}
704705
}
@@ -923,14 +924,28 @@ impl EmitterWriter {
923924
}
924925
},
925926
None => {
927+
let msg = if child.list.len() == 0 {
928+
child.message.to_owned()
929+
} else {
930+
format!("{}\n{}",
931+
&child.message,
932+
&child.list.iter().map(|item| {
933+
format!("{} - {}",
934+
(0..max_line_num_len)
935+
.map(|_| " ")
936+
.collect::<String>(),
937+
item)
938+
}).collect::<Vec<String>>()
939+
.join("\n"))
940+
};
926941
match self.emit_message_default(&child.span,
927-
&child.message,
942+
&msg,
928943
&None,
929944
&child.level,
930945
max_line_num_len,
931946
true) {
932947
Err(e) => panic!("failed to emit error: {}", e),
933-
_ => ()
948+
_ => (),
934949
}
935950
}
936951
}

src/librustc_typeck/check/demand.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
7070
ast::DUMMY_NODE_ID);
7171
let mut err = self.report_mismatched_types(&cause, expected, expr_ty, e);
7272
if suggestions.len() > 0 {
73-
err.help(&format!("here are some functions which \
74-
might fulfill your needs:\n - {}",
75-
self.get_best_match(&suggestions)));
73+
err.help_with_list("here are some functions which might fulfill your needs:",
74+
self.get_best_match(&suggestions));
7675
};
7776
err.emit();
7877
}
@@ -88,15 +87,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
8887
})
8988
}
9089

91-
fn display_suggested_methods(&self, methods: &[AssociatedItem]) -> String {
90+
fn display_suggested_methods(&self, methods: &[AssociatedItem]) -> Vec<String> {
9291
methods.iter()
9392
.take(5)
9493
.map(|method| self.format_method_suggestion(&*method))
9594
.collect::<Vec<String>>()
96-
.join("\n - ")
9795
}
9896

99-
fn get_best_match(&self, methods: &[AssociatedItem]) -> String {
97+
fn get_best_match(&self, methods: &[AssociatedItem]) -> Vec<String> {
10098
let no_argument_methods: Vec<_> =
10199
methods.iter()
102100
.filter(|ref x| self.has_no_input_arg(&*x))

src/test/ui/resolve/token-error-correct-3.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ error[E0308]: mismatched types
3737
= note: expected type `()`
3838
= note: found type `std::result::Result<bool, std::io::Error>`
3939
= help: here are some functions which might fulfill your needs:
40-
- .unwrap()
41-
- .unwrap_err()
42-
- .unwrap_or_default()
40+
- .unwrap()
41+
- .unwrap_err()
42+
- .unwrap_or_default()
4343

4444
error: aborting due to previous error
4545

src/test/ui/span/coerce-suggestions.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ error[E0308]: mismatched types
77
= note: expected type `usize`
88
= note: found type `std::string::String`
99
= help: here are some functions which might fulfill your needs:
10-
- .capacity()
11-
- .len()
10+
- .capacity()
11+
- .len()
1212

1313
error[E0308]: mismatched types
1414
--> $DIR/coerce-suggestions.rs:23:19
@@ -19,10 +19,10 @@ error[E0308]: mismatched types
1919
= note: expected type `&str`
2020
= note: found type `std::string::String`
2121
= help: here are some functions which might fulfill your needs:
22-
- .as_str()
23-
- .trim()
24-
- .trim_left()
25-
- .trim_right()
22+
- .as_str()
23+
- .trim()
24+
- .trim_left()
25+
- .trim_right()
2626

2727
error[E0308]: mismatched types
2828
--> $DIR/coerce-suggestions.rs:30:10

0 commit comments

Comments
 (0)