(&self, hir_id: HirId, target: Target)
| 269 | |
| 270 | impl CheckSpirvAttrVisitor<'_> { |
| 271 | fn check_spirv_attributes(&self, hir_id: HirId, target: Target) { |
| 272 | let mut aggregated_attrs = AggregatedSpirvAttributes::default(); |
| 273 | |
| 274 | let parse_attrs = |attrs| crate::symbols::parse_attrs_for_checking(&self.sym, attrs); |
| 275 | |
| 276 | let attrs = self.tcx.hir().attrs(hir_id); |
| 277 | for parse_attr_result in parse_attrs(attrs) { |
| 278 | let (span, parsed_attr) = match parse_attr_result { |
| 279 | Ok(span_and_parsed_attr) => span_and_parsed_attr, |
| 280 | Err((span, msg)) => { |
| 281 | self.tcx.sess.span_err(span, msg); |
| 282 | continue; |
| 283 | } |
| 284 | }; |
| 285 | |
| 286 | /// Error newtype marker used below for readability. |
| 287 | struct Expected<T>(T); |
| 288 | |
| 289 | let valid_target = match parsed_attr { |
| 290 | SpirvAttribute::IntrinsicType(_) | SpirvAttribute::Block => match target { |
| 291 | Target::Struct => { |
| 292 | // FIXME(eddyb) further check type attribute validity, |
| 293 | // e.g. layout, generics, other attributes, etc. |
| 294 | Ok(()) |
| 295 | } |
| 296 | |
| 297 | _ => Err(Expected("struct")), |
| 298 | }, |
| 299 | |
| 300 | SpirvAttribute::Entry(_) => match target { |
| 301 | Target::Fn |
| 302 | | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => { |
| 303 | // FIXME(eddyb) further check entry-point attribute validity, |
| 304 | // e.g. signature, shouldn't have `#[inline]` or generics, etc. |
| 305 | Ok(()) |
| 306 | } |
| 307 | |
| 308 | _ => Err(Expected("function")), |
| 309 | }, |
| 310 | |
| 311 | SpirvAttribute::StorageClass(_) |
| 312 | | SpirvAttribute::Builtin(_) |
| 313 | | SpirvAttribute::DescriptorSet(_) |
| 314 | | SpirvAttribute::Binding(_) |
| 315 | | SpirvAttribute::Flat |
| 316 | | SpirvAttribute::Invariant |
| 317 | | SpirvAttribute::InputAttachmentIndex(_) |
| 318 | | SpirvAttribute::SpecConstant(_) => match target { |
| 319 | Target::Param => { |
| 320 | let parent_hir_id = self.tcx.hir().parent_id(hir_id); |
| 321 | let parent_is_entry_point = |
| 322 | parse_attrs(self.tcx.hir().attrs(parent_hir_id)) |
| 323 | .filter_map(|r| r.ok()) |
| 324 | .any(|(_, attr)| matches!(attr, SpirvAttribute::Entry(_))); |
| 325 | if !parent_is_entry_point { |
| 326 | self.tcx.sess.span_err( |
| 327 | span, |
| 328 | "attribute is only valid on a parameter of an entry-point function", |
no test coverage detected