Why is the trait not implemented? - rust

I wanted to try the amethyst_physics library to make a game. (Duh)
I followed to Example, but somhow I does not work:
use amethyst::GameDataBuilder;
use amethyst_physics::{PhysicsBundle};
use amethyst_nphysics::NPhysicsBackend;
fn main() -> amethyst::Result<()> {
amethyst::start_logger(Default::default());
let game_data = GameDataBuilder::default()
.with_bundle(
PhysicsBundle::<f32, NPhysicsBackend>::new()
)
;
Ok(())
}
Error:
the trait bound `amethyst_physics::PhysicsBundle<'_, '_, f32, amethyst_nphysics::NPhysicsBackend>: amethyst::amethyst_core::SystemBundle<'_, '_>` is not satisfied
the trait `amethyst::amethyst_core::SystemBundle<'_, '_>` is not implemented for `amethyst_physics::PhysicsBundle<'_, '_, f32, amethyst_nphysics::NPhysicsBackend>`
Here is the example.
What am I doing wrong?

This appears to be a bug. It compiles successfully using amethyst version 0.15.1 but not 0.15.3. A regression like this is not expected during a patch change.
amethyst uses amethyst_core version 0.15.3 (where SystemBundle is defined) but amethyst_physics uses amethyst_core version 0.10.1.
I've filed an issue on the amethyst repository.
Use this as a workaround:
amethyst = { version = ">=0.15.0, <0.15.3", features = ["empty"] }

Related

Is there a way to have a function for a implementation for a struct that moves self instead of borrowing it as &self or &mut self?

I have been dealing with this because I want to create a style of configuration that is somewhat of functional as it would be used like:
struct.set_config(myConfig)
.set_other_config(myOtherConfig)
And to do this I need to return a owned version of the struct or another type that is similar to it in my case.
And to do this I would actually need to borrow that into a implemented function of that struct. My thought would be that it would look something like:
impl MyStruct {
fn set_config(self, ...) -> Self {
(...do something with self)
self // return the mutated self
}
}
But when trying something similar to this the Rust compiler did not like that very much.
Is there any way to kind of implement this? Or at least another way to get what I want without this?
EDIT:
My problem with just adding "mut self" is the Rust compiler seemed to complain with a warning:
warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #35203 <https://github.com/rust-lang/rust/issues/35203>
= note: `#[deny(patterns_in_fns_without_body)]` on by default
And I wanted to avoid that. This error originates in the trait that defines that function not in the implementation.
EDIT 2:
I am working on a Machine Learning crate and I have layers for a Model, there is a Layer trait and I want to have Initializers for instantiating the parameters depending on how the user wants to initialize them.
Another important thing is that I have a enum that can be all of the layers currently implemented in the crate, this enum has that same trait implemented and each method has a match for each possible type of Layer.
Currently in the crate, to define the layers for a model you currently need to do something like:
let layers = vec![
Dense::new(...),
TanH::new(...)
];
(The "new" method returns that enum that has all the implemented layers as variants)
I want to set the initializers (which are now a field of these layers's structs) as such:
let layers = vec![
Dense::new(...).set_initializer(...),
TanH::new(...)
];
Then the set_initializer would need to return that enum owning the Dense layer for example. Hence my problem.
The important part of my Layer trait definition would need to look like this:
pub trait Layer<'a> {
(...)
fn set_initializer(mut self, initializer: Initializer) -> ModelLayer<'a>; // This is the enum I mentioned
(...)
}
The pattern_in_fns_without_body error triggers on mut self parameters in body-less function signatures. This includes functions without bodies in trait definitions.
All you need to do to resolve the error is change mut self to just self in your trait definition:
pub trait Layer<'a> {
// ...
fn set_initializer(self, initializer: Initializer) -> ModelLayer<'a>;
// ...
}
This restriction only applies to body-less functions. Your actual trait implementation can still have the mut self if necessary:
impl<'a> Layer<'a> for SomeThing<'a> {
// ...
fn set_initializer(mut self, initializer: Initializer) -> ModelLayer<'a> {
// ...
}
// ...
}
I'm not sure what version of Rust you're working with, but recent versions of the compiler have a hint recommending just that:
error: patterns aren't allowed in functions without bodies
--> src/lib.rs:7:24
|
7 | fn set_initializer(mut self, initializer: Initializer) -> ModelLayer<'a>;
| ^^^^^^^^ help: remove `mut` from the parameter: `self`
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #35203 <https://github.com/rust-lang/rust/issues/35203>
= note: `#[deny(patterns_in_fns_without_body)]` on by default

Rust Generics, "`T` may not live long enough"

I'm trying to imbed Lua into Rust using Mlua. Using its guided tour, I successfully loaded and evaluated a chunk of Lua code. My next goal is to combine this with opening a file and reading its contents. This is where things get problematic:
use anyhow::Result;
use mlua::{Lua, UserData};
use std::fs;
pub struct LuaManager {
lua_state: Lua
}
impl LuaManager {
pub fn new() -> Self {
LuaManager {
lua_state: Lua::new(),
}
}
pub fn eval<T>(&self, chunk: &str) -> Result<T> where T: Clone + UserData {
let v = self.lua_state.load(chunk).eval::<T>()?;
Ok(v)
}
}
Since scripts can return literally anything, I thought a trait-locked generic annotation would solve the issue: The problem is this:
Error generated by rustc: the parameter type `T` may not live long enough... so that the type `T` will meet its required lifetime bounds...
For reference, here is the function signature as defined in lua.rs:
pub fn eval<R: FromLuaMulti<'lua>>(self) -> Result<R>
I don't understand why I'm having this issue. I've looked this up and this question pertained to user-created types, which to my knowledge I'm not doing... so what is the problem here? It's clear that things like <i32> won't die anytime soon. Cargo did suggest adding a static lifetime annotation, but doing some research into it points me to trying to solve the problem without using it first, since in 99% of cases you actually can get away without it.
Unfortunately in this case it seems like 'static is really required.
Lua::load() takes &'lua self and returns Chunk<'lua, '_>. Chunk::<'lua, '_>::eval::<R>() requires R: FromLuaMulti<'lua>. FromLuaMulti<'lua> is implemented for T: FromLua<'lua>. FromLua<'lua> is implemented for T: UserData, however it requires T: 'static (and also T: Clone, but this is irrelevant).

Unresolved import `core::array::FixedSizeArray`

I am new to Rust.
I've been given some Rust code to work with but the cargo build fails with error "unresolved import core::array::FixedSizeArray". In what way can I remove the error?
I'm using version 1.57.0 nightly; do not know which version of Rust the code base has been build successfully last time.
The code also uses a lot of '#![feature(...)]', which could not be used with stable version. How do I map a feature in older version's nightly build to the current version's functions/etc.?
Example of features:
#![feature(vec_resize_default)]
#![feature(fixed_size_array)]
Thanks.
The last version with FixedSizeArray was the 1.52.1 release. It was designed for generically working with fixed size arrays [T; N] in contexts where &[T] or AsRef<[T]> were not appropriate. But even in the tracking issue it is known that its usefulness was limited and would eventually be overshadowed by min_const_generics which was just made stable in the 1.51.0 release.
You will have to either downgrade your nightly version back to 1.52.1 or before, or fix the problems caused by its removal. There is no way to just use removed features on a newer version.
Some options for replacing this functionality:
It can be translated directly into the form [T; N] using const generics.
struct MyStruct<A: FixedSizeArray> {
data: A
}
fn make_my_struct<A: FixedSizeArray>(data: A) -> MyStruct<A> {
MyStruct { data }
}
Would become:
struct MyStruct<T, const N: usize> {
data: [T; N]
}
fn make_my_struct<T, const N: usize>(data: [T; N]) -> MyStruct<T, N> {
MyStruct { data }
}
Perhaps you didn't need it in the first place and can get by with just &[T] or AsRef<[T]>.
Use a trait from a crate that has a similar purpose like Array from the array_ext crate.
Make your own trait. FixedSizeArray doesn't require any compiler magic, but to implement it for all array types you'd have to use method #1 above anyway.
I "translated" a trait bound using FixedSizeArray like so:
old:
U: FixedSizeArray<T>
new:
U: AsRef<[T]> + AsMut<[T]>>

Trouble Benchmarking actix_web api with Criterion

I have been trying to add benchmarking using the Criterion crate to my actix_web application. I have been struggling to get it to work because the AsyncExecutor trait is not implemented for tokio 0.2.x. I tried implementing the trait for the actix_rt runtime but ran into issues there as well, code below
impl AsyncExecutor for ActixRuntime {
fn block_on<T>(&self, future: impl Future<Output=T>) -> T {
self.rt.block_on(future)
}
}
pub struct ActixRuntime {
rt: actix_rt::Runtime,
}
impl ActixRuntime {
pub fn new() -> Self {
ActixRuntime {
rt: actix_rt::Runtime::new().unwrap(),
}
}
}
this errors out because the block_on function for actix_rt (and tokio 0.2.x) is has a signature of
block_on(&mut self, ...) -> ... { ... }
So I cannot implement the trait since the trait has an immutable reference.
Before I dig myself further into trying to make this work I want to ask if what I am attempting is possible. Is there a way to use Criterion with actix? Or is this impossible as of now? If it is not possible are there any other frameworks available or should I look at solutions outside the rust toolchain?
Thanks for any advice or help, links and examples welcome!
Cheers!
actix-rt v2's block_on method takes &self now after upgrading to tokio 1.0. Upgrading should fix your issue:
// pin your deps: https://github.com/actix/actix-web/issues/1944
actix-rt = "=2.0.0-beta.2"
actix-web = "4.0.0-beta.1"
actix-service = "=2.0.0-beta.3"
If upgrading is not an option, you can use an interior mutability wrapper, such as RefCell:
impl AsyncExecutor for ActixRuntime {
fn block_on<T>(&self, future: impl Future<Output=T>) -> T {
self.rt.borrow_mut().block_on(future)
}
}
pub struct ActixRuntime {
rt: RefCell<actix_rt::Runtime>,
}
impl ActixRuntime {
pub fn new() -> Self {
ActixRuntime {
rt: RefCell::new(actix_rt::Runtime::new().unwrap())
}
}
There doesn't seem like a good way to do this. There are no stable actix versions supporting actix_rt 2.0.x (though it would fix the mutability conflicts in the AsyncExecutor). As of right now actix-web 4.0.x is in beta and too unstable for my existing application (causes all sorts of issues when used). For now I will wait until actix-web 4.0.0 is released and stable to implement benchmarks for my api.

Generator does not seem to expose `resume()` method

I was having a look at generators in Rust, and decided to give it a try. I implemented the most basic example I could come find:
#![feature(generators, generator_trait)]
use std::ops::Generator;
fn main() {
let mut generator = || {
println!("2");
yield;
println!("4");
};
println!("1");
generator.resume();
println!("3");
generator.resume();
println!("5");
}
However, when I try to compile I get this error:
error[E0599]: no method named `resume` found for type `[generator#src/main.rs:6:25: 10:6 _]` in the current scope
--> src/main.rs:13:15
|
13 | generator.resume();
| ^^^^^^
Am I doing something wrong or the resume() method actually does not exist on generators? If so, how can I wake up a generator? The documentation I could find all points to the resume() method, so I am confused now.
Note: Yes, I am aware that this is an unstable feature of the language, but on the doc it does encourage users to try and use it, so I am assuming it should be at least partially implemented?
My current environment: rustc 1.35.0-nightly (acd8dd6a5 2019-04-05)
Yes, I am aware that this is an unstable feature
Unstable features tend to change over time and this is the case. With the recent stabilization of Pin the signature of resume has been changed (PR #55704)
fn resume(self: Pin<&mut Self>) -> GeneratorState<Self::Yield, Self::Return>;
But fortunately the examples has also been adopted.
So your code needs to look like this:
#![feature(generators, generator_trait)]
use std::ops::Generator;
use std::pin::Pin;
fn main() {
let mut generator = || {
println!("2");
yield;
println!("4");
};
let mut pin = Pin::new(&mut generator);
println!("1");
pin.as_mut().resume();
println!("3");
pin.as_mut().resume();
println!("5");
}
The upside of this is, that this approach does not need unsafe anymore (which your code is missing and therefore should not compile on an older nightly) and that's why the Pin API has been choosen for the generator.
Lessons learned: If you are using the nightly compiler, also use the nightly doc.

Resources