I wanted to implement the Shl trait for Vec, the code is below. This would make things like vec << 4 possible, which would be nice sugar for vec.push(4).
use std::ops::Shl;
impl<T> Shl<T> for Vec<T> {
type Output = Vec<T>;
fn shl(&self, elem: &T) -> Vec<T> {
self.push(*elem);
*self
}
}
fn main() {
let v = vec![1, 2, 3];
v << 4;
}
The compilation fails with the following error:
cannot provide an extension implementation where both trait and type are not defined in this crate [E0117]
or
type parameter T must be used as the type parameter for some local type (e.g. MyStruct<T>); only traits defined in the current crate can be implemented for a type parameter [E0210]
As I understand it, I'd have to patch the stdlib, more specifically the collections::vec crate. Is there another way to change this code to compile successfully?
While you can't do that exactly, the usual workaround is to just wrap the type you want in your own type and implement the trait on that.
use somecrate::FooType;
use somecrate::BarTrait;
struct MyType(FooType);
impl BarTrait for MyType {
fn bar(&self) {
// use `self.0` here
}
}
This would make things like vec << 4 possible, which would be nice sugar for vec.push(4).
Although it can be done, it is generally a bad idea to implement an operator with a unexpected semantic.
Here is an example of how this can be done:
use std::ops::Shl;
struct BadVec<T>(Vec<T>);
impl<T> Shl<T> for BadVec<T> {
type Output = BadVec<T>;
fn shl(mut self, elem: T) -> Self::Output {
self.0.push(elem);
self
}
}
fn main() {
let mut v = BadVec(vec![1, 2, 3]);
v = v << 4;
assert_eq!(vec![1, 2, 3, 4], v.0)
}
If you implement Deref (DerefMut):
use std::ops::{Deref, DerefMut};
impl<T> Deref for BadVec<T> {
type Target = Vec<T>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for BadVec<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
you can call Vec methods:
fn main() {
let mut v = BadVec(vec![1, 2, 3]);
v = v << 4;
v.truncate(2);
assert_eq!(2, v.len());
}
Take a look at the newtype_derive crate, it can generate some boilerplate code for you.
That is intentionally forbidden and referred to as the orphan rule. It is for guaranteeing trait coherence. According to the orphan rule, you cannot provide implementations of a trait for a struct unless you are either the crate that defines the struct, or the crate that defines the trait. If you could achieve what you are asking, we would have conflicting implementations circling around.
There are some workarounds though, the most common one being the newtype pattern. In the newtype pattern, we wrap the external type in a local struct and through this wrapper we implement the desired methods.
// External struct
use foo::Foo;
// Create a new type.
pub struct Bar(Foo);
// Provide your own implementations
impl Bar {
pub fn new() -> Self {
//..
}
}
For more information check out these references:
Nicko's Blog Post: Little Orphan Impls
Chalk Book: Coherence
Rust Design Patterns: Newtype
Rust Book: Using the Newtype Pattern to Implement External Traits on External Types
Youtube: GPU Rasterization, the Orphan Rules, and Rocket
Related
I wanted to implement the Shl trait for Vec, the code is below. This would make things like vec << 4 possible, which would be nice sugar for vec.push(4).
use std::ops::Shl;
impl<T> Shl<T> for Vec<T> {
type Output = Vec<T>;
fn shl(&self, elem: &T) -> Vec<T> {
self.push(*elem);
*self
}
}
fn main() {
let v = vec![1, 2, 3];
v << 4;
}
The compilation fails with the following error:
cannot provide an extension implementation where both trait and type are not defined in this crate [E0117]
or
type parameter T must be used as the type parameter for some local type (e.g. MyStruct<T>); only traits defined in the current crate can be implemented for a type parameter [E0210]
As I understand it, I'd have to patch the stdlib, more specifically the collections::vec crate. Is there another way to change this code to compile successfully?
While you can't do that exactly, the usual workaround is to just wrap the type you want in your own type and implement the trait on that.
use somecrate::FooType;
use somecrate::BarTrait;
struct MyType(FooType);
impl BarTrait for MyType {
fn bar(&self) {
// use `self.0` here
}
}
This would make things like vec << 4 possible, which would be nice sugar for vec.push(4).
Although it can be done, it is generally a bad idea to implement an operator with a unexpected semantic.
Here is an example of how this can be done:
use std::ops::Shl;
struct BadVec<T>(Vec<T>);
impl<T> Shl<T> for BadVec<T> {
type Output = BadVec<T>;
fn shl(mut self, elem: T) -> Self::Output {
self.0.push(elem);
self
}
}
fn main() {
let mut v = BadVec(vec![1, 2, 3]);
v = v << 4;
assert_eq!(vec![1, 2, 3, 4], v.0)
}
If you implement Deref (DerefMut):
use std::ops::{Deref, DerefMut};
impl<T> Deref for BadVec<T> {
type Target = Vec<T>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for BadVec<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
you can call Vec methods:
fn main() {
let mut v = BadVec(vec![1, 2, 3]);
v = v << 4;
v.truncate(2);
assert_eq!(2, v.len());
}
Take a look at the newtype_derive crate, it can generate some boilerplate code for you.
That is intentionally forbidden and referred to as the orphan rule. It is for guaranteeing trait coherence. According to the orphan rule, you cannot provide implementations of a trait for a struct unless you are either the crate that defines the struct, or the crate that defines the trait. If you could achieve what you are asking, we would have conflicting implementations circling around.
There are some workarounds though, the most common one being the newtype pattern. In the newtype pattern, we wrap the external type in a local struct and through this wrapper we implement the desired methods.
// External struct
use foo::Foo;
// Create a new type.
pub struct Bar(Foo);
// Provide your own implementations
impl Bar {
pub fn new() -> Self {
//..
}
}
For more information check out these references:
Nicko's Blog Post: Little Orphan Impls
Chalk Book: Coherence
Rust Design Patterns: Newtype
Rust Book: Using the Newtype Pattern to Implement External Traits on External Types
Youtube: GPU Rasterization, the Orphan Rules, and Rocket
I wanted to implement the Shl trait for Vec, the code is below. This would make things like vec << 4 possible, which would be nice sugar for vec.push(4).
use std::ops::Shl;
impl<T> Shl<T> for Vec<T> {
type Output = Vec<T>;
fn shl(&self, elem: &T) -> Vec<T> {
self.push(*elem);
*self
}
}
fn main() {
let v = vec![1, 2, 3];
v << 4;
}
The compilation fails with the following error:
cannot provide an extension implementation where both trait and type are not defined in this crate [E0117]
or
type parameter T must be used as the type parameter for some local type (e.g. MyStruct<T>); only traits defined in the current crate can be implemented for a type parameter [E0210]
As I understand it, I'd have to patch the stdlib, more specifically the collections::vec crate. Is there another way to change this code to compile successfully?
While you can't do that exactly, the usual workaround is to just wrap the type you want in your own type and implement the trait on that.
use somecrate::FooType;
use somecrate::BarTrait;
struct MyType(FooType);
impl BarTrait for MyType {
fn bar(&self) {
// use `self.0` here
}
}
This would make things like vec << 4 possible, which would be nice sugar for vec.push(4).
Although it can be done, it is generally a bad idea to implement an operator with a unexpected semantic.
Here is an example of how this can be done:
use std::ops::Shl;
struct BadVec<T>(Vec<T>);
impl<T> Shl<T> for BadVec<T> {
type Output = BadVec<T>;
fn shl(mut self, elem: T) -> Self::Output {
self.0.push(elem);
self
}
}
fn main() {
let mut v = BadVec(vec![1, 2, 3]);
v = v << 4;
assert_eq!(vec![1, 2, 3, 4], v.0)
}
If you implement Deref (DerefMut):
use std::ops::{Deref, DerefMut};
impl<T> Deref for BadVec<T> {
type Target = Vec<T>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for BadVec<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
you can call Vec methods:
fn main() {
let mut v = BadVec(vec![1, 2, 3]);
v = v << 4;
v.truncate(2);
assert_eq!(2, v.len());
}
Take a look at the newtype_derive crate, it can generate some boilerplate code for you.
That is intentionally forbidden and referred to as the orphan rule. It is for guaranteeing trait coherence. According to the orphan rule, you cannot provide implementations of a trait for a struct unless you are either the crate that defines the struct, or the crate that defines the trait. If you could achieve what you are asking, we would have conflicting implementations circling around.
There are some workarounds though, the most common one being the newtype pattern. In the newtype pattern, we wrap the external type in a local struct and through this wrapper we implement the desired methods.
// External struct
use foo::Foo;
// Create a new type.
pub struct Bar(Foo);
// Provide your own implementations
impl Bar {
pub fn new() -> Self {
//..
}
}
For more information check out these references:
Nicko's Blog Post: Little Orphan Impls
Chalk Book: Coherence
Rust Design Patterns: Newtype
Rust Book: Using the Newtype Pattern to Implement External Traits on External Types
Youtube: GPU Rasterization, the Orphan Rules, and Rocket
I wanted to implement the Shl trait for Vec, the code is below. This would make things like vec << 4 possible, which would be nice sugar for vec.push(4).
use std::ops::Shl;
impl<T> Shl<T> for Vec<T> {
type Output = Vec<T>;
fn shl(&self, elem: &T) -> Vec<T> {
self.push(*elem);
*self
}
}
fn main() {
let v = vec![1, 2, 3];
v << 4;
}
The compilation fails with the following error:
cannot provide an extension implementation where both trait and type are not defined in this crate [E0117]
or
type parameter T must be used as the type parameter for some local type (e.g. MyStruct<T>); only traits defined in the current crate can be implemented for a type parameter [E0210]
As I understand it, I'd have to patch the stdlib, more specifically the collections::vec crate. Is there another way to change this code to compile successfully?
While you can't do that exactly, the usual workaround is to just wrap the type you want in your own type and implement the trait on that.
use somecrate::FooType;
use somecrate::BarTrait;
struct MyType(FooType);
impl BarTrait for MyType {
fn bar(&self) {
// use `self.0` here
}
}
This would make things like vec << 4 possible, which would be nice sugar for vec.push(4).
Although it can be done, it is generally a bad idea to implement an operator with a unexpected semantic.
Here is an example of how this can be done:
use std::ops::Shl;
struct BadVec<T>(Vec<T>);
impl<T> Shl<T> for BadVec<T> {
type Output = BadVec<T>;
fn shl(mut self, elem: T) -> Self::Output {
self.0.push(elem);
self
}
}
fn main() {
let mut v = BadVec(vec![1, 2, 3]);
v = v << 4;
assert_eq!(vec![1, 2, 3, 4], v.0)
}
If you implement Deref (DerefMut):
use std::ops::{Deref, DerefMut};
impl<T> Deref for BadVec<T> {
type Target = Vec<T>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for BadVec<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
you can call Vec methods:
fn main() {
let mut v = BadVec(vec![1, 2, 3]);
v = v << 4;
v.truncate(2);
assert_eq!(2, v.len());
}
Take a look at the newtype_derive crate, it can generate some boilerplate code for you.
That is intentionally forbidden and referred to as the orphan rule. It is for guaranteeing trait coherence. According to the orphan rule, you cannot provide implementations of a trait for a struct unless you are either the crate that defines the struct, or the crate that defines the trait. If you could achieve what you are asking, we would have conflicting implementations circling around.
There are some workarounds though, the most common one being the newtype pattern. In the newtype pattern, we wrap the external type in a local struct and through this wrapper we implement the desired methods.
// External struct
use foo::Foo;
// Create a new type.
pub struct Bar(Foo);
// Provide your own implementations
impl Bar {
pub fn new() -> Self {
//..
}
}
For more information check out these references:
Nicko's Blog Post: Little Orphan Impls
Chalk Book: Coherence
Rust Design Patterns: Newtype
Rust Book: Using the Newtype Pattern to Implement External Traits on External Types
Youtube: GPU Rasterization, the Orphan Rules, and Rocket
I wanted to implement the Shl trait for Vec, the code is below. This would make things like vec << 4 possible, which would be nice sugar for vec.push(4).
use std::ops::Shl;
impl<T> Shl<T> for Vec<T> {
type Output = Vec<T>;
fn shl(&self, elem: &T) -> Vec<T> {
self.push(*elem);
*self
}
}
fn main() {
let v = vec![1, 2, 3];
v << 4;
}
The compilation fails with the following error:
cannot provide an extension implementation where both trait and type are not defined in this crate [E0117]
or
type parameter T must be used as the type parameter for some local type (e.g. MyStruct<T>); only traits defined in the current crate can be implemented for a type parameter [E0210]
As I understand it, I'd have to patch the stdlib, more specifically the collections::vec crate. Is there another way to change this code to compile successfully?
While you can't do that exactly, the usual workaround is to just wrap the type you want in your own type and implement the trait on that.
use somecrate::FooType;
use somecrate::BarTrait;
struct MyType(FooType);
impl BarTrait for MyType {
fn bar(&self) {
// use `self.0` here
}
}
This would make things like vec << 4 possible, which would be nice sugar for vec.push(4).
Although it can be done, it is generally a bad idea to implement an operator with a unexpected semantic.
Here is an example of how this can be done:
use std::ops::Shl;
struct BadVec<T>(Vec<T>);
impl<T> Shl<T> for BadVec<T> {
type Output = BadVec<T>;
fn shl(mut self, elem: T) -> Self::Output {
self.0.push(elem);
self
}
}
fn main() {
let mut v = BadVec(vec![1, 2, 3]);
v = v << 4;
assert_eq!(vec![1, 2, 3, 4], v.0)
}
If you implement Deref (DerefMut):
use std::ops::{Deref, DerefMut};
impl<T> Deref for BadVec<T> {
type Target = Vec<T>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for BadVec<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
you can call Vec methods:
fn main() {
let mut v = BadVec(vec![1, 2, 3]);
v = v << 4;
v.truncate(2);
assert_eq!(2, v.len());
}
Take a look at the newtype_derive crate, it can generate some boilerplate code for you.
That is intentionally forbidden and referred to as the orphan rule. It is for guaranteeing trait coherence. According to the orphan rule, you cannot provide implementations of a trait for a struct unless you are either the crate that defines the struct, or the crate that defines the trait. If you could achieve what you are asking, we would have conflicting implementations circling around.
There are some workarounds though, the most common one being the newtype pattern. In the newtype pattern, we wrap the external type in a local struct and through this wrapper we implement the desired methods.
// External struct
use foo::Foo;
// Create a new type.
pub struct Bar(Foo);
// Provide your own implementations
impl Bar {
pub fn new() -> Self {
//..
}
}
For more information check out these references:
Nicko's Blog Post: Little Orphan Impls
Chalk Book: Coherence
Rust Design Patterns: Newtype
Rust Book: Using the Newtype Pattern to Implement External Traits on External Types
Youtube: GPU Rasterization, the Orphan Rules, and Rocket
I wanted to implement the Shl trait for Vec, the code is below. This would make things like vec << 4 possible, which would be nice sugar for vec.push(4).
use std::ops::Shl;
impl<T> Shl<T> for Vec<T> {
type Output = Vec<T>;
fn shl(&self, elem: &T) -> Vec<T> {
self.push(*elem);
*self
}
}
fn main() {
let v = vec![1, 2, 3];
v << 4;
}
The compilation fails with the following error:
cannot provide an extension implementation where both trait and type are not defined in this crate [E0117]
or
type parameter T must be used as the type parameter for some local type (e.g. MyStruct<T>); only traits defined in the current crate can be implemented for a type parameter [E0210]
As I understand it, I'd have to patch the stdlib, more specifically the collections::vec crate. Is there another way to change this code to compile successfully?
While you can't do that exactly, the usual workaround is to just wrap the type you want in your own type and implement the trait on that.
use somecrate::FooType;
use somecrate::BarTrait;
struct MyType(FooType);
impl BarTrait for MyType {
fn bar(&self) {
// use `self.0` here
}
}
This would make things like vec << 4 possible, which would be nice sugar for vec.push(4).
Although it can be done, it is generally a bad idea to implement an operator with a unexpected semantic.
Here is an example of how this can be done:
use std::ops::Shl;
struct BadVec<T>(Vec<T>);
impl<T> Shl<T> for BadVec<T> {
type Output = BadVec<T>;
fn shl(mut self, elem: T) -> Self::Output {
self.0.push(elem);
self
}
}
fn main() {
let mut v = BadVec(vec![1, 2, 3]);
v = v << 4;
assert_eq!(vec![1, 2, 3, 4], v.0)
}
If you implement Deref (DerefMut):
use std::ops::{Deref, DerefMut};
impl<T> Deref for BadVec<T> {
type Target = Vec<T>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for BadVec<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
you can call Vec methods:
fn main() {
let mut v = BadVec(vec![1, 2, 3]);
v = v << 4;
v.truncate(2);
assert_eq!(2, v.len());
}
Take a look at the newtype_derive crate, it can generate some boilerplate code for you.
That is intentionally forbidden and referred to as the orphan rule. It is for guaranteeing trait coherence. According to the orphan rule, you cannot provide implementations of a trait for a struct unless you are either the crate that defines the struct, or the crate that defines the trait. If you could achieve what you are asking, we would have conflicting implementations circling around.
There are some workarounds though, the most common one being the newtype pattern. In the newtype pattern, we wrap the external type in a local struct and through this wrapper we implement the desired methods.
// External struct
use foo::Foo;
// Create a new type.
pub struct Bar(Foo);
// Provide your own implementations
impl Bar {
pub fn new() -> Self {
//..
}
}
For more information check out these references:
Nicko's Blog Post: Little Orphan Impls
Chalk Book: Coherence
Rust Design Patterns: Newtype
Rust Book: Using the Newtype Pattern to Implement External Traits on External Types
Youtube: GPU Rasterization, the Orphan Rules, and Rocket