imazen / imazen/archmage

#[arcane] should support multi-tier suffixed variant generation like #[rite]

Open
#21 0 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
Rust
Stars
12
Forks
2
Avg merge
13h 55m
Merged PRs (30d)
28

Description

## Summary

`#[rite(v3, v4, neon)]` generates suffixed variants (`fn_v3`, `fn_v4`, `fn_neon`) with `#[target_feature]` + `#[inline]`. `#[arcane]` cannot — it only handles one token type per function, requiring you to manually duplicate the function and rename it for each tier.

This means when you need a hand-tuned intrinsics function for multiple tiers (e.g., SSE2 vs AVX2 vs NEON, all using platform-specific intrinsics), you write the same boilerplate wrapper three times with different names and token types. `#[rite]` already solves this for inner helpers — `#[arcane]` should too for entry points.

## Current state

```rust
// Must write three separate functions manually:
#[arcane(import_intrinsics)]
fn crc32_impl_v4x(_token: X64V4xToken, crc: u32, data: &[u8]) -> u32 { /* VPCLMULQDQ */ }

#[arcane(import_intrinsics)]
fn crc32_impl_x64_crypto(_token: X64CryptoToken, crc: u32, data: &[u8]) -> u32 { /* PCLMULQDQ */ }

#[arcane(import_intrinsics)]
fn crc32_impl_neon_aes(_token: NeonAesToken, crc: u32, data: &[u8]) -> u32 { /* PMULL */ }

fn crc32_impl_scalar(_token: ScalarToken, crc: u32, data: &[u8]) -> u32 { /* slice-by-8 */ }
```

## Proposed

```rust
// arcane generates _v4x, _x64_crypto, _neon_aes suffixed variants + cfg gates
#[arcane(v4x, x64_crypto, neon_aes, import_intrinsics)]
fn crc32_impl(token: Token, crc: u32, data: &[u8]) -> u32 {
// Token replaced per tier, same as #[magetypes]
// Body has access to safe intrinsics via import_intrinsics
// Each variant wrapped with #[target_feature] + safe wrapper
}
```

This mirrors `#[rite]`'s multi-tier mode but produces `#[arcane]`-style safe wrappers (with the optimization boundary) instead of `#[rite]`'s direct `#[target_feature]` + `#[inline]`.

The `Token` substitution would work identically to `#[magetypes]`. The difference: `#[magetypes]` applies `#[arcane]` to each generated variant automatically, while this would be `#[arcane]` doing its own multi-tier generation directly — same end result, but without the two-macro indirection.

## Why not just use `#[magetypes]`?

`#[magetypes]` works well for this today. The main motivation is consistency: `#[rite]` already supports `#[rite(v3, v4, neon)]`, so users expect `#[arcane(v3, v4, neon)]` to work too. Currently the parser rejects it with "unknown arcane argument: `v3`", which is surprising.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by reading the existing multi-tier behavior of #[rite] and the Token substitution performed by #[magetypes], then trace the #[arcane] argument parser that rejects v3. Implement matching multi-tier generation with suffixed variants, cfg gates, target features, safe wrappers, and import_intrinsics behavior. Done means #[arcane(v4x, x64_crypto, neon_aes, import_intrinsics)] produces the described entry points without requiring manual duplication.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.