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