Substrate pallet does not compile with tag devhub/latest - substrate

I've been using substrate-node-template of tag="monthly-2021-05" for a while, but decided to switch everything to the tag="devhub/latest". Now my pallet fails to compile with the folowing errors:
error[E0277]: the trait bound `AuthorizedAccount<T, VendorPermission>: TypeInfo` is not satisfied
--> pallets/aipallet/src/lib.rs:53:1
|
53 | #[frame_support::pallet]
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TypeInfo` is not implemented for`MyStruct
This error is repeated for all my structs and enums. It seems to be something simple and I tried to few things like adding TypeInfo into derive part of struct declaration or adding/removing scale_info into Cargo.toml etc, but no luck. Please help

Fixed by adding TypeInfo to each struct and enum declaration derive list plus adding to Config trait declaration
+ scale_info::TypeInfo

Related

msvc function traits on lambda

I'm trying to use the function traits that was posted as the marked answer here:
Is it possible to figure out the parameter type and return type of a lambda?
While trying to compile it with msvc 19.16.27034 I get the following errors:
Error C2825 'T': must be a class or namespace when followed by '::'
Error C2510 'T': left of '::' must be a class/struct/union
Error C2065 '()': undeclared identifier
Error C2955 'function_traits': use of class template requires template argument list
On godbolt this works on any compiler but for some reason on my local machine I can't get this to compile because of these errors. Am I missing something?
UPDATE:
Adding std::remove_reference_t
template <typename T>
struct function_traits
: public function_traits<decltype(&std::remove_reference_t<T>::operator())>
{
};
to the declaration solves the problem.
The weird part is that even without any instantiation to the template I still get this error on the specified compiler, unless I'm adding std::remove_reference_t.
Anyone can explain this weird behaviour?

Why is `impl` needed when passing traits as function parameters?

In the following example of passing a trait as a parameter, what's the need of sending impl in the function signature?
I understand that traits are more generic types and not concrete types, but since the Rust compiler doesn't allow sharing names across structs and traits, why is there a need to provide impl in the function signature to represent the type?
pub fn notify(item: impl Summary) {
println!("Breaking news! {}", item.summarize());
}
The documentation mentions that the above signature is just syntactic sugar for the below signature. Wouldn't it make sense to use trait Summary instead of impl Summary as impl can also be used to define methods on structs?
pub fn notify<T: Summary>(item: T) {
println!("Breaking news! {}", item.summarize());
}
Is there any hidden concept around it that I'm missing?
Contrary to languages such as Go or Java, Rust allows for both static and dynamic dispatch, and some syntax was required to let programmers choose between the two.
As dynamic dispatch must work on objects which might not be Sized, you need a reference to use it. That is, you would use &dyn Trait or Box<dyn Trait> (note: for historical reasons, the dyn keyword is not required, but modern Rust uses it). In C++, dynamic dispatch also requires a reference or pointer.
Static dispatch is not something Go or Java have. In C++, it works with templates and duck-typing. In Rust, it works with generics and traits, and its original syntax was:
fn some_function<T: Trait>(foo: T) { … }
Later, the following syntax was added to the language:
fn some_function(foo: impl Trait) { … }
which is equivalent to the above.
This syntax was originally invented to be used in return types, where there is no generic equivalent:
fn some_function() -> impl Trait { … }
This means that some_function can return any single type that implements Trait, but this type must be known at compile time. This has some performance benefits over returning Box<Trait> for example. In C++, the closest equivalent would be returning auto or decltype(auto).
The syntax in parameter position was added for symmetry.
You might wonder why not simply make the generics implicit and have:
fn some_function(foo: Trait) { … }
But this would be slightly confusing. Trait by itself is not sized, and therefore cannot be used as a parameter, unless they are generic. This would make traits stand out in the realm of unsized types. For example, if (foo: Trait) would work, you might wonder why (foo: str) doesn't, but what would that one mean? There is also other problems with making generics implicit, for example, generics in traits make the trait non-object-safe.
Later, Rust will likely extend those existential types and allow this at a module level:
type Foo = impl Bar;
(which is currently allowed on nightly, guarded by the type_alias_impl_trait feature)
Finally, you are asking why the syntax is impl Foo, rather than trait Foo. This reads well as "a type that implements Foo". The original RFC doesn't discuss alternative syntaxes much. Another RFC discusses the syntax more, in particular whether the syntax should have been any Foo in parameter position, and some Foo in return position. The syntax trait Foo was never considered as far as I am aware.

What does "dyn" mean in a type?

I have recently seen code using the dyn keyword:
fn foo(arg: &dyn Display) {}
fn bar() -> Box<dyn Display> {}
What does this syntax mean?
TL;DR: It's a syntax for specifying the type of a trait object and must be specified for clarity reasons.
Since Rust 1.0, traits have led a double life. Once a trait has been declared, it can be used either as a trait or as a type:
// As a trait
impl MyTrait for SomeType {}
// As a type!
impl MyTrait {}
impl AnotherTrait for MyTrait {}
As you can imagine, this double meaning can cause some confusion. Additionally, since the MyTrait type is an unsized / dynamically-sized type, this can expose people to very complex error messages.
To ameliorate this problem, RFC 2113 introduced the dyn syntax. This syntax is available starting in Rust 1.27:
use std::{fmt::Display, sync::Arc};
fn main() {
let display_ref: &dyn Display = &42;
let display_box: Box<dyn Display> = Box::new(42);
let display_arc: Arc<dyn Display> = Arc::new(42);
}
This new keyword parallels the impl Trait syntax and strives to make the type of a trait object more obviously distinct from the "bare" trait syntax.
dyn is short for "dynamic" and refers to the fact that trait objects perform dynamic dispatch. This means that the decision of exactly which function is called will occur at program run time. Contrast this to static dispatch which uses the impl Trait syntax.
The syntax without dyn is now deprecated and it's likely that in a subsequent edition of Rust it will be removed.
Why would I implement methods on a trait instead of as part of the trait?
What makes something a "trait object"?
TLDR: "dyn" allows you to store in a Box a mix of Apples and Oranges, because they all implement the same trait of Fruit, which is what your Box is using as a type constraint, instead of just a generic type. This is because Generic allows any ONE of Apple OR Orange, but not both:
Vec<Box<T>> --> Vector can hold boxes of either Apples OR Oranges structs
Vec<Box<dyn Fruit>> --> Vector can now hold a mix of boxes of Apples AND Oranges Structs
If you want to store multiple types to the same instance of a data-structure, you have to use a trait wrapping a generic type and tag it as a "dyn", which will then cause that generic type to be resolved each time it's called, during runtime.
Sometimes, rather than using a type (String, &str, i32, etc...) or generic (T, Vec, etc...), we are using a trait as the type constraint (i.e. TryFrom). This is to allow us to store multiple types (all implementing the required trait), in the same data-structure instance (you will probably need to Box<> it too).
"dyn" basically tells the compiler that we don't know what the type is going to be at compile-time in place of the trait, and that it will be determined at run-time. This allows the final type to actually be a mixture of types that all implement the trait.
For generics, the compiler will hard-code the type in place of our generic type at the first use of the call to our data-structure consuming the generics. Every other call to store data in that same data-structure is expected to be using the same type as in the first call.
WARNING
As with all things, there is a performance penalty for implementing added flexibility, and this case definitely has a performance penalty.
I found this blog post to explain this feature really clearly: https://medium.com/digitalfrontiers/rust-dynamic-dispatching-deep-dive-236a5896e49b
Relevant excerpt:
struct Service<T:Backend>{
backend: Vec<T> // Either Vec<TypeA> or Vec<TypeB>, not both
}
...
let mut backends = Vec::new();
backends.push(TypeA);
backends.push(TypeB); // <---- Type error here
vs
struct Service{
backends: Vec<Box<dyn Backend>>
}
...
let mut backends = Vec::new();
backends.push( Box::new(PositiveBackend{}) as Box<dyn Backend>);
backends.push( Box::new(NegativeBackend{}) as Box<dyn Backend>);
The dyn keyword is used to indicate that a type is a trait object. According to the Rust docs:
A trait object is an opaque value of another type that implements a
set of traits.
In other words, we do not know the specific type of the object at compile time, we just know that the object implements the trait.
Because the size of a trait object is unknown at compile time they must be placed behind a pointer. For example, if Trait is your trait name then you can use your trait objects in the following manner:
Box<dyn Trait>
&dyn Trait
and other pointer types
The variables/parameters which hold the trait objects are fat pointers which consists of the following components:
pointer to the object in memory
pointer to that object’s vtable, a vtable is a table with pointers which point to the actual method(s) implementation(s).
See my answer on What makes something a “trait object”? for further details.

OMNeT++ issue with linking INET

During the build of my new OMNeT++ project I have encountered following error:
out/clang-debug//myUdp.o:(.rdata[_ZTI5myUdp]+0x10): undefined reference to 'typeinfo for inet::ApplicationBase'
I have already configured INET reference (Project "myUdp" -> Properties -> Project reference -> inet checkbox selected)
This is INET Makemake configuration: Target tab and Compile tab
This is Makemake configuration of my project (myUdp): Compile tab and Link tab
And the C++ code:
MyUdp.cc
#include <inet/applications/udpapp/UDPBasicApp.h>
class myUdp: public inet::UDPBasicApp {
};
Define_Module(myUdp);
MyUdp.ned
import inet.applications.udpapp.UDPBasicApp;
simple myUdp extends UDPBasicApp {
#class(myUdp);
}
Can somebody help me to solve this error?
That is probably because UDPBasicApp's methods are defined as virtual.
Compare the GCC infos on "vague linking" from http://gcc.gnu.org/onlinedocs/gcc/Vague-Linkage.html, for example this part:
type_info objects
C++ requires information about types to be written out in order to
implement dynamic_cast, typeid and exception handling. For
polymorphic classes (classes with virtual functions), the type_info
object is written out along with the vtable so that dynamic_cast can
determine the dynamic type of a class object at run time. For all
other types, we write out the type_info object when it is used: when
applying typeid to an expression, throwing an object, or referring
to a type in a catch clause or exception specification.
You would need to provide either a definition for the virtual functions in the base class (UDPBasicApp) or declare them pure, because the compiler (GCC or Clang in your case) is trying to determine the right method for the translation unit (where the vtable and typeinfo objects are then created) and it cannot determine it correctly apparently.

C++/CLI: Public ref struct generates C2011: 'class' type redefinition

I have a header file in a managed DLL project like so:
Enums.h:
#pragma once
...
public ref struct ManagedStruct {
Bitmap^ image;
}
...
This header is referenced both from another class in the DLL and from a separate executable. The managed struct alone is generating:
error C2011: 'ManagedStruct' : 'class' type redefinition.
If I move the struct to the main header file in the DLL it works fine, and is publicly accessible, so that's what I'm doing, but I would very much like to learn why this is happening when I just move it to another file.
I have checked all necessary includes and namespaces AND tried the obvious header guards, to no avail; I still get the error.
Thanks very much for any insight!
You have to de-tune the traditional C/C++ header file think a bit when you work with managed code. The principal source of type declarations is the assembly metadata. This is very different from the native C/C++ compilation model where you have to have a header file for types that you make visible to other modules.
I'm going to guess that you get this C2011 error in the EXE project. Where you both added a reference to the DLL project assembly (like you should) and used #include on the header file. Like you should not. That's a guaranteed duplicate definition, #pragma once doesn't fix that.
Don't use header files for exported type definitions. Always use assembly references.
I Know this question is a bit old, but I'm writing this for future usage:
I had the following problem, which was similar:
managed DLL had a managed class.
managed.h:
namespace Managed {
ref class CManagedClass {...}
}
in an unamanged class I wanted to use this above class and so in unmanaged.h
#include "managed.h"
in another DLL I also did:
#include "unmanged.h"
which resolved in the type redefinition error.
I have found a solution to this issue using the following method:
forward declaration in the unmanaged.h
namespace Managed {
ref class CManagedClass;
}
and include the managed.h in the unmanaged.cpp file as usual.

Resources