Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 27 additions & 18 deletions archmage-macros/src/arcane.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,34 +14,43 @@ impl Parse for crate::engine::boundary::BoundaryOptions {
while !input.is_empty() {
let ident: Ident = input.parse()?;
if !parse_shared_option(&ident, input, &mut args.shared)? {
match ident.to_string().as_str() {
"suppress_const_test" => args.suppress_const_test = true,
"inline_always" => args.inline_always = true,
"nested" | "in_trait" => args.nested = true,
"in_impl" => args.in_impl = true,
with_ident_str(&ident, |s| match s {
"suppress_const_test" => {
args.suppress_const_test = true;
Ok(())
}
"inline_always" => {
args.inline_always = true;
Ok(())
}
"nested" | "in_trait" => {
args.nested = true;
Ok(())
}
"in_impl" => {
args.in_impl = true;
Ok(())
}
"_self" => {
let _: Token![=] = input.parse()?;
args.self_type = Some(input.parse()?);
Ok(())
}
other => {
return Err(syn::Error::new(
ident.span(),
format!(
"unknown arcane argument: `{other}`. Supported: `in_impl`, \
`in_trait` (or `nested`), `_self = Type`, `import_intrinsics`, \
`import_magetypes`, `cfg(feature)`, `suppress_const_test`."
),
));
}
}
other => Err(syn::Error::new(
ident.span(),
format!(
"unknown arcane argument: `{other}`. Supported: `in_impl`, \
`in_trait` (or `nested`), `_self = Type`, `import_intrinsics`, \
`import_magetypes`, `cfg(feature)`, `suppress_const_test`."
),
)),
})?;
}
// Consume optional comma
if input.peek(Token![,]) {
let _: Token![,] = input.parse()?;
}
}

// _self = Type implies nested (inner fn needed for Self replacement)
if args.self_type.is_some() {
args.nested = true;
}
Expand Down
39 changes: 22 additions & 17 deletions archmage-macros/src/attune/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ impl Parse for Call {
let mut entries = Vec::new();
while !inner.is_empty() {
let name: Ident = inner.parse()?;
let (tier, form) = syntax::selector(&name.to_string(), name.span())?;
let (tier, form) =
crate::common::with_ident_str(&name, |s| syntax::selector(s, name.span()))?;
let gate = syntax::gate(&inner)?;
entries.push(Selection {
tier,
Expand All @@ -63,8 +64,11 @@ impl Parse for Call {
selections = Some(entries);
} else {
let name: Ident = input.parse()?;
match name.to_string().as_str() {
"names" => names = syntax::parse_names(input)?,
crate::common::with_ident_str(&name, |kw| match kw {
"names" => {
names = syntax::parse_names(input)?;
Ok(())
}
"using" => {
if proof.is_some() {
return Err(input.error("duplicate using(...)"));
Expand All @@ -75,14 +79,13 @@ impl Parse for Call {
if !inner.is_empty() {
return Err(inner.error("expected one proof expression"));
}
Ok(())
}
_ => {
return Err(syn::Error::new(
name.span(),
"expected a callee list, names(...), or using(...)",
));
}
}
_ => Err(syn::Error::new(
name.span(),
"expected a callee list, names(...), or using(...)",
)),
})?;
}
}
Ok(Self {
Expand Down Expand Up @@ -224,8 +227,7 @@ impl Call {
} else {
None
};
let token: syn::Path =
syn::parse_str(&format!("::{}", tier.token_path)).expect("registered token path");
let token = crate::common::colon_path_tokens(tier.token_path, true);
let runtime = !covered || self.proof.is_some();
let form = if caller.is_none() || runtime {
Form::Proof
Expand Down Expand Up @@ -304,7 +306,7 @@ impl Call {
}

fn selection_condition(caller: Option<Context<'_>>, selection: &Selection) -> Option<TokenStream> {
let mut preds = Vec::new();
let mut preds = crate::common::SmallVec::<TokenStream, 5>::new();
if let Some(arch) = selection.tier.target_arch {
let same_arch = caller.is_some_and(|c| c.target_arch == Some(arch));
if !same_arch {
Expand All @@ -324,10 +326,13 @@ fn selection_condition(caller: Option<Context<'_>>, selection: &Selection) -> Op
if let Some(f) = selection.gate.as_deref() {
preds.push(quote!(feature = #f));
}
match preds.as_slice() {
[] => None,
[only] => Some(only.clone()),
many => Some(quote!(all(#(#many),*))),
match preds.len() {
0 => None,
1 => preds.iter().next().cloned(),
_ => {
let many = preds.iter();
Some(quote!(all(#(#many),*)))
}
}
}

Expand Down
Loading
Loading