diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-01-21 02:21:53 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-01-21 02:21:53 +0100 |
| commit | ebc70e2e9ecdd0920c5e78f53ed694f1c050c5ed (patch) | |
| tree | 7b5c2dc6e750f5f8e0e9ca86920761b95cc8e534 | |
| parent | e73069767f11d992f0dca7e31d53d7e1a77fd237 (diff) | |
| parent | ea68b3ff3dd5a49c5984c476570fb5404c342079 (diff) | |
| download | rust-ebc70e2e9ecdd0920c5e78f53ed694f1c050c5ed.tar.gz rust-ebc70e2e9ecdd0920c5e78f53ed694f1c050c5ed.zip | |
Rollup merge of #56796 - KrishnaSannasi:try_from_impl_change, r=shepmaster
Change bounds on `TryFrom` blanket impl to use `Into` instead of `From` This is from this [comment](https://github.com/rust-lang/rust/issues/33417#issuecomment-447111156) I made. This will expand the impls available for `TryFrom` and `TryInto`, without losing anything in the process.
| -rw-r--r-- | src/libcore/convert.rs | 4 | ||||
| -rw-r--r-- | src/test/run-pass/try_from.rs | 37 | ||||
| -rw-r--r-- | src/test/ui/e0119/conflict-with-std.stderr | 2 |
3 files changed, 40 insertions, 3 deletions
diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index 08b5ac06f72..203be541e49 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -463,11 +463,11 @@ impl<T, U> TryInto<U> for T where U: TryFrom<T> // Infallible conversions are semantically equivalent to fallible conversions // with an uninhabited error type. #[unstable(feature = "try_from", issue = "33417")] -impl<T, U> TryFrom<U> for T where T: From<U> { +impl<T, U> TryFrom<U> for T where U: Into<T> { type Error = !; fn try_from(value: U) -> Result<Self, Self::Error> { - Ok(T::from(value)) + Ok(U::into(value)) } } diff --git a/src/test/run-pass/try_from.rs b/src/test/run-pass/try_from.rs new file mode 100644 index 00000000000..4522ce3a8d6 --- /dev/null +++ b/src/test/run-pass/try_from.rs @@ -0,0 +1,37 @@ +// This test relies on `TryFrom` being blanket impl for all `T: Into` +// and `TryInto` being blanket impl for all `U: TryFrom` + +// This test was added to show the motivation for doing this +// over `TryFrom` being blanket impl for all `T: From` + +#![feature(try_from, never_type)] + +use std::convert::TryInto; + +struct Foo<T> { + t: T, +} + +// This fails to compile due to coherence restrictions +// as of Rust version 1.32.x, therefore it could not be used +// instead of the `Into` version of the impl, and serves as +// motivation for a blanket impl for all `T: Into`, instead +// of a blanket impl for all `T: From` +/* +impl<T> From<Foo<T>> for Box<T> { + fn from(foo: Foo<T>) -> Box<T> { + Box::new(foo.t) + } +} +*/ + +impl<T> Into<Vec<T>> for Foo<T> { + fn into(self) -> Vec<T> { + vec![self.t] + } +} + +pub fn main() { + let _: Result<Vec<i32>, !> = Foo { t: 10 }.try_into(); +} + diff --git a/src/test/ui/e0119/conflict-with-std.stderr b/src/test/ui/e0119/conflict-with-std.stderr index d94e4dc5b6e..c2ae321aa5e 100644 --- a/src/test/ui/e0119/conflict-with-std.stderr +++ b/src/test/ui/e0119/conflict-with-std.stderr @@ -25,7 +25,7 @@ LL | impl TryFrom<X> for X { //~ ERROR conflicting implementations | = note: conflicting implementation in crate `core`: - impl<T, U> std::convert::TryFrom<U> for T - where T: std::convert::From<U>; + where U: std::convert::Into<T>; error: aborting due to 3 previous errors |
