Is Rust has thing like "private trait"?
I mean trait defined without pub keyword is private?
Code bellow gives compilation error:
error[E0119]: conflicting implementations of trait `MyFrom<i64>` for type `std::option::Option<&_>`:
--> src/main.rs:22:1
|
16 | impl<T: Foo> MyFrom<i64> for Option<T> {
| -------------------------------------- first implementation here
...
22 | impl<T: Foo> MyFrom<i64> for Option<&T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `std::option::Option<&_>`
|
= note: downstream crates may implement trait `Foo` for type `&_`
But this is not public trait, and this is exe , how can " downstream crates may implement trait Foo for type &_" ? It is impossible to import trait from exe crate, and even if possible this is not pub trait,
so rustc doesn't support private traits?
fn main() {
trait MyFrom<T> {
fn my_from(_: T) -> Self;
}
trait Foo {}
impl<T: Foo> MyFrom<i64> for Option<T> {
fn my_from(x: i64) -> Self {
unimplemented!();
}
}
impl<T: Foo> MyFrom<i64> for Option<&T> {
fn my_from(x: i64) -> Self {
unimplemented!();
}
}
}
Related
The documentation of the Clone trait states that "This trait can be used with #[derive] if all fields are Clone." I'm struggling with a case where all fields are Clone, and yet deriving Clone doesn't work.
Consider the following simplified example (Playground link):
use std::fmt;
use std::rc::Rc;
trait Printer: Clone {
fn print(&self) -> ();
}
#[derive(Clone)]
struct ClosurePrinter<T: fmt::Display> {
get_value: Rc<dyn Fn() ->T>,
}
impl<T: fmt::Display> ClosurePrinter<T> {
pub fn new(get_value: Rc<dyn Fn() -> T>) -> ClosurePrinter<T> {
ClosurePrinter { get_value }
}
}
impl<T: fmt::Display> Printer for ClosurePrinter<T> {
fn print(&self) -> () {
println!("{}", (self.get_value)())
}
}
The struct ClosurePrinter has a single field, get_value: Rc<dyn Fn() -> T>. Rc implements Clone, so I'm assuming that get_value is Clone. Yet the compiler insists that T must be Clone, too:
error[E0277]: the trait bound `T: Clone` is not satisfied
--> src/lib.rs:19:23
|
19 | impl<T: fmt::Display> Printer for ClosurePrinter<T> {
| ^^^^^^^ the trait `Clone` is not implemented for `T`
|
note: required because of the requirements on the impl of `Clone` for `ClosurePrinter<T>`
--> src/lib.rs:8:10
|
8 | #[derive(Clone)]
| ^^^^^
note: required by a bound in `Printer`
--> src/lib.rs:4:16
|
4 | trait Printer: Clone {
| ^^^^^ required by this bound in `Printer`
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider further restricting this bound
|
19 | impl<T: fmt::Display + std::clone::Clone> Printer for ClosurePrinter<T> {
| +++++++++++++++++++
Why does the compiler insist that T must be Clone?
The second sentence in the documentation should explain this
For a generic struct, #[derive] implements Clone conditionally by adding bound Clone on generic parameters.
This is just how the derive macro works. Moreover it is the only way it could work, since procedural macro execution happens before compiler could reason if these trait bounds are necessary. Luckily you can solve this problem, by implementing Clone trait manually.
use std::fmt;
use std::rc::Rc;
struct ClosurePrinter<T: fmt::Display> {
get_value: Rc<dyn Fn() ->T>,
}
impl<T: fmt::Display> Clone for ClosurePrinter<T> {
fn clone(&self) -> Self {
let get_value = Rc::clone(&self.get_value);
Self { get_value }
}
}
I'm running into an issue where the compiler seems unable to coerce the desired type by recursive deref-coersion. I have the following code:
use std::ops::Deref;
struct MyStruct<T> {
data: T
}
impl<T> Deref for MyStruct<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.data
}
}
pub trait MyTrait {
fn bar(&self);
}
impl<T> MyTrait for MyStruct<T> {
fn bar(&self) {}
}
fn foo<T: MyTrait>(arg: T) {
//
}
fn main() {
let data = Box::new(MyStruct { data: 42 });
foo(&data);
}
And I get the following error:
error[E0277]: the trait bound `&Box<MyStruct<{integer}>>: MyTrait` is not satisfied
--> src\bin\main.rs:36:9
|
36 | foo(&data);
| ^^^^^ the trait `MyTrait` is not implemented for `&Box<MyStruct<{integer}>>`
|
note: required by a bound in `foo`
--> src\bin\main.rs:30:11
|
30 | fn foo<T: MyTrait>(arg: T) {
| ^^^^^^^ required by this bound in `foo`
My expectation is that the compiler would be able to recursively deref Box<MyStruct> until it encountered a type that satisfied the trait requirement (MyTrait) for the argument.
How might I be able to achieve this without modifying the calling syntax of foo(&data)?
On this simple sketch I made, I'm trying to do use a trait called Runnable to run an Arc<dyn LockableOption<T>>:
use std::sync::{Arc, LockResult, Mutex, MutexGuard, PoisonError};
pub type LockableArc<T> = Arc<Mutex<Option<T>>>;
pub struct MutexGuardOptionRef<'a, T: ?Sized> {
pub mutex_guard: MutexGuard<'a, Option<Box<T>>>,
}
pub trait LockableOption<T: ?Sized>: Send + Sync {
fn lock(&self) -> LockResult<MutexGuardOptionRef<T>>;
}
impl<T: ?Sized + Send> LockableOption<T> for LockableArc<Box<T>> {
fn lock(&self) -> LockResult<MutexGuardOptionRef<T>> {
unimplemented!()
}
}
pub trait Decoder<T>: Send {
}
pub struct FfmpegDecoder<T> {
x: T,
}
impl<T: 'static + Send> Decoder<T> for FfmpegDecoder<T> {
}
trait DecoderRunnable<T> {
fn run(s: Arc<dyn LockableOption<dyn Decoder<T>>>);
}
impl<T: 'static + Send> DecoderRunnable<T> for FfmpegDecoder<T> {
fn run(s_lockable: Arc<dyn LockableOption<dyn Decoder<T>>>) {
unimplemented!()
}
}
fn main() {
let r: LockableArc<Box<dyn Decoder<u8>>> = Arc::new(Mutex::new(Some(Box::new(FfmpegDecoder{x: 0u8}))));
let rr: Arc<dyn LockableOption<dyn Decoder<u8>>> = Arc::new(r);
DecoderRunnable::<u8>::run(rr.clone());
}
Playground
I get the error:
error[E0283]: type annotations needed
--> src/main.rs:42:5
|
30 | fn run(s: Arc<dyn LockableOption<dyn Decoder<T>>>);
| --------------------------------------------------- required by `DecoderRunnable::run`
...
42 | DecoderRunnable::<u8>::run(rr.clone());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
|
= note: cannot satisfy `_: DecoderRunnable<u8>`
which I don't get. Why anything here should satisfy DecoderRunnable? DecoderRunnable is a trait that has a run function that expects Arc<dyn LockableOption<dyn Decoder<T>>> and I'm passing rr which is exactly that.
Traits have to be implemented types so the compiler can figure out which implementation to run. In your example, DecoderRunnable is only implemented for FfmpegDecoder<T> and you're trying to call it on an Arc<dyn LockableOption<dyn Decoder<u8>>>, which has no implementation.
You can always specify which implementation needs to be called by using this syntax:
<FfmpegDecoder<u8> as DecoderRunnable::<u8>>::run(rr);
Although it doesn't seem like what you're trying to do . It's not clear what you're trying to abstract, since you also have the decoder deeply nested inside LockableArc<T>.
If you just want to add convenience methods to LockableArc<Box<dyn Decoder<u8>>>, you can add an impl block for Arc<dyn ...> , and make the run method take &self instead of Arc<dyn ...> as its first parameter.
Suppose there is a trait, whose methods all only take a reference of self, such as
trait Trait {
fn foo(&self) -> i32;
}
I'd like to have this trait implemented for both Option<T> and Option<&T> (as I can't always afford ownership), with a trivial implementation such as
impl<T: Trait> Trait for Option<T> {
fn foo(&self) -> i32 {
if let Some(inner) = self { return inner.foo(); }
0
}
}
impl<T: Trait> Trait for Option<&T> {
fn foo(&self) -> i32 {
if let Some(inner) = self { return inner.foo(); }
0
}
}
However, doing so produces the following error:
error[E0119]: conflicting implementations of trait `Trait` for type `std::option::Option<&_>`:
--> option.rs:12:1
|
5 | impl<T: Trait> Trait for Option<T> {
| ---------------------------------- first implementation here
...
12 | impl<T: Trait> Trait for Option<&T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `std::option::Option<&_>`
|
= note: downstream crates may implement trait `Trait` for type `&_`
Moreover, the implementations are literally the same. Is it possible to do this in a more compact way?
This does not compile because I, as a user of your trait could do something like this:
struct Yo;
impl Trait for Yo {
fn foo(&self) -> i32 { 0 }
}
impl Trait for &Yo {
fn foo(&self) -> i32 { 1 }
}
fn main() {
let a = Yo;
let b: Option<&Yo> = Some(&a);
b.foo(); // ambiguous call!
}
And there are two conflicting implementations of your trait for Option<&Yo>! Unfortunately trait specialization is still unstable, so that is probably not an option.
In your particular case you may solve with this generic impl, if you are willing:
impl<T: Trait> Trait for &T {
fn foo(&self) -> i32 {
(*self).foo()
}
}
This, combined with your generic impl for Option<T>, will give an unambiguous implementation for Option<&T>.
Is it possible for a struct to have a reference to a trait object that has generic methods, without making the struct itself generic?
trait Foo {
fn generic_method<T>(&self) {}
}
struct MyFoo {}
impl Foo for MyFoo {}
struct Bar<'a> {
my_foo: &'a mut (Foo + 'a),
}
impl<'a> Bar<'a> {
fn new(my_foo: &'a mut Foo) -> Self {
Self { my_foo }
}
}
This code gives me the error:
error[E0038]: the trait `Foo` cannot be made into an object
--> src/main.rs:9:5
|
9 | my_foo: &'a mut (Foo + 'a),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
|
= note: method `generic_method` has generic type parameters
error[E0038]: the trait `Foo` cannot be made into an object
--> src/main.rs:13:5
|
13 | fn new(my_foo: &'a mut Foo) -> Self {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
|
= note: method `generic_method` has generic type parameters
It is not possible because all the possible instantiations of generic_method are not known beforehand, so there is no way that the compiler could generate a proper vtable for generic_method.
As you mentioned, you can make the struct generic instead:
struct Bar<'a, T: Foo + 'a> {
my_foo: &'a mut T
}
impl<'a, T: Foo> Bar<'a, T> {
fn new(my_foo: &'a mut T) -> Self {
Self {my_foo}
}
}