diff --git a/hercules_opt/src/gcm.rs b/hercules_opt/src/gcm.rs index 3f326051a228d731c47e5ae72aac4a3892c363e8..1dcedd97cfa2365d905cb17ea74624349be866b3 100644 --- a/hercules_opt/src/gcm.rs +++ b/hercules_opt/src/gcm.rs @@ -1302,9 +1302,7 @@ enum UTerm { Device(Device), } -fn unify( - mut equations: VecDeque<(UTerm, UTerm)>, -) -> Result<BTreeMap<NodeID, Device>, (NodeID, NodeID)> { +fn unify(mut equations: VecDeque<(UTerm, UTerm)>) -> Result<BTreeMap<NodeID, Device>, NodeID> { let mut theta = BTreeMap::new(); // First, assign devices to nodes when a rule directly says to. @@ -1312,7 +1310,11 @@ fn unify( let (l, r) = equations.pop_front().unwrap(); match (l, r) { (UTerm::Node(n), UTerm::Device(d)) | (UTerm::Device(d), UTerm::Node(n)) => { - theta.insert(n, d); + if let Some(old_d) = theta.insert(n, d) + && old_d != d + { + return Err(n); + } } _ => equations.push_back((l, r)), } @@ -1333,7 +1335,7 @@ fn unify( match (theta.get(&l), theta.get(&r)) { (Some(ld), Some(rd)) => { if ld != rd { - return Err((l, r)); + return Err(l); } else { no_progress_iters = 0; } @@ -1545,12 +1547,11 @@ fn color_nodes( } Some(func_colors) } - Err(inconsistency) => { + Err(id) => { // If unification failed, then there's some node using a node in - // that's expecting a different type than what it got. Pick one and - // add potentially inter-device copies on each def-use edge. We'll - // clean these up later. - let id = inconsistency.0; + // that's expecting a different type than what it got. Add + // potentially inter-device copies on each def-use edge. We'll clean + // these up later. let users: Vec<_> = editor.get_users(id).collect(); let success = editor.edit(|mut edit| { let cons = edit.add_zero_constant(typing[id.idx()]);