Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compact trait bounds overflow #65

Open
ascjones opened this issue Feb 3, 2021 · 4 comments
Open

Compact trait bounds overflow #65

ascjones opened this issue Feb 3, 2021 · 4 comments

Comments

@ascjones
Copy link
Contributor

ascjones commented Feb 3, 2021

When integrating the latest scale-info master into substrate (see https://github.com/paritytech/substrate/compare/aj-metadata-vnext) I receive the following error:

image

It appears to have been introduced in #53.

Removing the TypeInfo derive on MultiAddress makes it compile:

diff --git a/primitives/runtime/src/multiaddress.rs b/primitives/runtime/src/multiaddress.rs
index a47201008..d09cd7aca 100644
--- a/primitives/runtime/src/multiaddress.rs
+++ b/primitives/runtime/src/multiaddress.rs
@@ -21,7 +21,7 @@ use codec::{Encode, Decode};
 use sp_std::vec::Vec;
 
 /// A multi-format address wrapper for on-chain accounts.
-#[derive(Encode, Decode, PartialEq, Eq, Clone, crate::RuntimeDebug, scale_info::TypeInfo)]
+#[derive(Encode, Decode, PartialEq, Eq, Clone, crate::RuntimeDebug)]
 #[cfg_attr(feature = "std", derive(Hash))]
 pub enum MultiAddress<AccountId, AccountIndex> {
 	/// It's an account ID (pubkey).
diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs
index 00fae6fe6..0fdf6d55b 100644
--- a/primitives/runtime/src/traits.rs
+++ b/primitives/runtime/src/traits.rs
@@ -203,7 +203,7 @@ pub trait Lookup {
 /// context.
 pub trait StaticLookup {
 	/// Type to lookup from.
-	type Source: Codec + Clone + PartialEq + Debug + scale_info::TypeInfo;
+	type Source: Codec + Clone + PartialEq + Debug;
 	/// Type to lookup into.
 	type Target;
 	/// Attempt a lookup.

Here is the expanded derived TypeInfo impl for MultiAddress:

impl<AccountId, AccountIndex> ::scale_info::TypeInfo for MultiAddress<AccountId, AccountIndex>
        where
            AccountId: ::scale_info::TypeInfo + 'static,
            AccountIndex: ::codec::HasCompact,
            <AccountIndex as ::codec::HasCompact>::Type: ::scale_info::TypeInfo + 'static,
            AccountId: ::scale_info::TypeInfo + 'static,
            AccountIndex: ::scale_info::TypeInfo + 'static,
        {
            type Identity = Self;
            fn type_info() -> ::scale_info::Type {
                ::scale_info::Type::builder()
                    .path(::scale_info::Path::new(
                        "MultiAddress",
                        "sp_runtime::multiaddress",
                    ))
                    .type_params(<[_]>::into_vec(box [
                        ::scale_info::meta_type::<AccountId>(),
                        ::scale_info::meta_type::<AccountIndex>(),
                    ]))
                    .variant(
                        ::scale_info::build::Variants::with_fields()
                            .variant(
                                "Id",
                                ::scale_info::build::Fields::unnamed()
                                    .field_of::<AccountId>("AccountId"),
                            )
                            .variant(
                                "Index",
                                ::scale_info::build::Fields::unnamed()
                                    .compact_of::<AccountIndex>("AccountIndex"),
                            )
                            .variant(
                                "Raw",
                                ::scale_info::build::Fields::unnamed()
                                    .field_of::<Vec<u8>>("Vec<u8>"),
                            )
                            .variant(
                                "Address32",
                                ::scale_info::build::Fields::unnamed()
                                    .field_of::<[u8; 32]>("[u8; 32]"),
                            )
                            .variant(
                                "Address20",
                                ::scale_info::build::Fields::unnamed()
                                    .field_of::<[u8; 20]>("[u8; 20]"),
                            ),
                    )
            }
        };
@ascjones
Copy link
Contributor Author

ascjones commented Feb 3, 2021

Managed to repro in scale-info finally, could do with some more minimization but here is what I have so far:

    #[allow(unused)]
    #[derive(Encode, scale::Decode, TypeInfo)]
    enum MutilatedMultiAddress<AccountId, AccountIndex> {
        Id(AccountId),
        Index(#[codec(compact)] AccountIndex),
        Address32([u8; 32]),
    }

    pub trait StaticLookup {
        type Source: scale::Codec // works
        /// Type to lookup from.
        // type Source: scale::Codec + TypeInfo + 'static; // recursion error
    }

    pub struct AccountIdLookup<AccountId, AccountIndex>(PhantomData<(AccountId, AccountIndex)>);

    impl<AccountId, AccountIndex> StaticLookup for AccountIdLookup<AccountId, AccountIndex>
        where
            AccountId: scale::Codec + Clone + PartialEq + scale_info::TypeInfo + 'static,
            AccountIndex: scale::Codec + Clone + PartialEq + scale_info::TypeInfo + 'static,
            MutilatedMultiAddress<AccountId, AccountIndex>: scale::Codec,
    {
        type Source = MutilatedMultiAddress<AccountId, AccountIndex>;
    }

@dvdplm
Copy link
Contributor

dvdplm commented Feb 3, 2021

Managed to repro in scale-info finally,

Confirmed, I see it here too.

@ascjones
Copy link
Contributor Author

ascjones commented Feb 4, 2021

The fix for this particaular snippet is to remove the TypeInfo + 'static bounds for the StaticLookup from AccountId and AccountIndex and add them instead to MutilatedMultiAddress<AccountId, AccountIndex>.

Edit: I think just adding to MutilatedMultiAddress<AccountId, AccountIndex> is enough, see #66.

    pub trait StaticLookup {
        type Source: scale::Codec + TypeInfo + 'static;
    }

    struct AccountIdLookup<AccountId, AccountIndex>(PhantomData<(AccountId, AccountIndex)>);

    impl<AccountId, AccountIndex> StaticLookup for AccountIdLookup<AccountId, AccountIndex>
        where
            AccountId: scale::Codec + Clone + PartialEq,
            AccountIndex: scale::Codec + Clone + PartialEq,
            MutilatedMultiAddress<AccountId, AccountIndex>: scale::Codec + TypeInfo + 'static,
    {
        type Source = MutilatedMultiAddress<AccountId, AccountIndex>;
    }

@ascjones
Copy link
Contributor Author

ascjones commented Feb 5, 2021

Note the fix for the above snippet is to apply the TypeInfo bounds to the MultiAddress rather than the type parameters themselves:

    AccountId: Codec + Clone + PartialEq + Debug,
    AccountIndex: Codec + Clone + PartialEq + Debug,
    crate::MultiAddress<AccountId, AccountIndex>: Codec + scale_info::TypeInfo + 'static,

Also see rust-lang/rust#81785 for the rust issue to improve the error message.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants