Merge #9317
9317: internal: add From to minicore r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
84507a0b9c
@ -3016,8 +3016,8 @@ fn foo() {
|
||||
file_id: FileId(
|
||||
1,
|
||||
),
|
||||
full_range: 246..428,
|
||||
focus_range: 285..291,
|
||||
full_range: 247..429,
|
||||
focus_range: 286..292,
|
||||
name: "Future",
|
||||
kind: Trait,
|
||||
description: "pub trait Future",
|
||||
|
@ -6,6 +6,8 @@ use syntax::ast::{self, AstNode, NameOwner};
|
||||
|
||||
use crate::{AssistContext, AssistId, AssistKind, Assists};
|
||||
|
||||
// FIXME: this should be a diagnostic
|
||||
|
||||
// Assist: convert_into_to_from
|
||||
//
|
||||
// Converts an Into impl to an equivalent From impl.
|
||||
@ -114,12 +116,14 @@ pub(crate) fn convert_into_to_from(acc: &mut Assists, ctx: &AssistContext) -> Op
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use crate::tests::check_assist;
|
||||
use crate::tests::{check_assist, check_assist_not_applicable};
|
||||
|
||||
#[test]
|
||||
fn convert_into_to_from_converts_a_struct() {
|
||||
check_convert_into_to_from(
|
||||
check_assist(
|
||||
convert_into_to_from,
|
||||
r#"
|
||||
//- minicore: from
|
||||
struct Thing {
|
||||
a: String,
|
||||
b: usize
|
||||
@ -154,8 +158,10 @@ impl From<usize> for Thing {
|
||||
|
||||
#[test]
|
||||
fn convert_into_to_from_converts_enums() {
|
||||
check_convert_into_to_from(
|
||||
check_assist(
|
||||
convert_into_to_from,
|
||||
r#"
|
||||
//- minicore: from
|
||||
enum Thing {
|
||||
Foo(String),
|
||||
Bar(String)
|
||||
@ -190,8 +196,10 @@ impl From<Thing> for String {
|
||||
|
||||
#[test]
|
||||
fn convert_into_to_from_on_enum_with_lifetimes() {
|
||||
check_convert_into_to_from(
|
||||
check_assist(
|
||||
convert_into_to_from,
|
||||
r#"
|
||||
//- minicore: from
|
||||
enum Thing<'a> {
|
||||
Foo(&'a str),
|
||||
Bar(&'a str)
|
||||
@ -226,8 +234,10 @@ impl<'a> From<Thing<'a>> for &'a str {
|
||||
|
||||
#[test]
|
||||
fn convert_into_to_from_works_on_references() {
|
||||
check_convert_into_to_from(
|
||||
check_assist(
|
||||
convert_into_to_from,
|
||||
r#"
|
||||
//- minicore: from
|
||||
struct Thing(String);
|
||||
|
||||
impl $0core::convert::Into<String> for &Thing {
|
||||
@ -250,8 +260,10 @@ impl From<&Thing> for String {
|
||||
|
||||
#[test]
|
||||
fn convert_into_to_from_works_on_qualified_structs() {
|
||||
check_convert_into_to_from(
|
||||
check_assist(
|
||||
convert_into_to_from,
|
||||
r#"
|
||||
//- minicore: from
|
||||
mod things {
|
||||
pub struct Thing(String);
|
||||
pub struct BetterThing(String);
|
||||
@ -280,8 +292,10 @@ impl From<&things::Thing> for things::BetterThing {
|
||||
|
||||
#[test]
|
||||
fn convert_into_to_from_works_on_qualified_enums() {
|
||||
check_convert_into_to_from(
|
||||
check_assist(
|
||||
convert_into_to_from,
|
||||
r#"
|
||||
//- minicore: from
|
||||
mod things {
|
||||
pub enum Thing {
|
||||
A(String)
|
||||
@ -323,10 +337,12 @@ impl From<&things::Thing> for things::BetterThing {
|
||||
#[test]
|
||||
fn convert_into_to_from_not_applicable_on_any_trait_named_into() {
|
||||
check_assist_not_applicable(
|
||||
convert_into_to_from,
|
||||
r#"
|
||||
pub trait Into<T> {{
|
||||
//- minicore: from
|
||||
pub trait Into<T> {
|
||||
pub fn into(self) -> T;
|
||||
}}
|
||||
}
|
||||
|
||||
struct Thing {
|
||||
a: String,
|
||||
@ -342,14 +358,4 @@ impl $0Into<Thing> for String {
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
fn check_convert_into_to_from(before: &str, after: &str) {
|
||||
let before = &format!("//- /main.rs crate:main deps:core{}{}", before, FamousDefs::FIXTURE);
|
||||
check_assist(convert_into_to_from, before, after);
|
||||
}
|
||||
|
||||
fn check_assist_not_applicable(before: &str) {
|
||||
let before = &format!("//- /main.rs crate:main deps:core{}{}", before, FamousDefs::FIXTURE);
|
||||
crate::tests::check_assist_not_applicable(convert_into_to_from, before);
|
||||
}
|
||||
}
|
||||
|
@ -110,14 +110,19 @@ mod tests {
|
||||
fn test_generate_from_impl_for_enum() {
|
||||
check_assist(
|
||||
generate_from_impl_for_enum,
|
||||
"enum A { $0One(u32) }",
|
||||
r#"enum A { One(u32) }
|
||||
r#"
|
||||
//- minicore: from
|
||||
enum A { $0One(u32) }
|
||||
"#,
|
||||
r#"
|
||||
enum A { One(u32) }
|
||||
|
||||
impl From<u32> for A {
|
||||
fn from(v: u32) -> Self {
|
||||
Self::One(v)
|
||||
}
|
||||
}"#,
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
@ -125,53 +130,71 @@ impl From<u32> for A {
|
||||
fn test_generate_from_impl_for_enum_complicated_path() {
|
||||
check_assist(
|
||||
generate_from_impl_for_enum,
|
||||
r#"enum A { $0One(foo::bar::baz::Boo) }"#,
|
||||
r#"enum A { One(foo::bar::baz::Boo) }
|
||||
r#"
|
||||
//- minicore: from
|
||||
enum A { $0One(foo::bar::baz::Boo) }
|
||||
"#,
|
||||
r#"
|
||||
enum A { One(foo::bar::baz::Boo) }
|
||||
|
||||
impl From<foo::bar::baz::Boo> for A {
|
||||
fn from(v: foo::bar::baz::Boo) -> Self {
|
||||
Self::One(v)
|
||||
}
|
||||
}"#,
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
fn check_not_applicable(ra_fixture: &str) {
|
||||
let fixture =
|
||||
format!("//- /main.rs crate:main deps:core\n{}\n{}", ra_fixture, FamousDefs::FIXTURE);
|
||||
check_assist_not_applicable(generate_from_impl_for_enum, &fixture)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_from_impl_no_element() {
|
||||
check_not_applicable("enum A { $0One }");
|
||||
check_assist_not_applicable(
|
||||
generate_from_impl_for_enum,
|
||||
r#"
|
||||
//- minicore: from
|
||||
enum A { $0One }
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_from_impl_more_than_one_element_in_tuple() {
|
||||
check_not_applicable("enum A { $0One(u32, String) }");
|
||||
check_assist_not_applicable(
|
||||
generate_from_impl_for_enum,
|
||||
r#"
|
||||
//- minicore: from
|
||||
enum A { $0One(u32, String) }
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_from_impl_struct_variant() {
|
||||
check_assist(
|
||||
generate_from_impl_for_enum,
|
||||
"enum A { $0One { x: u32 } }",
|
||||
r#"enum A { One { x: u32 } }
|
||||
r#"
|
||||
//- minicore: from
|
||||
enum A { $0One { x: u32 } }
|
||||
"#,
|
||||
r#"
|
||||
enum A { One { x: u32 } }
|
||||
|
||||
impl From<u32> for A {
|
||||
fn from(x: u32) -> Self {
|
||||
Self::One { x }
|
||||
}
|
||||
}"#,
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_from_impl_already_exists() {
|
||||
cov_mark::check!(test_add_from_impl_already_exists);
|
||||
check_not_applicable(
|
||||
check_assist_not_applicable(
|
||||
generate_from_impl_for_enum,
|
||||
r#"
|
||||
//- minicore: from
|
||||
enum A { $0One(u32), }
|
||||
|
||||
impl From<u32> for A {
|
||||
@ -187,7 +210,9 @@ impl From<u32> for A {
|
||||
fn test_add_from_impl_different_variant_impl_exists() {
|
||||
check_assist(
|
||||
generate_from_impl_for_enum,
|
||||
r#"enum A { $0One(u32), Two(String), }
|
||||
r#"
|
||||
//- minicore: from
|
||||
enum A { $0One(u32), Two(String), }
|
||||
|
||||
impl From<String> for A {
|
||||
fn from(v: String) -> Self {
|
||||
@ -197,8 +222,10 @@ impl From<String> for A {
|
||||
|
||||
pub trait From<T> {
|
||||
fn from(T) -> Self;
|
||||
}"#,
|
||||
r#"enum A { One(u32), Two(String), }
|
||||
}
|
||||
"#,
|
||||
r#"
|
||||
enum A { One(u32), Two(String), }
|
||||
|
||||
impl From<u32> for A {
|
||||
fn from(v: u32) -> Self {
|
||||
@ -214,7 +241,8 @@ impl From<String> for A {
|
||||
|
||||
pub trait From<T> {
|
||||
fn from(T) -> Self;
|
||||
}"#,
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
@ -222,14 +250,19 @@ pub trait From<T> {
|
||||
fn test_add_from_impl_static_str() {
|
||||
check_assist(
|
||||
generate_from_impl_for_enum,
|
||||
"enum A { $0One(&'static str) }",
|
||||
r#"enum A { One(&'static str) }
|
||||
r#"
|
||||
//- minicore: from
|
||||
enum A { $0One(&'static str) }
|
||||
"#,
|
||||
r#"
|
||||
enum A { One(&'static str) }
|
||||
|
||||
impl From<&'static str> for A {
|
||||
fn from(v: &'static str) -> Self {
|
||||
Self::One(v)
|
||||
}
|
||||
}"#,
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
@ -237,14 +270,19 @@ impl From<&'static str> for A {
|
||||
fn test_add_from_impl_generic_enum() {
|
||||
check_assist(
|
||||
generate_from_impl_for_enum,
|
||||
"enum Generic<T, U: Clone> { $0One(T), Two(U) }",
|
||||
r#"enum Generic<T, U: Clone> { One(T), Two(U) }
|
||||
r#"
|
||||
//- minicore: from
|
||||
enum Generic<T, U: Clone> { $0One(T), Two(U) }
|
||||
"#,
|
||||
r#"
|
||||
enum Generic<T, U: Clone> { One(T), Two(U) }
|
||||
|
||||
impl<T, U: Clone> From<T> for Generic<T, U> {
|
||||
fn from(v: T) -> Self {
|
||||
Self::One(v)
|
||||
}
|
||||
}"#,
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
@ -252,14 +290,19 @@ impl<T, U: Clone> From<T> for Generic<T, U> {
|
||||
fn test_add_from_impl_with_lifetime() {
|
||||
check_assist(
|
||||
generate_from_impl_for_enum,
|
||||
"enum Generic<'a> { $0One(&'a i32) }",
|
||||
r#"enum Generic<'a> { One(&'a i32) }
|
||||
r#"
|
||||
//- minicore: from
|
||||
enum Generic<'a> { $0One(&'a i32) }
|
||||
"#,
|
||||
r#"
|
||||
enum Generic<'a> { One(&'a i32) }
|
||||
|
||||
impl<'a> From<&'a i32> for Generic<'a> {
|
||||
fn from(v: &'a i32) -> Self {
|
||||
Self::One(v)
|
||||
}
|
||||
}"#,
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -10,23 +10,6 @@ pub mod cmp {
|
||||
}
|
||||
}
|
||||
|
||||
pub mod convert {
|
||||
pub trait From<T> {
|
||||
fn from(t: T) -> Self;
|
||||
}
|
||||
|
||||
pub trait Into<T> {
|
||||
pub fn into(self) -> T;
|
||||
}
|
||||
}
|
||||
|
||||
pub mod option {
|
||||
pub enum Option<T> {
|
||||
None,
|
||||
Some(T),
|
||||
}
|
||||
}
|
||||
|
||||
pub mod prelude {
|
||||
pub mod rust_2018 {
|
||||
pub use crate::{
|
||||
|
@ -23,6 +23,7 @@
|
||||
//! iterator: option
|
||||
//! iterators: iterator
|
||||
//! default: sized
|
||||
//! from: sized
|
||||
|
||||
pub mod marker {
|
||||
// region:sized
|
||||
@ -46,6 +47,32 @@ pub mod default {
|
||||
}
|
||||
// endregion:default
|
||||
|
||||
// region:from
|
||||
pub mod convert {
|
||||
pub trait From<T>: Sized {
|
||||
fn from(_: T) -> Self;
|
||||
}
|
||||
pub trait Into<T>: Sized {
|
||||
fn into(self) -> T;
|
||||
}
|
||||
|
||||
impl<T, U> Into<U> for T
|
||||
where
|
||||
U: From<T>,
|
||||
{
|
||||
fn into(self) -> U {
|
||||
U::from(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<T> for T {
|
||||
fn from(t: T) -> T {
|
||||
t
|
||||
}
|
||||
}
|
||||
}
|
||||
// endregion:from
|
||||
|
||||
pub mod ops {
|
||||
// region:coerce_unsized
|
||||
mod unsize {
|
||||
@ -324,6 +351,7 @@ pub mod prelude {
|
||||
ops::{Fn, FnMut, FnOnce}, // :fn
|
||||
option::Option::{self, None, Some}, // :option
|
||||
result::Result::{self, Err, Ok}, // :result
|
||||
convert::{From, Into}, // :from
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user