diff --git a/src/transform/expand_extends.rs b/src/transform/expand_extends.rs index 768fdaa..caa41ab 100644 --- a/src/transform/expand_extends.rs +++ b/src/transform/expand_extends.rs @@ -1,3 +1,4 @@ +use anyhow::{bail, Result}; use log::*; use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, BTreeSet}; @@ -15,7 +16,7 @@ impl ExpandExtends { .iter() .map(|(k, v)| (k.clone(), v.extends.clone())) .collect(); - for name in topological_sort(deps) { + for name in topological_sort(deps)? { let block = ir.blocks.get(&name).unwrap(); if let Some(parent_name) = &block.extends { let parent = ir.blocks.get(parent_name).unwrap(); @@ -36,7 +37,7 @@ impl ExpandExtends { .iter() .map(|(k, v)| (k.clone(), v.extends.clone())) .collect(); - for name in topological_sort(deps) { + for name in topological_sort(deps)? { let fieldset = ir.fieldsets.get(&name).unwrap(); if let Some(parent_name) = &fieldset.extends { let parent = ir.fieldsets.get(parent_name).unwrap(); @@ -56,19 +57,23 @@ impl ExpandExtends { } } -fn topological_sort(vals: BTreeMap>) -> Vec { +fn topological_sort(vals: BTreeMap>) -> Result> { for (name, dep) in &vals { - info!("{:?} => {:?}", name, dep); + info!("{:?} → {:?}", name, dep); } let mut done = BTreeSet::new(); let mut res = Vec::new(); + while done.len() != vals.len() { for (name, dep) in &vals { if done.contains(name) { continue; } if let Some(dep) = dep { + if !vals.contains_key(dep) { + bail!("Couldn't resolve dependency for {name} → {dep}"); + } if !done.contains(dep) { continue; } @@ -78,5 +83,6 @@ fn topological_sort(vals: BTreeMap>) -> Vec { res.push(name.clone()); } } - res + + Ok(res) }