]> git.lizzy.rs Git - rust.git/commitdiff
Merge #4530
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>
Wed, 20 May 2020 09:10:52 +0000 (09:10 +0000)
committerGitHub <noreply@github.com>
Wed, 20 May 2020 09:10:52 +0000 (09:10 +0000)
4530: Use snippets in change_return_type_to_result r=matklad a=matklad

bors r+
🤖

Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
crates/ra_assists/src/handlers/fill_match_arms.rs
crates/ra_assists/src/marks.rs
crates/ra_assists/src/utils.rs
editors/code/src/cargo.ts

index 13c1e7e8014b1317aeebc4992a44a4261943b784..b57ff75aedb9c3626d5fb853fc7e82704c58144a 100644 (file)
@@ -4,8 +4,9 @@
 use itertools::Itertools;
 use ra_ide_db::RootDatabase;
 use ra_syntax::ast::{self, make, AstNode, MatchArm, NameOwner, Pat};
+use test_utils::tested_by;
 
-use crate::{AssistContext, AssistId, Assists};
+use crate::{utils::FamousDefs, AssistContext, AssistId, Assists};
 
 // Assist: fill_match_arms
 //
@@ -49,12 +50,18 @@ pub(crate) fn fill_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option<
     let missing_arms: Vec<MatchArm> = if let Some(enum_def) = resolve_enum_def(&ctx.sema, &expr) {
         let variants = enum_def.variants(ctx.db);
 
-        variants
+        let mut variants = variants
             .into_iter()
             .filter_map(|variant| build_pat(ctx.db, module, variant))
             .filter(|variant_pat| is_variant_missing(&mut arms, variant_pat))
             .map(|pat| make::match_arm(iter::once(pat), make::expr_empty_block()))
-            .collect()
+            .collect::<Vec<_>>();
+        if Some(enum_def) == FamousDefs(&ctx.sema, module.krate()).core_option_Option() {
+            // Match `Some` variant first.
+            tested_by!(option_order);
+            variants.reverse()
+        }
+        variants
     } else if let Some(enum_defs) = resolve_tuple_of_enum_def(&ctx.sema, &expr) {
         // Partial fill not currently supported for tuple of enums.
         if !arms.is_empty() {
@@ -167,9 +174,13 @@ fn build_pat(db: &RootDatabase, module: hir::Module, var: hir::EnumVariant) -> O
 
 #[cfg(test)]
 mod tests {
-    use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
+    use crate::{
+        tests::{check_assist, check_assist_not_applicable, check_assist_target},
+        utils::FamousDefs,
+    };
 
     use super::fill_match_arms;
+    use test_utils::covers;
 
     #[test]
     fn all_match_arms_provided() {
@@ -736,4 +747,29 @@ fn foo(a: A) {
             "#,
         );
     }
+
+    #[test]
+    fn option_order() {
+        covers!(option_order);
+        let before = r#"
+fn foo(opt: Option<i32>) {
+    match opt<|> {
+    }
+}"#;
+        let before =
+            &format!("//- main.rs crate:main deps:core\n{}{}", before, FamousDefs::FIXTURE);
+
+        check_assist(
+            fill_match_arms,
+            before,
+            r#"
+fn foo(opt: Option<i32>) {
+    match <|>opt {
+        Some(_) => {}
+        None => {}
+    }
+}
+"#,
+        );
+    }
 }
index d579e627f0406769e414a6dbfeac3ec53e7b02ae..722f3c6a4b7b543bf816a09478c8188c754e4de0 100644 (file)
@@ -1,6 +1,7 @@
 //! See test_utils/src/marks.rs
 
 test_utils::marks![
+    option_order
     introduce_var_in_comment_is_not_applicable
     test_introduce_var_expr_stmt
     test_introduce_var_last_expr
index 9af27180bc57708ae582ece30e1540e94928231c..0038a9764b15da65f5a82c61404afd9f66c2b871 100644 (file)
@@ -3,7 +3,7 @@
 
 use std::{iter, ops};
 
-use hir::{Adt, Crate, Semantics, Trait, Type};
+use hir::{Adt, Crate, Enum, ScopeDef, Semantics, Trait, Type};
 use ra_ide_db::RootDatabase;
 use ra_syntax::{
     ast::{self, make, NameOwner},
@@ -200,13 +200,19 @@ impl FamousDefs<'_, '_> {
     #[cfg(test)]
     pub(crate) const FIXTURE: &'static str = r#"
 //- /libcore.rs crate:core
-pub mod convert{
+pub mod convert {
     pub trait From<T> {
         fn from(T) -> Self;
     }
 }
 
-pub mod prelude { pub use crate::convert::From }
+pub mod option {
+    pub enum Option<T> { None, Some(T)}
+}
+
+pub mod prelude {
+    pub use crate::{convert::From, option::Option::{self, *}};
+}
 #[prelude_import]
 pub use prelude::*;
 "#;
@@ -215,7 +221,25 @@ pub(crate) fn core_convert_From(&self) -> Option<Trait> {
         self.find_trait("core:convert:From")
     }
 
+    pub(crate) fn core_option_Option(&self) -> Option<Enum> {
+        self.find_enum("core:option:Option")
+    }
+
     fn find_trait(&self, path: &str) -> Option<Trait> {
+        match self.find_def(path)? {
+            hir::ScopeDef::ModuleDef(hir::ModuleDef::Trait(it)) => Some(it),
+            _ => None,
+        }
+    }
+
+    fn find_enum(&self, path: &str) -> Option<Enum> {
+        match self.find_def(path)? {
+            hir::ScopeDef::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Enum(it))) => Some(it),
+            _ => None,
+        }
+    }
+
+    fn find_def(&self, path: &str) -> Option<ScopeDef> {
         let db = self.0.db;
         let mut path = path.split(':');
         let trait_ = path.next_back()?;
@@ -240,9 +264,6 @@ fn find_trait(&self, path: &str) -> Option<Trait> {
         }
         let def =
             module.scope(db, None).into_iter().find(|(name, _def)| &name.to_string() == trait_)?.1;
-        match def {
-            hir::ScopeDef::ModuleDef(hir::ModuleDef::Trait(it)) => Some(it),
-            _ => None,
-        }
+        Some(def)
     }
 }
index 28c7de992b4dd4cf335e7daa4690f5b26fc67f40..6a41873d0067b5438472a7c9ae140582be946983 100644 (file)
@@ -51,10 +51,14 @@ export class Cargo {
 
         // arguments for a runnable from the quick pick should be updated.
         // see crates\rust-analyzer\src\main_loop\handlers.rs, handle_code_lens
-        if (cargoArgs[0] === "run") {
-            cargoArgs[0] = "build";
-        } else if (cargoArgs.indexOf("--no-run") === -1) {
-            cargoArgs.push("--no-run");
+        switch (cargoArgs[0]) {
+            case "run": cargoArgs[0] = "build"; break;
+            case "test": {
+                if (cargoArgs.indexOf("--no-run") === -1) {
+                    cargoArgs.push("--no-run");
+                }
+                break;
+            }
         }
 
         let artifacts = await this.artifactsFromArgs(cargoArgs);