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:
bors[bot] 2021-06-17 18:04:38 +00:00 committed by GitHub
commit 84507a0b9c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 129 additions and 69 deletions

View File

@ -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",

View File

@ -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);
}
}

View File

@ -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)
}
}"#,
}
"#,
);
}
}

View File

@ -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::{

View File

@ -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
};
}