Error compiling dependency to a proc-macro when targeting wasm - rust

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?

Related

Rust Diesel left join on multiple conditions

I am having difficulty determining from Diesel's documentation how to express this query with Diesel (without using raw_sql):
SELECT *
FROM budgets AS b
LEFT JOIN user_budgets AS ub
ON (ub.budget_id = {budget_id}
AND ub.user_id = {user_id})
WHERE b.id = {budget_id}
LIMIT 1;
{budget_id} and {user_id} are variable. This is what I've tried:
let budget = budgets
.select(budget_fields::all_columns)
.left_join(user_budgets.on(user_budget_fields::budget_id.eq(budget_id)))
.left_join(user_budget_fields::user_id.eq(user_id))
.filter(budget_fields::id.eq(budget_id))
.first::<Budget>(db_connection)?;
but I get this error:
error[E0277]: the trait bound `budgets::table: JoinTo<diesel::expression::operators::Eq<user_budgets::columns::user_id, diesel::expression::bound::Bound<diesel::sql_types::Uuid, uuid::Uuid>>>` is not satisfied
--> src/utils/db/budget.rs:46:10
|
46 | .left_join(user_budget_fields::user_id.eq(user_id))
| ^^^^^^^^^ the trait `JoinTo<diesel::expression::operators::Eq<user_budgets::columns::user_id, diesel::expression::bound::Bound<diesel::sql_types::Uuid, uuid::Uuid>>>` is not implemented for `budgets::table`
|
= help: the following other types implement trait `JoinTo<T>`:
<budgets::table as JoinTo<JoinOn<Join, On>>>
<budgets::table as JoinTo<diesel::query_builder::BoxedSelectStatement<'a, QS, ST, DB>>>
<budgets::table as JoinTo<diesel::query_builder::SelectStatement<F, S, D, W, O, L, Of, G>>>
<budgets::table as JoinTo<diesel::query_source::joins::Join<Left, Right, Kind>>>
= note: required because of the requirements on the impl of `JoinTo<diesel::expression::operators::Eq<user_budgets::columns::user_id, diesel::expression::bound::Bound<diesel::sql_types::Uuid, uuid::Uuid>>>` for `diesel::query_source::joins::Join<budgets::table, user_budgets::table, LeftOuter>`
= note: required because of the requirements on the impl of `JoinWithImplicitOnClause<diesel::expression::operators::Eq<user_budgets::columns::user_id, diesel::expression::bound::Bound<diesel::sql_types::Uuid, uuid::Uuid>>, LeftOuter>` for `diesel::query_builder::SelectStatement<JoinOn<diesel::query_source::joins::Join<budgets::table, user_budgets::table, LeftOuter>, diesel::expression::operators::Eq<user_budgets::columns::budget_id, diesel::expression::bound::Bound<diesel::sql_types::Uuid, uuid::Uuid>>>, query_builder::select_clause::SelectClause<(budgets::columns::id, budgets::columns::is_shared, budgets::columns::is_private, budgets::columns::is_deleted, budgets::columns::name, budgets::columns::description, budgets::columns::start_date, budgets::columns::end_date, budgets::columns::latest_entry_time, budgets::columns::modified_timestamp, budgets::columns::created_timestamp)>>`
For more information about this error, try `rustc --explain E0277`.
I have also tried this:
let budget = budgets
.select(budget_fields::all_columns)
.left_join(
user_budgets
.on(user_budget_fields::budget_id.eq(budget_id))
.and(user_budget_fields::user_id.eq(user_id)),
)
.filter(budget_fields::id.eq(budget_id))
.first::<Budget>(db_connection)?;
but I get this error:
error[E0599]: the method `and` exists for struct `OnClauseWrapper<user_budgets::table, diesel::expression::operators::Eq<user_budgets::columns::budget_id, diesel::expression::bound::Bound<diesel::sql_types::Uuid, uuid::Uuid>>>`, but its trait bounds were not satisfied
--> src/utils/db/budget.rs:48:18
|
48 | .and(user_budget_fields::user_id.eq(user_id)),
| ^^^ method cannot be called on `OnClauseWrapper<user_budgets::table, diesel::expression::operators::Eq<user_budgets::columns::budget_id, diesel::expression::bound::Bound<diesel::sql_types::Uuid, uuid::Uuid>>>` due to unsatisfied trait bounds
|
::: /Users/tanner/.cargo/registry/src/github.com-1ecc6299db9ec823/diesel-1.4.8/src/query_source/joins.rs:281:1
|
281 | pub struct OnClauseWrapper<Source, On> {
| --------------------------------------
| |
| doesn't satisfy `<_ as diesel::Expression>::SqlType = diesel::sql_types::Bool`
| doesn't satisfy `_: BoolExpressionMethods`
| doesn't satisfy `_: diesel::Expression`
|
= note: the following trait bounds were not satisfied:
`<OnClauseWrapper<user_budgets::table, diesel::expression::operators::Eq<user_budgets::columns::budget_id, diesel::expression::bound::Bound<diesel::sql_types::Uuid, uuid::Uuid>>> as diesel::Expression>::SqlType = diesel::sql_types::Bool`
which is required by `OnClauseWrapper<user_budgets::table, diesel::expression::operators::Eq<user_budgets::columns::budget_id, diesel::expression::bound::Bound<diesel::sql_types::Uuid, uuid::Uuid>>>: BoolExpressionMethods`
For more information about this error, try `rustc --explain E0599`.
What am I missing here?
You definitely want a single left_join. In your second attempt, the error is that the and needs to be inside the call to on, not after it (the argument to on must be the full boolean expression).
let budget = budgets
.select(budget_fields::all_columns)
.left_join(
user_budgets.on(
user_budget_fields::budget_id.eq(budget_id)
.and(user_budget_fields::user_id.eq(user_id))),
)
.filter(budget_fields::id.eq(budget_id))
.first::<Budget>(db_connection)?;

Rust config::builder::ConfigBuilder with static string source?

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));

"this trait cannot be made into an object because it requires `Self: Sized`", except it has Sized

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

Unable to mock a trait returning Option<&String>

I am trying to mock a trait using the mockall crate:
#[automock]
trait Foo {
fn foo(input: &Vec<String>) -> Option<&String>;
}
However, I get the following error:
error[E0637]: `&` without an explicit lifetime name cannot be used here
--> src/names_matcher.rs:79:51
|
79 | fn foo(input: &Vec<String>) -> Option<&String>;
| ^ explicit lifetime name needed here
error[E0623]: lifetime mismatch
--> src/names_matcher.rs:77:9
|
77 | #[automock]
| ^^^^^^^^^^^
| |
| ...but data from `input` is returned here
78 | trait Foo {
79 | fn foo(input: &Vec<String>) -> Option<&String>;
| ------------ this parameter and the return type are declared with different lifetimes...
The function I want to implement will return either None or Some with a reference to one of the elements of the vector in input. If I try to define the lifetimes taking this into account:
#[automock]
trait Foo {
fn foo<'r>(input: &'r Vec<String>) -> Option<&'r String>;
}
I get the following:
error[E0261]: use of undeclared lifetime name `'r`
--> src/names_matcher.rs:79:20
|
79 | fn foo<'r>(input: &'r Vec<String>) -> Option<&'r String>;
| ^^ undeclared lifetime
|
help: consider introducing lifetime `'r` here
|
77 | #[automock]<'r>
| ^^^^
help: consider introducing lifetime `'r` here
|
77 | 'r, #[automock]
| ^^^
But none of the suggestions work, they produce syntax errors. Is there a way to mock a trait like the one I defined above?

Vec of objects implementing generic trait [duplicate]

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?

Resources