What counts as a conflicting implementation? - rust

In the following code:
enum Either<A, B> { Left(A), Right(B) }
use Either::{Left, Right};
impl<A, B> From<A> for Either<A, B> {
fn from(a: A) -> Self {
Left(a)
}
}
impl<A, B> From<B> for Either<A, B> {
fn from(b: B) -> Self {
Right(b)
}
}
I'm getting the following error: "conflicting implementations of trait std::convert::From<_> for type Either<_, _>". I do not understand how the implementation of From<A> and From<B> for Either<A, B> is conflicting.
I saw an example in the standard library docs where they're doing almost exactly what I'm doing but it works there:
use std::fs;
use std::io;
use std::num;
enum CliError {
IoError(io::Error),
ParseError(num::ParseIntError),
}
impl From<io::Error> for CliError {
fn from(error: io::Error) -> Self {
CliError::IoError(error)
}
}
impl From<num::ParseIntError> for CliError {
fn from(error: num::ParseIntError) -> Self {
CliError::ParseError(error)
}
}
Please can someone explain? Thanks.

In your original code:
enum Either<A, B> { Left(A), Right(B) }
use Either::{Left, Right};
impl<A, B> From<A> for Either<A, B> {
fn from(a: A) -> Self {
Left(a)
}
}
impl<A, B> From<B> for Either<A, B> {
fn from(b: B) -> Self {
Right(b)
}
}
You implement the From trait for Either<A, B> twice for From bound by the same traits A and B. Which is likely causing your issue where From is implemented multiple times. I cannot confirm that since the issue is not reproducible from the provided code. Using the code provided directly throws errors stating that A and B are undefined.
Combining the original and functional code together; we can provide definitions to the types. However, the following code will still fail due to improper bounding. In this case, the trait bounds are bound by a structure:
use std::{io, num};
enum Either<A, B> { Left(A), Right(B) }
use Either::{Left, Right};
impl<A: io::Error, B: num::ParseIntError> From<A> for Either<A, B> {
fn from(a: A) -> Self {
Left(a)
}
}
impl<A: io::Error, B: num::ParseIntError> From<B> for Either<A, B> {
fn from(b: B) -> Self {
Right(b)
}
}
Will result in the following error:
error[E0404]: expected trait, found struct `num::ParseIntError`
To make a functional version, the trait bounds should be removed. Resulting in something like the following which will compile without errors:
use std::{io, num};
enum Either<A, B> { Left(A), Right(B) }
type A = io::Error;
type B = num::ParseIntError;
use Either::{Left, Right};
impl From<A> for Either<A, B> {
fn from(a: A) -> Self {
Left(a)
}
}
impl From<B> for Either<A, B> {
fn from(b: B) -> Self {
Right(b)
}
}
From will only be usable on the type parameter it is implemented on and does not require the trait bounds.
You can find more information on trait bounds here: https://doc.rust-lang.org/reference/trait-bounds.html
You can find more information on type parameters here: https://doc.rust-lang.org/reference/types/parameters.html
You can find the documentation for the From trait here: https://doc.rust-lang.org/std/convert/trait.From.html

Related

how to add Functors with generic types on the function?

The title is probably confusing, but I am not sure how to express this idea very well. I will clarify what I mean.
Is it possible to pass a function that acts differently depending on the variable passed to it.
Let me give you this example
trait Lift<A, B> {
type Source;
type Target1;
}
impl<A, B> Lift<A, B> for Option<A> {
type Source = Self;
type Target1 = Option<B>;
}
trait Functor<A, B>: Lift<A, B> {
fn fmap<F>(self, f: F) -> <Self as Lift<A, B>>::Target1
where
F: Fn(A) -> B;
}
impl<A, B> Functor<A, B> for Option<A> {
fn fmap<F>(self, f: F) -> <Self as Lift<A, B>>::Target1
where
F: Fn(A) -> B,
{
self.map(f)
}
}
#[derive(Copy, Clone, Debug)]
struct Identity<T>(T);
impl<A, B> Lift<A, B> for Identity<A> {
type Source = Self;
type Target1 = Identity<B>;
}
impl<A, B> Functor<A, B> for Identity<A> {
fn fmap<F>(self, f: F) -> <Self as Lift<A, B>>::Target1
where
F: Fn(A) -> B,
{
Identity(f(self.0))
}
}
#[derive(Copy, Clone, Debug)]
struct Pair<T>(T,T);
impl<A, B> Lift<A, B> for Pair<A> {
type Source = Self;
type Target1 = Pair<B>;
}
impl<A, B> Functor<A, B> for Pair<A> {
fn fmap<F>(self, f: F) -> <Self as Lift<A, B>>::Target1
where
F: Fn(A) -> B,
{
Pair(f(self.0),f(self.1))
}
}
#[derive(Copy, Clone, Debug)]
struct Pair2<T,E>(T,E);
impl<A,D, B,C> Lift<(A,C), (B,D)> for Pair2<A,C> {
type Source = Self;
type Target1 = Pair2<B,D>;
}
//Can you even implement a functor that takes a generic function?
impl<A, B,C,D> Functor<(A,C), (B,D)> for Pair2<A,C> {
fn fmap<F>(self, f: F) -> <Self as Lift<(A,C), (B,D)>>::Target1
where
F: Fn((A,C)) -> (B,D),
{
let a=f((self.0,self.1));
Pair2(a.0,a.1)
}
}
fn main() {
let a=Some(5);
println!("{:?}\n{:?}",a,a.fmap(|a| a+2));
let a=Identity(5);
println!("{:?}\n{:?}",a,a.fmap(|a| a+2));
let a=Pair(4,7);
println!("{:?}\n{:?}",a,a.fmap(|a| a+2));
let a=Pair2(4,6.8);
//challenge, make a fmap that takes a variadic a and adds 2 or something like that like in just "Pair"
println!("{:?}\n{:?}",a,a.fmap(|a| (a.0+2,a.1+3.4)));
}
https://www.rustexplorer.com/b/90nk7p
This is the output
Some(5)
Some(7)
Identity(5)
Identity(7)
Pair(4, 7)
Pair(6, 9)
Pair2(4, 6.8)
Pair2(6, 10.2)
Ok that's pretty cool, what I would like to do, is to create an fmap on Pair2 such that it "works" exactly like the one above just Pair, coercing the types. Is there a way to do this?
What I mean, instead of a function that takes a tuple, I can give a function that takes a single element, that changes depending on the type.
That is to say
fn id<T>(a: T) -> T {
a
}
let a=Pair2(4,6.8);
a.fmap(id)
//This would somehow work.
Or for example
a.fmap(Some)
//This would wrap it into
//Pair2(Some(4),Some(6.8))
With functions, no. Type parameters are early bound, meaning that Some is always Some::<T> with some T, it can be multiple Ts.
You may be able to go with a custom generic trait, but I don't see how given that the bounds on Functor::fmap() are dictated by the trait.

I don't understand "T::parse.parse(token_stream)" syntax in parse_macro_input macro of syn crate

#[doc(hidden)]
pub fn parse<T: ParseMacroInput>(token_stream: TokenStream) -> Result<T> {
T::parse.parse(token_stream)
} // Not public API.
#[doc(hidden)]
pub trait ParseMacroInput: Sized {
fn parse(input: ParseStream) -> Result<Self>;
}
impl<T: Parse> ParseMacroInput for T {
fn parse(input: ParseStream) -> Result<Self> {
<T as Parse>::parse(input)
}
}
I guess that the code you find weird is that in the title:
T::parse.parse(token_stream)
Here T is a generic type that implements ParseMacroInput, because of the constraint T: ParseMacroInput above. The only member of that trait is that fn parse(input: ParseStream) -> Result<Self>; function, so T::parse must be a reference to that function.
Now, what about the next .parse? Well functions are values too, and they can implement traits. And indeed in synthere is this trait:
pub trait Parser: Sized {
// ...
fn parse(self, tokens: proc_macro::TokenStream) -> Result<Self::Output> { ... }
}
and an implementation for functions that take a ParseStream and returns a Result<_>, just like function ParseMacroInput::parse.
impl<F, T> Parser for F
where
F: FnOnce(ParseStream) -> Result<T>
And that is the function your original T::parse.parse() calls: a function of a trait implemented by a function type or another generic type. The fact that both functions have the same name is an unfortunate coincidence.

Automatic error conversion using the '?' operator for custom types

I'm struggling to understand the nuances of the ? operator. Take the following code:
link to playground
use std::{error::Error as StdError, fmt};
#[derive(Debug)]
struct MyError(Box<dyn StdError>);
impl fmt::Display for MyError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self, f)
}
}
impl StdError for MyError{}
impl From<Box<dyn StdError>> for MyError {
fn from(err: Box<dyn StdError>) -> Self {
MyError(err)
}
}
#[derive(Debug)]
struct RandomErr(String);
impl fmt::Display for RandomErr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self, f)
}
}
impl StdError for RandomErr{}
fn no_custom() -> Result<(), Box<dyn StdError>> {
Err(RandomErr("hello there".to_owned()))?
}
// This fails to compile
fn custom() -> Result<(), MyError> {
Err(RandomErr("hello there".to_owned()))?
}
I would think that custom() should compile. RandomError is a StdError, so RandomErr should be convertable to MyError since there's an impl for converting from StdError, no?
I would think that custom() should compile. RandomError is a StdError, so RandomErr should be convertable to MyError since there's an impl for converting from StdError, no?
Nope. There is no transitivity in From (or any trait, as far as I know). Rustc generally does what you tell it and no more to avoid problems like combinatory explosions in trait resolution.
So that C: From<B> and B: From<A> does not imply / translate to C: From<A>, you can write that reduced case and will hit E0277 (trait not satisfied):
struct A;
struct B;
struct C;
impl From<A> for B {
fn from(a: A) -> Self { B }
}
impl From<B> for C {
fn from(b: B) -> Self { C }
}
fn main() {
let _: C = From::from(A);
}

How do I write a function that allows me to convert a type T into any Box<B> if Box<T> can be coerced into Box<B>?

I'm trying to write an extension trait that allows me to move any value of type T into any Box<B>, where Box<T> can be coerced into Box<B>. My first attempt is the following:
trait IntoBox<B: ?Sized> {
fn into_box(self) -> Box<B>;
}
impl<T, B: ?Sized> IntoBox<B> for T
where
Box<T>: Into<Box<B>>,
{
fn into_box(self) -> Box<B> {
Box::new(self).into()
}
}
fn main() {
// Ok
let _: Box<u32> = 42.into_box();
// Error: the trait bound `std::boxed::Box<std::fmt::Display>:
// std::convert::From<std::boxed::Box<&str>>` is not satisfied
let _: Box<std::fmt::Display> = "Hello World".into_box();
}
This code works for regular boxes, but not trait objects. I suspect Into is the wrong bound here. What should I use instead?
Edit: As explained in the answer to this question, this problem can be solved with respect to any number of concrete types T by providing a blanket impl for T: Unsize<U>. However this does not work in the generic case because the impls would be conflicting:
impl<T, B> IntoBox<B> for T
where
Box<T>: Into<Box<B>>,
{
fn into_box(self) -> Box<B> {
Box::new(self).into()
}
}
impl<T, B: ?Sized> IntoBox<B> for T
where
B: std::marker::Unsize<T>
{
fn into_box(self) -> Box<B> {
Box::new(self)
}
}

Why does my Trait implementation not match?

How can I make this code compile ?
trait Pair<'a, A, B> {
fn first_ref(&'a self) -> &'a A;
fn second_ref(&'a self) -> &'a B;
};
struct PairOwned<A, B> {
first: A,
second: B,
}
// Only implemented for the cases we are interested in ...
impl<'a, A, B> Pair<'a, A, B> for &'a PairOwned<&'a A,&'a B> {
fn first_ref(&'a self) -> &'a A {
self.first
}
fn second_ref(&'a self) -> &'a B {
self.second
}
}
impl<'a, A, B> Pair<'a, A, B> for &'a(&'a A, &'a B) {
fn first_ref(&'a self) -> &'a A {
self.0
}
fn second_ref(&'a self) -> &'a B {
self.1
}
}
fn pair_transformer<'a, I, T>(pairs: I) -> String
where T: Pair<'a, &'a Str, &'a Str> + 'a,
I: Iterator<Item=T> {
let mut s = String::new();
for pair in pairs {
s = s
+ pair.first_ref().as_slice()
+ pair.second_ref().as_slice();
}
s
}
pair_transformer([PairOwned { first: "a", second: "b" }].iter());
pair_transformer([("a", "b")].iter());
The compiler says:
tests/lang.rs:902:5: 902:21 error: the trait `pair_trait_for_iteration::Pair<'_, &core::str::Str, &core::str::Str>` is not implemented for the type `&pair_trait_for_iteration::PairOwned<&str, &str>` [E0277]
tests/lang.rs:902 pair_transformer([PairOwned { first: "a", second: "b" }].iter());
^~~~~~~~~~~~~~~~
tests/lang.rs:903:5: 903:21 error: the trait `pair_trait_for_iteration::Pair<'_, &core::str::Str, &core::str::Str>` is not implemented for the type `&(&str, &str)` [E0277]
tests/lang.rs:903 pair_transformer([("a", "b")].iter());
Notes
I have the feeling it is somehow related to the various ways to specify what a trait should be implemented for, something I have not fully understood yet.
// As stated in the answer at
// http://stackoverflow.com/questions/28283641/what-is-the-preferred-way-to-implement-the-add-trait-efficiently-for-vector-type
impl Add<YourType> for YourType { ... }
impl<'r> Add<YourType> for &'r YourType { ... }
impl<'a> Add<&'a YourType> for YourType { ... }
impl<'r, 'a> Add<&'a YourType> for &'r YourType { ... }
Using rustc 1.0.0-nightly (522d09dfe 2015-02-19) (built 2015-02-19)
There are a couple of mistakes in your code:
You probably want to implement your trait directly for your type, as the methods defined by the trait take the trait by reference (which is not the case of the Add trait in the other post you linked)
Your use of OwnedPair { first: "a", second: "b"} isn't actually owned: your type will be OwnedPair<&'static str, &'static str> so I included examples with String (which are owned) as I assume that is what you wanted
The items returned by your iterator are actually references, so you probably want to bind I to Iterator<Item=&'a T>
As I tried to be as generic as possible (and for the example to compile with both OwnedPair<&str,&str> and OwnedPair<String,String>) I used the trait std::borrow::Borrow, which basically means that it is possible to borrow a reference to the type T from the type by which this trait is implemented.
I also needed to use ?Sized as a bound for most type parameters. This allows to use types which size is not known at compile time, and will be used behind a "fat pointer". More information in this blog post (a little bit old)
Here is the full corrected code (runnable in playpen)
use std::borrow::Borrow;
trait Pair<'a, A: ?Sized, B: ?Sized> {
fn first_ref(&'a self) -> &'a A;
fn second_ref(&'a self) -> &'a B;
}
struct PairOwned<A, B> {
first: A,
second: B,
}
// Only implemented for the cases we are interested in ...
impl<'a, ARef: ?Sized, BRef: ?Sized, A: Borrow<ARef>, B: Borrow<BRef>> Pair<'a, ARef, BRef> for PairOwned<A,B> {
fn first_ref(&'a self) -> &'a ARef {
self.first.borrow()
}
fn second_ref(&'a self) -> &'a BRef {
self.second.borrow()
}
}
// It should also be possible to be more generic here with Borrow
// But I wanted to leave your original implementation
impl<'a, A: ?Sized, B: ?Sized> Pair<'a, A, B> for (&'a A, &'a B) {
fn first_ref(&'a self) -> &'a A {
self.0
}
fn second_ref(&'a self) -> &'a B {
self.1
}
}
fn pair_transformer<'a, I, T>(pairs: I) -> String
where T: Pair<'a, str, str> + 'a,
I: Iterator<Item=&'a T> {
let mut s = String::new();
for pair in pairs {
s = s
+ pair.first_ref().as_slice()
+ pair.second_ref().as_slice();
}
s
}
fn main() {
pair_transformer([PairOwned { first: "a".to_string(), second: "b".to_string() }].iter());
pair_transformer([PairOwned { first: "a".to_string(), second: "b" }].iter()); // It is even possible to mix String and &str
pair_transformer([PairOwned { first: "a", second: "b" }].iter());
pair_transformer([("a", "b")].iter());
}

Resources