@@ -9,7 +9,7 @@ use core_types::{Context, ContextDependencies, Cow, MemoHash, ProtoNodeIdentifie
99use dyn_any:: DynAny ;
1010use glam:: IVec2 ;
1111use log:: Metadata ;
12- use rustc_hash:: { FxBuildHasher , FxHashMap } ;
12+ use rustc_hash:: FxHashMap ;
1313use std:: collections:: HashMap ;
1414use std:: collections:: hash_map:: DefaultHasher ;
1515use std:: hash:: { Hash , Hasher } ;
@@ -32,7 +32,7 @@ fn return_true() -> bool {
3232/// An instance of a [`DocumentNodeDefinition`] that has been instantiated in a [`NodeNetwork`].
3333/// Currently, when an instance is made, it lives all on its own without any lasting connection to the definition.
3434/// But we will want to change it in the future so it merely references its definition.
35- #[ derive( Clone , Debug , PartialEq , Hash , DynAny , serde:: Serialize , serde:: Deserialize ) ]
35+ #[ derive( Clone , Debug , PartialEq , DynAny , serde:: Serialize , serde:: Deserialize ) ]
3636pub struct DocumentNode {
3737 /// The inputs to a node, which are either:
3838 /// - From other nodes within this graph [`NodeInput::Node`],
@@ -172,7 +172,7 @@ impl DocumentNode {
172172}
173173
174174/// Represents the possible inputs to a node.
175- #[ derive( Debug , Clone , PartialEq , Hash , DynAny , serde:: Serialize , serde:: Deserialize ) ]
175+ #[ derive( Debug , Clone , PartialEq , Hash , core_types :: CacheHash , DynAny , serde:: Serialize , serde:: Deserialize ) ]
176176pub enum NodeInput {
177177 /// A reference to another node in the same network from which this node can receive its input.
178178 Node { node_id : NodeId , output_index : usize } ,
@@ -196,7 +196,7 @@ pub enum NodeInput {
196196 Inline ( InlineRust ) ,
197197}
198198
199- #[ derive( Debug , Clone , PartialEq , Hash , DynAny , serde:: Serialize , serde:: Deserialize ) ]
199+ #[ derive( Debug , Clone , PartialEq , Hash , core_types :: CacheHash , DynAny , serde:: Serialize , serde:: Deserialize ) ]
200200pub struct InlineRust {
201201 pub expr : String ,
202202 pub ty : Type ,
@@ -208,7 +208,7 @@ impl InlineRust {
208208 }
209209}
210210
211- #[ derive( Debug , Clone , PartialEq , Hash , DynAny , serde:: Serialize , serde:: Deserialize ) ]
211+ #[ derive( Debug , Clone , PartialEq , Hash , core_types :: CacheHash , DynAny , serde:: Serialize , serde:: Deserialize ) ]
212212pub enum DocumentNodeMetadata {
213213 DocumentNodePath ,
214214}
@@ -292,7 +292,7 @@ pub enum OldDocumentNodeImplementation {
292292 Extract ,
293293}
294294
295- #[ derive( Clone , Debug , PartialEq , Hash , DynAny , serde:: Serialize , serde:: Deserialize ) ]
295+ #[ derive( Clone , Debug , PartialEq , core_types :: CacheHash , DynAny , serde:: Serialize , serde:: Deserialize ) ]
296296/// Represents the implementation of a node, which can be a nested [`NodeNetwork`], a proto [`ProtoNodeIdentifier`], or `Extract`.
297297pub enum DocumentNodeImplementation {
298298 /// This describes a (document) node built out of a subgraph of other (document) nodes.
@@ -548,14 +548,22 @@ pub struct NodeNetwork {
548548
549549impl core_types:: CacheHash for NodeNetwork {
550550 fn cache_hash < H : :: core:: hash:: Hasher > ( & self , state : & mut H ) {
551- use core_types:: CacheHash ;
552551 self . exports . cache_hash ( state) ;
552+
553553 let mut nodes: Vec < _ > = self . nodes . iter ( ) . collect ( ) ;
554554 nodes. sort_by_key ( |( id, _) | * id) ;
555555 for ( id, node) in nodes {
556556 id. cache_hash ( state) ;
557557 node. cache_hash ( state) ;
558558 }
559+
560+ let mut scope_injections: Vec < _ > = self . scope_injections . iter ( ) . collect ( ) ;
561+ scope_injections. sort_by_key ( |( key, _) | key. as_str ( ) ) ;
562+ for ( key, ( node_id, ty) ) in scope_injections {
563+ key. cache_hash ( state) ;
564+ node_id. cache_hash ( state) ;
565+ ty. cache_hash ( state) ;
566+ }
559567 }
560568}
561569
@@ -1143,7 +1151,12 @@ fn migrate_call_argument<'de, D: serde::Deserializer<'de>>(deserializer: D) -> R
11431151
11441152impl core_types:: graphene_hash:: CacheHash for DocumentNode {
11451153 fn cache_hash < H : core:: hash:: Hasher > ( & self , state : & mut H ) {
1146- core:: hash:: Hash :: hash ( self , state) ;
1154+ self . inputs . cache_hash ( state) ;
1155+ self . call_argument . cache_hash ( state) ;
1156+ self . implementation . cache_hash ( state) ;
1157+ self . visible . cache_hash ( state) ;
1158+ self . skip_deduplication . cache_hash ( state) ;
1159+ self . context_features . cache_hash ( state) ;
11471160 }
11481161}
11491162
@@ -1265,11 +1278,11 @@ mod test {
12651278 } ;
12661279 network. populate_dependants ( ) ;
12671280 network. flatten_with_fns ( NodeId ( 1 ) , |self_id, inner_id| NodeId ( self_id. 0 * 10 + inner_id. 0 ) , gen_node_id) ;
1268- let flat_network = flat_network ( ) ;
1269- println ! ( "{flat_network :#?}" ) ;
1281+ let expected = flatten_add_expected ( ) ;
1282+ println ! ( "{expected :#?}" ) ;
12701283 println ! ( "{network:#?}" ) ;
12711284
1272- assert_eq ! ( flat_network , network) ;
1285+ assert_eq ! ( expected , network) ;
12731286 }
12741287
12751288 #[ test]
@@ -1356,6 +1369,60 @@ mod test {
13561369 pretty_assertions:: assert_eq!( resolved_network[ 0 ] , construction_network) ;
13571370 }
13581371
1372+ /// Expected output of `flatten_with_fns` on the outer add network.
1373+ /// Contains unresolved `Import` inputs (the call argument still flows through as an import)
1374+ /// and `dependants` populated by the prior `populate_dependants` call.
1375+ fn flatten_add_expected ( ) -> NodeNetwork {
1376+ NodeNetwork {
1377+ exports : vec ! [ NodeInput :: node( NodeId ( 11 ) , 0 ) ] ,
1378+ nodes : [
1379+ (
1380+ NodeId ( 10 ) ,
1381+ DocumentNode {
1382+ inputs : vec ! [ NodeInput :: import( concrete!( u32 ) , 0 ) , NodeInput :: node( NodeId ( 14 ) , 0 ) ] ,
1383+ implementation : DocumentNodeImplementation :: ProtoNode ( ProtoNodeIdentifier :: new ( "core_types::structural::ConsNode" ) ) ,
1384+ original_location : OriginalLocation {
1385+ inputs_source : [ ( Source { node : vec ! [ ] , index : 0 } , 1 ) ] . into ( ) ,
1386+ dependants : vec ! [ vec![ NodeId ( 11 ) ] ] ,
1387+ ..Default :: default ( )
1388+ } ,
1389+ ..Default :: default ( )
1390+ } ,
1391+ ) ,
1392+ (
1393+ NodeId ( 14 ) ,
1394+ DocumentNode {
1395+ inputs : vec ! [ NodeInput :: value( TaggedValue :: U32 ( 2 ) , false ) ] ,
1396+ implementation : DocumentNodeImplementation :: ProtoNode ( ProtoNodeIdentifier :: new ( "core_types::value::ClonedNode" ) ) ,
1397+ original_location : OriginalLocation {
1398+ path : Some ( vec ! [ NodeId ( 4 ) ] ) ,
1399+ dependants : vec ! [ vec![ NodeId ( 1 ) , NodeId ( 10 ) ] ] ,
1400+ ..Default :: default ( )
1401+ } ,
1402+ ..Default :: default ( )
1403+ } ,
1404+ ) ,
1405+ (
1406+ NodeId ( 11 ) ,
1407+ DocumentNode {
1408+ inputs : vec ! [ NodeInput :: node( NodeId ( 10 ) , 0 ) ] ,
1409+ implementation : DocumentNodeImplementation :: ProtoNode ( ProtoNodeIdentifier :: new ( "core_types::ops::AddPairNode" ) ) ,
1410+ original_location : OriginalLocation {
1411+ dependants : vec ! [ vec![ ] ] ,
1412+ ..Default :: default ( )
1413+ } ,
1414+ ..Default :: default ( )
1415+ } ,
1416+ ) ,
1417+ ]
1418+ . into_iter ( )
1419+ . collect ( ) ,
1420+ ..Default :: default ( )
1421+ }
1422+ }
1423+
1424+ /// A fully resolved flat network ready for proto compilation (no `Import` inputs remain).
1425+ /// Used as input to `into_proto_networks` in `resolve_flatten_add_as_proto_network`.
13591426 fn flat_network ( ) -> NodeNetwork {
13601427 NodeNetwork {
13611428 exports : vec ! [ NodeInput :: node( NodeId ( 11 ) , 0 ) ] ,
0 commit comments