diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 3459771459a0..26dda2dc42d2 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -217,8 +217,10 @@ impl CodeSuggestion { 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 } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 500639dfde69..a0d7ee44faf6 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -584,6 +584,7 @@ impl ::std::ops::IndexMut for PerNS { struct UsePlacementFinder { target_module: NodeId, span: Option, + found_use: bool, } impl<'tcx> Visitor<'tcx> for UsePlacementFinder { @@ -611,6 +612,7 @@ impl<'tcx> Visitor<'tcx> for UsePlacementFinder { let mut span = item.span; span.hi = span.lo; self.span = Some(span); + self.found_use = true; return; } }, @@ -3576,11 +3578,12 @@ impl<'a> Resolver<'a> { 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(); } @@ -3776,7 +3779,8 @@ fn import_candidate_to_paths(suggestion: &ImportSuggestion) -> (Span, String, St 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: @@ -3792,7 +3796,14 @@ fn show_candidates(err: &mut DiagnosticBuilder, 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);