@@ -48,7 +48,8 @@ use crate::protocol::{address::AztecAddress, traits::{Deserialize, Serialize}};
4848/// - `CallSelfStatic`: Macro-generated type for calling contract's own view functions
4949/// - `EnqueueSelfStatic`: Macro-generated type for enqueuing calls to the contract's own view functions
5050/// - `CallInternal`: Macro-generated type for calling internal functions
51- pub struct ContractSelfPrivate <Storage , CallSelf , EnqueueSelf , CallSelfStatic , EnqueueSelfStatic , CallInternal > {
51+ /// - `CallSelfUtility`: Macro-generated type for calling the contract's own utility functions
52+ pub struct ContractSelfPrivate <Storage , CallSelf , EnqueueSelf , CallSelfStatic , EnqueueSelfStatic , CallInternal , CallSelfUtility > {
5253 /// The address of this contract
5354 pub address : AztecAddress ,
5455
@@ -110,17 +111,17 @@ pub struct ContractSelfPrivate<Storage, CallSelf, EnqueueSelf, CallSelfStatic, E
110111 /// ```
111112 pub internal : CallInternal ,
112113
113- /// Gateway for calling utility functions from this private context.
114+ /// A struct that allows for ergonomic calling of utility functions from this private context.
114115 ///
115116 /// Example API:
116117 /// ```noir
117118 /// // Safety: result is unconstrained
118119 /// unsafe { self.utility.call(MyContract::at(address).my_utility_function(args)) }
119120 /// ```
120- pub utility : PrivateUtility ,
121+ pub utility : PrivateUtilityCalls < CallSelfUtility > ,
121122}
122123
123- impl <Storage , CallSelf , EnqueueSelf , CallSelfStatic , EnqueueSelfStatic , CallInternal > ContractSelfPrivate <Storage , CallSelf , EnqueueSelf , CallSelfStatic , EnqueueSelfStatic , CallInternal > {
124+ impl <Storage , CallSelf , EnqueueSelf , CallSelfStatic , EnqueueSelfStatic , CallInternal , CallSelfUtility > ContractSelfPrivate <Storage , CallSelf , EnqueueSelf , CallSelfStatic , EnqueueSelfStatic , CallInternal , CallSelfUtility > {
124125 /// Creates a new `ContractSelfPrivate` instance for a private function.
125126 ///
126127 /// This constructor is called automatically by the macro system and should not be called directly.
@@ -132,6 +133,7 @@ impl<Storage, CallSelf, EnqueueSelf, CallSelfStatic, EnqueueSelfStatic, CallInte
132133 call_self_static : CallSelfStatic ,
133134 enqueue_self_static : EnqueueSelfStatic ,
134135 internal : CallInternal ,
136+ utility : PrivateUtilityCalls <CallSelfUtility >,
135137 ) -> Self {
136138 Self {
137139 context ,
@@ -142,7 +144,7 @@ impl<Storage, CallSelf, EnqueueSelf, CallSelfStatic, EnqueueSelfStatic, CallInte
142144 call_self_static ,
143145 enqueue_self_static ,
144146 internal ,
145- utility : PrivateUtility {} ,
147+ utility ,
146148 }
147149 }
148150
@@ -407,16 +409,31 @@ impl<Storage, CallSelf, EnqueueSelf, CallSelfStatic, EnqueueSelfStatic, CallInte
407409 }
408410}
409411
410- /// Gateway for calling utility functions from a private context.
412+ /// A struct that allows for ergonomic calling of utility functions from a private context.
411413///
412414/// Accessible via `self.utility` in private functions. Results are not part of any circuit
413415/// proof; use them to inform logic, not as inputs to constrained assertions.
414- // Implemented as a separate empty struct because Noir does not allow passing `&mut PrivateContext`
415- // (held by `ContractSelfPrivate`) into unconstrained code. This struct holds no mutable references,
416- // so it can be passed freely into `unconstrained` functions.
417- pub struct PrivateUtility {}
416+ ///
417+ /// ## Type Parameters
418+ ///
419+ /// - `CallSelf`: Macro-generated type for calling the contract's own utility functions (same type
420+ /// as `CallSelf` in \[`ContractSelfUtility`\])
421+ // Implemented as a separate struct (rather than inlined in ContractSelfPrivate) because Noir does
422+ // not allow passing `&mut PrivateContext` (held by `ContractSelfPrivate`) into unconstrained code.
423+ // This struct holds no mutable references, so it can be passed freely into `unconstrained`
424+ // functions.
425+ pub struct PrivateUtilityCalls <CallSelf > {
426+ /// Provides type-safe methods for calling this contract's own utility functions.
427+ ///
428+ /// Example API:
429+ /// ```noir
430+ /// // Safety: result is unconstrained
431+ /// unsafe { self.utility.call_self.some_utility_function(args) }
432+ /// ```
433+ pub call_self : CallSelf ,
434+ }
418435
419- impl PrivateUtility {
436+ impl < CallSelf > PrivateUtilityCalls < CallSelf > {
420437 /// Makes a utility contract call from a private function.
421438 ///
422439 /// Note: only same-contract utility calls are currently supported. See TODO(F-29).
0 commit comments