6151: Constrain ImportMap to only store simple paths r=matklad a=matklad

bors r+
🤖

Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
bors[bot] 2020-10-06 15:06:28 +00:00 committed by GitHub
commit ec1f459980
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -4,17 +4,16 @@ use std::{cmp::Ordering, fmt, hash::BuildHasherDefault, sync::Arc};
use base_db::CrateId;
use fst::{self, Streamer};
use hir_expand::name::Name;
use indexmap::{map::Entry, IndexMap};
use itertools::Itertools;
use rustc_hash::{FxHashMap, FxHasher};
use smallvec::SmallVec;
use syntax::SmolStr;
use crate::{
db::DefDatabase,
item_scope::ItemInNs,
path::{ModPath, PathKind},
visibility::Visibility,
AssocItemId, ModuleDefId, ModuleId, TraitId,
db::DefDatabase, item_scope::ItemInNs, visibility::Visibility, AssocItemId, ModuleDefId,
ModuleId, TraitId,
};
type FxIndexMap<K, V> = IndexMap<K, V, BuildHasherDefault<FxHasher>>;
@ -23,11 +22,28 @@ type FxIndexMap<K, V> = IndexMap<K, V, BuildHasherDefault<FxHasher>>;
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct ImportInfo {
/// A path that can be used to import the item, relative to the crate's root.
pub path: ModPath,
pub path: ImportPath,
/// The module containing this item.
pub container: ModuleId,
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct ImportPath {
pub segments: Vec<Name>,
}
impl fmt::Display for ImportPath {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.segments.iter().format("::"), f)
}
}
impl ImportPath {
fn len(&self) -> usize {
self.segments.len()
}
}
/// A map from publicly exported items to the path needed to import/name them from a downstream
/// crate.
///
@ -61,7 +77,7 @@ impl ImportMap {
let mut import_map = Self::default();
// We look only into modules that are public(ly reexported), starting with the crate root.
let empty = ModPath { kind: PathKind::Plain, segments: vec![] };
let empty = ImportPath { segments: vec![] };
let root = ModuleId { krate, local_id: def_map.root };
let mut worklist = vec![(root, empty)];
while let Some((module, mod_path)) = worklist.pop() {
@ -152,8 +168,8 @@ impl ImportMap {
}
/// Returns the `ModPath` needed to import/mention `item`, relative to this crate's root.
pub fn path_of(&self, item: ItemInNs) -> Option<&ModPath> {
Some(&self.map.get(&item)?.path)
pub fn path_of(&self, item: ItemInNs) -> Option<&ImportPath> {
self.import_info_for(item).map(|it| &it.path)
}
pub fn import_info_for(&self, item: ItemInNs) -> Option<&ImportInfo> {
@ -197,7 +213,7 @@ impl fmt::Debug for ImportMap {
}
}
fn fst_path(path: &ModPath) -> String {
fn fst_path(path: &ImportPath) -> String {
let mut s = path.to_string();
s.make_ascii_lowercase();
s