Expected method signatures in trait error messages - rust

I'm trying Rust and finding it hard to interpret what to do when my function signatures don't correspond to those expected by a trait. Example
impl std::fmt::Display for MyType {
// Not sure what to put here so I stub it and hope to get help from error
fn fmt() -> () { }
}
The compiler error message is
method `fmt` has a `&self` declaration in the trait, but not in the impl
What I was hoping to see was something helping me implement the method for example:
Incorrect method signature for `fmt`
Actual signature fn fmt() -> ()
Expected signature fn fmt(&self, &mut Formatter) -> Result<(), Error>
Is it possible to get signature help from the compiler like this? I'm usually very impressed by the very friendly and detailed compiler errors, so this one really surprised me. I'm using the rust playground (https://play.rust-lang.org/) but I don't think that makes any difference to compiler output.

No, it is not possible. If you think this is an important feature, you can always submit a feature request to Rust issue tracker.
Meanwhile, you can use docs generated by rustdoc, e.g. these for the standard library. They are usually pretty awesome, especially given that there is search function.

Related

Will GATs allow HKTs for non-associated generic parameters?

When looking into Higher-kinded types (HKTs), Generic associated types (GATs) constantly pop up as "the solution". They allow you to express things like this (which I think is really cool):
trait Foo {
type Bar<T>;
fn process<T>(&mut self, ctx: Self::Bar<T>);
}
I'm really excited about GATs being close to landing, but from what I understand it only enables HKTs for traits that use associated types. Or is there a way to express something like this too? (And if not, is there a feature flag or working issue for it?)
trait Foo<for<T> Bar> {
fn process<T>(&mut self, ctx: Self::Bar<T>);
}

How do I call a getter from another Substrate module?

I have two modules, MyCore and Special. MyCore has a public getter:
pub fn get_core_account() -> Option<T::AccountId>
Which gets an accountId. If I call this from Special in a simple manner:
let core_account = MyCore::get_core_account();
then rustc complains that it can't infer the type, which is odd because the public setters don't need further info. So I make the type explicit
let core_account: Option<T::AccountId> = MyCore::get_core_account();
But this triggers demands for type specifiers on the call, so we elaborate:
let core_account: Option<T::AccountId> = MyCore::<T>::get_core_account();
At which point rust complains that it can't find get_core_account, because Special doesn't have a restriction to implement MyCore::Trait. But I don't want Special to implement MyCore::Trait! I want to call a getter!
Perhaps I'm missing something regarding the use of T here - in theory, Special is a trait templated over some T, which we can implement using a Test class if we implement the required types.
Does Special really need to implement MyCore::Trait?
What you want to do is possible, yet you are probably doing something wrong which is not clearly demonstrated in the question. Would be very helpful if you post the Trait definitions of both modules.
Does Special really need to implement MyCore::Trait?
No. You might have to make it a trait bound though.
Basically, you have two options in such cases:
If your Core is something that all other modules will depend on, similar to frame-system, you can explicitly depend on it. Note that this path should be taken with care and you don't want to create too big of a monolithic software with this mindset. Nonetheless, in that case, you can just do:
// in special.rs
// This is needed because then we can pass `T` into `mycore::Module<_>`.
pub trait Trait: mucore::Trait {
...
}
// and then later on you can call:
<mycore::Module<T>>:: get_core_account()
This seems like the approach that you wanted to take.
Alternatively, you can bind the two modules together without this explicit dependency. This is useful for when you want your Special to receive the getter eventually, but you don't really care who provides it. Or in other words, if multiple candidates can provide this getter and you want to be generic over it.
For this, you first need a common trait definition.
// in some common dependency
trait CoreGetterProvider<AccountId> {
fn getter() -> Option<AccountId>;
}
and your Special would express:
pub trait Trait {
// .. other stuff. Assuming that it has a common AccountId with Core.
type Getter: CoreGetterProvider<Self::AccountId>
}
And your Core implements it
// in Core.rs
impl<T: Trait> CoreGetterProvider<T::AccountId> for Module<T> { ... }
Finally, when building the runtime, you can pass the Core module to Special.
impl core::Trait for Runtime { ... }
impl special::Trait for Runtime {
type Getter = core::Module<Runtime> // or just `Core`. construct_runtime! creates this type alias.
}

In Rust how do I pass a diverging function as parameter to another function

Non-diverging functions work fine
fn test(f: &Fn() -> u8) {}
But I can't accept a diverging function like this
fn test_diverging(f: &Fn() -> !) {}
I get the following error
error[E0658]: The `!` type is experimental (see issue #35121)
--> examples/two_tasks.rs:44:31
|
44 | fn test_diverging(f: &Fn() -> !) {}
| ^
Looking at issue #35121 I could see how that might fix it but in the mean time is there a work around?
! in some contexts is still experimental, which means it's not available on the stable compiler (1.33 as of today). You can use it on the nightly compiler, but you have to opt-in explicitly to feature(never_type):
#![feature(never_type)]
fn test_diverging(f: &Fn() -> !) {}
(playground)
Be aware this means the feature may yet change before stabilization, so you're accepting the risk that a future compiler version will break your code.
See also
What is a crate attribute and where do I add it?
What is the stabilization process?
How to use nightly: Is it possible to have multiple coexisting Rust installations?
Using the never type in functions and function pointer types is already stable. So if you don't need to use the Fn trait, you can just use this:
fn test_diverging(f: fn() -> !) {}
// ^ note the lowercase f
test_diverging(|| panic!("ouch"));
That way you can't pass closures that reference their environment, but non-capturing closures and standard functions work fine.
If you want to stay on stable, you can use Void (basically an enum with no variants, which can't be constructed without unsafe) as a workaround.
Playground link
To use unstable feature you need to use nightly toolchain and active the desired unstable feature.
#![feature(never_type)]
fn test_diverging(f: &Fn() -> !) {}
See also:
What is a crate attribute and where do I add it?

Differences in syntax for invoking trait method on generic type

I'm trying to understand the need for the Trait:: and <T as Trait>:: method invocation syntax. In particular, I'm looking at the following function from this answer:
fn clone_into_array<A, T>(slice: &[T]) -> A
where
A: Default + AsMut<[T]>,
T: Clone,
{
assert_eq!(
slice.len(),
std::mem::size_of::<A>() / std::mem::size_of::<T>()
);
let mut a = Default::default();
<A as AsMut<[T]>>::as_mut(&mut a).clone_from_slice(slice);
a
}
It seems that the middle two method invocation lines can be rewritten as:
let mut a = A::default();
a.as_mut().clone_from_slice(slice);
I believe this is more readable, as we already know that A implements Default and AsMut<[T]> and we can invoke as_mut directly as a method instead of having to pass a to it explicitly.
However, am I missing a good reason for the linked answer to have written it more verbosely? Is it considered good style? Are the two semantically different under certain conditions?
I agree with your rewrites — they are more clear and are what I would recommend for that function.
am I missing a good reason for the linked answer to have written it more verbosely?
My guess is that the author simply was tired of writing that function and stopped. If they took a look at it again, they might refine it to be shorter.
Is it considered good style?
I don't think there's a general community stylistic preference around this yet, other than the general "shorter is better until it isn't".
Are the two semantically different under certain conditions?
They shouldn't be.
There are times where the <>:: syntax is needed because otherwise it would be ambiguous. One example from a recent question:
let array = <&mut [u8; 3]>::try_from(slice);
Another time is when you don't have a nicely-named intermediate type or the intermediate type is ambiguous across multiple traits. One gross example is from a where clause but shows the same issue as an expression would:
<<Tbl as OrderDsl<Desc<Expr>>>::Output as LimitDsl>::Output: QueryId,
See also:
How to call a method when a trait and struct use the same name?

Function behaviour depending on whether a trait is implemented

Given a situation like this one :
trait Basic {
// Some functions
}
trait Derived : Basic {
// some other functions
}
fn do_someting<T : Basic>(target: &mut T) {
// do stuff
}
Is it possible to have the do_something function behave differently depending on whether target implements the trait Derived or not (the information being known at compilation time) ?
I guess something similar could be achieved in C++ using template specialization, but I don't see a Rust equivalent.
AFAIK this is not currently possible. Defining fn do_something<T : Derived> alongside your existing function leads to compilation error:
error: duplicate definition of value `do_someting`
because both versions can be used for Basic.
There are some proposals to allow explicit bounds like <T: Basic + !Derived> that will allow you to resolve this conflict.
But I personally hope that impl overloading/specialization will be possible some day after 1.0 version is released.

Resources