Skip to content

Commit

Permalink
Make more types use interned names
Browse files Browse the repository at this point in the history
  • Loading branch information
purefunctor committed Jan 7, 2024
1 parent 887bfbc commit 20ed392
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 37 deletions.
48 changes: 41 additions & 7 deletions crates/analyzer/src/names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//! the interning mechanism [`interner::Interner`]; this makes them cheap to clone and relatively
//! easy to clean up as they're discarded.
use std::sync::Arc;
use std::{fmt::Display, ops::Deref, sync::Arc};

use rowan::ast::AstNode;
use syntax::ast;
Expand Down Expand Up @@ -81,16 +81,30 @@ impl AsRef<str> for Name {
}
}

/// Names appearing as usages.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct NameRef(Arc<str>);
impl Deref for Name {
type Target = Arc<str>;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl NameRef {
pub(crate) fn from_raw(raw: Arc<str>) -> NameRef {
NameRef(raw)
impl From<NameRef> for Name {
fn from(value: NameRef) -> Name {
Name(value.0)
}
}

impl Display for Name {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.as_ref().fmt(f)
}
}

/// Names appearing as usages.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct NameRef(Arc<str>);

impl InDb<NameRef> for ast::NameRef {
fn in_db(self, db: &(impl SourceDatabase + ?Sized)) -> Option<NameRef> {
Some(NameRef(db.interner().intern(self.token()?.text())))
Expand All @@ -103,6 +117,26 @@ impl AsRef<str> for NameRef {
}
}

impl Deref for NameRef {
type Target = Arc<str>;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl From<Name> for NameRef {
fn from(value: Name) -> NameRef {
NameRef(value.0)
}
}

impl Display for NameRef {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.as_ref().fmt(f)
}
}

/// Values optionally qualified by a [`ModuleName`].
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Qualified<N> {
Expand Down
44 changes: 23 additions & 21 deletions crates/analyzer/src/resolver/nominal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,29 @@ use itertools::Itertools;
use la_arena::{Arena, Idx};
use rowan::ast::{AstChildren, AstNode};
use rustc_hash::{FxHashMap, FxHashSet};
use smol_str::SmolStr;
use syntax::ast;

use crate::{
id::{AstId, InFile},
names::{InDb, Name},
ResolverDatabase,
};

use super::PositionalMap;

#[derive(Debug, PartialEq, Eq)]
pub struct DataGroup {
pub name: SmolStr,
pub name: Name,
pub annotation: Option<AstId<ast::DataAnnotation>>,
pub declaration: AstId<ast::DataDeclaration>,
pub constructors: FxHashMap<SmolStr, AstId<ast::DataConstructor>>,
pub constructors: FxHashMap<Name, AstId<ast::DataConstructor>>,
}

pub type DataGroupId = Idx<DataGroup>;

#[derive(Debug, PartialEq, Eq)]
pub struct ValueGroup {
pub name: SmolStr,
pub name: Name,
pub annotation: Option<AstId<ast::ValueAnnotationDeclaration>>,
pub equations: FxHashSet<AstId<ast::ValueEquationDeclaration>>,
}
Expand All @@ -53,11 +53,11 @@ pub struct NominalMap {
file_id: FileId,

data_groups: Arena<DataGroup>,
name_to_data: FxHashMap<SmolStr, DataGroupId>,
name_to_constructor: FxHashMap<SmolStr, (DataGroupId, AstId<ast::DataConstructor>)>,
name_to_data: FxHashMap<Arc<str>, DataGroupId>,
name_to_constructor: FxHashMap<Arc<str>, (DataGroupId, AstId<ast::DataConstructor>)>,

value_groups: Arena<ValueGroup>,
name_to_value: FxHashMap<SmolStr, ValueGroupId>,
name_to_value: FxHashMap<Arc<str>, ValueGroupId>,
}

impl NominalMap {
Expand Down Expand Up @@ -88,7 +88,7 @@ impl NominalMap {

if let Some(declarations) = declarations {
let positional_map = db.positional_map(file_id);
collect(&mut nominal_map, &positional_map, declarations);
collect(db, &mut nominal_map, &positional_map, declarations);
}

Arc::new(nominal_map)
Expand Down Expand Up @@ -142,11 +142,12 @@ impl NominalMap {

#[derive(Debug, PartialEq, Eq)]
enum DeclarationKey {
Data(Option<SmolStr>),
Value(Option<SmolStr>),
Data(Option<Name>),
Value(Option<Name>),
}

fn collect(
db: &dyn ResolverDatabase,
nominal_map: &mut NominalMap,
positional_map: &PositionalMap,
declarations: AstChildren<ast::Declaration>,
Expand All @@ -159,24 +160,24 @@ fn collect(

let groups = declarations.group_by(|declaration| match declaration {
ast::Declaration::DataAnnotation(data) => {
DeclarationKey::Data(data.name().and_then(|name| name.as_str()))
DeclarationKey::Data(data.name().and_then(|name| name.in_db(db)))
}
ast::Declaration::DataDeclaration(data) => {
DeclarationKey::Data(data.name().and_then(|name| name.as_str()))
DeclarationKey::Data(data.name().and_then(|name| name.in_db(db)))
}
ast::Declaration::ForeignDataDeclaration(_) => todo!("Unimplemented!"),
ast::Declaration::ValueAnnotationDeclaration(value) => {
DeclarationKey::Value(value.name().and_then(|name| name.as_str()))
DeclarationKey::Value(value.name().and_then(|name| name.in_db(db)))
}
ast::Declaration::ValueEquationDeclaration(value) => {
DeclarationKey::Value(value.name().and_then(|name| name.as_str()))
DeclarationKey::Value(value.name().and_then(|name| name.in_db(db)))
}
});

for (key, group) in groups.into_iter() {
match key {
DeclarationKey::Data(name) => {
collect_data(nominal_map, positional_map, name, group)?;
collect_data(db, nominal_map, positional_map, name, group)?;
}
DeclarationKey::Value(name) => {
collect_value(nominal_map, positional_map, name, group)?;
Expand All @@ -188,9 +189,10 @@ fn collect(
}

fn collect_data(
db: &dyn ResolverDatabase,
nominal_map: &mut NominalMap,
positional_map: &PositionalMap,
name: Option<SmolStr>,
name: Option<Name>,
group: impl Iterator<Item = ast::Declaration>,
) -> Option<()> {
let name = name?;
Expand All @@ -209,11 +211,11 @@ fn collect_data(
let mut constructors = FxHashMap::default();

for constructor_ast in d.constructors()?.children() {
let constructor_name = constructor_ast.name()?.as_str()?;
let constructor_name = constructor_ast.name()?.in_db(db)?;
constructors.insert(constructor_name, positional_map.ast_id(&constructor_ast));
}

let data_name = name.clone();
let data_name = Arc::clone(&name);
let data_group_id = nominal_map.data_groups.alloc(DataGroup {
name,
annotation,
Expand All @@ -227,7 +229,7 @@ fn collect_data(
for (constructor_name, constructor_id) in data_group.constructors.iter() {
nominal_map
.name_to_constructor
.insert(constructor_name.clone(), (data_group_id, *constructor_id));
.insert(Arc::clone(constructor_name), (data_group_id, *constructor_id));
}
} else {
unreachable!("Impossible.");
Expand All @@ -239,7 +241,7 @@ fn collect_data(
fn collect_value(
nominal_map: &mut NominalMap,
positional_map: &PositionalMap,
name: Option<SmolStr>,
name: Option<Name>,
group: impl Iterator<Item = ast::Declaration>,
) -> Option<()> {
let name = name?;
Expand All @@ -266,7 +268,7 @@ fn collect_value(
}
}));

let value_name = name.clone();
let value_name = Arc::clone(&name);
let value_index = nominal_map.value_groups.alloc(ValueGroup { name, annotation, equations });

nominal_map.name_to_value.insert(value_name, value_index);
Expand Down
10 changes: 4 additions & 6 deletions crates/analyzer/src/surface/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ impl<'db> SurfaceContext<'db> {
let group_data = nominal_map.data_group_data(id);
let mut surface_context = SurfaceContext::new(db);

let name = group_data.name.clone();
let name = Name::clone(&group_data.name);
let annotation = group_data.annotation.and_then(|annotation| {
let annotation = annotation.in_file(id.file_id).to_ast(db);
surface_context.lower_data_annotation(&annotation)
Expand Down Expand Up @@ -119,7 +119,7 @@ impl<'db> SurfaceContext<'db> {
let group_data = nominal_map.value_group_data(id);
let mut surface_context = SurfaceContext::new(db);

let name = group_data.name.clone();
let name = Name::clone(&group_data.name);
let annotation = group_data.annotation.and_then(|annotation| {
let annotation = annotation.in_file(id.file_id).to_ast(db);
surface_context.lower_value_annotation(&annotation)
Expand Down Expand Up @@ -578,7 +578,7 @@ impl<'db> SurfaceContext<'db> {
&mut self,
constructor: &ast::DataConstructor,
) -> Option<DataConstructor> {
let name = constructor.name()?.as_str()?;
let name = constructor.name()?.in_db(self.db)?;
let fields = constructor
.fields()?
.children()
Expand Down Expand Up @@ -684,9 +684,7 @@ impl ModuleExports {
items = nominal_map
.value_groups()
.map(|(_, value_group)| {
// FIXME: use interned names for ValueGroup
let name = NameRef::from_raw(db.interner().intern(&value_group.name));
ExportItem::ExportValue(name)
ExportItem::ExportValue(NameRef::from(Name::clone(&value_group.name)))
})
.collect();
explicit = false;
Expand Down
6 changes: 3 additions & 3 deletions crates/analyzer/src/surface/trees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,13 @@ impl DataDeclaration {

#[derive(Debug, PartialEq, Eq)]
pub struct DataConstructor {
pub name: SmolStr,
pub name: Name,
pub fields: Vec<TypeId>,
}

#[derive(Debug, PartialEq, Eq)]
pub struct DataGroup {
pub name: SmolStr,
pub name: Name,
pub annotation: Option<DataAnnotation>,
pub declaration: DataDeclaration,
}
Expand All @@ -174,7 +174,7 @@ pub struct ValueEquation {

#[derive(Debug, PartialEq, Eq)]
pub struct ValueGroup {
pub name: SmolStr,
pub name: Name,
pub annotation: Option<ValueAnnotation>,
pub equations: FxHashMap<AstId<ast::ValueEquationDeclaration>, ValueEquation>,
}
Expand Down

0 comments on commit 20ed392

Please sign in to comment.