I introduced error-chain into a previously working application. The error itself is clear, std::error::Error + 'static lacks an implementation of the trait std::marker::Send:
error[E0277]: the trait bound `std::error::Error + 'static: std::marker::Send` is not satisfied
--> src/main.rs:35:5
|
35 | / error_chain!{
36 | |
37 | | foreign_links {
38 | | Mqttc(::mqttc::Error);
... |
53 | | }
54 | | }
| |_____^ `std::error::Error + 'static` cannot be sent between threads safely
|
= help: the trait `std::marker::Send` is not implemented for `std::error::Error + 'static`
= note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<std::error::Error + 'static>`
= note: required because it appears within the type `std::boxed::Box<std::error::Error + 'static>`
= note: required because it appears within the type `mqttc::netopt::Error`
= note: required because it appears within the type `mqttc::Error`
= note: required because it appears within the type `errors::ErrorKind`
= note: required because it appears within the type `errors::Error`
= note: required by `error_chain::ChainedError`
= note: this error originates in a macro outside of the current crate
I am not sure how to resolve this. Note that I am using the more up to date fork of mqttc/mqtt3 instead of the upstream crates.
mqttc::Error contains a mqttc::netopt::Error, which in turns contains a Box<std::error::Error> (which desugars to std::boxed::Box<std::error::Error + 'static>. std::error::Error here is a trait object. Because the Error trait doesn't have Send as a supertrait, implementations of Error are not required to implement Send. Therefore, Box<std::error::Error> doesn't implement Send because not all types T: std::error::Error implement Send.
This could be fixed by changing the mqttc::netopt::Error type to use Box<std::error::Error + Send> instead of Box<std::error::Error> (which would be a breaking change for the library).
Related
I have a procedural macro I have implemented which depends on the proc-macro-error crate. My client project depends on this macro crate.
When I build for native, everything works perfectly, but when I build for wasm, I get a number of errors thrown from proc-macro-error:
error[E0599]: no method named `unwrap` found for struct `proc_macro2::Span` in the current scope
--> /Users/spencerkohan/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro-error-1.0.4/src/imp/delegate.rs:33:38
|
33 | let span = span_range.collapse().unwrap();
| ^^^^^^ method not found in `proc_macro2::Span`
error[E0599]: no method named `unwrap` found for struct `proc_macro2::Span` in the current scope
--> /Users/spencerkohan/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro-error-1.0.4/src/imp/delegate.rs:49:53
|
49 | res.span_note(span_range.collapse().unwrap(), msg)
| ^^^^^^ method not found in `proc_macro2::Span`
error[E0599]: no method named `unwrap` found for struct `proc_macro2::Span` in the current scope
--> /Users/spencerkohan/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro-error-1.0.4/src/imp/delegate.rs:52:53
|
52 | res.span_help(span_range.collapse().unwrap(), msg)
| ^^^^^^ method not found in `proc_macro2::Span`
error[E0599]: no method named `unwrap` found for struct `proc_macro2::Span` in the current scope
--> /Users/spencerkohan/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro-error-1.0.4/src/imp/delegate.rs:60:42
|
60 | let span = span_range.collapse().unwrap();
| ^^^^^^ method not found in `proc_macro2::Span`
error[E0277]: the trait bound `proc_macro::TokenStream: From<TokenStream2>` is not satisfied
--> /Users/spencerkohan/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro-error-1.0.4/src/lib.rs:459:29
|
459 | gen_error().into()
| ^^^^ the trait `From<TokenStream2>` is not implemented for `proc_macro::TokenStream`
|
= help: the trait `From<proc_macro::TokenTree>` is implemented for `proc_macro::TokenStream`
= note: required because of the requirements on the impl of `Into<proc_macro::TokenStream>` for `TokenStream2`
error[E0277]: the trait bound `proc_macro::TokenStream: From<TokenStream2>` is not satisfied
--> /Users/spencerkohan/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro-error-1.0.4/src/lib.rs:464:34
|
464 | Ok(_) => gen_error().into(),
| ^^^^ the trait `From<TokenStream2>` is not implemented for `proc_macro::TokenStream`
|
= help: the trait `From<proc_macro::TokenTree>` is implemented for `proc_macro::TokenStream`
= note: required because of the requirements on the impl of `Into<proc_macro::TokenStream>` for `TokenStream2`
error[E0277]: the trait bound `proc_macro2::Span: From<proc_macro::Span>` is not satisfied
--> /Users/spencerkohan/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro-error-1.0.4/src/lib.rs:549:37
|
549 | first: self.clone().into(),
| ^^^^ the trait `From<proc_macro::Span>` is not implemented for `proc_macro2::Span`
|
= note: required because of the requirements on the impl of `Into<proc_macro2::Span>` for `proc_macro::Span`
error[E0277]: the trait bound `proc_macro2::Span: From<proc_macro::Span>` is not satisfied
--> /Users/spencerkohan/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro-error-1.0.4/src/lib.rs:550:36
|
550 | last: self.clone().into(),
| ^^^^ the trait `From<proc_macro::Span>` is not implemented for `proc_macro2::Span`
|
= note: required because of the requirements on the impl of `Into<proc_macro2::Span>` for `proc_macro::Span`
It doesn't make sense to me why there should be an issue: this code is not actually compiled for wasm, it's only called inside the proc macro, which is used at compile time.
How can I solve this issue?
I am using the Rust config crate and want to switch from loading configuration from a file at runtime to a static string created at compile time.
Right now, it works like this:
config::Config::builder().add_source(File::new("default.toml", FileFormat::Toml));
However when I try it with a static string, it does not:
static DEFAULT: &str = std::include_str!("./default.toml");
[...]
config::Config::builder().add_source(DEFAULT)
Error Message
error[E0277]: the trait bound `&str: Source` is not satisfied
--> src/config.rs:21:25
|
21 | .add_source(DEFAULT)
| ---------- ^^^^^^^ the trait `Source` is not implemented for `&str`
| |
| required by a bound introduced by this call
|
note: required by a bound in `ConfigBuilder::<DefaultState>::add_source`
--> /home/konrad/.cargo/registry/src/github.com-1ecc6299db9ec823/config-0.13.1/src/builder.rs:207:12
|
207 | T: Source + Send + Sync + 'static,
| ^^^^^^ required by this bound in `ConfigBuilder::<DefaultState>::add_source`
How can I read my config from a static string instead of a file?
Use File::from_str():
config::Config::builder().add_source(File::from_str(DEFAULT, FileFormat::Toml));
Here's the error message:
error[E0038]: the trait `room::RoomInterface` cannot be made into an object
--> src\permanent\registry\mod.rs:12:33
|
12 | pub fn load(id : String) -> Result<Box<dyn RoomInterface>, String>{
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `room::RoomInterface` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> src\permanent\rooms\mod.rs:36:31
|
36 | pub trait RoomInterface : Copy + Sized {
| ------------- ^^^^ ^^^^^ ...because it requires `Self: Sized`
| | |
| | ...because it requires `Self: Sized`
| this trait cannot be made into an object...
For more information about this error, try `rustc --explain E0038`.
It says that to use the trait as an object, it requires Sized. Except that Sized is right there, in the declaration of the trait! It literally points to the word "Sized" and tells me I need to have "Sized". What's going on?
The problem is opposite to what you think: The problem is that you require Self: Sized but only traits which do not require Self: Sized can be made into an object.
As the error message states you must remove both bounds for Copy and Sized for RoomInterface:
pub trait RoomInterface {
The article linked in the error message is a great resource, I recommend reading it:
https://doc.rust-lang.org/reference/items/traits.html#object-safety
Also this discussion might be interesting:
https://users.rust-lang.org/t/trait-objects-and-the-sized-trait/14410/2
I wanted to implement a conversion trait that would cover all types supporting already existing conversion. I thought that this could be done in following way:
impl<T> Into<B> for T
where
T: Into<A>,
{
fn into(self) -> B {
let a: A = self.into();
B::CaseA(a)
}
}
However compiler throws a following error:
error[E0119]: conflicting implementations of trait `std::convert::Into<block::ItemContent>`
--> yrs\src\block.rs:945:1
|
945 | / impl<T> Into<B> for T
946 | | where
947 | | T: Into<A>,
948 | | {
... |
952 | | }
953 | | }
| |_^
|
= note: conflicting implementation in crate `core`:
- impl<T, U> Into<U> for T
where U: From<T>;
error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`B`)
--> yrs\src\block.rs:945:6
|
945 | impl<T> Into<B> for T
| ^ type parameter `T` must be covered by another type when it appears before the first local type (`B`)
|
= note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
= note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
Is it possible to achieve this? I'm looking for a way to automatically extend conversion for a new type for all instances, that support conversion to another existing type.
What you are trying to do can be achieved (as the error says) by covering T with a local type. The reason you cannot do it without that is because otherwise someone else could also do the same and the Rust won't be able to tell which impl to use. So you need a local wrapper type to keep the separation.
The complete reasoning behind this is referenced in the error explanation:
https://github.com/rust-lang/rfcs/blob/master/text/1023-rebalancing-coherence.md
And https://rust-lang.github.io/rfcs/2451-re-rebalancing-coherence.html
hope this helps ;)
A
This question already has answers here:
How can I have a collection of objects that differ by their associated type?
(3 answers)
Vector of objects belonging to a trait
(3 answers)
Closed 4 years ago.
I am building a command-line application. I have the following trait:
trait ValidatedCommand {
type Output;
fn run() -> Result<Self::Output, std::io::Error>;
}
and I have the following two implementations for it:
struct First;
impl ValidatedCommand for First {
type Output = i32;
fn run() -> Result<i32, std::io::Error> {
Ok(1)
}
}
impl First {
fn new() -> First {
First {}
}
}
struct Second;
impl ValidatedCommand for Second {
type Output = String;
fn run() -> Result<String, std::io::Error> {
Ok(String::from("hello"))
}
}
impl Second {
fn new() -> Second {
Second {}
}
}
Both structs implement the trait, one returning a String and the other an i32.
I'm trying to create a Vec of that trait, but I'm not sure how to go about it. I tried the following:
fn main() {
let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
playground.
which errors with
error[E0191]: the value of the associated type `Output` (from the trait `ValidatedCommand`) must be specified
--> src/main.rs:33:23
|
2 | type Output;
| ------------ `Output` defined here
...
33 | let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
| ^^^^^^^^^^^^^^^^^^^^ associated type `Output` must be specified
error[E0277]: the size for values of type `dyn ValidatedCommand` cannot be known at compilation time
--> src/main.rs:33:19
|
33 | let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
| ^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `dyn ValidatedCommand`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: required by `std::vec::Vec`
error[E0038]: the trait `ValidatedCommand` cannot be made into an object
--> src/main.rs:33:19
|
33 | let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
| ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `ValidatedCommand` cannot be made into an object
|
= note: method `run` has no receiver
error[E0308]: mismatched types
--> src/main.rs:33:52
|
33 | let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
| ^^^^^^^^^^^^ expected trait ValidatedCommand, found struct `First`
|
= note: expected type `dyn ValidatedCommand`
found type `First`
error[E0277]: the size for values of type `dyn ValidatedCommand` cannot be known at compilation time
--> src/main.rs:33:47
|
33 | let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `dyn ValidatedCommand`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: required by `std::slice::<impl [T]>::into_vec`
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error[E0277]: the size for values of type `dyn ValidatedCommand` cannot be known at compilation time
--> src/main.rs:33:47
|
33 | let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `dyn ValidatedCommand`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: slice and array elements must have `Sized` type
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error[E0038]: the trait `ValidatedCommand` cannot be made into an object
--> src/main.rs:33:47
|
33 | let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `ValidatedCommand` cannot be made into an object
|
= note: method `run` has no receiver
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error[E0277]: the size for values of type `dyn ValidatedCommand` cannot be known at compilation time
--> src/main.rs:33:47
|
33 | let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `dyn ValidatedCommand`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: required by `std::vec::Vec`
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error[E0038]: the trait `ValidatedCommand` cannot be made into an object
--> src/main.rs:33:47
|
33 | let commands: Vec<dyn ValidatedCommand> = vec![First::new(), Second::new()];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `ValidatedCommand` cannot be made into an object
|
= note: method `run` has no receiver
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
I am thinking that maybe there is a way to make use of the associated type, but I have no idea how I might go about it.
Is there a way to get this vector creation to compile?