use crate::{
db::DefDatabase,
+ intern::Interned,
item_tree::{ItemTreeId, ItemTreeNode},
nameres::ModuleSource,
path::{ModPath, PathKind},
Either::Right(comment) => comment.doc_comment().map(|doc| Attr {
index: i as u32,
input: Some(AttrInput::Literal(SmolStr::new(doc))),
- path: ModPath::from(hir_expand::name!(doc)),
+ path: Interned::new(ModPath::from(hir_expand::name!(doc))),
}),
})
.collect::<Arc<_>>();
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Attr {
index: u32,
- pub(crate) path: ModPath,
+ pub(crate) path: Interned<ModPath>,
pub(crate) input: Option<AttrInput>,
}
impl Attr {
fn from_src(ast: ast::Attr, hygiene: &Hygiene, index: u32) -> Option<Attr> {
- let path = ModPath::from_src(ast.path()?, hygiene)?;
+ let path = Interned::new(ModPath::from_src(ast.path()?, hygiene)?);
let input = if let Some(ast::Expr::Literal(lit)) = ast.expr() {
let value = match lit.kind() {
ast::LiteralKind::String(string) => string.value()?.into(),
type InternMap<T> = DashMap<Arc<T>, (), BuildHasherDefault<FxHasher>>;
+#[derive(Hash)]
pub struct Interned<T: Internable> {
arc: Arc<T>,
}
)+ };
}
-impl_internable!(crate::type_ref::TypeRef, crate::type_ref::TraitRef);
+impl_internable!(crate::type_ref::TypeRef, crate::type_ref::TraitRef, crate::path::ModPath);
// endregion
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct MacroCall {
/// Path to the called macro.
- pub path: ModPath,
+ pub path: Interned<ModPath>,
pub ast_id: FileAstId<ast::MacroCall>,
}
}
fn lower_macro_call(&mut self, m: &ast::MacroCall) -> Option<FileItemTreeId<MacroCall>> {
- let path = ModPath::from_src(m.path()?, &self.hygiene)?;
+ let path = Interned::new(ModPath::from_src(m.path()?, &self.hygiene)?);
let ast_id = self.source_ast_id_map.ast_id(m);
let res = MacroCall { path, ast_id };
Some(id(self.data().macro_calls.alloc(res)))
}
fn collect_macro_call(&mut self, mac: &MacroCall) {
- let mut ast_id = AstIdWithPath::new(self.file_id, mac.ast_id, mac.path.clone());
+ let mut ast_id = AstIdWithPath::new(self.file_id, mac.ast_id, (*mac.path).clone());
// Case 1: try to resolve in legacy scope and expand macro_rules
let mut error = None;
sync::Arc,
};
-use crate::{body::LowerCtx, type_ref::LifetimeRef};
+use crate::{body::LowerCtx, intern::Interned, type_ref::LifetimeRef};
use base_db::CrateId;
use hir_expand::{
hygiene::Hygiene,
impl ModPath {
pub fn from_src(path: ast::Path, hygiene: &Hygiene) -> Option<ModPath> {
- lower::lower_path(path, hygiene).map(|it| it.mod_path)
+ lower::lower_path(path, hygiene).map(|it| (*it.mod_path).clone())
}
pub fn from_segments(kind: PathKind, segments: impl IntoIterator<Item = Name>) -> ModPath {
/// Type based path like `<T>::foo`.
/// Note that paths like `<Type as Trait>::foo` are desugard to `Trait::<Self=Type>::foo`.
type_anchor: Option<Box<TypeRef>>,
- mod_path: ModPath,
+ mod_path: Interned<ModPath>,
/// Invariant: the same len as `self.mod_path.segments`
generic_args: Vec<Option<Arc<GenericArgs>>>,
}
path: ModPath,
generic_args: Vec<Option<Arc<GenericArgs>>>,
) -> Path {
- Path { type_anchor: None, mod_path: path, generic_args }
+ Path { type_anchor: None, mod_path: Interned::new(path), generic_args }
}
pub fn kind(&self) -> &PathKind {
}
let res = Path {
type_anchor: self.type_anchor.clone(),
- mod_path: ModPath::from_segments(
+ mod_path: Interned::new(ModPath::from_segments(
self.mod_path.kind.clone(),
self.mod_path.segments[..self.mod_path.segments.len() - 1].iter().cloned(),
- ),
+ )),
generic_args: self.generic_args[..self.generic_args.len() - 1].to_vec(),
};
Some(res)
fn from(name: Name) -> Path {
Path {
type_anchor: None,
- mod_path: ModPath::from_segments(PathKind::Plain, iter::once(name)),
+ mod_path: Interned::new(ModPath::from_segments(PathKind::Plain, iter::once(name))),
generic_args: vec![None],
}
}
mod lower_use;
+use crate::intern::Interned;
use std::sync::Arc;
use either::Either;
// <T as Trait<A>>::Foo desugars to Trait<Self=T, A>::Foo
Some(trait_ref) => {
let path = Path::from_src(trait_ref.path()?, hygiene)?;
+ let mod_path = (*path.mod_path).clone();
let num_segments = path.mod_path.segments.len();
- kind = path.mod_path.kind;
+ kind = mod_path.kind;
- let mut prefix_segments = path.mod_path.segments;
+ let mut prefix_segments = mod_path.segments;
prefix_segments.reverse();
segments.extend(prefix_segments);
}
}
- let mod_path = ModPath::from_segments(kind, segments);
+ let mod_path = Interned::new(ModPath::from_segments(kind, segments));
return Some(Path { type_anchor, mod_path, generic_args });
fn qualifier(path: &ast::Path) -> Option<ast::Path> {