Skip to content

Commit fa6a953

Browse files
committed
tool: simplify attr parsing 2
1 parent 7a140a7 commit fa6a953

File tree

1 file changed

+71
-60
lines changed
  • crates/rustc_codegen_spirv/src

1 file changed

+71
-60
lines changed

crates/rustc_codegen_spirv/src/attr.rs

Lines changed: 71 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use rustc_middle::hir::nested_filter;
1414
use rustc_middle::query::Providers;
1515
use rustc_middle::ty::TyCtxt;
1616
use rustc_span::{Ident, Span, Symbol};
17+
use smallvec::SmallVec;
1718
use std::rc::Rc;
1819

1920
// FIXME(eddyb) replace with `ArrayVec<[Word; 3]>`.
@@ -529,25 +530,33 @@ fn parse_attrs_for_checking<'a>(
529530
Attribute::Unparsed(item) => {
530531
// #[...]
531532
let s = &item.path.segments;
532-
if s.len() > 1 && s[0].name == sym.rust_gpu {
533+
if let Some(rust_gpu) = s.get(0)
534+
&& rust_gpu.name == sym.rust_gpu
535+
{
533536
// #[rust_gpu ...]
534-
if s.len() != 2 || s[1].name != sym.spirv {
535-
// #[rust_gpu::...] but not #[rust_gpu::spirv]
536-
Err((
537-
attr.span(),
538-
"unknown `rust_gpu` attribute, expected `rust_gpu::spirv`"
539-
.to_string(),
540-
))
541-
} else if let Some(args) = attr.meta_item_list() {
542-
// #[rust_gpu::spirv(...)]
543-
Ok(args)
544-
} else {
545-
// #[rust_gpu::spirv]
546-
Err((
547-
attr.span(),
548-
"#[rust_gpu::spirv(..)] attribute must have at least one argument"
549-
.to_string(),
550-
))
537+
match s.get(1) {
538+
Some(command) if command.name == sym.spirv => {
539+
// #[rust_gpu::spirv ...]
540+
if let Some(args) = attr.meta_item_list() {
541+
// #[rust_gpu::spirv(...)]
542+
Ok(parse_spirv_attr(sym, args.iter()))
543+
} else {
544+
// #[rust_gpu::spirv]
545+
Err((
546+
attr.span(),
547+
"#[spirv(..)] attribute must have at least one argument"
548+
.to_string(),
549+
))
550+
}
551+
}
552+
_ => {
553+
// #[rust_gpu::...] but not a know version
554+
Err((
555+
attr.span(),
556+
"unknown `rust_gpu` attribute, expected `rust_gpu::spirv`"
557+
.to_string(),
558+
))
559+
}
551560
}
552561
} else {
553562
// #[...] but not #[rust_gpu ...]
@@ -558,52 +567,54 @@ fn parse_attrs_for_checking<'a>(
558567
}
559568
})
560569
.flat_map(|result| {
561-
// parse each element of the inner list
562-
let (v, e) = match result {
563-
Ok(v) => (Some(v), None),
564-
Err(e) => (None, Some(e)),
565-
};
566-
v.unwrap_or_default()
570+
result
571+
.unwrap_or_else(|err| SmallVec::from_iter([Err(err)]))
567572
.into_iter()
568-
.map(|ref arg| {
569-
let span = arg.span();
570-
let parsed_attr = if arg.has_name(sym.descriptor_set) {
571-
SpirvAttribute::DescriptorSet(parse_attr_int_value(arg)?)
572-
} else if arg.has_name(sym.binding) {
573-
SpirvAttribute::Binding(parse_attr_int_value(arg)?)
574-
} else if arg.has_name(sym.input_attachment_index) {
575-
SpirvAttribute::InputAttachmentIndex(parse_attr_int_value(arg)?)
576-
} else if arg.has_name(sym.spec_constant) {
577-
SpirvAttribute::SpecConstant(parse_spec_constant_attr(sym, arg)?)
578-
} else {
579-
let name = match arg.ident() {
580-
Some(i) => i,
581-
None => {
582-
return Err((
583-
span,
584-
"#[spirv(..)] attribute argument must be single identifier"
585-
.to_string(),
586-
));
587-
}
588-
};
589-
sym.attributes.get(&name.name).map_or_else(
590-
|| Err((name.span, "unknown argument to spirv attribute".to_string())),
591-
|a| {
592-
Ok(match a {
593-
SpirvAttribute::Entry(entry) => SpirvAttribute::Entry(
594-
parse_entry_attrs(sym, arg, &name, entry.execution_model)?,
595-
),
596-
_ => a.clone(),
597-
})
598-
},
599-
)?
600-
};
601-
Ok((span, parsed_attr))
602-
})
603-
.chain(e.map(|e| Err(e)))
604573
})
605574
}
606575

576+
fn parse_spirv_attr<'a>(
577+
sym: &Symbols,
578+
iter: impl Iterator<Item = &'a MetaItemInner>,
579+
) -> SmallVec<[Result<(Span, SpirvAttribute), ParseAttrError>; 4]> {
580+
iter.map(|arg| {
581+
let span = arg.span();
582+
let parsed_attr =
583+
if arg.has_name(sym.descriptor_set) {
584+
SpirvAttribute::DescriptorSet(parse_attr_int_value(arg)?)
585+
} else if arg.has_name(sym.binding) {
586+
SpirvAttribute::Binding(parse_attr_int_value(arg)?)
587+
} else if arg.has_name(sym.input_attachment_index) {
588+
SpirvAttribute::InputAttachmentIndex(parse_attr_int_value(arg)?)
589+
} else if arg.has_name(sym.spec_constant) {
590+
SpirvAttribute::SpecConstant(parse_spec_constant_attr(sym, arg)?)
591+
} else {
592+
let name = match arg.ident() {
593+
Some(i) => i,
594+
None => {
595+
return Err((
596+
span,
597+
"#[spirv(..)] attribute argument must be single identifier".to_string(),
598+
));
599+
}
600+
};
601+
sym.attributes.get(&name.name).map_or_else(
602+
|| Err((name.span, "unknown argument to spirv attribute".to_string())),
603+
|a| {
604+
Ok(match a {
605+
SpirvAttribute::Entry(entry) => SpirvAttribute::Entry(
606+
parse_entry_attrs(sym, arg, &name, entry.execution_model)?,
607+
),
608+
_ => a.clone(),
609+
})
610+
},
611+
)?
612+
};
613+
Ok((span, parsed_attr))
614+
})
615+
.collect()
616+
}
617+
607618
fn parse_spec_constant_attr(
608619
sym: &Symbols,
609620
arg: &MetaItemInner,

0 commit comments

Comments
 (0)