about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNicholas Nethercote <nnethercote@mozilla.com>2020-08-05 17:29:13 +1000
committerNicholas Nethercote <nnethercote@mozilla.com>2020-08-10 07:12:59 +1000
commit75b67c2d5e12d98b70323bd7874886dd650c5499 (patch)
tree62febac00e5ee2d4e9b0928d64333f54cae36cab /src
parent39e593ab14c53fda63c3f2756716c5ad3cbb6465 (diff)
downloadrust-75b67c2d5e12d98b70323bd7874886dd650c5499.tar.gz
rust-75b67c2d5e12d98b70323bd7874886dd650c5499.zip
Fix symbol ordering for confusable idents detection.
Confusable idents detection uses a type `BTreeMap<Symbol, Span>`. This is
highly dubious given that `Symbol` doesn't guarantee a meaningful order. (In
practice, it currently gives an order that mostly matches source code order.)

As a result, changes in `Symbol` representation make the
`lint-confusable-idents.rs` test fail, because this error message:

> identifier pair considered confusable between `s` and `s`

is changed to this:

> identifier pair considered confusable between `s` and `s`

and the corresponding span pointers get swapped erroneously, leading to
an incorrect "previous identifier" label.

This commit sorts the relevant symbols by span before doing the checking,
which ensures that the ident that appears first in the code will be mentioned
first in the message. The commit also extends the test slightly to be more
thorough.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_lint/non_ascii_idents.rs6
-rw-r--r--src/librustc_session/parse.rs3
-rw-r--r--src/test/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.rs2
-rw-r--r--src/test/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.stderr13
4 files changed, 20 insertions, 4 deletions
diff --git a/src/librustc_lint/non_ascii_idents.rs b/src/librustc_lint/non_ascii_idents.rs
index 30dbd069c29..7c45d826473 100644
--- a/src/librustc_lint/non_ascii_idents.rs
+++ b/src/librustc_lint/non_ascii_idents.rs
@@ -58,6 +58,12 @@ impl EarlyLintPass for NonAsciiIdents {
 
         let mut has_non_ascii_idents = false;
         let symbols = cx.sess.parse_sess.symbol_gallery.symbols.lock();
+
+        // Sort by `Span` so that error messages make sense with respect to the
+        // order of identifier locations in the code.
+        let mut symbols: Vec<_> = symbols.iter().collect();
+        symbols.sort_by_key(|k| k.1);
+
         for (symbol, &sp) in symbols.iter() {
             let symbol_str = symbol.as_str();
             if symbol_str.is_ascii() {
diff --git a/src/librustc_session/parse.rs b/src/librustc_session/parse.rs
index 9cdb7e966fe..a2bb8c4f91f 100644
--- a/src/librustc_session/parse.rs
+++ b/src/librustc_session/parse.rs
@@ -13,7 +13,6 @@ use rustc_span::hygiene::ExpnId;
 use rustc_span::source_map::{FilePathMapping, SourceMap};
 use rustc_span::{MultiSpan, Span, Symbol};
 
-use std::collections::BTreeMap;
 use std::path::PathBuf;
 use std::str;
 
@@ -64,7 +63,7 @@ impl GatedSpans {
 #[derive(Default)]
 pub struct SymbolGallery {
     /// All symbols occurred and their first occurrence span.
-    pub symbols: Lock<BTreeMap<Symbol, Span>>,
+    pub symbols: Lock<FxHashMap<Symbol, Span>>,
 }
 
 impl SymbolGallery {
diff --git a/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.rs b/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.rs
index e15ed2e70b8..2c711f99404 100644
--- a/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.rs
+++ b/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.rs
@@ -3,9 +3,11 @@
 #![allow(uncommon_codepoints, non_upper_case_globals)]
 
 const s: usize = 42;
+const s_s: usize = 42;
 
 fn main() {
     let s = "rust"; //~ ERROR identifier pair considered confusable
+    let s_s = "rust2"; //~ ERROR identifier pair considered confusable
     not_affected();
 }
 
diff --git a/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.stderr b/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.stderr
index 218f94f7b58..b9af60963ad 100644
--- a/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.stderr
+++ b/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.stderr
@@ -1,5 +1,5 @@
 error: identifier pair considered confusable between `s` and `s`
-  --> $DIR/lint-confusable-idents.rs:8:9
+  --> $DIR/lint-confusable-idents.rs:9:9
    |
 LL | const s: usize = 42;
    |       -- this is where the previous identifier occurred
@@ -13,5 +13,14 @@ note: the lint level is defined here
 LL | #![deny(confusable_idents)]
    |         ^^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: identifier pair considered confusable between `s_s` and `s_s`
+  --> $DIR/lint-confusable-idents.rs:10:9
+   |
+LL | const s_s: usize = 42;
+   |       --- this is where the previous identifier occurred
+...
+LL |     let s_s = "rust2";
+   |         ^^^^^
+
+error: aborting due to 2 previous errors