diff --git a/crates/graph/src/nodes/context/typing.rs b/crates/graph/src/nodes/context/typing.rs index 68d2e25e..0c64b7ee 100644 --- a/crates/graph/src/nodes/context/typing.rs +++ b/crates/graph/src/nodes/context/typing.rs @@ -89,6 +89,7 @@ impl ContextNode { .underlying(analyzer)? .inherits .iter() + .filter_map(|i| i.as_ref()) .any(|inherited| *inherited == fn_ctrt)) } else { Ok(false) diff --git a/crates/graph/src/nodes/contract_ty.rs b/crates/graph/src/nodes/contract_ty.rs index 4e946351..a91138c3 100644 --- a/crates/graph/src/nodes/contract_ty.rs +++ b/crates/graph/src/nodes/contract_ty.rs @@ -108,7 +108,7 @@ impl ContractNode { self.underlying_mut(analyzer) .unwrap() .inherits - .push(ContractNode::from(*found)); + .push(Some(ContractNode::from(*found))); analyzer.add_edge(*found, *self, Edge::InheritedContract); }); self.order_inherits(analyzer); @@ -119,17 +119,25 @@ impl ContractNode { let inherits = self.underlying(analyzer).unwrap().inherits.clone(); let mut tmp_inherits = vec![]; - tmp_inherits.resize(inherits.len(), ContractNode::from(NodeIdx::from(0))); + tmp_inherits.resize(inherits.len(), None); inherits.into_iter().for_each(|inherited| { - let i_name = inherited.name(analyzer).unwrap(); - let position = raw_inherits.iter().position(|raw| &i_name == raw).unwrap(); - tmp_inherits[position] = inherited; + if let Some(inherited) = inherited { + let i_name = inherited.name(analyzer).unwrap(); + let position = raw_inherits.iter().position(|raw| &i_name == raw).unwrap(); + tmp_inherits[position] = Some(inherited); + } }); self.underlying_mut(analyzer).unwrap().inherits = tmp_inherits; } pub fn direct_inherited_contracts(&self, analyzer: &impl GraphBackend) -> Vec { - self.underlying(analyzer).unwrap().inherits.clone() + self.underlying(analyzer) + .unwrap() + .inherits + .iter() + .filter_map(|i| i.as_ref()) + .cloned() + .collect() } pub fn all_inherited_contracts(&self, analyzer: &impl GraphBackend) -> Vec { @@ -384,7 +392,7 @@ pub struct Contract { /// Raw inherited strings, ordered by least base to most base pub raw_inherits: Vec, /// A list of contracts that this contract inherits (TODO: inheritance linearization) - pub inherits: Vec, + pub inherits: Vec>, /// Cached linearized functions pub cached_functions: Option>, } @@ -416,7 +424,7 @@ impl Contract { { let name = ContractNode::from(contract).name(analyzer).unwrap(); if &name == inherited_name { - inherits.push(ContractNode::from(contract)); + inherits.push(Some(ContractNode::from(contract))); found = true; break; } @@ -430,7 +438,7 @@ impl Contract { { let name = ContractNode::from(contract).name(analyzer).unwrap(); if &name == inherited_name { - inherits.push(ContractNode::from(contract)); + inherits.push(Some(ContractNode::from(contract))); found = true; break; } @@ -462,11 +470,13 @@ impl Contract { let inherits = self.inherits.clone(); let mut tmp_inherits = vec![]; - tmp_inherits.resize(inherits.len(), ContractNode::from(NodeIdx::from(0))); + tmp_inherits.resize(raw_inherits.len(), None); inherits.into_iter().for_each(|inherited| { - let i_name = inherited.name(analyzer).unwrap(); - let position = raw_inherits.iter().position(|raw| &i_name == raw).unwrap(); - tmp_inherits[position] = inherited; + if let Some(inherited) = inherited { + let i_name = inherited.name(analyzer).unwrap(); + let position = raw_inherits.iter().position(|raw| &i_name == raw).unwrap(); + tmp_inherits[position] = Some(inherited); + } }); self.inherits = tmp_inherits; } diff --git a/crates/pyrometer/src/analyzer.rs b/crates/pyrometer/src/analyzer.rs index 82665d06..6aeda249 100644 --- a/crates/pyrometer/src/analyzer.rs +++ b/crates/pyrometer/src/analyzer.rs @@ -1049,8 +1049,8 @@ impl Analyzer { node.into() }; - inherits.iter().for_each(|contract_node| { - self.add_edge(*contract_node, con_node, Edge::InheritedContract); + inherits.into_iter().flatten().for_each(|contract_node| { + self.add_edge(contract_node, con_node, Edge::InheritedContract); }); let mut usings = vec![];