if !buf.ends_with('\n') {
push_trailing(buf, prev_line.as_ref(), &prev_hi, None);
}
- // remove trailing newline
- buf.pop();
+ // remove trailing newlines
+ while buf.ends_with('\n') {
+ buf.pop();
+ }
}
bufs
}
struct UsePlacementFinder {
target_module: NodeId,
span: Option<Span>,
+ found_use: bool,
}
impl<'tcx> Visitor<'tcx> for UsePlacementFinder {
let mut span = item.span;
span.hi = span.lo;
self.span = Some(span);
+ self.found_use = true;
return;
}
},
let mut finder = UsePlacementFinder {
target_module: node_id,
span: None,
+ found_use: false,
};
visit::walk_crate(&mut finder, krate);
if !candidates.is_empty() {
let span = finder.span.expect("did not find module");
- show_candidates(&mut err, span, &candidates, better);
+ show_candidates(&mut err, span, &candidates, better, finder.found_use);
}
err.emit();
}
fn show_candidates(err: &mut DiagnosticBuilder,
span: Span,
candidates: &[ImportSuggestion],
- better: bool) {
+ better: bool,
+ found_use: bool) {
// we want consistent results across executions, but candidates are produced
// by iterating through a hash map, so make sure they are ordered:
let msg = format!("possible {}candidate{} into scope", better, msg_diff);
for candidate in &mut path_strings {
- *candidate = format!("use {};\n", candidate);
+ // produce an additional newline to separate the new use statement
+ // from the directly following item.
+ let additional_newline = if found_use {
+ ""
+ } else {
+ "\n"
+ };
+ *candidate = format!("use {};\n{}", candidate, additional_newline);
}
err.span_suggestions(span, &msg, path_strings);