diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index 2d4813718f41a..18ead0877fe85 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -476,11 +476,11 @@ impl TryInto for T where U: TryFrom // Infallible conversions are semantically equivalent to fallible conversions // with an uninhabited error type. #[unstable(feature = "try_from", issue = "33417")] -impl TryFrom for T where T: From { +impl TryFrom for T where U: Into { type Error = !; fn try_from(value: U) -> Result { - 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 0000000000000..4522ce3a8d617 --- /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, +} + +// 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 From> for Box { + fn from(foo: Foo) -> Box { + Box::new(foo.t) + } +} +*/ + +impl Into> for Foo { + fn into(self) -> Vec { + vec![self.t] + } +} + +pub fn main() { + let _: Result, !> = 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 e8b2c84c0df0b..fd016941d258e 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 for X { //~ ERROR conflicting implementations | = note: conflicting implementation in crate `core`: - impl std::convert::TryFrom for T - where T: std::convert::From; + where U: std::convert::Into; error: aborting due to 3 previous errors