Intern Attr, MacroCall and Path components

This commit is contained in:
Jonas Schievink 2021-04-01 20:35:21 +02:00
parent b00266b79f
commit 39d992ef55
7 changed files with 21 additions and 17 deletions

View File

@ -18,6 +18,7 @@ use tt::Subtree;
use crate::{
db::DefDatabase,
intern::Interned,
item_tree::{ItemTreeId, ItemTreeNode},
nameres::ModuleSource,
path::{ModPath, PathKind},
@ -98,7 +99,7 @@ impl RawAttrs {
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<_>>();
@ -510,7 +511,7 @@ impl AttrSourceMap {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Attr {
index: u32,
pub(crate) path: ModPath,
pub(crate) path: Interned<ModPath>,
pub(crate) input: Option<AttrInput>,
}
@ -524,7 +525,7 @@ pub enum 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(),

View File

@ -15,6 +15,7 @@ use rustc_hash::FxHasher;
type InternMap<T> = DashMap<Arc<T>, (), BuildHasherDefault<FxHasher>>;
#[derive(Hash)]
pub struct Interned<T: Internable> {
arc: Arc<T>,
}
@ -152,6 +153,6 @@ macro_rules! impl_internable {
)+ };
}
impl_internable!(crate::type_ref::TypeRef, crate::type_ref::TraitRef);
impl_internable!(crate::type_ref::TypeRef, crate::type_ref::TraitRef, crate::path::ModPath);
// endregion

View File

@ -694,7 +694,7 @@ pub enum ModKind {
#[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>,
}

View File

@ -606,7 +606,7 @@ impl Ctx {
}
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)))

View File

@ -1464,7 +1464,7 @@ impl ModCollector<'_, '_> {
}
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;

View File

@ -7,7 +7,7 @@ use std::{
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,
@ -48,7 +48,7 @@ pub enum ImportAlias {
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 {
@ -123,7 +123,7 @@ pub struct Path {
/// 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>>>,
}
@ -176,7 +176,7 @@ impl Path {
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 {
@ -204,10 +204,10 @@ impl Path {
}
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)
@ -283,7 +283,7 @@ impl From<Name> for Path {
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],
}
}

View File

@ -2,6 +2,7 @@
mod lower_use;
use crate::intern::Interned;
use std::sync::Arc;
use either::Either;
@ -74,10 +75,11 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
// <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);
@ -140,7 +142,7 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
}
}
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> {