device-driver-mir 2.1.0

Internal compiler crate for the device-driver toolkit
Documentation
use std::collections::HashSet;

use crate::{
    model::{Manifest, Object, Unique, UniqueId},
    passes::{Assumption, Pass},
    search_object,
};
use device_driver_diagnostics::{Diagnostics, DynError, errors::InvalidFieldsetRef};

/// Checks whether all registers and commands point to existing fieldsets
pub struct FieldsetRefsValid;

impl Pass for FieldsetRefsValid {
    const ASSUMPTIONS_MADE: &[Assumption] = &[Assumption::NamesUnique];
    const ASSUMPTIONS_RELEASED: &[Assumption] = &[Assumption::FieldsetRefsValid];

    fn run_pass(
        manifest: &mut Manifest,
        diagnostics: &mut Diagnostics,
    ) -> Result<HashSet<UniqueId>, DynError> {
        let mut removals = HashSet::new();

        for object in manifest.iter_objects() {
            let fieldset_refs = object.fieldset_refs();

            for fieldset_ref in fieldset_refs {
                let pointee = match search_object(manifest, &fieldset_ref) {
                    Some(Object::FieldSet(_)) => continue,
                    Some(found_object) => Some(found_object.name_span()),
                    None => None,
                };

                diagnostics.add(InvalidFieldsetRef {
                    reference: fieldset_ref.span,
                    pointee,
                });

                removals.insert(object.id());
                break;
            }
        }

        Ok(removals)
    }
}