Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save nikomatsakis/7351f61938624c8e5a9921bbef63add3 to your computer and use it in GitHub Desktop.
Save nikomatsakis/7351f61938624c8e5a9921bbef63add3 to your computer and use it in GitHub Desktop.
Staged
modified src/librustc_typeck/check_unused.rs
@@ -137,8 +137,9 @@ fn unused_crates_lint<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) {
let hir_id = tcx.hir.definitions().def_index_to_hir_id(extern_crate.def_id.index);
let id = tcx.hir.hir_to_node_id(hir_id);
let msg = "unused extern crate";
+ let span_to_replace = tcx.sess.codemap().span_extend_end_while_newline(span);
tcx.struct_span_lint_node(lint, id, span, msg)
- .span_suggestion_short(span, "remove it", "".to_string())
+ .span_suggestion_short(span_to_replace, "remove it", "".to_string())
.emit();
continue;
}
modified src/libsyntax/codemap.rs
@@ -539,9 +539,11 @@ impl CodeMap {
/// Extract the source surrounding the given `Span` using the `extract_source` function. The
/// extract function takes three arguments: a string slice containing the source, an index in
/// the slice for the beginning of the span and an index in the slice for the end of the span.
- fn span_to_source<F>(&self, sp: Span, extract_source: F) -> Result<String, SpanSnippetError>
- where F: Fn(&str, usize, usize) -> String
- {
+ fn span_to_source<R>(
+ &self,
+ sp: Span,
+ mut extract_source: impl FnMut(&str, usize, usize) -> R,
+ ) -> Result<R, SpanSnippetError> {
if sp.lo() > sp.hi() {
return Err(SpanSnippetError::IllFormedSpan(sp));
}
@@ -701,6 +703,52 @@ impl CodeMap {
}
}
+ /// Returns a new span equal to `sp` except that it may include
+ /// any newlines that come immediately afterwards. This is useful
+ /// when removing a statement like `extern crate foo;` entirely
+ /// that is typically on its own line (really we should probably
+ /// check that `sp` is an entire line).
+ pub fn span_extend_end_while_newline(&self, sp: Span) -> Span {
+ self.span_extend_end_while(sp, |c| c == '\n' || c == '\r')
+ }
+
+ /// Given a `Span`, get a **longer** one by adding characters
+ /// until `predicate` yields false.
+ ///
+ /// NB: In some cases, such as if `sp` is the result of a macro
+ /// expansion, `sp` is returned unchanged no matter what.
+ pub fn span_extend_end_while(
+ &self,
+ sp: Span,
+ mut predicate: impl FnMut(char) -> bool,
+ ) -> Span {
+ // Refuse to expand spans that results from macro
+ // expansions. Too tricky.
+ if sp.ctxt().outer().expn_info().is_some() {
+ return sp;
+ }
+
+ // Find the offset of the first character that fails
+ // `predicate`, or just `0`.
+ let offset = self.span_to_source(sp, |src, _start_index, end_index| {
+ src[end_index..]
+ .char_indices()
+ .filter_map(|(index, ch)| {
+ if predicate(ch) {
+ None
+ } else {
+ Some(index)
+ }
+ })
+ .next()
+ .unwrap_or(0)
+ }).unwrap_or(0);
+
+ // Add zero to the end here.
+ assert!(offset < (u32::max_value() as usize));
+ sp.with_hi(BytePos(sp.hi().0 + (offset as u32)))
+ }
+
pub fn def_span(&self, sp: Span) -> Span {
self.span_until_char(sp, '{')
}
modified src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed
@@ -19,7 +19,6 @@
#![deny(rust_2018_idioms)]
#![allow(dead_code)]
-
//~^ ERROR unused extern crate
use edition_lint_paths as bar;
modified src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.stderr
@@ -1,8 +1,10 @@
error: unused extern crate
--> $DIR/extern-crate-idiomatic-in-2018.rs:22:1
|
-LL | extern crate edition_lint_paths;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
+LL | extern crate edition_lint_paths;
+ | _-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | | //~^ ERROR unused extern crate
+ | |_ help: remove it
|
note: lint level defined here
--> $DIR/extern-crate-idiomatic-in-2018.rs:19:9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment