Skip to main content

pliron_derive/
lib.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) The pliron contributors
3
4mod derive_attr;
5mod derive_decontext;
6mod derive_entity;
7mod derive_format;
8mod derive_op;
9mod derive_type;
10mod interfaces;
11mod irfmt;
12mod verify_succ;
13
14use proc_macro::TokenStream;
15use syn::parse_quote;
16
17use derive_format::DeriveIRObject;
18
19/// A hash map with a fast, non-cryptographic hasher and deterministic iteration order.
20type IMap<K, V> = indexmap::IndexMap<K, V, rustc_hash::FxBuildHasher>;
21
22/// `#[def_attribute(...)]`: Annotate a Rust struct as a new IR attribute.
23///
24/// *Note*: It is suggested to use the [pliron_attr] macro instead of using this macro directly.
25///         The documention here is useful though, because [pliron_attr]'s `name` field expands
26///         to this macro.
27///
28/// The argument to the macro is the fully qualified name of the attribute in the form of
29/// `"dialect.attribute_name"`.
30///
31/// The macro will leave the struct definition unchanged, but it will generate an implementation of
32/// the pliron::Attribute trait and implements other internal traits and types resources required
33/// to use the IR attribute.
34///
35/// **Note**: pre-requisite traits for `Attribute` must already be implemented.
36///         Additionaly, [Eq] and [Hash](core::hash::Hash) must be implemented by the type.
37///
38/// Usage:
39///
40/// ```
41/// use pliron::derive::{def_attribute, format_attribute, verify_succ};
42///
43/// #[verify_succ]
44/// #[def_attribute("my_dialect.attribute")]
45/// #[format_attribute]
46/// #[derive(Debug, Clone, PartialEq, Eq, Hash)]
47/// pub struct StringAttr(String);
48/// # use pliron::{printable::{State, Printable}, context::Context};
49/// ```
50#[proc_macro_attribute]
51pub fn def_attribute(args: TokenStream, input: TokenStream) -> TokenStream {
52    to_token_stream(derive_attr::def_attribute(args, input))
53}
54
55/// `#[def_type(...)]`: Annotate a Rust struct as a new IR type.
56///
57/// *Note*: It is suggested to use the [pliron_type] macro instead of using this macro directly.
58///         The documention here is useful though, because [pliron_type]'s `name` field expands
59///         to this macro.
60///
61/// The argument to the macro is the fully qualified name of the type in the form of
62/// `"dialect.type_name"`.
63///
64/// The macro will leave the struct definition unchanged, but it will generate an implementation of
65/// the pliron::Type trait and implements other internal traits and types resources required
66/// to use the IR type.
67///
68/// **Note**: pre-requisite traits for `Type` must already be implemented.
69///         Additionaly, [Hash](core::hash::Hash) and [Eq] must be implemented by the rust type.
70///
71/// Usage:
72///
73/// ```
74/// use pliron::derive::{def_type, format_type, verify_succ};
75/// #[verify_succ]
76/// #[def_type("my_dialect.unit")]
77/// #[format_type]
78/// #[derive(Debug, Clone, PartialEq, Eq, Hash)]
79/// pub struct UnitType;
80/// ```
81#[proc_macro_attribute]
82pub fn def_type(args: TokenStream, input: TokenStream) -> TokenStream {
83    to_token_stream(derive_type::def_type(args, input))
84}
85
86/// Derive get methods for types that retrieve interned types.
87///
88/// *Note*: It is suggested to use the [pliron_type] macro instead of using this macro directly.
89///         The documention here is useful though, because [pliron_type]'s `generate_get` field
90///         expands to this macro.
91///
92/// This macro generates a `get` method that returns a uniqued instance of the type.
93/// For unit structs (no fields), it takes only a `Context` parameter.
94/// For structs with fields, it takes a `Context` parameter plus a parameter for each field.
95///
96/// ## Examples
97///
98/// ### Named fields struct:
99/// ```
100/// use pliron::derive::{def_type, derive_type_get, format_type, verify_succ};
101/// use pliron::context::Context;
102///
103/// #[verify_succ]
104/// #[def_type("my_dialect.vector_type")]
105/// #[format_type]
106/// #[derive_type_get]  // Auto-generates get method
107/// #[derive(Debug, Clone, PartialEq, Eq, Hash)]
108/// pub struct VectorType {
109///     elem_ty: u32,
110///     num_elems: u32,
111/// }
112///
113/// // Usage of the auto-generated get method:
114/// # fn example(ctx: &Context) {
115/// let vector_type = VectorType::get(ctx, 42, 8); // get(ctx, elem_ty, num_elems)
116/// # }
117/// ```
118///
119/// ### Tuple struct:
120/// ```
121/// use pliron::derive::{def_type, derive_type_get, format_type, verify_succ};
122/// use pliron::context::Context;
123///
124/// #[verify_succ]
125/// #[def_type("my_dialect.tuple_type")]
126/// #[format_type]
127/// #[derive_type_get]  // Auto-generates get method
128/// #[derive(Debug, Clone, PartialEq, Eq, Hash)]
129/// pub struct TupleType(u32, String, bool);
130///
131/// // Usage of the auto-generated get method:
132/// # fn example(ctx: &Context) {
133/// let tuple_type = TupleType::get(ctx, 42, "hello".to_string(), true); // get(ctx, field_0, field_1, field_2)
134/// # }
135/// ```
136///
137/// ### Unit struct:
138/// ```
139/// use pliron::derive::{def_type, derive_type_get, format_type, verify_succ};
140/// use pliron::context::Context;
141///
142/// #[verify_succ]
143/// #[def_type("my_dialect.unit_type")]
144/// #[format_type]
145/// #[derive_type_get]  // Auto-generates get method
146/// #[derive(Debug, Clone, PartialEq, Eq, Hash)]
147/// pub struct UnitType;
148///
149/// // Usage of the auto-generated get method:
150/// # fn example(ctx: &Context) {
151/// let unit_type = UnitType::get(ctx); // get(ctx) - no additional parameters
152/// # }
153/// ```
154#[proc_macro_attribute]
155pub fn derive_type_get(args: TokenStream, input: TokenStream) -> TokenStream {
156    to_token_stream(derive_type::derive_type_get(args, input))
157}
158
159/// `#[verify_succ]`: Implement [Verify](../pliron/common_traits/trait.Verify.html)
160/// for a Rust struct or enum with a verifier that always succeeds.
161///
162/// This leaves the original item unchanged and adds:
163/// `impl Verify for T { fn verify(...) -> Result<()> { Ok(()) } }`.
164///
165/// Usage:
166///
167/// ```
168/// use pliron::derive::verify_succ;
169/// use pliron::{common_traits::Verify, context::Context};
170///
171/// #[verify_succ]
172/// struct AlwaysValid;
173///
174/// let ctx = Context::new();
175/// assert!(AlwaysValid.verify(&ctx).is_ok());
176/// ```
177#[proc_macro_attribute]
178pub fn verify_succ(args: TokenStream, input: TokenStream) -> TokenStream {
179    to_token_stream(verify_succ::verify_succ_impl(args.into(), input.into()))
180}
181
182/// `#[def_op(...)]`: Create a new IR operation.
183///
184/// *Note*: It is suggested to use the [pliron_op] macro instead of using this macro directly.
185///         The documention here is useful though, because [pliron_op]'s `name` field expands
186///         to this macro.
187///
188/// The argument to the macro is the fully qualified name of the operation in the form of
189/// `"dialect.op_name"`.
190///
191/// The macro assumes an empty struct and will add the `op: Ptr<Operation>` field used to access
192/// the underlying Operation in the context.
193///
194/// The macro will automatically derive the `Clone`, `Copy`, `Hash`, `PartialEq` and `Eq` traits
195/// for the new struct definition.
196///
197/// **Note**: pre-requisite traits for `Op` (Printable, Verify etc) must already be implemented
198///
199/// Usage:
200///
201/// ```
202/// use pliron::derive::{def_op, format_op, verify_succ};
203///
204/// #[verify_succ]
205/// #[def_op("my_dialect.op")]
206/// #[format_op]
207/// pub struct MyOp;
208/// ```
209/// The example will create a struct definition equivalent to:
210///
211/// ```
212/// #[derive(Clone, Copy, PartialEq, Eq, Hash)]
213/// pub struct MyOp {
214///   op: Ptr<Operation>,
215/// }
216/// # use pliron::{context::Ptr, operation::Operation};
217/// ```
218#[proc_macro_attribute]
219pub fn def_op(args: TokenStream, input: TokenStream) -> TokenStream {
220    to_token_stream(derive_op::def_op(args, input))
221}
222
223/// Derive getter and setters for operation attributes listed as arguments.
224///
225/// *Note*: It is suggested to use the [pliron_op] macro instead of using this macro directly.
226///         The documention here is useful though, because [pliron_op]'s `attributes` field
227///         expands to this macro.
228///
229/// The arguments are a comma separated list of attribute names
230/// (which must be an [Identifier](../pliron/identifier/struct.Identifier.html)),
231/// each of which may have an optional concrete Rust type specified,
232/// denoting the [Attribute](../pliron/attribute/trait.Attribute.html)'s concrete type.
233///
234/// ```
235/// # use pliron::derive::{def_op, derive_attr_get_set, format_op, verify_succ};
236/// // A test for the `derive_attr_get_set` macro.
237/// #[verify_succ]
238/// #[def_op("llvm.with_attrs")]
239/// #[format_op]
240/// #[derive_attr_get_set(name1_any_attr, name2_ty_attr : pliron::builtin::attributes::TypeAttr)]
241/// pub struct WithAttrsOp {}
242/// ```
243///
244/// This expands to add the following getter / setter items:
245/// ```Rust
246/// # use pliron::derive::{def_op, format_op, derive_attr_get_set};
247/// # use core::cell::Ref;
248/// # use pliron::dict_key;
249/// # use pliron::{attribute::AttrObj, context::Context};
250/// # use pliron::{builtin::attributes::TypeAttr};
251/// # use pliron::derive::verify_succ;
252/// # #[verify_succ]
253/// #[format_op]
254/// #[def_op("llvm.with_attrs")]
255/// pub struct WithAttrsOp {}
256/// dict_key!(ATTR_KEY_NAME1_ANY_ATTR, "name1_any_attr");
257/// dict_key!(ATTR_KEY_NAME2_TY_ATTR, "name2_ty_attr");
258/// impl WithAttrsOp {
259///   pub fn get_attr_name1_any_attr<'a>
260///     (&self, ctx: &'a Context)-> Option<Ref<'a, AttrObj>> { todo!() }
261///   pub fn set_attr_name1_any_attr(&self, ctx: &Context, value: AttrObj) { todo!() }
262///   pub fn get_attr_name2_ty_attr<'a>
263///     (&self, ctx: &'a Context) -> Option<Ref<'a, TypeAttr>> { todo!() }
264///   pub fn set_attr_name2_ty_attr(&self, ctx: &Context, value: TypeAttr) { todo!() }
265/// }
266/// ```
267#[proc_macro_attribute]
268pub fn derive_attr_get_set(args: TokenStream, input: TokenStream) -> TokenStream {
269    to_token_stream(derive_op::derive_attr_get_set(args, input))
270}
271
272/// Derive getter methods and / or operand type interfaces for operation operands.
273///
274/// *Note*: It is suggested to use the [pliron_op] macro instead of using this macro directly.
275///         The documention here is useful though, because [pliron_op]'s `operands` field expands
276///         to this macro.
277///
278/// The arguments are a comma-separated list where each entry is:
279/// - `name` or `name: Type` for a named operand getter `get_operand_<name>()`.
280/// - `_` or `_: Type` to skip getter generation for that position.
281///
282/// When `Type` is provided, this macro derives
283/// [OperandNOfType](../pliron/builtin/op_interfaces/trait.OperandNOfType.html)
284/// for the corresponding operand index.
285///
286/// The op is allowed to have more operands than those specified in the macro arguments.
287/// They just won't have getters or type interfaces generated for them.
288///
289/// ```
290/// use pliron::derive::{def_op, format_op, operands, verify_succ};
291/// use pliron::builtin::types::{IntegerType, UnitType};
292///
293/// #[verify_succ]
294/// #[def_op("dialect.with_operands")]
295/// #[format_op]
296/// #[operands(lhs: IntegerType, _, rhs, _: UnitType)]
297/// pub struct WithOperandsOp {}
298/// ```
299#[proc_macro_attribute]
300pub fn operands(args: TokenStream, input: TokenStream) -> TokenStream {
301    to_token_stream(derive_op::operands(args, input))
302}
303
304/// Derive getter methods and / or result type interfaces for operation results.
305///
306/// *Note*: It is suggested to use the [pliron_op] macro instead of using this macro directly.
307///         The documention here is useful though, because [pliron_op]'s `results` field expands
308///         to this macro.
309///
310/// The arguments are a comma-separated list where each entry is:
311/// - `name` or `name: Type` for a named result getter `get_result_<name>()`.
312/// - `_` or `_: Type` to skip getter generation for that position.
313///
314/// When `Type` is provided, this macro derives
315/// [ResultNOfType](../pliron/builtin/op_interfaces/trait.ResultNOfType.html)
316/// for the corresponding result index.
317///
318/// The op is allowed to have more results than those specified in the macro arguments.
319/// They just won't have getters or type interfaces generated for them.
320///
321/// ```
322/// use pliron::derive::{def_op, format_op, results, verify_succ};
323/// use pliron::builtin::types::{IntegerType, UnitType};
324///
325/// #[verify_succ]
326/// #[def_op("dialect.with_results")]
327/// #[format_op]
328/// #[results(out: IntegerType, _: UnitType)]
329/// pub struct WithResultsOp {}
330/// ```
331#[proc_macro_attribute]
332pub fn results(args: TokenStream, input: TokenStream) -> TokenStream {
333    to_token_stream(derive_op::results(args, input))
334}
335
336/// Derive [Printable](../pliron/printable/trait.Printable.html) and
337/// [Parsable](../pliron/parsable/trait.Parsable.html) for Rust types.
338/// Use this for types other than `Op`, `Type` and `Attribute`s.
339///
340/// A format string can be specified as an argument to the macro, to customize the syntax.
341/// Without a format string, the default syntax is used. For enums, no format string is allowed
342/// on the enum itself, but it is allowed on its variants.
343///
344/// Primarily, the following two are used to refer to fields in a struct or tuple:
345///   1. A named variable `$name` specifies a named struct field.
346///   2. An unnamed variable `$i` specifies the i'th field of a tuple struct.
347///
348/// Struct (or tuple) fields that are either [Option] or [Vec] (or an array) must to be specified
349/// using the `opt` and `vec` directives respectively (i.e., a format string is mandatory).
350///
351/// The `opt` directive takes one mandatory argument, a variable specifying the field name with
352/// type `Option`. It also supports optional `label` and `delimiters` directives:
353/// 1. `label($name)`: uses `name :` as a prefix for the optional value.
354/// 2. `delimiters(`open`, `close`)`: wraps the optional value with the given delimiters.
355///
356/// The `vec` directive takes two arguments, the first is a variable specifying the field name
357/// with type `Vec` (or array) and the second is another directive to specify a
358/// [ListSeparator](../pliron/printable/enum.ListSeparator.html).
359///
360/// The following directives are supported:
361///   1. `NewLine`: takes no argument, and specifies a newline to be used as list separator.
362///   2. ``CharNewline(`c`)``: takes a single character argument that will be followed by a newline.
363///   3. ``Char(`c`)``: takes a single character argument that will be used as separator.
364///   4. ``CharSpace(`c`)``: takes a single character argument that will be followed by a space.
365///
366/// Generic structs and enums are supported. The macro preserves generic parameters on the
367/// generated `Printable` and `Parsable` impls, but it does not synthesize trait bounds.
368/// Any generic field that is parsed or printed through the format must therefore carry explicit
369/// bounds on the type itself. In practice, this usually means a bound like
370/// `T: Printable + Parsable<Arg = (), Parsed = T>`.
371///
372/// Examples:
373/// 1. Derive for a struct, with no format string (default format):
374///    (Note that the field u64 has both `Printable` and `Parsable` implemented).
375/// ```
376/// use pliron::derive::format;
377/// #[format]
378/// struct IntWrapper {
379///    inner: u64,
380/// }
381/// ```
382/// 2. An example with a custom format string:
383/// ```
384/// use pliron::derive::format;
385/// #[format("`BubbleWrap` `[` $inner `]`")]
386/// struct IntWrapperCustom {
387///   inner: u64,
388/// }
389/// ```
390/// 3. An example for an enum (custom format strings are allowed for the variants only).
391/// ```
392/// use pliron::derive::format;
393/// use pliron::{builtin::types::IntegerType, r#type::TypedHandle};
394/// #[format]
395/// enum Enum {
396///     A(TypedHandle<IntegerType>),
397///     B {
398///         one: TypedHandle<IntegerType>,
399///         two: u64,
400///     },
401///     C,
402///     #[format("`<` $upper `/` $lower `>`")]
403///     Op {
404///         upper: u64,
405///         lower: u64,
406///     },
407/// }
408/// ```
409/// 4. An example with `Option` and `Vec` fields
410/// ```
411/// use pliron::derive::format;
412/// #[format("`<` opt($a) `;` vec($b, Char(`,`)) `>`")]
413/// struct OptAndVec {
414///    a: Option<u64>,
415///    b: Vec<u64>,
416///}
417/// ```
418/// 5. An example with a generic field and explicit bounds:
419/// ```
420/// use pliron::derive::format;
421/// use pliron::{parsable::Parsable, printable::Printable};
422///
423/// #[format]
424/// struct Wrapper<T>
425/// where
426///     T: Printable + Parsable<Arg = (), Parsed = T>,
427/// {
428///     value: T,
429/// }
430/// ```
431/// 6. An example with an optional field using `label` and `delimiters` in `opt`:
432/// ```
433/// use pliron::derive::format;
434/// #[format("`<` opt($a, label($value), delimiters(`(`, `)`)) `>`")]
435/// struct OptionalField {
436///    a: Option<u64>,
437/// }
438/// ```
439#[proc_macro_attribute]
440pub fn format(args: TokenStream, input: TokenStream) -> TokenStream {
441    to_token_stream(derive_format::derive(
442        args,
443        input,
444        DeriveIRObject::AnyOtherRustType,
445    ))
446}
447
448/// Derive [Printable](../pliron/printable/trait.Printable.html) and
449/// [Parsable](../pliron/parsable/trait.Parsable.html) for [Op](../pliron/op/trait.Op.html)s
450///
451/// *Note*: It is suggested to use the [pliron_op] macro instead of using this macro directly.
452///         The documention here is useful though, because [pliron_op]'s `format` field
453///         expands to this macro.
454///
455/// This derive only supports a syntax in which results appear before the opid:
456///   `res1, ... = opid ...`
457/// The format string specifies what comes after the opid.
458///   1. A named variable `$name` specifies a named attribute of the operation.
459///      This cannot be combined with the [attr_dict](#attr_dict) directive.
460///   2. An unnamed variable `$i` specifies `operands[i]`, except when inside some directives.
461///      This cannot be combined with the "operands" directive.
462///   3. The "type" directive specifies that a type must be parsed. It takes one argument,
463///      which is an unnamed variable `$i` with `i` specifying `result[i]`. This cannot be
464///      combined with the "types" directive.
465///   4. The "region" directive specifies that a region must be parsed. It takes one argument,
466///      which is an unnamed variable `$i` with `i` specifying `region[i]`. This cannot be
467///      combined with the "regions" directive.
468///   5. The <a name="attr"></a> "attr" directive can be used to specify attribute on an `Op` when
469///      the attribute's rust type is fixed at compile time. It takes two mandatory and two optional
470///      arguments.
471///
472///      1. The first operand is a named variable `$name` which is used as a key into the
473///         operation's attribute dictionary
474///      2. The second is the concrete rust type of the attribute. This second argument can be a
475///         named variable `$name` (with `name` being in scope) or a literal string denoting the path
476///         to a rust type (e.g. `` `::pliron::builtin::attributes::IntegerAttr` ``).
477///      3. Two additional optional arguments can be specified:
478///         * The "label" directive, with one argument, a named variable `$label`, which
479///           specifies the label to be used while printing / parsing the attribute.
480///         * The "delimiters" directive, which takes two literal arguments,
481///           specifying the opening and closing delimiters to be used while printing / parsing.
482///
483///      The advantage over specifying an attribute using the [attr](#attr) directive (as against
484///      just using a named variable) is that the attribute-id is not a part of the syntax
485///      here (because the type is statically known, allowing us to be able to parse it),
486///      thus allowing it to be more succinct. This cannot be combined with the [attr_dict](#attr_dict)
487///      directive.
488///   6. The "succ" directive specifies an operation's successor. It takes one argument,
489///      which is an unnamed variable `$i` with `i` specifying `successor[i]`.
490///   7. The "operands" directive specifies all the operands of an operation. It takes one argument
491///      which is a directive specifying the separator between operands. This cannot be combined
492///      with using unnamed variables `$i` to refer to operands.
493///      The following directives are supported:
494///        1. `NewLine`: takes no argument, and specifies a newline to be used as list separator.
495///        2. ``CharNewline(`c`)``: takes a single character argument that will be followed by a newline.
496///        3. ``Char(`c`)``: takes a single character argument that will be used as separator.
497///        4. ``CharSpace(`c`)``: takes a single character argument that will be followed by a space.
498///   8. The "successors" directive specifies all the successors of an operation. It takes one argument
499///      which is a directive specifying the separator between successors. The separator directive is
500///      same as that for "operands" above. This cannot be combined with the "succ" directive.
501///   9. The "regions" directive specifies all the regions of an operation. It takes one argument
502///      which is a directive specifying the separator between regions. The separator directive is same
503///      as that for "operands" above. This cannot be combined with the "region" directive.
504///  10. The <a name="attr_dict"></a> "attr_dict" directive specifies an
505///      [AttributeDict](../pliron/attribute/struct.AttributeDict.html).
506///      It cannot be combined with any of [attr](#attr), [opt_attr](#opt_attr) directives or
507///      a named variable (`$name`).
508///  11. The "types" directive specifies all the result types of an operation. It takes one argument
509///      which is a directive specifying the separator between result types. The separator directive is
510///      same as that for "operands" above. This cannot be combined with the "type" directive.
511///  12. The "typesig" directive prints the full type signature of an operation as
512///      `(operand_types) -> (result_types)`. It takes no arguments. When parsing, the operand
513///      types are consumed and ignored; only the result types are used to build the operation.
514///      This cannot be combined with any of "type", "types", "opdtype" or "opdtypes" directives.
515///  13. The "opdtype" directive specifies that an operand type should be printed. It takes one
516///      argument, which is an unnamed variable `$i` with `i` specifying `operands[i]`. This cannot
517///      be combined with the "opdtypes" or "typesig" directives. **Note**: Parsed operand types
518///      are ignored, and not validated against actual operand types.
519///  14. The "opdtypes" directive specifies all the operand types of an operation. It takes one
520///      argument which is a directive specifying the separator between operand types. The separator
521///      directive is same as that for "operands" above. This cannot be combined with the "opdtype"
522///      or "typesig" directives. **Note**: Parsed operand types are ignored and not validated against
523///      actual operand types.
524///  15. The <a name="opt_attr"></a> "opt_attr" directive specifies an optional attribute on an `Op`.
525///      It takes two or more arguments, which are same as those of the [attr](#attr) directive.
526///      This cannot be combined with the [attr_dict](#attr_dict) directive.
527///
528/// Named attributes, `attr` and `opt_attr` print the marker
529/// [`!outlined`](../pliron/irfmt/outlined/constant.OUTLINED_ATTR_MARKER.html) instead of an
530/// attribute that [attr_should_outline](../pliron/attribute/fn.attr_should_outline.html).
531/// `attr_dict` drops the whole entry.
532///
533/// Examples:
534/// 1. Derive for a struct, with no format string (default format):
535/// ```
536/// use pliron::derive::{def_op, format_op, verify_succ};
537/// #[verify_succ]
538/// #[format_op]
539/// #[def_op("test.myop")]
540/// struct MyOp;
541/// ```
542/// 2. An example with a custom format string:
543/// ```
544/// use pliron::derive::{def_op, derive_op_interface_impl, format_op, verify_succ};
545/// use pliron::{op::Op, builtin::op_interfaces::{OneOpdInterface, OneResultInterface}};
546/// #[verify_succ]
547/// #[format_op("$0 `<` $attr `>` `:` type($0)")]
548/// #[def_op("test.one_result_one_operand")]
549/// #[derive_op_interface_impl(OneOpdInterface, OneResultInterface)]
550/// struct OneResultOneOperandOp;
551/// ```
552/// More examples can be seen in the tests for this macro in `pliron-derive/tests/format_op.rs`.
553#[proc_macro_attribute]
554pub fn format_op(args: TokenStream, input: TokenStream) -> TokenStream {
555    to_token_stream(derive_format::derive(args, input, DeriveIRObject::Op))
556}
557
558/// Derive [Printable](../pliron/printable/trait.Printable.html) and
559/// [Parsable](../pliron/parsable/trait.Parsable.html) for
560/// [Attribute](../pliron/attribute/trait.Attribute.html)s
561///
562/// *Note*: It is suggested to use the [pliron_attr] macro instead of using this macro directly.
563///
564/// Refer to [macro@format] for the syntax specification and examples.
565#[proc_macro_attribute]
566pub fn format_attribute(args: TokenStream, input: TokenStream) -> TokenStream {
567    to_token_stream(derive_format::derive(
568        args,
569        input,
570        DeriveIRObject::Attribute,
571    ))
572}
573
574/// Derive [Printable](../pliron/printable/trait.Printable.html) and
575/// [Parsable](../pliron/parsable/trait.Parsable.html) for
576/// [Type](../pliron/type/trait.Type.html)s
577///
578/// *Note*: It is suggested to use the [pliron_type] macro instead of using this macro directly.
579///
580/// Refer to [macro@format] for the syntax specification and examples.
581#[proc_macro_attribute]
582pub fn format_type(args: TokenStream, input: TokenStream) -> TokenStream {
583    to_token_stream(derive_format::derive(args, input, DeriveIRObject::Type))
584}
585
586pub(crate) fn to_token_stream(res: syn::Result<proc_macro2::TokenStream>) -> TokenStream {
587    let tokens = match res {
588        Ok(tokens) => tokens,
589        Err(error) => {
590            let error = error.to_compile_error();
591            quote::quote!(
592                #error
593            )
594        }
595    };
596    TokenStream::from(tokens)
597}
598
599/// Declare an [Op](../pliron/op/trait.Op.html) interface, which can be implemented
600/// by any `Op`.
601///
602/// If the interface requires any other interface to be already implemented,
603/// they can be specified super-traits.
604///
605/// When an `Op` is verified, its interfaces are also automatically verified,
606/// with guarantee that a super-interface is verified before an interface itself is.
607///
608/// Example: Here `SameOperandsAndResultType` and `SymbolOpInterface` are super interfaces
609/// for the new interface `MyOpIntr`.
610/// ```
611/// # use pliron::builtin::op_interfaces::{SameOperandsAndResultType, SymbolOpInterface};
612/// # use pliron::derive::{op_interface};
613/// # use pliron::{op::Op, context::Context, result::Result};
614///   /// MyOpIntr is my first op interface.
615///   #[op_interface]
616///   trait MyOpIntr: SameOperandsAndResultType + SymbolOpInterface {
617///       fn verify(_op: &dyn Op, _ctx: &Context) -> Result<()>
618///       where Self: Sized,
619///       {
620///           Ok(())
621///       }
622///   }
623/// ```
624#[proc_macro_attribute]
625pub fn op_interface(_attr: TokenStream, item: TokenStream) -> TokenStream {
626    let supertrait = parse_quote! { ::pliron::op::Op };
627    let verifier_type = parse_quote! { ::pliron::op::OpInterfaceVerifier };
628    let target_marker_trait = parse_quote! { ::pliron::op::OpInterfaceMarker };
629
630    to_token_stream(interfaces::interface_define(
631        item,
632        supertrait,
633        verifier_type,
634        true,
635        target_marker_trait,
636    ))
637}
638
639/// Implement [Op](../pliron/op/trait.Op.html) Interface for an Op. The interface trait must define
640/// a `verify` function with type [OpInterfaceVerifier](../pliron/op/type.OpInterfaceVerifier.html)
641///
642/// Usage:
643/// ```
644/// # use pliron::derive::{def_op, format_op, op_interface, op_interface_impl, verify_succ};
645///
646/// #[verify_succ]
647/// #[def_op("dialect.name")]
648/// #[format_op]
649/// struct MyOp;
650///
651/// #[op_interface]
652/// pub trait MyOpInterface {
653///     fn gubbi(&self);
654///     fn verify(op: &dyn Op, ctx: &Context) -> Result<()>
655///     where Self: Sized,
656///     {
657///         Ok(())
658///     }
659/// }
660///
661/// #[op_interface_impl]
662/// impl MyOpInterface for MyOp {
663///     fn gubbi(&self) { println!("gubbi"); }
664/// }
665/// # use pliron::{
666/// #     op::Op, context::Context, result::Result, common_traits::Verify
667/// # };
668/// ```
669#[proc_macro_attribute]
670pub fn op_interface_impl(_attr: TokenStream, item: TokenStream) -> TokenStream {
671    to_token_stream(interfaces::interface_impl(
672        item.into(),
673        interfaces::InterfaceImplOpts::op(),
674    ))
675}
676
677/// `#[pliron_type(...)]`: Unified macro for defining IR types.
678///
679/// This macro provides a simplified, unified syntax for defining IR types by expanding
680/// into the existing type definition macros. It supports the following configuration options:
681///
682/// - `name = "dialect.type_name"`: The fully qualified name of the type (required).\
683///   Expands to [def_type].
684/// - `format = "format_string"`: Custom format string for printing/parsing (optional).\
685///   Expands to [format_type].
686/// - `verifier = "succ"`: Verifier implementation, currently only "succ" is supported (optional).\
687///   Expands to [macro@verify_succ].
688/// - `generate_get = true/false`: Whether to generate a get method for the type (optional, default: false).\
689///   Expands to [derive_type_get].
690///
691/// ## Examples
692///
693/// ### Basic type definition:
694/// ```
695/// use pliron::derive::pliron_type;
696///
697/// #[pliron_type(name = "test.unit_type", format, verifier = "succ")]
698/// #[derive(Debug, Clone, PartialEq, Eq, Hash)]
699/// pub struct UnitType;
700/// ```
701///
702/// ### Type with custom format:
703/// ```
704/// use pliron::derive::pliron_type;
705///
706/// #[pliron_type(
707///     name = "test.flags_type",
708///     format = "`type` `{` $flags `}`",
709///     verifier = "succ"
710/// )]
711/// #[derive(Debug, Clone, PartialEq, Eq, Hash)]
712/// struct FlagsType {
713///     flags: u32,
714/// }
715/// ```
716///
717/// ### Type with get method generation:
718/// ```
719/// use pliron::derive::pliron_type;
720///
721/// #[pliron_type(
722///     name = "test.vector_type",
723///     generate_get = true,
724///     format,
725///     verifier = "succ"
726/// )]
727/// #[derive(Debug, Clone, PartialEq, Eq, Hash)]
728/// struct VectorType {
729///     elem_ty: u32,
730///     num_elems: u32,
731/// }
732/// ```
733#[proc_macro_attribute]
734pub fn pliron_type(args: TokenStream, input: TokenStream) -> TokenStream {
735    to_token_stream(derive_entity::pliron_type(args, input))
736}
737
738/// `#[pliron_attr(...)]`: Unified macro for defining IR attributes.
739///
740/// This macro provides a simplified, unified syntax for defining IR attributes by expanding
741/// into the existing attribute definition macros. It supports the following configuration options:
742///
743/// - `name = "dialect.attribute_name"`: The fully qualified name of the attribute (required).\
744///   Expands to [def_attribute].
745/// - `format = "format_string"`: Custom format string for printing/parsing (optional).\
746///   Expands to [format_attribute].
747/// - `verifier = "succ"`: Verifier implementation, currently only "succ" is supported (optional).\
748///   Expands to [macro@verify_succ].
749///
750/// ## Examples
751///
752/// ### Basic attribute definition:
753/// ```
754/// use pliron::derive::pliron_attr;
755///
756/// #[pliron_attr(name = "test.string_attr", format, verifier = "succ")]
757/// #[derive(Debug, Clone, PartialEq, Eq, Hash)]
758/// struct StringAttr {
759///     value: String,
760/// }
761/// ```
762///
763/// ### Attribute with custom format:
764/// ```
765/// use pliron::derive::pliron_attr;
766///
767/// #[pliron_attr(
768///     name = "test.string_attr",
769///     format = "`attr` `(` $value `)`",
770///     verifier = "succ"
771/// )]
772/// #[derive(Debug, Clone, PartialEq, Eq, Hash)]
773/// struct StringAttr {
774///     value: String,
775/// }
776/// ```
777#[proc_macro_attribute]
778pub fn pliron_attr(args: TokenStream, input: TokenStream) -> TokenStream {
779    to_token_stream(derive_entity::pliron_attr(args, input))
780}
781
782/// `#[pliron_op(...)]`: Unified macro for defining IR operations.
783///
784/// This macro provides a simplified, unified syntax for defining IR operations by expanding
785/// into the existing operation definition macros. It supports the following configuration options:
786///
787/// - `name = "dialect.op_name"`: The fully qualified name of the operation (required).\
788///   Expands to [def_op].
789/// - `format = "format_string"`: Custom format string for printing/parsing (optional).\
790///   Expands to [format_op].
791/// - `interfaces = [Interface1, Interface2, ...]`: List of interfaces to implement (optional).\
792///   Expands to [derive_op_interface_impl].
793/// - `attributes = (attr_name: AttrType, ...)`: List of attributes with their types (optional).\
794///   Expands to [derive_attr_get_set], generating getter and setter methods.
795/// - `operands = (name, name: Type, _, _: Type, ...)`: List of operand specs (optional).\
796///   Expands to [operands].
797/// - `results = (name, name: Type, _, _: Type, ...)`: List of result specs (optional).\
798///   Expands to [results].
799/// - `verifier = "succ"`: Verifier implementation, currently only "succ" is supported (optional).\
800///   Expands to [macro@verify_succ].
801///
802/// ## Examples
803///
804/// ### Basic operation definition:
805/// ```
806/// use pliron::derive::pliron_op;
807///
808/// #[pliron_op(name = "test.my_op", format, verifier = "succ")]
809/// struct MyOp;
810/// ```
811///
812/// ### Operation with custom format and interfaces:
813/// ```
814/// use pliron::derive::pliron_op;
815/// use pliron::builtin::op_interfaces::NRegionsInterface;
816///
817/// #[pliron_op(
818///     name = "test.if_op",
819///     format = "`(`$0`)` region($0)",
820///     interfaces = [ NRegionsInterface<1> ],
821///     verifier = "succ"
822/// )]
823/// struct IfOp;
824/// ```
825///
826/// ### Operation with specified attributes:
827/// ```
828/// use pliron::derive::pliron_op;
829/// use pliron::builtin::attributes::{UnitAttr, IntegerAttr};
830///
831/// #[pliron_op(
832///     name = "dialect.test",
833///     format,
834///     attributes = (attr1: UnitAttr, attr2: IntegerAttr),
835///     verifier = "succ"
836/// )]
837/// struct CallOp;
838/// ```
839///
840/// ### Operation with specified operands:
841/// ```
842/// use pliron::derive::pliron_op;
843/// use pliron::builtin::types::{IntegerType, UnitType};
844///
845/// #[pliron_op(
846///     name = "dialect.with_operands",
847///     format,
848///     operands = (lhs: IntegerType, _, rhs, _: UnitType),
849///     verifier = "succ"
850/// )]
851/// struct WithOperandsOp;
852/// ```
853///
854/// ### Operation with specified results:
855/// ```
856/// use pliron::derive::pliron_op;
857/// use pliron::builtin::types::{IntegerType, UnitType};
858///
859/// #[pliron_op(
860///     name = "dialect.with_results",
861///     format,
862///     results = (out: IntegerType, _: UnitType),
863///     verifier = "succ"
864/// )]
865/// struct WithResultsOp;
866/// ```
867#[proc_macro_attribute]
868pub fn pliron_op(args: TokenStream, input: TokenStream) -> TokenStream {
869    to_token_stream(derive_entity::pliron_op(args, input))
870}
871
872/// Derive implementation of an [Op](../pliron/op/trait.Op.html) Interface for an Op.
873/// Note that an impl can be derived only for those interfaces that do not require any
874/// methods to be defined during the impl.
875///
876/// *Note*: It is suggested to use the [pliron_op] macro instead of using this macro directly.
877///         The documention here is useful though, because [pliron_op]'s `interfaces` field
878///         expands to this macro.
879///
880/// Usage:
881/// ```
882/// # use pliron::derive::{derive_op_interface_impl, format_op, op_interface, verify_succ};
883///
884/// #[verify_succ]
885/// #[def_op("dialect.name")]
886/// #[format_op]
887/// #[derive_op_interface_impl(MyOpInterface)]
888/// struct MyOp;
889///
890/// #[op_interface]
891/// pub trait MyOpInterface {
892///     fn gubbi(&self) { println!("gubbi"); }
893///     fn verify(op: &dyn Op, ctx: &Context) -> Result<()>
894///     where Self: Sized,
895///     {
896///         Ok(())
897///     }
898/// }
899/// # use pliron::derive::def_op;
900/// # use pliron::{
901/// #     op::Op, context::Context, result::Result,
902/// #     common_traits::Verify
903/// # };
904/// ```
905#[proc_macro_attribute]
906pub fn derive_op_interface_impl(attr: TokenStream, item: TokenStream) -> TokenStream {
907    to_token_stream(interfaces::derive_op_interface_impl(attr, item))
908}
909
910/// Declare an [Attribute](../pliron/attribute/trait.Attribute.html) interface,
911/// which can be implemented by any `Attribute`.
912///
913/// If the interface requires any other interface to be already implemented,
914/// they can be specified super-traits.
915///
916/// When an `Attribute` is verified, its interfaces are also automatically verified,
917/// with guarantee that a super-interface is verified before an interface itself is.
918///
919/// Example: Here `Super1` and `Super2` are super interfaces for the interface `MyAttrIntr`.
920/// ```
921/// # use pliron::{attribute::Attribute, context::Context, result::Result};
922/// use pliron::derive::attr_interface;
923///
924/// #[attr_interface]
925/// trait Super1 {
926///     fn verify(_attr: &dyn Attribute, _ctx: &Context) -> Result<()>
927///     where
928///         Self: Sized,
929///     {
930///         Ok(())
931///     }
932/// }
933///
934/// #[attr_interface]
935/// trait Super2 {
936///     fn verify(_attr: &dyn Attribute, _ctx: &Context) -> Result<()>
937///     where
938///         Self: Sized,
939///     {
940///         Ok(())
941///     }
942/// }
943///
944/// // MyAttrIntr is my best attribute interface.
945/// #[attr_interface]
946/// trait MyAttrIntr: Super1 + Super2 {
947///     fn verify(_attr: &dyn Attribute, _ctx: &Context) -> Result<()>
948///     where
949///         Self: Sized,
950///     {
951///         Ok(())
952///     }
953/// }
954/// ```
955#[proc_macro_attribute]
956pub fn attr_interface(_attr: TokenStream, item: TokenStream) -> TokenStream {
957    let supertrait = parse_quote! { ::pliron::attribute::Attribute };
958    let verifier_type = parse_quote! { ::pliron::attribute::AttrInterfaceVerifier };
959    let target_marker_trait = parse_quote! { ::pliron::attribute::AttrInterfaceMarker };
960
961    let define = interfaces::interface_define(
962        item.clone(),
963        supertrait,
964        verifier_type,
965        true,
966        target_marker_trait,
967    );
968
969    // Implement common traits for `dyn Interface` that we already implement for `AttrObj`.
970    let obj_traits = interfaces::attr_interface_obj_traits(item);
971
972    to_token_stream(define.and_then(|mut output| {
973        output.extend(obj_traits?);
974        Ok(output)
975    }))
976}
977
978/// Implement [Attribute](../pliron/attribute/trait.Attribute.html) Interface for an Attribute.
979/// The interface trait must define a `verify` function with type
980/// [AttrInterfaceVerifier](../pliron/attribute/type.AttrInterfaceVerifier.html).
981///
982/// Usage:
983/// ```
984/// use pliron::derive::{attr_interface, attr_interface_impl, def_attribute, format_attribute, verify_succ};
985///
986/// #[verify_succ]
987/// #[def_attribute("dialect.name")]
988/// #[format_attribute]
989/// #[derive(PartialEq, Eq, Clone, Debug, Hash)]
990/// struct MyAttr { }
991///
992///     /// My first attribute interface.
993/// #[attr_interface]
994/// trait MyAttrInterface {
995///     fn monu(&self);
996///     fn verify(attr: &dyn Attribute, ctx: &Context) -> Result<()>
997///     where Self: Sized,
998///     {
999///          Ok(())
1000///     }
1001/// }
1002///
1003/// #[attr_interface_impl]
1004/// impl MyAttrInterface for MyAttr
1005/// {
1006///     fn monu(&self) { println!("monu"); }
1007/// }
1008/// # use pliron::{
1009/// #     printable::{self, Printable},
1010/// #     context::Context, result::Result, common_traits::Verify,
1011/// #     attribute::Attribute
1012/// # };
1013#[proc_macro_attribute]
1014pub fn attr_interface_impl(_attr: TokenStream, item: TokenStream) -> TokenStream {
1015    to_token_stream(interfaces::interface_impl(
1016        item.into(),
1017        interfaces::InterfaceImplOpts::attr(),
1018    ))
1019}
1020
1021/// Declare a [Type](../pliron/type/trait.Type.html) interface,
1022/// which can be implemented by any `Type`.
1023///
1024/// If the interface requires any other interface to be already implemented,
1025/// they can be specified super-traits.
1026///
1027/// When an `Attribute` is verified, its interfaces are also automatically verified,
1028/// with guarantee that a super-interface is verified before an interface itself is.
1029///
1030/// Example: Here `Super1` and `Super2` are super interfaces for the interface `MyTypeIntr`.
1031/// ```
1032/// use pliron::derive::type_interface;
1033/// # use pliron::{r#type::Type, context::Context, result::Result};
1034/// #[type_interface]
1035/// trait Super1 {
1036///     fn verify(_type: &dyn Type, _ctx: &Context) -> Result<()>
1037///     where
1038///         Self: Sized,
1039///     {
1040///         Ok(())
1041///     }
1042/// }
1043///
1044/// #[type_interface]
1045/// trait Super2 {
1046///     fn verify(_type: &dyn Type, _ctx: &Context) -> Result<()>
1047///     where
1048///         Self: Sized,
1049///     {
1050///         Ok(())
1051///     }
1052/// }
1053///
1054/// #[type_interface]
1055/// // MyTypeIntr is my best type interface.
1056/// trait MyTypeIntr: Super1 + Super2 {
1057///     fn verify(_type: &dyn Type, _ctx: &Context) -> Result<()>
1058///     where
1059///         Self: Sized,
1060///     {
1061///         Ok(())
1062///     }
1063/// }
1064/// ```
1065#[proc_macro_attribute]
1066pub fn type_interface(_attr: TokenStream, item: TokenStream) -> TokenStream {
1067    let supertrait = parse_quote! { ::pliron::r#type::Type };
1068    let verifier_type = parse_quote! { ::pliron::r#type::TypeInterfaceVerifier };
1069    let target_marker_trait = parse_quote! { ::pliron::r#type::TypeInterfaceMarker };
1070
1071    to_token_stream(interfaces::interface_define(
1072        item,
1073        supertrait,
1074        verifier_type,
1075        false,
1076        target_marker_trait,
1077    ))
1078}
1079
1080/// Implement [Type](../pliron/type/trait.Type.html) Interface for a Type.
1081/// The interface trait must define a `verify` function with type
1082/// [TypeInterfaceVerifier](../pliron/type/type.TypeInterfaceVerifier.html).
1083///
1084/// Usage:
1085/// ```
1086/// use pliron::derive::{def_type, format_type, type_interface, type_interface_impl, verify_succ};
1087///
1088/// #[verify_succ]
1089/// #[def_type("dialect.name")]
1090/// #[format_type]
1091/// #[derive(PartialEq, Eq, Clone, Debug, Hash)]
1092/// struct MyType { }
1093///
1094/// #[type_interface]
1095/// /// My first type interface.
1096/// trait MyTypeInterface {
1097///     fn monu(&self);
1098///     fn verify(r#type: &dyn Type, ctx: &Context) -> Result<()>
1099///     where Self: Sized,
1100///     {
1101///          Ok(())
1102///     }
1103/// }
1104///
1105/// #[type_interface_impl]
1106/// impl MyTypeInterface for MyType
1107/// {
1108///     fn monu(&self) { println!("monu"); }
1109/// }
1110/// # use pliron::{
1111/// #     printable::{self, Printable},
1112/// #     context::Context, result::Result, common_traits::Verify,
1113/// #     r#type::Type
1114/// # };
1115#[proc_macro_attribute]
1116pub fn type_interface_impl(_attr: TokenStream, item: TokenStream) -> TokenStream {
1117    to_token_stream(interfaces::interface_impl(
1118        item.into(),
1119        interfaces::InterfaceImplOpts::r#type(),
1120    ))
1121}
1122
1123/// Implement [StableHash](../pliron/irbuild/decontext/trait.StableHash.html)
1124/// for a struct or enum, assuming every field's type already implements it.
1125/// For an enum, the matched variant's discriminant is also mixed into the hash.
1126///
1127/// This also registers the impl with [type_to_trait!](../pliron/macro.type_to_trait.html).
1128///
1129/// Usage:
1130///
1131/// ```
1132/// use pliron::{derive::StableHash, r#type::TypeHandle};
1133///
1134/// #[derive(StableHash)]
1135/// struct MyAttr {
1136///     ty: TypeHandle,
1137///     val: u64,
1138/// }
1139/// ```
1140///
1141/// This fails to compile because `NotHashable` doesn't implement `StableHash`:
1142/// ```compile_fail
1143/// use pliron::derive::StableHash;
1144///
1145/// struct NotHashable;
1146///
1147/// #[derive(StableHash)]
1148/// struct MyAttr {
1149///     val: NotHashable,
1150/// }
1151/// ```
1152#[proc_macro_derive(StableHash)]
1153pub fn stable_hash(input: TokenStream) -> TokenStream {
1154    to_token_stream(derive_decontext::derive_stable_hash(input.into()))
1155}
1156
1157/// Implement [CloneIntoContext](../pliron/irbuild/decontext/trait.CloneIntoContext.html)
1158/// for a struct or enum, assuming every field's type already implements it. For an enum,
1159/// the matched variant is reconstructed with its (cloned) fields.
1160///
1161/// Usage:
1162///
1163/// ```
1164/// use pliron::{derive::CloneIntoContext, r#type::TypeHandle};
1165///
1166/// #[derive(CloneIntoContext)]
1167/// struct MyAttr {
1168///     ty: TypeHandle,
1169///     val: u64,
1170/// }
1171/// ```
1172///
1173/// A generic struct, with the field's bound written explicitly:
1174/// ```
1175/// use pliron::{
1176///     context::Context, derive::CloneIntoContext,
1177///     irbuild::decontext::CloneIntoContext as CloneIntoContextTrait,
1178/// };
1179///
1180/// #[derive(CloneIntoContext)]
1181/// struct Wrapper<T: CloneIntoContextTrait> {
1182///     inner: T,
1183/// }
1184///
1185/// let src_ctx = Context::new();
1186/// let mut dst_ctx = Context::new();
1187/// let cloned = Wrapper { inner: 42u64 }.clone_into_context(&src_ctx, &mut dst_ctx);
1188/// assert_eq!(cloned.inner, 42);
1189/// ```
1190///
1191/// This fails to compile because `NotCloneable` doesn't implement `CloneIntoContext`:
1192/// ```compile_fail
1193/// use pliron::derive::CloneIntoContext;
1194///
1195/// struct NotCloneable;
1196///
1197/// #[derive(CloneIntoContext)]
1198/// struct MyAttr {
1199///     val: NotCloneable,
1200/// }
1201/// ```
1202#[proc_macro_derive(CloneIntoContext)]
1203pub fn clone_into_context(input: TokenStream) -> TokenStream {
1204    to_token_stream(derive_decontext::derive_clone_into_context(input.into()))
1205}
1206
1207/// Implement [CloneAttributeIntoContext](../pliron/irbuild/decontext/trait.CloneAttributeIntoContext.html)
1208/// for an [Attribute](../pliron/attribute/trait.Attribute.html) by delegating to its own
1209/// [CloneIntoContext](../pliron/irbuild/decontext/trait.CloneIntoContext.html) impl and boxing the result.
1210///
1211/// The type must already implement
1212/// [CloneIntoContext](../pliron/irbuild/decontext/trait.CloneIntoContext.html) (e.g. via
1213/// [`#[derive(CloneIntoContext)]`](derive@CloneIntoContext),
1214/// or [`impl_clone_into_context_for_clone!`](../pliron/macro.impl_clone_into_context_for_clone.html)).
1215///
1216/// Usage:
1217///
1218/// ```
1219/// use pliron::{
1220///     attribute::AttrObj, context::Context,
1221///     derive::{CloneAttributeIntoContext, CloneIntoContext, pliron_attr},
1222///     irbuild::decontext::CloneIntoContext as _, printable::Printable,
1223/// };
1224///
1225/// #[pliron_attr(name = "test.point_attr", format = "`<` $x `>`", verifier = "succ")]
1226/// #[derive(Debug, Clone, PartialEq, Eq, Hash, CloneIntoContext, CloneAttributeIntoContext)]
1227/// struct PointAttr {
1228///     x: i32,
1229/// }
1230///
1231/// let src_ctx = Context::new();
1232/// let mut dst_ctx = Context::new();
1233/// let a: AttrObj = Box::new(PointAttr { x: 1 });
1234/// let a2 = a.clone_into_context(&src_ctx, &mut dst_ctx);
1235/// assert_eq!(a.disp(&src_ctx).to_string(), a2.disp(&dst_ctx).to_string());
1236/// ```
1237#[proc_macro_derive(CloneAttributeIntoContext)]
1238pub fn clone_attribute_into_context(input: TokenStream) -> TokenStream {
1239    to_token_stream(derive_decontext::derive_clone_attribute_into_context(
1240        input.into(),
1241    ))
1242}
1243
1244/// Implement [CloneTypeIntoContext](../pliron/irbuild/decontext/trait.CloneTypeIntoContext.html)
1245/// for a [Type](../pliron/type/trait.Type.html) by delegating to its own
1246/// [CloneIntoContext](../pliron/irbuild/decontext/trait.CloneIntoContext.html) impl,
1247/// then re-interning the clone into `dst_ctx`.
1248///
1249/// The type must already implement
1250/// [CloneIntoContext](../pliron/irbuild/decontext/trait.CloneIntoContext.html) (e.g. via
1251/// [`#[derive(CloneIntoContext)]`](derive@CloneIntoContext),
1252/// or [`impl_clone_into_context_for_clone!`](../pliron/macro.impl_clone_into_context_for_clone.html)).
1253///
1254/// Usage:
1255///
1256/// ```
1257/// use pliron::{
1258///     context::Context,
1259///     derive::{CloneIntoContext, CloneTypeIntoContext, pliron_type},
1260///     irbuild::decontext::CloneIntoContext as _, printable::Printable,
1261/// };
1262///
1263/// #[pliron_type(
1264///     name = "test.point_type",
1265///     format = "`<` $x `>`",
1266///     generate_get = true,
1267///     verifier = "succ"
1268/// )]
1269/// #[derive(Debug, Clone, PartialEq, Eq, Hash, CloneIntoContext, CloneTypeIntoContext)]
1270/// struct PointType {
1271///     x: i32,
1272/// }
1273///
1274/// let src_ctx = Context::new();
1275/// let mut dst_ctx = Context::new();
1276/// let p = PointType::get(&src_ctx, 1).to_handle();
1277/// let p2 = p.clone_into_context(&src_ctx, &mut dst_ctx);
1278/// assert_eq!(p.disp(&src_ctx).to_string(), p2.disp(&dst_ctx).to_string());
1279/// ```
1280#[proc_macro_derive(CloneTypeIntoContext)]
1281pub fn clone_type_into_context(input: TokenStream) -> TokenStream {
1282    to_token_stream(derive_decontext::derive_clone_type_into_context(
1283        input.into(),
1284    ))
1285}