diff options
| author | David Wood <david@davidtw.co> | 2018-10-03 15:20:20 +0200 |
|---|---|---|
| committer | David Wood <david@davidtw.co> | 2018-10-03 15:20:20 +0200 |
| commit | 5872d3eacd61113c8c241444b2d2403aaec2fbfd (patch) | |
| tree | bfbc85b2a5627e6fa33adca42524e06d961ccbd3 | |
| parent | 9d408e0511aeb02ae46c692b2432886372f71c37 (diff) | |
| download | rust-5872d3eacd61113c8c241444b2d2403aaec2fbfd.tar.gz rust-5872d3eacd61113c8c241444b2d2403aaec2fbfd.zip | |
Deterministic external crate suggestion.
This commit ensures that the external crate suggestion is deterministic by using a `BTreeMap` rather than a `FxHashMap`. This is particularly useful as `std` and `core` will often contain the same items and therefore the suggestion would previously suggest either for any given error - in this case, the suggestion will always prefer `std` now.
| -rw-r--r-- | src/librustc_resolve/error_reporting.rs | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/src/librustc_resolve/error_reporting.rs b/src/librustc_resolve/error_reporting.rs index 7a66750d700..b9194fdfc15 100644 --- a/src/librustc_resolve/error_reporting.rs +++ b/src/librustc_resolve/error_reporting.rs @@ -10,8 +10,10 @@ use {CrateLint, PathResult}; +use std::collections::BTreeSet; + use syntax::ast::Ident; -use syntax::symbol::keywords; +use syntax::symbol::{keywords, Symbol}; use syntax_pos::Span; use resolve_imports::ImportResolver; @@ -131,14 +133,19 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { span: Span, mut path: Vec<Ident> ) -> Option<Vec<Ident>> { - // Need to clone else we can't call `resolve_path` without a borrow error. - let external_crate_names = self.resolver.session.extern_prelude.clone(); + // Need to clone else we can't call `resolve_path` without a borrow error. We also store + // into a `BTreeMap` so we can get consistent ordering (and therefore the same diagnostic) + // each time. + let external_crate_names: BTreeSet<Symbol> = self.resolver.session.extern_prelude + .clone().drain().collect(); // Insert a new path segment that we can replace. let new_path_segment = path[0].clone(); path.insert(1, new_path_segment); - for name in &external_crate_names { + // Iterate in reverse so that we start with crates at the end of the alphabet. This means + // that we'll always get `std` before `core`. + for name in external_crate_names.iter().rev() { let ident = Ident::with_empty_ctxt(*name); // Calling `maybe_process_path_extern` ensures that we're only running `resolve_path` // on a crate name that won't ICE. |
