Browse Source

idl: Move IDL types from the `anchor-syn` crate to the new IDL crate (#2882)

acheron 1 year ago
parent
commit
c138a55b72
41 changed files with 584 additions and 592 deletions
  1. 1 0
      CHANGELOG.md
  2. 2 1
      Cargo.lock
  3. 5 10
      idl/Cargo.toml
  4. 32 0
      idl/src/build.rs
  5. 3 0
      idl/src/lib.rs
  6. 485 2
      idl/src/types.rs
  7. 3 3
      lang/Cargo.toml
  8. 2 2
      lang/attribute/account/src/lib.rs
  9. 1 1
      lang/attribute/constant/src/lib.rs
  10. 1 1
      lang/attribute/event/src/lib.rs
  11. 2 1
      lang/attribute/program/Cargo.toml
  12. 1 1
      lang/attribute/program/src/declare_program/common.rs
  13. 1 1
      lang/attribute/program/src/declare_program/mod.rs
  14. 1 1
      lang/attribute/program/src/declare_program/mods/accounts.rs
  15. 1 1
      lang/attribute/program/src/declare_program/mods/client.rs
  16. 1 1
      lang/attribute/program/src/declare_program/mods/constants.rs
  17. 1 1
      lang/attribute/program/src/declare_program/mods/cpi.rs
  18. 1 1
      lang/attribute/program/src/declare_program/mods/events.rs
  19. 1 1
      lang/attribute/program/src/declare_program/mods/internal.rs
  20. 1 1
      lang/attribute/program/src/declare_program/mods/types.rs
  21. 1 1
      lang/derive/serde/src/lib.rs
  22. 3 0
      lang/src/idl.rs
  23. 2 2
      lang/src/lib.rs
  24. 1 2
      lang/syn/Cargo.toml
  25. 1 1
      lang/syn/src/codegen/accounts/mod.rs
  26. 1 1
      lang/syn/src/codegen/error.rs
  27. 1 1
      lang/syn/src/codegen/program/mod.rs
  28. 0 0
      lang/syn/src/idl/accounts.rs
  29. 0 0
      lang/syn/src/idl/address.rs
  30. 0 21
      lang/syn/src/idl/build/mod.rs
  31. 2 2
      lang/syn/src/idl/common.rs
  32. 0 0
      lang/syn/src/idl/constant.rs
  33. 6 40
      lang/syn/src/idl/defined.rs
  34. 0 0
      lang/syn/src/idl/error.rs
  35. 0 0
      lang/syn/src/idl/event.rs
  36. 0 0
      lang/syn/src/idl/external.rs
  37. 18 3
      lang/syn/src/idl/mod.rs
  38. 0 0
      lang/syn/src/idl/program.rs
  39. 0 486
      lang/syn/src/idl/types.rs
  40. 1 1
      lang/syn/src/lib.rs
  41. 1 1
      tests/idl/programs/new-idl/src/lib.rs

+ 1 - 0
CHANGELOG.md

@@ -87,6 +87,7 @@ The minor version will be incremented upon a breaking change and the patch versi
 - ts: `Program` instances use camelCase for everything ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
 - ts: Remove discriminator functions ([#2824](https://github.com/coral-xyz/anchor/pull/2824)).
 - ts: Remove `programId` parameter of the `Program` constructor ([#2864](https://github.com/coral-xyz/anchor/pull/2864)).
+- idl, syn: Move IDL types from the `anchor-syn` crate to the new IDL crate ([#2882](https://github.com/coral-xyz/anchor/pull/2882)).
 
 ## [0.29.0] - 2023-10-16
 

+ 2 - 1
Cargo.lock

@@ -170,6 +170,7 @@ dependencies = [
 name = "anchor-attribute-program"
 version = "0.29.0"
 dependencies = [
+ "anchor-idl",
  "anchor-syn",
  "anyhow",
  "bs58 0.5.0",
@@ -286,7 +287,7 @@ dependencies = [
  "anchor-derive-accounts",
  "anchor-derive-serde",
  "anchor-derive-space",
- "anchor-syn",
+ "anchor-idl",
  "arrayref",
  "base64 0.21.7",
  "bincode",

+ 5 - 10
idl/Cargo.toml

@@ -13,18 +13,13 @@ all-features = true
 rustdoc-args = ["--cfg", "docsrs"]
 
 [features]
-build = [
-    "anyhow",
-    "regex",
-    "serde",
-    "serde_json",
-]
+build = ["anchor-syn", "regex"]
 
 [dependencies]
-anchor-syn = { path = "../lang/syn", version = "0.29.0", features = ["idl-types"] }
+anyhow = "1"
+serde = { version = "1", features = ["derive"] }
+serde_json = "1"
 
 # `build` feature only
-anyhow = { version = "1", optional = true }
+anchor-syn = { path = "../lang/syn", version = "0.29.0", optional = true }
 regex = { version = "1", optional = true }
-serde = { version = "1", features = ["derive"], optional = true }
-serde_json = { version = "1", optional = true }

+ 32 - 0
idl/src/build.rs

@@ -12,6 +12,38 @@ use serde::Deserialize;
 
 use crate::types::{Idl, IdlEvent, IdlTypeDef};
 
+/// A trait that types must implement in order to include the type in the IDL definition.
+///
+/// This trait is automatically implemented for Anchor all types that use the `AnchorSerialize`
+/// proc macro. Note that manually implementing the `AnchorSerialize` trait does **NOT** have the
+/// same effect.
+///
+/// Types that don't implement this trait will cause a compile error during the IDL generation.
+///
+/// The default implementation of the trait allows the program to compile but the type does **NOT**
+/// get included in the IDL.
+pub trait IdlBuild {
+    /// Create an IDL type definition for the type.
+    ///
+    /// The type is only included in the IDL if this method returns `Some`.
+    fn create_type() -> Option<IdlTypeDef> {
+        None
+    }
+
+    /// Insert all types that are included in the current type definition to the given map.
+    fn insert_types(_types: &mut BTreeMap<String, IdlTypeDef>) {}
+
+    /// Get the full module path of the type.
+    ///
+    /// The full path will be used in the case of a conflicting type definition, e.g. when there
+    /// are multiple structs with the same name.
+    ///
+    /// The default implementation covers most cases.
+    fn get_full_path() -> String {
+        std::any::type_name::<Self>().into()
+    }
+}
+
 /// Generate IDL via compilation.
 pub fn build_idl(
     program_path: impl AsRef<Path>,

+ 3 - 0
idl/src/lib.rs

@@ -4,3 +4,6 @@ pub mod types;
 
 #[cfg(feature = "build")]
 pub mod build;
+
+#[cfg(feature = "build")]
+pub use serde_json;

+ 485 - 2
idl/src/types.rs

@@ -1,3 +1,486 @@
-//! IDL types are re-exported from [`anchor_syn`].
+use std::str::FromStr;
 
-pub use anchor_syn::idl::types::*;
+use anyhow::anyhow;
+use serde::{Deserialize, Serialize};
+
+/// IDL specification Semantic Version
+pub const IDL_SPEC: &str = "0.1.0";
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+pub struct Idl {
+    pub address: String,
+    pub metadata: IdlMetadata,
+    #[serde(default, skip_serializing_if = "is_default")]
+    pub docs: Vec<String>,
+    pub instructions: Vec<IdlInstruction>,
+    #[serde(default, skip_serializing_if = "is_default")]
+    pub accounts: Vec<IdlAccount>,
+    #[serde(default, skip_serializing_if = "is_default")]
+    pub events: Vec<IdlEvent>,
+    #[serde(default, skip_serializing_if = "is_default")]
+    pub errors: Vec<IdlErrorCode>,
+    #[serde(default, skip_serializing_if = "is_default")]
+    pub types: Vec<IdlTypeDef>,
+    #[serde(default, skip_serializing_if = "is_default")]
+    pub constants: Vec<IdlConst>,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+pub struct IdlMetadata {
+    pub name: String,
+    pub version: String,
+    pub spec: String,
+    #[serde(skip_serializing_if = "is_default")]
+    pub description: Option<String>,
+    #[serde(skip_serializing_if = "is_default")]
+    pub repository: Option<String>,
+    #[serde(default, skip_serializing_if = "is_default")]
+    pub dependencies: Vec<IdlDependency>,
+    #[serde(skip_serializing_if = "is_default")]
+    pub contact: Option<String>,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+pub struct IdlDependency {
+    pub name: String,
+    pub version: String,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+pub struct IdlInstruction {
+    pub name: String,
+    #[serde(default, skip_serializing_if = "is_default")]
+    pub docs: Vec<String>,
+    pub discriminator: IdlDiscriminator,
+    pub accounts: Vec<IdlInstructionAccountItem>,
+    pub args: Vec<IdlField>,
+    #[serde(skip_serializing_if = "is_default")]
+    pub returns: Option<IdlType>,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+#[serde(untagged)]
+pub enum IdlInstructionAccountItem {
+    Composite(IdlInstructionAccounts),
+    Single(IdlInstructionAccount),
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+pub struct IdlInstructionAccount {
+    pub name: String,
+    #[serde(default, skip_serializing_if = "is_default")]
+    pub docs: Vec<String>,
+    #[serde(default, skip_serializing_if = "is_default")]
+    pub writable: bool,
+    #[serde(default, skip_serializing_if = "is_default")]
+    pub signer: bool,
+    #[serde(default, skip_serializing_if = "is_default")]
+    pub optional: bool,
+    #[serde(skip_serializing_if = "is_default")]
+    pub address: Option<String>,
+    #[serde(skip_serializing_if = "is_default")]
+    pub pda: Option<IdlPda>,
+    #[serde(default, skip_serializing_if = "is_default")]
+    pub relations: Vec<String>,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+pub struct IdlInstructionAccounts {
+    pub name: String,
+    pub accounts: Vec<IdlInstructionAccountItem>,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+pub struct IdlPda {
+    pub seeds: Vec<IdlSeed>,
+    #[serde(skip_serializing_if = "is_default")]
+    pub program: Option<IdlSeed>,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+#[serde(tag = "kind", rename_all = "lowercase")]
+pub enum IdlSeed {
+    Const(IdlSeedConst),
+    Arg(IdlSeedArg),
+    Account(IdlSeedAccount),
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+pub struct IdlSeedConst {
+    pub value: Vec<u8>,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+pub struct IdlSeedArg {
+    pub path: String,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+pub struct IdlSeedAccount {
+    pub path: String,
+    #[serde(skip_serializing_if = "is_default")]
+    pub account: Option<String>,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+pub struct IdlAccount {
+    pub name: String,
+    pub discriminator: IdlDiscriminator,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+pub struct IdlEvent {
+    pub name: String,
+    pub discriminator: IdlDiscriminator,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+pub struct IdlConst {
+    pub name: String,
+    #[serde(rename = "type")]
+    pub ty: IdlType,
+    pub value: String,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
+pub struct IdlErrorCode {
+    pub code: u32,
+    pub name: String,
+    #[serde(skip_serializing_if = "is_default")]
+    pub msg: Option<String>,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+pub struct IdlField {
+    pub name: String,
+    #[serde(default, skip_serializing_if = "is_default")]
+    pub docs: Vec<String>,
+    #[serde(rename = "type")]
+    pub ty: IdlType,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+pub struct IdlTypeDef {
+    pub name: String,
+    #[serde(default, skip_serializing_if = "is_default")]
+    pub docs: Vec<String>,
+    #[serde(default, skip_serializing_if = "is_default")]
+    pub serialization: IdlSerialization,
+    #[serde(skip_serializing_if = "is_default")]
+    pub repr: Option<IdlRepr>,
+    #[serde(default, skip_serializing_if = "is_default")]
+    pub generics: Vec<IdlTypeDefGeneric>,
+    #[serde(rename = "type")]
+    pub ty: IdlTypeDefTy,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
+#[serde(rename_all = "lowercase")]
+pub enum IdlSerialization {
+    #[default]
+    Borsh,
+    Bytemuck,
+    BytemuckUnsafe,
+    Custom(String),
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+#[serde(tag = "kind", rename_all = "lowercase")]
+pub enum IdlRepr {
+    Rust(IdlReprModifier),
+    C(IdlReprModifier),
+    Transparent,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+pub struct IdlReprModifier {
+    #[serde(default, skip_serializing_if = "is_default")]
+    pub packed: bool,
+    #[serde(skip_serializing_if = "is_default")]
+    pub align: Option<usize>,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+#[serde(tag = "kind", rename_all = "lowercase")]
+pub enum IdlTypeDefGeneric {
+    Type {
+        name: String,
+    },
+    Const {
+        name: String,
+        #[serde(rename = "type")]
+        ty: String,
+    },
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+#[serde(tag = "kind", rename_all = "lowercase")]
+pub enum IdlTypeDefTy {
+    Struct {
+        #[serde(skip_serializing_if = "is_default")]
+        fields: Option<IdlDefinedFields>,
+    },
+    Enum {
+        variants: Vec<IdlEnumVariant>,
+    },
+    Type {
+        alias: IdlType,
+    },
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+pub struct IdlEnumVariant {
+    pub name: String,
+    #[serde(skip_serializing_if = "is_default")]
+    pub fields: Option<IdlDefinedFields>,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+#[serde(untagged)]
+pub enum IdlDefinedFields {
+    Named(Vec<IdlField>),
+    Tuple(Vec<IdlType>),
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+#[serde(rename_all = "lowercase")]
+pub enum IdlArrayLen {
+    Generic(String),
+    #[serde(untagged)]
+    Value(usize),
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+#[serde(tag = "kind", rename_all = "lowercase")]
+pub enum IdlGenericArg {
+    Type {
+        #[serde(rename = "type")]
+        ty: IdlType,
+    },
+    Const {
+        value: String,
+    },
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
+#[serde(rename_all = "lowercase")]
+pub enum IdlType {
+    Bool,
+    U8,
+    I8,
+    U16,
+    I16,
+    U32,
+    I32,
+    F32,
+    U64,
+    I64,
+    F64,
+    U128,
+    I128,
+    U256,
+    I256,
+    Bytes,
+    String,
+    Pubkey,
+    Option(Box<IdlType>),
+    Vec(Box<IdlType>),
+    Array(Box<IdlType>, IdlArrayLen),
+    Defined {
+        name: String,
+        #[serde(default, skip_serializing_if = "is_default")]
+        generics: Vec<IdlGenericArg>,
+    },
+    Generic(String),
+}
+
+impl FromStr for IdlType {
+    type Err = anyhow::Error;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        let mut s = s.to_owned();
+        s.retain(|c| !c.is_whitespace());
+
+        let r = match s.as_str() {
+            "bool" => IdlType::Bool,
+            "u8" => IdlType::U8,
+            "i8" => IdlType::I8,
+            "u16" => IdlType::U16,
+            "i16" => IdlType::I16,
+            "u32" => IdlType::U32,
+            "i32" => IdlType::I32,
+            "f32" => IdlType::F32,
+            "u64" => IdlType::U64,
+            "i64" => IdlType::I64,
+            "f64" => IdlType::F64,
+            "u128" => IdlType::U128,
+            "i128" => IdlType::I128,
+            "u256" => IdlType::U256,
+            "i256" => IdlType::I256,
+            "Vec<u8>" => IdlType::Bytes,
+            "String" | "&str" | "&'staticstr" => IdlType::String,
+            "Pubkey" => IdlType::Pubkey,
+            _ => {
+                if let Some(inner) = s.strip_prefix("Option<") {
+                    let inner_ty = Self::from_str(
+                        inner
+                            .strip_suffix('>')
+                            .ok_or_else(|| anyhow!("Invalid Option"))?,
+                    )?;
+                    return Ok(IdlType::Option(Box::new(inner_ty)));
+                }
+
+                if let Some(inner) = s.strip_prefix("Vec<") {
+                    let inner_ty = Self::from_str(
+                        inner
+                            .strip_suffix('>')
+                            .ok_or_else(|| anyhow!("Invalid Vec"))?,
+                    )?;
+                    return Ok(IdlType::Vec(Box::new(inner_ty)));
+                }
+
+                if s.starts_with('[') {
+                    fn array_from_str(inner: &str) -> IdlType {
+                        match inner.strip_suffix(']') {
+                            Some(nested_inner) => array_from_str(&nested_inner[1..]),
+                            None => {
+                                let (raw_type, raw_length) = inner.rsplit_once(';').unwrap();
+                                let ty = IdlType::from_str(raw_type).unwrap();
+                                let len = match raw_length.replace('_', "").parse::<usize>() {
+                                    Ok(len) => IdlArrayLen::Value(len),
+                                    Err(_) => IdlArrayLen::Generic(raw_length.to_owned()),
+                                };
+                                IdlType::Array(Box::new(ty), len)
+                            }
+                        }
+                    }
+                    return Ok(array_from_str(&s));
+                }
+
+                // Defined
+                let (name, generics) = if let Some(i) = s.find('<') {
+                    (
+                        s.get(..i).unwrap().to_owned(),
+                        s.get(i + 1..)
+                            .unwrap()
+                            .strip_suffix('>')
+                            .unwrap()
+                            .split(',')
+                            .map(|g| g.trim().to_owned())
+                            .map(|g| {
+                                if g.parse::<bool>().is_ok()
+                                    || g.parse::<u128>().is_ok()
+                                    || g.parse::<i128>().is_ok()
+                                    || g.parse::<char>().is_ok()
+                                {
+                                    Ok(IdlGenericArg::Const { value: g })
+                                } else {
+                                    Self::from_str(&g).map(|ty| IdlGenericArg::Type { ty })
+                                }
+                            })
+                            .collect::<Result<Vec<_>, _>>()?,
+                    )
+                } else {
+                    (s.to_owned(), vec![])
+                };
+
+                IdlType::Defined { name, generics }
+            }
+        };
+        Ok(r)
+    }
+}
+
+pub type IdlDiscriminator = Vec<u8>;
+
+/// Get whether the given data is the default of its type.
+fn is_default<T: Default + PartialEq>(it: &T) -> bool {
+    *it == T::default()
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn option() {
+        assert_eq!(
+            IdlType::from_str("Option<bool>").unwrap(),
+            IdlType::Option(Box::new(IdlType::Bool))
+        )
+    }
+
+    #[test]
+    fn vector() {
+        assert_eq!(
+            IdlType::from_str("Vec<bool>").unwrap(),
+            IdlType::Vec(Box::new(IdlType::Bool))
+        )
+    }
+
+    #[test]
+    fn array() {
+        assert_eq!(
+            IdlType::from_str("[Pubkey; 16]").unwrap(),
+            IdlType::Array(Box::new(IdlType::Pubkey), IdlArrayLen::Value(16))
+        );
+    }
+
+    #[test]
+    fn array_with_underscored_length() {
+        assert_eq!(
+            IdlType::from_str("[u8; 50_000]").unwrap(),
+            IdlType::Array(Box::new(IdlType::U8), IdlArrayLen::Value(50000))
+        );
+    }
+
+    #[test]
+    fn multidimensional_array() {
+        assert_eq!(
+            IdlType::from_str("[[u8; 16]; 32]").unwrap(),
+            IdlType::Array(
+                Box::new(IdlType::Array(
+                    Box::new(IdlType::U8),
+                    IdlArrayLen::Value(16)
+                )),
+                IdlArrayLen::Value(32)
+            )
+        );
+    }
+
+    #[test]
+    fn generic_array() {
+        assert_eq!(
+            IdlType::from_str("[u64; T]").unwrap(),
+            IdlType::Array(Box::new(IdlType::U64), IdlArrayLen::Generic("T".into()))
+        );
+    }
+
+    #[test]
+    fn defined() {
+        assert_eq!(
+            IdlType::from_str("MyStruct").unwrap(),
+            IdlType::Defined {
+                name: "MyStruct".into(),
+                generics: vec![]
+            }
+        )
+    }
+
+    #[test]
+    fn defined_with_generics() {
+        assert_eq!(
+            IdlType::from_str("MyStruct<Pubkey, u64, 8>").unwrap(),
+            IdlType::Defined {
+                name: "MyStruct".into(),
+                generics: vec![
+                    IdlGenericArg::Type {
+                        ty: IdlType::Pubkey
+                    },
+                    IdlGenericArg::Type { ty: IdlType::U64 },
+                    IdlGenericArg::Const { value: "8".into() },
+                ],
+            }
+        )
+    }
+}

+ 3 - 3
lang/Cargo.toml

@@ -33,7 +33,7 @@ idl-build = [
     "anchor-attribute-program/idl-build",
     "anchor-derive-accounts/idl-build",
     "anchor-derive-serde/idl-build",
-    "anchor-syn/idl-build",
+    "anchor-idl/build",
 ]
 init-if-needed = ["anchor-derive-accounts/init-if-needed"]
 interface-instructions = ["anchor-attribute-program/interface-instructions"]
@@ -49,8 +49,8 @@ anchor-derive-accounts = { path = "./derive/accounts", version = "0.29.0" }
 anchor-derive-serde = { path = "./derive/serde", version = "0.29.0" }
 anchor-derive-space = { path = "./derive/space", version = "0.29.0" }
 
-# `anchor-syn` should only be included with `idl-build` feature
-anchor-syn = { path = "./syn", version = "0.29.0", optional = true }
+# `anchor-idl` should only be included with `idl-build` feature
+anchor-idl = { path = "../idl", version = "0.29.0", optional = true }
 
 arrayref = "0.3"
 base64 = "0.21"

+ 2 - 2
lang/attribute/account/src/lib.rs

@@ -413,7 +413,7 @@ pub fn zero_copy(
             #ret
         })
         .unwrap();
-        let idl_build_impl = anchor_syn::idl::build::impl_idl_build_struct(&zc_struct);
+        let idl_build_impl = anchor_syn::idl::impl_idl_build_struct(&zc_struct);
         return proc_macro::TokenStream::from(quote! {
             #ret
             #idl_build_impl
@@ -436,7 +436,7 @@ pub fn declare_id(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
 
     #[cfg(feature = "idl-build")]
     {
-        let idl_print = anchor_syn::idl::build::gen_idl_print_fn_address(address);
+        let idl_print = anchor_syn::idl::gen_idl_print_fn_address(address);
         return proc_macro::TokenStream::from(quote! {
             #ret
             #idl_print

+ 1 - 1
lang/attribute/constant/src/lib.rs

@@ -13,7 +13,7 @@ pub fn constant(
 
         let ts = match syn::parse(input).unwrap() {
             syn::Item::Const(item) => {
-                let idl_print = anchor_syn::idl::build::gen_idl_print_fn_constant(&item);
+                let idl_print = anchor_syn::idl::gen_idl_print_fn_constant(&item);
                 quote! {
                     #item
                     #idl_print

+ 1 - 1
lang/attribute/event/src/lib.rs

@@ -46,7 +46,7 @@ pub fn event(
 
     #[cfg(feature = "idl-build")]
     {
-        let idl_build = anchor_syn::idl::build::gen_idl_print_fn_event(&event_strct);
+        let idl_build = anchor_syn::idl::gen_idl_print_fn_event(&event_strct);
         return proc_macro::TokenStream::from(quote! {
             #ret
             #idl_build

+ 2 - 1
lang/attribute/program/Cargo.toml

@@ -17,7 +17,8 @@ idl-build = ["anchor-syn/idl-build"]
 interface-instructions = ["anchor-syn/interface-instructions"]
 
 [dependencies]
-anchor-syn = { path = "../../syn", version = "0.29.0", features = ["idl-types"] }
+anchor-idl = { path = "../../../idl", version = "0.29.0" }
+anchor-syn = { path = "../../syn", version = "0.29.0" }
 anyhow = "1"
 bs58 = "0.5"
 heck = "0.3"

+ 1 - 1
lang/attribute/program/src/declare_program/common.rs

@@ -1,4 +1,4 @@
-use anchor_syn::idl::types::{
+use anchor_idl::types::{
     Idl, IdlArrayLen, IdlDefinedFields, IdlField, IdlGenericArg, IdlRepr, IdlSerialization,
     IdlType, IdlTypeDef, IdlTypeDefGeneric, IdlTypeDefTy,
 };

+ 1 - 1
lang/attribute/program/src/declare_program/mod.rs

@@ -1,7 +1,7 @@
 mod common;
 mod mods;
 
-use anchor_syn::idl::types::Idl;
+use anchor_idl::types::Idl;
 use anyhow::anyhow;
 use quote::{quote, ToTokens};
 use syn::parse::{Parse, ParseStream};

+ 1 - 1
lang/attribute/program/src/declare_program/mods/accounts.rs

@@ -1,4 +1,4 @@
-use anchor_syn::idl::types::{Idl, IdlSerialization};
+use anchor_idl::types::{Idl, IdlSerialization};
 use quote::{format_ident, quote};
 
 use super::common::{convert_idl_type_def_to_ts, gen_discriminator, get_canonical_program_id};

+ 1 - 1
lang/attribute/program/src/declare_program/mods/client.rs

@@ -1,4 +1,4 @@
-use anchor_syn::idl::types::Idl;
+use anchor_idl::types::Idl;
 use quote::quote;
 
 use super::common::gen_accounts_common;

+ 1 - 1
lang/attribute/program/src/declare_program/mods/constants.rs

@@ -1,4 +1,4 @@
-use anchor_syn::idl::types::{Idl, IdlType};
+use anchor_idl::types::{Idl, IdlType};
 use quote::{format_ident, quote, ToTokens};
 
 use super::common::convert_idl_type_to_str;

+ 1 - 1
lang/attribute/program/src/declare_program/mods/cpi.rs

@@ -1,4 +1,4 @@
-use anchor_syn::idl::types::Idl;
+use anchor_idl::types::Idl;
 use heck::CamelCase;
 use quote::{format_ident, quote};
 

+ 1 - 1
lang/attribute/program/src/declare_program/mods/events.rs

@@ -1,4 +1,4 @@
-use anchor_syn::idl::types::Idl;
+use anchor_idl::types::Idl;
 use quote::{format_ident, quote};
 
 use super::common::{convert_idl_type_def_to_ts, gen_discriminator};

+ 1 - 1
lang/attribute/program/src/declare_program/mods/internal.rs

@@ -1,6 +1,6 @@
+use anchor_idl::types::{Idl, IdlInstructionAccountItem};
 use anchor_syn::{
     codegen::accounts::{__client_accounts, __cpi_client_accounts},
-    idl::types::{Idl, IdlInstructionAccountItem},
     parser::accounts,
     AccountsStruct,
 };

+ 1 - 1
lang/attribute/program/src/declare_program/mods/types.rs

@@ -1,4 +1,4 @@
-use anchor_syn::idl::types::Idl;
+use anchor_idl::types::Idl;
 use quote::quote;
 
 use super::common::convert_idl_type_def_to_ts;

+ 1 - 1
lang/derive/serde/src/lib.rs

@@ -32,7 +32,7 @@ pub fn anchor_serialize(input: TokenStream) -> TokenStream {
 
     #[cfg(feature = "idl-build")]
     {
-        use anchor_syn::idl::build::*;
+        use anchor_syn::idl::*;
         use quote::quote;
 
         let idl_build_impl = match syn::parse(input).unwrap() {

+ 3 - 0
lang/src/idl.rs

@@ -79,3 +79,6 @@ impl IdlAccount {
         "anchor:idl"
     }
 }
+
+#[cfg(feature = "idl-build")]
+pub use anchor_idl::{build::IdlBuild, *};

+ 2 - 2
lang/src/lib.rs

@@ -65,7 +65,7 @@ pub use solana_program;
 pub use anchor_attribute_event::{emit_cpi, event_cpi};
 
 #[cfg(feature = "idl-build")]
-pub use anchor_syn::{self, idl::build::IdlBuild};
+pub use idl::IdlBuild;
 
 #[cfg(feature = "interface-instructions")]
 pub use anchor_attribute_program::interface;
@@ -423,7 +423,7 @@ pub mod prelude {
     pub use super::{emit_cpi, event_cpi};
 
     #[cfg(feature = "idl-build")]
-    pub use super::IdlBuild;
+    pub use super::idl::IdlBuild;
 
     #[cfg(feature = "interface-instructions")]
     pub use super::interface;

+ 1 - 2
lang/syn/Cargo.toml

@@ -17,8 +17,7 @@ allow-missing-optionals = []
 anchor-debug = []
 event-cpi = []
 hash = []
-idl-build = ["idl-types", "cargo_toml"]
-idl-types = []
+idl-build = ["cargo_toml"]
 init-if-needed = []
 interface-instructions = []
 

+ 1 - 1
lang/syn/src/codegen/accounts/mod.rs

@@ -37,7 +37,7 @@ pub fn generate(accs: &AccountsStruct) -> proc_macro2::TokenStream {
 
     #[cfg(feature = "idl-build")]
     {
-        let idl_build_impl = crate::idl::build::gen_idl_build_impl_accounts_struct(accs);
+        let idl_build_impl = crate::idl::gen_idl_build_impl_accounts_struct(accs);
         return quote! {
             #ret
             #idl_build_impl

+ 1 - 1
lang/syn/src/codegen/error.rs

@@ -100,7 +100,7 @@ pub fn generate(error: Error) -> proc_macro2::TokenStream {
 
     #[cfg(feature = "idl-build")]
     {
-        let idl_print = crate::idl::build::gen_idl_print_fn_error(&error);
+        let idl_print = crate::idl::gen_idl_print_fn_error(&error);
         return quote! {
             #ret
             #idl_print

+ 1 - 1
lang/syn/src/codegen/program/mod.rs

@@ -39,7 +39,7 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream {
 
     #[cfg(feature = "idl-build")]
     {
-        let idl_build_impl = crate::idl::build::gen_idl_print_fn_program(program);
+        let idl_build_impl = crate::idl::gen_idl_print_fn_program(program);
         return quote! {
             #ret
             #idl_build_impl

+ 0 - 0
lang/syn/src/idl/build/accounts.rs → lang/syn/src/idl/accounts.rs


+ 0 - 0
lang/syn/src/idl/build/address.rs → lang/syn/src/idl/address.rs


+ 0 - 21
lang/syn/src/idl/build/mod.rs

@@ -1,21 +0,0 @@
-#![allow(dead_code)]
-
-mod accounts;
-mod address;
-mod common;
-mod constant;
-mod defined;
-mod error;
-mod event;
-mod external;
-mod program;
-
-pub use accounts::gen_idl_build_impl_accounts_struct;
-pub use address::gen_idl_print_fn_address;
-pub use constant::gen_idl_print_fn_constant;
-pub use defined::{impl_idl_build_enum, impl_idl_build_struct, impl_idl_build_union, IdlBuild};
-pub use error::gen_idl_print_fn_error;
-pub use event::gen_idl_print_fn_event;
-pub use program::gen_idl_print_fn_program;
-
-pub use serde_json;

+ 2 - 2
lang/syn/src/idl/build/common.rs → lang/syn/src/idl/common.rs

@@ -26,11 +26,11 @@ pub fn get_no_docs() -> bool {
 }
 
 pub fn get_idl_module_path() -> TokenStream {
-    quote!(anchor_lang::anchor_syn::idl::types)
+    quote!(anchor_lang::idl::types)
 }
 
 pub fn get_serde_json_module_path() -> TokenStream {
-    quote!(anchor_lang::anchor_syn::idl::build::serde_json)
+    quote!(anchor_lang::idl::serde_json)
 }
 
 pub fn gen_print_section(name: &str, value: impl ToTokens) -> TokenStream {

+ 0 - 0
lang/syn/src/idl/build/constant.rs → lang/syn/src/idl/constant.rs


+ 6 - 40
lang/syn/src/idl/build/defined.rs → lang/syn/src/idl/defined.rs

@@ -1,55 +1,21 @@
-use std::collections::BTreeMap;
-
 use anyhow::{anyhow, Result};
 use proc_macro2::TokenStream;
 use quote::quote;
 
 use super::common::{get_idl_module_path, get_no_docs};
-use crate::{idl::types::IdlTypeDef, parser::docs};
-
-/// A trait that types must implement in order to include the type in the IDL definition.
-///
-/// This trait is automatically implemented for Anchor all types that use the `AnchorSerialize`
-/// proc macro. Note that manually implementing the `AnchorSerialize` trait does **NOT** have the
-/// same effect.
-///
-/// Types that don't implement this trait will cause a compile error during the IDL generation.
-///
-/// The default implementation of the trait allows the program to compile but the type does **NOT**
-/// get included in the IDL.
-pub trait IdlBuild {
-    /// Create an IDL type definition for the type.
-    ///
-    /// The type is only included in the IDL if this method returns `Some`.
-    fn create_type() -> Option<IdlTypeDef> {
-        None
-    }
-
-    /// Insert all types that are included in the current type definition to the given map.
-    fn insert_types(_types: &mut BTreeMap<String, IdlTypeDef>) {}
-
-    /// Get the full module path of the type.
-    ///
-    /// The full path will be used in the case of a conflicting type definition, e.g. when there
-    /// are multiple structs with the same name.
-    ///
-    /// The default implementation covers most cases.
-    fn get_full_path() -> String {
-        std::any::type_name::<Self>().into()
-    }
-}
+use crate::parser::docs;
 
-/// Generate [`IdlBuild`] impl for a struct.
+/// Generate `IdlBuild` impl for a struct.
 pub fn impl_idl_build_struct(item: &syn::ItemStruct) -> TokenStream {
     impl_idl_build(&item.ident, &item.generics, gen_idl_type_def_struct(item))
 }
 
-/// Generate [`IdlBuild`] impl for an enum.
+/// Generate `IdlBuild` impl for an enum.
 pub fn impl_idl_build_enum(item: &syn::ItemEnum) -> TokenStream {
     impl_idl_build(&item.ident, &item.generics, gen_idl_type_def_enum(item))
 }
 
-/// Generate [`IdlBuild`] impl for a union.
+/// Generate `IdlBuild` impl for a union.
 ///
 /// Unions are not currently supported in the IDL.
 pub fn impl_idl_build_union(item: &syn::ItemUnion) -> TokenStream {
@@ -60,7 +26,7 @@ pub fn impl_idl_build_union(item: &syn::ItemUnion) -> TokenStream {
     )
 }
 
-/// Generate [`IdlBuild`] implementation.
+/// Generate `IdlBuild` implementation.
 fn impl_idl_build(
     ident: &syn::Ident,
     generics: &syn::Generics,
@@ -68,7 +34,7 @@ fn impl_idl_build(
 ) -> TokenStream {
     let idl = get_idl_module_path();
     let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
-    let idl_build_trait = quote!(anchor_lang::anchor_syn::idl::build::IdlBuild);
+    let idl_build_trait = quote!(anchor_lang::idl::build::IdlBuild);
 
     let (idl_type_def, insert_defined) = match type_def {
         Ok((ts, defined)) => (

+ 0 - 0
lang/syn/src/idl/build/error.rs → lang/syn/src/idl/error.rs


+ 0 - 0
lang/syn/src/idl/build/event.rs → lang/syn/src/idl/event.rs


+ 0 - 0
lang/syn/src/idl/build/external.rs → lang/syn/src/idl/external.rs


+ 18 - 3
lang/syn/src/idl/mod.rs

@@ -1,4 +1,19 @@
-pub mod types;
+#![allow(dead_code)]
 
-#[cfg(feature = "idl-build")]
-pub mod build;
+mod accounts;
+mod address;
+mod common;
+mod constant;
+mod defined;
+mod error;
+mod event;
+mod external;
+mod program;
+
+pub use accounts::gen_idl_build_impl_accounts_struct;
+pub use address::gen_idl_print_fn_address;
+pub use constant::gen_idl_print_fn_constant;
+pub use defined::{impl_idl_build_enum, impl_idl_build_struct, impl_idl_build_union};
+pub use error::gen_idl_print_fn_error;
+pub use event::gen_idl_print_fn_event;
+pub use program::gen_idl_print_fn_program;

+ 0 - 0
lang/syn/src/idl/build/program.rs → lang/syn/src/idl/program.rs


+ 0 - 486
lang/syn/src/idl/types.rs

@@ -1,486 +0,0 @@
-use std::str::FromStr;
-
-use anyhow::anyhow;
-use serde::{Deserialize, Serialize};
-
-/// IDL specification Semantic Version
-pub const IDL_SPEC: &str = "0.1.0";
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-pub struct Idl {
-    pub address: String,
-    pub metadata: IdlMetadata,
-    #[serde(default, skip_serializing_if = "is_default")]
-    pub docs: Vec<String>,
-    pub instructions: Vec<IdlInstruction>,
-    #[serde(default, skip_serializing_if = "is_default")]
-    pub accounts: Vec<IdlAccount>,
-    #[serde(default, skip_serializing_if = "is_default")]
-    pub events: Vec<IdlEvent>,
-    #[serde(default, skip_serializing_if = "is_default")]
-    pub errors: Vec<IdlErrorCode>,
-    #[serde(default, skip_serializing_if = "is_default")]
-    pub types: Vec<IdlTypeDef>,
-    #[serde(default, skip_serializing_if = "is_default")]
-    pub constants: Vec<IdlConst>,
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-pub struct IdlMetadata {
-    pub name: String,
-    pub version: String,
-    pub spec: String,
-    #[serde(skip_serializing_if = "is_default")]
-    pub description: Option<String>,
-    #[serde(skip_serializing_if = "is_default")]
-    pub repository: Option<String>,
-    #[serde(default, skip_serializing_if = "is_default")]
-    pub dependencies: Vec<IdlDependency>,
-    #[serde(skip_serializing_if = "is_default")]
-    pub contact: Option<String>,
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-pub struct IdlDependency {
-    pub name: String,
-    pub version: String,
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-pub struct IdlInstruction {
-    pub name: String,
-    #[serde(default, skip_serializing_if = "is_default")]
-    pub docs: Vec<String>,
-    pub discriminator: IdlDiscriminator,
-    pub accounts: Vec<IdlInstructionAccountItem>,
-    pub args: Vec<IdlField>,
-    #[serde(skip_serializing_if = "is_default")]
-    pub returns: Option<IdlType>,
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-#[serde(untagged)]
-pub enum IdlInstructionAccountItem {
-    Composite(IdlInstructionAccounts),
-    Single(IdlInstructionAccount),
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-pub struct IdlInstructionAccount {
-    pub name: String,
-    #[serde(default, skip_serializing_if = "is_default")]
-    pub docs: Vec<String>,
-    #[serde(default, skip_serializing_if = "is_default")]
-    pub writable: bool,
-    #[serde(default, skip_serializing_if = "is_default")]
-    pub signer: bool,
-    #[serde(default, skip_serializing_if = "is_default")]
-    pub optional: bool,
-    #[serde(skip_serializing_if = "is_default")]
-    pub address: Option<String>,
-    #[serde(skip_serializing_if = "is_default")]
-    pub pda: Option<IdlPda>,
-    #[serde(default, skip_serializing_if = "is_default")]
-    pub relations: Vec<String>,
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-pub struct IdlInstructionAccounts {
-    pub name: String,
-    pub accounts: Vec<IdlInstructionAccountItem>,
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-pub struct IdlPda {
-    pub seeds: Vec<IdlSeed>,
-    #[serde(skip_serializing_if = "is_default")]
-    pub program: Option<IdlSeed>,
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-#[serde(tag = "kind", rename_all = "lowercase")]
-pub enum IdlSeed {
-    Const(IdlSeedConst),
-    Arg(IdlSeedArg),
-    Account(IdlSeedAccount),
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-pub struct IdlSeedConst {
-    pub value: Vec<u8>,
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-pub struct IdlSeedArg {
-    pub path: String,
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-pub struct IdlSeedAccount {
-    pub path: String,
-    #[serde(skip_serializing_if = "is_default")]
-    pub account: Option<String>,
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-pub struct IdlAccount {
-    pub name: String,
-    pub discriminator: IdlDiscriminator,
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-pub struct IdlEvent {
-    pub name: String,
-    pub discriminator: IdlDiscriminator,
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-pub struct IdlConst {
-    pub name: String,
-    #[serde(rename = "type")]
-    pub ty: IdlType,
-    pub value: String,
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
-pub struct IdlErrorCode {
-    pub code: u32,
-    pub name: String,
-    #[serde(skip_serializing_if = "is_default")]
-    pub msg: Option<String>,
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-pub struct IdlField {
-    pub name: String,
-    #[serde(default, skip_serializing_if = "is_default")]
-    pub docs: Vec<String>,
-    #[serde(rename = "type")]
-    pub ty: IdlType,
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-pub struct IdlTypeDef {
-    pub name: String,
-    #[serde(default, skip_serializing_if = "is_default")]
-    pub docs: Vec<String>,
-    #[serde(default, skip_serializing_if = "is_default")]
-    pub serialization: IdlSerialization,
-    #[serde(skip_serializing_if = "is_default")]
-    pub repr: Option<IdlRepr>,
-    #[serde(default, skip_serializing_if = "is_default")]
-    pub generics: Vec<IdlTypeDefGeneric>,
-    #[serde(rename = "type")]
-    pub ty: IdlTypeDefTy,
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
-#[serde(rename_all = "lowercase")]
-pub enum IdlSerialization {
-    #[default]
-    Borsh,
-    Bytemuck,
-    BytemuckUnsafe,
-    Custom(String),
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-#[serde(tag = "kind", rename_all = "lowercase")]
-pub enum IdlRepr {
-    Rust(IdlReprModifier),
-    C(IdlReprModifier),
-    Transparent,
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-pub struct IdlReprModifier {
-    #[serde(default, skip_serializing_if = "is_default")]
-    pub packed: bool,
-    #[serde(skip_serializing_if = "is_default")]
-    pub align: Option<usize>,
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-#[serde(tag = "kind", rename_all = "lowercase")]
-pub enum IdlTypeDefGeneric {
-    Type {
-        name: String,
-    },
-    Const {
-        name: String,
-        #[serde(rename = "type")]
-        ty: String,
-    },
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-#[serde(tag = "kind", rename_all = "lowercase")]
-pub enum IdlTypeDefTy {
-    Struct {
-        #[serde(skip_serializing_if = "is_default")]
-        fields: Option<IdlDefinedFields>,
-    },
-    Enum {
-        variants: Vec<IdlEnumVariant>,
-    },
-    Type {
-        alias: IdlType,
-    },
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-pub struct IdlEnumVariant {
-    pub name: String,
-    #[serde(skip_serializing_if = "is_default")]
-    pub fields: Option<IdlDefinedFields>,
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-#[serde(untagged)]
-pub enum IdlDefinedFields {
-    Named(Vec<IdlField>),
-    Tuple(Vec<IdlType>),
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-#[serde(rename_all = "lowercase")]
-pub enum IdlArrayLen {
-    Generic(String),
-    #[serde(untagged)]
-    Value(usize),
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-#[serde(tag = "kind", rename_all = "lowercase")]
-pub enum IdlGenericArg {
-    Type {
-        #[serde(rename = "type")]
-        ty: IdlType,
-    },
-    Const {
-        value: String,
-    },
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
-#[serde(rename_all = "lowercase")]
-pub enum IdlType {
-    Bool,
-    U8,
-    I8,
-    U16,
-    I16,
-    U32,
-    I32,
-    F32,
-    U64,
-    I64,
-    F64,
-    U128,
-    I128,
-    U256,
-    I256,
-    Bytes,
-    String,
-    Pubkey,
-    Option(Box<IdlType>),
-    Vec(Box<IdlType>),
-    Array(Box<IdlType>, IdlArrayLen),
-    Defined {
-        name: String,
-        #[serde(default, skip_serializing_if = "is_default")]
-        generics: Vec<IdlGenericArg>,
-    },
-    Generic(String),
-}
-
-impl FromStr for IdlType {
-    type Err = anyhow::Error;
-
-    fn from_str(s: &str) -> Result<Self, Self::Err> {
-        let mut s = s.to_owned();
-        s.retain(|c| !c.is_whitespace());
-
-        let r = match s.as_str() {
-            "bool" => IdlType::Bool,
-            "u8" => IdlType::U8,
-            "i8" => IdlType::I8,
-            "u16" => IdlType::U16,
-            "i16" => IdlType::I16,
-            "u32" => IdlType::U32,
-            "i32" => IdlType::I32,
-            "f32" => IdlType::F32,
-            "u64" => IdlType::U64,
-            "i64" => IdlType::I64,
-            "f64" => IdlType::F64,
-            "u128" => IdlType::U128,
-            "i128" => IdlType::I128,
-            "u256" => IdlType::U256,
-            "i256" => IdlType::I256,
-            "Vec<u8>" => IdlType::Bytes,
-            "String" | "&str" | "&'staticstr" => IdlType::String,
-            "Pubkey" => IdlType::Pubkey,
-            _ => {
-                if let Some(inner) = s.strip_prefix("Option<") {
-                    let inner_ty = Self::from_str(
-                        inner
-                            .strip_suffix('>')
-                            .ok_or_else(|| anyhow!("Invalid Option"))?,
-                    )?;
-                    return Ok(IdlType::Option(Box::new(inner_ty)));
-                }
-
-                if let Some(inner) = s.strip_prefix("Vec<") {
-                    let inner_ty = Self::from_str(
-                        inner
-                            .strip_suffix('>')
-                            .ok_or_else(|| anyhow!("Invalid Vec"))?,
-                    )?;
-                    return Ok(IdlType::Vec(Box::new(inner_ty)));
-                }
-
-                if s.starts_with('[') {
-                    fn array_from_str(inner: &str) -> IdlType {
-                        match inner.strip_suffix(']') {
-                            Some(nested_inner) => array_from_str(&nested_inner[1..]),
-                            None => {
-                                let (raw_type, raw_length) = inner.rsplit_once(';').unwrap();
-                                let ty = IdlType::from_str(raw_type).unwrap();
-                                let len = match raw_length.replace('_', "").parse::<usize>() {
-                                    Ok(len) => IdlArrayLen::Value(len),
-                                    Err(_) => IdlArrayLen::Generic(raw_length.to_owned()),
-                                };
-                                IdlType::Array(Box::new(ty), len)
-                            }
-                        }
-                    }
-                    return Ok(array_from_str(&s));
-                }
-
-                // Defined
-                let (name, generics) = if let Some(i) = s.find('<') {
-                    (
-                        s.get(..i).unwrap().to_owned(),
-                        s.get(i + 1..)
-                            .unwrap()
-                            .strip_suffix('>')
-                            .unwrap()
-                            .split(',')
-                            .map(|g| g.trim().to_owned())
-                            .map(|g| {
-                                if g.parse::<bool>().is_ok()
-                                    || g.parse::<u128>().is_ok()
-                                    || g.parse::<i128>().is_ok()
-                                    || g.parse::<char>().is_ok()
-                                {
-                                    Ok(IdlGenericArg::Const { value: g })
-                                } else {
-                                    Self::from_str(&g).map(|ty| IdlGenericArg::Type { ty })
-                                }
-                            })
-                            .collect::<Result<Vec<_>, _>>()?,
-                    )
-                } else {
-                    (s.to_owned(), vec![])
-                };
-
-                IdlType::Defined { name, generics }
-            }
-        };
-        Ok(r)
-    }
-}
-
-pub type IdlDiscriminator = Vec<u8>;
-
-/// Get whether the given data is the default of its type.
-fn is_default<T: Default + PartialEq>(it: &T) -> bool {
-    *it == T::default()
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn option() {
-        assert_eq!(
-            IdlType::from_str("Option<bool>").unwrap(),
-            IdlType::Option(Box::new(IdlType::Bool))
-        )
-    }
-
-    #[test]
-    fn vector() {
-        assert_eq!(
-            IdlType::from_str("Vec<bool>").unwrap(),
-            IdlType::Vec(Box::new(IdlType::Bool))
-        )
-    }
-
-    #[test]
-    fn array() {
-        assert_eq!(
-            IdlType::from_str("[Pubkey; 16]").unwrap(),
-            IdlType::Array(Box::new(IdlType::Pubkey), IdlArrayLen::Value(16))
-        );
-    }
-
-    #[test]
-    fn array_with_underscored_length() {
-        assert_eq!(
-            IdlType::from_str("[u8; 50_000]").unwrap(),
-            IdlType::Array(Box::new(IdlType::U8), IdlArrayLen::Value(50000))
-        );
-    }
-
-    #[test]
-    fn multidimensional_array() {
-        assert_eq!(
-            IdlType::from_str("[[u8; 16]; 32]").unwrap(),
-            IdlType::Array(
-                Box::new(IdlType::Array(
-                    Box::new(IdlType::U8),
-                    IdlArrayLen::Value(16)
-                )),
-                IdlArrayLen::Value(32)
-            )
-        );
-    }
-
-    #[test]
-    fn generic_array() {
-        assert_eq!(
-            IdlType::from_str("[u64; T]").unwrap(),
-            IdlType::Array(Box::new(IdlType::U64), IdlArrayLen::Generic("T".into()))
-        );
-    }
-
-    #[test]
-    fn defined() {
-        assert_eq!(
-            IdlType::from_str("MyStruct").unwrap(),
-            IdlType::Defined {
-                name: "MyStruct".into(),
-                generics: vec![]
-            }
-        )
-    }
-
-    #[test]
-    fn defined_with_generics() {
-        assert_eq!(
-            IdlType::from_str("MyStruct<Pubkey, u64, 8>").unwrap(),
-            IdlType::Defined {
-                name: "MyStruct".into(),
-                generics: vec![
-                    IdlGenericArg::Type {
-                        ty: IdlType::Pubkey
-                    },
-                    IdlGenericArg::Type { ty: IdlType::U64 },
-                    IdlGenericArg::Const { value: "8".into() },
-                ],
-            }
-        )
-    }
-}

+ 1 - 1
lang/syn/src/lib.rs

@@ -3,7 +3,7 @@
 pub mod codegen;
 pub mod parser;
 
-#[cfg(feature = "idl-types")]
+#[cfg(feature = "idl-build")]
 pub mod idl;
 
 #[cfg(feature = "hash")]

+ 1 - 1
tests/idl/programs/new-idl/src/lib.rs

@@ -366,7 +366,7 @@ mod wrapped {
     use super::*;
 
     #[cfg(feature = "idl-build")]
-    use anchor_lang::anchor_syn::idl::types::*;
+    use anchor_lang::idl::types::*;
 
     pub struct Feature(anchor_lang::solana_program::feature::Feature);