Skip to content

Commit

Permalink
address pr comments
Browse files Browse the repository at this point in the history
  • Loading branch information
feds01 committed Aug 28, 2023
1 parent 84aa84f commit 073128b
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 96 deletions.
2 changes: 1 addition & 1 deletion compiler/hash-attrs/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! All of the defined logic and data structures for attribute management in the
//! Hash compiler.
#![feature(lazy_cell, let_chains)]
#![feature(lazy_cell, let_chains, macro_metavar_expr)]

pub mod attr;
pub mod ty;
Expand Down
68 changes: 35 additions & 33 deletions compiler/hash-attrs/src/target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::fmt;
use hash_ast::ast;
use hash_utils::{
bitflags,
itertools::Itertools,
printing::{SequenceDisplay, SequenceDisplayOptions, SequenceJoinMode},
};

Expand Down Expand Up @@ -96,8 +97,11 @@ bitflags::bitflags! {
/// A pattern argument.
const PatArg = 1 << 24;

/// A trait definition.
const TraitDef = 1 << 25;

/// A general item definition e.g. `struct`, `enum`, `impl`, `mod` and `fn`.
const Item = Self::StructDef.bits() | Self::EnumDef.bits() | Self::FnDef.bits() | Self::TyFnDef.bits() | Self::ImplDef.bits() | Self::ModDef.bits();
const Item = Self::StructDef.bits() | Self::EnumDef.bits() | Self::FnDef.bits() | Self::TyFnDef.bits() | Self::ImplDef.bits() | Self::ModDef.bits() | Self::TraitDef.bits();
}
}

Expand All @@ -118,7 +122,7 @@ impl AttrTarget {
ast::Expr::StructDef(_) => AttrTarget::StructDef,
ast::Expr::EnumDef(_) => AttrTarget::EnumDef,
ast::Expr::TyFnDef(_) => AttrTarget::TyFnDef,
ast::Expr::TraitDef(_) => AttrTarget::Item,
ast::Expr::TraitDef(_) => AttrTarget::TraitDef,
ast::Expr::ImplDef(_) => AttrTarget::ImplDef,
ast::Expr::ModDef(_) => AttrTarget::ModDef,
ast::Expr::FnDef(_) => AttrTarget::FnDef,
Expand All @@ -135,38 +139,36 @@ impl AttrTarget {

impl fmt::Display for AttrTarget {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let item_count = self.bits().count_ones();

// We will collect all of the allowed argument kinds into a vector
let mut allowed_argument_kinds = Vec::with_capacity(item_count as usize);

for kind in (*self).iter() {
match kind {
AttrTarget::ConstructorCall => allowed_argument_kinds.push("constructor call"),
AttrTarget::MacroInvocation => allowed_argument_kinds.push("directive"),
AttrTarget::Unsafe => allowed_argument_kinds.push("unsafe expression"),
AttrTarget::Lit => allowed_argument_kinds.push("literal"),
AttrTarget::Loop => allowed_argument_kinds.push("loop block"),
AttrTarget::Match => allowed_argument_kinds.push("match block"),
AttrTarget::ImplDef => allowed_argument_kinds.push("impl block"),
AttrTarget::Mod => allowed_argument_kinds.push("module"),
AttrTarget::ModDef => allowed_argument_kinds.push("mod block"),
AttrTarget::Block => allowed_argument_kinds.push("body block"),
AttrTarget::Import => allowed_argument_kinds.push("import"),
AttrTarget::StructDef => allowed_argument_kinds.push("`struct` definition"),
AttrTarget::EnumDef => allowed_argument_kinds.push("`enum` definition"),
AttrTarget::TyFnDef => allowed_argument_kinds.push("type function definition"),
AttrTarget::FnDef => allowed_argument_kinds.push("`function` definition"),
AttrTarget::Ty => allowed_argument_kinds.push("type"),
AttrTarget::Expr => allowed_argument_kinds.push("expression"),
AttrTarget::Pat | AttrTarget::PatArg => allowed_argument_kinds.push("pattern"),
AttrTarget::TyArg => allowed_argument_kinds.push("type argument"),
AttrTarget::Field => allowed_argument_kinds.push("field"),
AttrTarget::EnumVariant => allowed_argument_kinds.push("enum variant"),
AttrTarget::MatchCase => allowed_argument_kinds.push("match case"),
_ => {}
}
}
let allowed_argument_kinds = self
.iter()
.map(|item| match item {
AttrTarget::ConstructorCall => "constructor call",
AttrTarget::MacroInvocation => "directive",
AttrTarget::Unsafe => "unsafe expression",
AttrTarget::Lit => "literal",
AttrTarget::Loop => "loop block",
AttrTarget::Match => "match block",
AttrTarget::ImplDef => "impl block",
AttrTarget::Mod => "module",
AttrTarget::ModDef => "mod block",
AttrTarget::Block => "body block",
AttrTarget::Import => "import",
AttrTarget::StructDef => "`struct` definition",
AttrTarget::EnumDef => "`enum` definition",
AttrTarget::TyFnDef => "implicit function definition",
AttrTarget::FnDef => "`function` definition",
AttrTarget::Ty => "type",
AttrTarget::Expr => "expression",
AttrTarget::Pat | AttrTarget::PatArg => "pattern",
AttrTarget::TyArg => "type argument",
AttrTarget::Field => "field",
AttrTarget::EnumVariant => "enum variant",
AttrTarget::MatchCase => "match case",
AttrTarget::TraitDef => "trait definition",
_ => unreachable!(),
})
.collect_vec();

write!(
f,
Expand Down
112 changes: 50 additions & 62 deletions compiler/hash-attrs/src/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ use hash_tir::{
use hash_utils::{
fxhash::FxHashMap,
index_vec::{define_index_type, IndexVec},
lazy_static,
};

use crate::target::AttrTarget;
Expand Down Expand Up @@ -92,18 +91,11 @@ impl AttrTy {
}
}

// @@Future: add more complex rules which allow to specify more exotic types,
// i.e. a list of values.
macro_rules! make_ty {
(str) => {
Ty::data(primitives().str())
};
(int) => {
Ty::data(primitives().i32())
};
(float) => {
Ty::data(primitives().f64())
};
(char) => {
Ty::data(primitives().char())
($kind: ident) => {
Ty::data(primitives().$kind())
};
}

Expand All @@ -115,66 +107,62 @@ macro_rules! define_attr {
($table:expr, $name:ident, ($($arg:ident : $ty:ident),*), $subject:expr) => {
let name: Identifier = stringify!($name).into();

let params = Param::seq_data([
$(
Param { name: sym(name), ty: make_ty!($ty), default: None }
),*
]);
let params = if ${count(arg)} == 0 {
Param::empty_seq()
} else {
Param::seq_data([
$(
Param { name: sym(name), ty: make_ty!($ty), default: None }
),*
])
};

let index = $table.map.push(AttrTy::new(name, params, $subject));
if $table.name_map.insert(name, index).is_some() {
panic!("duplicate attribute name: `{}`", name);
}
};
($table:expr, $name:ident, $subject:expr) => {
let name: Identifier = stringify!($name).into();
let index = $table.map.push(AttrTy::new(name, Param::empty_seq(), $subject));

if $table.name_map.insert(name, index).is_some() {
panic!("duplicate attribute name: `{}`", name);
}
define_attr!($table, $name, (), $subject);
}
}

lazy_static::lazy_static! {
pub static ref ATTR_MAP: LazyLock<AttrTyMap> = {
LazyLock::new(|| {
let mut table = AttrTyMap::new();

// ------------------------------------------
// Internal compiler attributes and tooling.
// ------------------------------------------
define_attr!(table, dump_ast, AttrTarget::all());
define_attr!(table, dump_tir, AttrTarget::all());
define_attr!(table, dump_ir, AttrTarget::FnDef);
define_attr!(table, dump_llvm_ir, AttrTarget::FnDef);
define_attr!(table, layout_of, AttrTarget::StructDef | AttrTarget::EnumDef);


// ------------------------------------------
// Language feature based attributes.
// ------------------------------------------
define_attr!(table, run, AttrTarget::Expr);

// ------------------------------------------
// Function attributes.
// ------------------------------------------
define_attr!(table, lang, AttrTarget::FnDef);
define_attr!(table, entry_point, AttrTarget::FnDef);
define_attr!(table, pure, AttrTarget::FnDef);
define_attr!(table, foreign, AttrTarget::FnDef);
define_attr!(table, no_mangle, AttrTarget::FnDef);
define_attr!(table, link_name, (name: str), AttrTarget::FnDef);

// ------------------------------------------
// Type attributes.
// ------------------------------------------
define_attr!(table, repr, (abi: str), AttrTarget::StructDef | AttrTarget::EnumDef);

table
})
};
}
pub static ATTR_MAP: LazyLock<AttrTyMap> = {
LazyLock::new(|| {
let mut table = AttrTyMap::new();

// ------------------------------------------
// Internal compiler attributes and tooling.
// ------------------------------------------
define_attr!(table, dump_ast, AttrTarget::all());
define_attr!(table, dump_tir, AttrTarget::all());
define_attr!(table, dump_ir, AttrTarget::FnDef);
define_attr!(table, dump_llvm_ir, AttrTarget::FnDef);
define_attr!(table, layout_of, AttrTarget::StructDef | AttrTarget::EnumDef);

// ------------------------------------------
// Language feature based attributes.
// ------------------------------------------
define_attr!(table, run, AttrTarget::Expr);

// ------------------------------------------
// Function attributes.
// ------------------------------------------
define_attr!(table, lang, AttrTarget::FnDef);
define_attr!(table, entry_point, AttrTarget::FnDef);
define_attr!(table, pure, AttrTarget::FnDef);
define_attr!(table, foreign, AttrTarget::FnDef);
define_attr!(table, no_mangle, AttrTarget::FnDef);
define_attr!(table, link_name, (name: str), AttrTarget::FnDef);

// ------------------------------------------
// Type attributes.
// ------------------------------------------
define_attr!(table, repr, (abi: str), AttrTarget::StructDef | AttrTarget::EnumDef);

table
})
};

/// Valid `#[repr(...)]` options, ideally we should be able to just generate
/// this in the macro.
Expand Down

0 comments on commit 073128b

Please sign in to comment.