From 073128b7bad1a8832b3496fe578690dae5856618 Mon Sep 17 00:00:00 2001 From: Alexander Fedotov Date: Mon, 28 Aug 2023 13:27:31 -0400 Subject: [PATCH] address pr comments --- compiler/hash-attrs/src/lib.rs | 2 +- compiler/hash-attrs/src/target.rs | 68 +++++++++--------- compiler/hash-attrs/src/ty.rs | 112 +++++++++++++----------------- 3 files changed, 86 insertions(+), 96 deletions(-) diff --git a/compiler/hash-attrs/src/lib.rs b/compiler/hash-attrs/src/lib.rs index a9f3d5c5e..2a5abeac7 100644 --- a/compiler/hash-attrs/src/lib.rs +++ b/compiler/hash-attrs/src/lib.rs @@ -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; diff --git a/compiler/hash-attrs/src/target.rs b/compiler/hash-attrs/src/target.rs index 505a1c384..e2d4cdaa1 100644 --- a/compiler/hash-attrs/src/target.rs +++ b/compiler/hash-attrs/src/target.rs @@ -6,6 +6,7 @@ use std::fmt; use hash_ast::ast; use hash_utils::{ bitflags, + itertools::Itertools, printing::{SequenceDisplay, SequenceDisplayOptions, SequenceJoinMode}, }; @@ -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(); } } @@ -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, @@ -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, diff --git a/compiler/hash-attrs/src/ty.rs b/compiler/hash-attrs/src/ty.rs index 41912f0e0..6eb617d26 100644 --- a/compiler/hash-attrs/src/ty.rs +++ b/compiler/hash-attrs/src/ty.rs @@ -15,7 +15,6 @@ use hash_tir::{ use hash_utils::{ fxhash::FxHashMap, index_vec::{define_index_type, IndexVec}, - lazy_static, }; use crate::target::AttrTarget; @@ -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()) }; } @@ -115,11 +107,15 @@ 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() { @@ -127,54 +123,46 @@ macro_rules! define_attr { } }; ($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 = { - 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 = { + 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.