From 8cb139090f969c9e8f8eecf9ffe3cd89624526d5 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 28 Apr 2020 22:45:46 +0200 Subject: Complete union fields after dot --- crates/ra_ide/src/completion/complete_dot.rs | 38 ++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'crates/ra_ide/src') diff --git a/crates/ra_ide/src/completion/complete_dot.rs b/crates/ra_ide/src/completion/complete_dot.rs index 814354ffa..05f825c6f 100644 --- a/crates/ra_ide/src/completion/complete_dot.rs +++ b/crates/ra_ide/src/completion/complete_dot.rs @@ -249,6 +249,44 @@ mod tests { ); } + #[test] + fn test_union_field_completion() { + assert_debug_snapshot!( + do_ref_completion( + r" + union Un { + field: u8, + other: u16, + } + + fn foo(u: Un) { + u.<|> + } + ", + ), + @r###" + [ + CompletionItem { + label: "field", + source_range: 140..140, + delete: 140..140, + insert: "field", + kind: Field, + detail: "u8", + }, + CompletionItem { + label: "other", + source_range: 140..140, + delete: 140..140, + insert: "other", + kind: Field, + detail: "u16", + }, + ] + "### + ); + } + #[test] fn test_method_completion() { assert_debug_snapshot!( -- cgit v1.2.3 From 041aea2263aed03431f5e8d110c0423911e2496b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 29 Apr 2020 11:26:21 +0200 Subject: Better filtering of qualified enum variants in completion --- .../src/completion/complete_unqualified_path.rs | 12 +++++- crates/ra_ide/src/completion/presentation.rs | 46 ++++++++++++++++++---- 2 files changed, 49 insertions(+), 9 deletions(-) (limited to 'crates/ra_ide/src') diff --git a/crates/ra_ide/src/completion/complete_unqualified_path.rs b/crates/ra_ide/src/completion/complete_unqualified_path.rs index f559f2b97..a6a5568de 100644 --- a/crates/ra_ide/src/completion/complete_unqualified_path.rs +++ b/crates/ra_ide/src/completion/complete_unqualified_path.rs @@ -53,7 +53,7 @@ fn complete_enum_variants(acc: &mut Completions, ctx: &CompletionContext, ty: &T // Variants with trivial paths are already added by the existing completion logic, // so we should avoid adding these twice if path.segments.len() > 1 { - acc.add_enum_variant(ctx, variant, Some(path.to_string())); + acc.add_qualified_enum_variant(ctx, variant, path); } } } @@ -1173,6 +1173,7 @@ mod tests { delete: 248..250, insert: "Foo::Bar", kind: EnumVariant, + lookup: "Bar", detail: "()", }, CompletionItem { @@ -1181,6 +1182,7 @@ mod tests { delete: 248..250, insert: "Foo::Baz", kind: EnumVariant, + lookup: "Baz", detail: "()", }, CompletionItem { @@ -1189,6 +1191,7 @@ mod tests { delete: 248..250, insert: "Foo::Quux", kind: EnumVariant, + lookup: "Quux", detail: "()", }, ] @@ -1231,6 +1234,7 @@ mod tests { delete: 219..221, insert: "Foo::Bar", kind: EnumVariant, + lookup: "Bar", detail: "()", }, CompletionItem { @@ -1239,6 +1243,7 @@ mod tests { delete: 219..221, insert: "Foo::Baz", kind: EnumVariant, + lookup: "Baz", detail: "()", }, CompletionItem { @@ -1247,6 +1252,7 @@ mod tests { delete: 219..221, insert: "Foo::Quux", kind: EnumVariant, + lookup: "Quux", detail: "()", }, ] @@ -1285,6 +1291,7 @@ mod tests { delete: 185..186, insert: "Foo::Bar", kind: EnumVariant, + lookup: "Bar", detail: "()", }, CompletionItem { @@ -1293,6 +1300,7 @@ mod tests { delete: 185..186, insert: "Foo::Baz", kind: EnumVariant, + lookup: "Baz", detail: "()", }, CompletionItem { @@ -1301,6 +1309,7 @@ mod tests { delete: 185..186, insert: "Foo::Quux", kind: EnumVariant, + lookup: "Quux", detail: "()", }, CompletionItem { @@ -1353,6 +1362,7 @@ mod tests { delete: 98..99, insert: "m::E::V", kind: EnumVariant, + lookup: "V", detail: "()", }, ] diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs index 77d354376..2edb130cf 100644 --- a/crates/ra_ide/src/completion/presentation.rs +++ b/crates/ra_ide/src/completion/presentation.rs @@ -1,6 +1,6 @@ //! This modules takes care of rendering various definitions as completion items. -use hir::{Docs, HasAttrs, HasSource, HirDisplay, ScopeDef, StructKind, Type}; +use hir::{Docs, HasAttrs, HasSource, HirDisplay, ModPath, ScopeDef, StructKind, Type}; use ra_syntax::ast::NameOwner; use stdx::SepBy; use test_utils::tested_by; @@ -246,14 +246,37 @@ impl Completions { .add_to(self); } + pub(crate) fn add_qualified_enum_variant( + &mut self, + ctx: &CompletionContext, + variant: hir::EnumVariant, + path: ModPath, + ) { + self.add_enum_variant_impl(ctx, variant, None, Some(path)) + } + pub(crate) fn add_enum_variant( &mut self, ctx: &CompletionContext, variant: hir::EnumVariant, local_name: Option, + ) { + self.add_enum_variant_impl(ctx, variant, local_name, None) + } + + fn add_enum_variant_impl( + &mut self, + ctx: &CompletionContext, + variant: hir::EnumVariant, + local_name: Option, + path: Option, ) { let is_deprecated = is_deprecated(variant, ctx.db); let name = local_name.unwrap_or_else(|| variant.name(ctx.db).to_string()); + let qualified_name = match &path { + Some(it) => it.to_string(), + None => name.to_string(), + }; let detail_types = variant .fields(ctx.db) .into_iter() @@ -271,16 +294,23 @@ impl Completions { .surround_with("{ ", " }") .to_string(), }; - let mut res = - CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.clone()) - .kind(CompletionItemKind::EnumVariant) - .set_documentation(variant.docs(ctx.db)) - .set_deprecated(is_deprecated) - .detail(detail); + let mut res = CompletionItem::new( + CompletionKind::Reference, + ctx.source_range(), + qualified_name.clone(), + ) + .kind(CompletionItemKind::EnumVariant) + .set_documentation(variant.docs(ctx.db)) + .set_deprecated(is_deprecated) + .detail(detail); + + if path.is_some() { + res = res.lookup_by(name); + } if variant_kind == StructKind::Tuple { let params = Params::Anonymous(variant.fields(ctx.db).len()); - res = res.add_call_parens(ctx, name, params) + res = res.add_call_parens(ctx, qualified_name, params) } res.add_to(self); -- cgit v1.2.3 From 414d8d9c3884cd4144b9dab7eb4a0d72b8f3a496 Mon Sep 17 00:00:00 2001 From: oxalica Date: Thu, 30 Apr 2020 00:34:46 +0800 Subject: Include function qualifiers in signature --- crates/ra_ide/src/display/function_signature.rs | 40 +++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'crates/ra_ide/src') diff --git a/crates/ra_ide/src/display/function_signature.rs b/crates/ra_ide/src/display/function_signature.rs index b5e2785fe..db3907fe6 100644 --- a/crates/ra_ide/src/display/function_signature.rs +++ b/crates/ra_ide/src/display/function_signature.rs @@ -26,6 +26,8 @@ pub struct FunctionSignature { pub kind: CallableKind, /// Optional visibility pub visibility: Option, + /// Qualifiers like `async`, `unsafe`, ... + pub qualifier: FunctionQualifier, /// Name of the function pub name: Option, /// Documentation for the function @@ -46,6 +48,16 @@ pub struct FunctionSignature { pub has_self_param: bool, } +#[derive(Debug, Default)] +pub struct FunctionQualifier { + // `async` and `const` are mutually exclusive. Do we need to enforcing it here? + pub is_async: bool, + pub is_const: bool, + pub is_unsafe: bool, + /// The string `extern ".."` + pub extern_abi: Option, +} + impl FunctionSignature { pub(crate) fn with_doc_opt(mut self, doc: Option) -> Self { self.doc = doc; @@ -83,6 +95,8 @@ impl FunctionSignature { FunctionSignature { kind: CallableKind::StructConstructor, visibility: node.visibility().map(|n| n.syntax().text().to_string()), + // Do we need `const`? + qualifier: Default::default(), name: node.name().map(|n| n.text().to_string()), ret_type: node.name().map(|n| n.text().to_string()), parameters: params, @@ -128,6 +142,8 @@ impl FunctionSignature { FunctionSignature { kind: CallableKind::VariantConstructor, visibility: None, + // Do we need `const`? + qualifier: Default::default(), name: Some(name), ret_type: None, parameters: params, @@ -151,6 +167,7 @@ impl FunctionSignature { FunctionSignature { kind: CallableKind::Macro, visibility: None, + qualifier: Default::default(), name: node.name().map(|n| n.text().to_string()), ret_type: None, parameters: params, @@ -223,6 +240,12 @@ impl From<&'_ ast::FnDef> for FunctionSignature { FunctionSignature { kind: CallableKind::Function, visibility: node.visibility().map(|n| n.syntax().text().to_string()), + qualifier: FunctionQualifier { + is_async: node.async_token().is_some(), + is_const: node.const_token().is_some(), + is_unsafe: node.unsafe_token().is_some(), + extern_abi: node.abi().map(|n| n.to_string()), + }, name: node.name().map(|n| n.text().to_string()), ret_type: node .ret_type() @@ -246,6 +269,23 @@ impl Display for FunctionSignature { write!(f, "{} ", t)?; } + if self.qualifier.is_async { + write!(f, "async ")?; + } + + if self.qualifier.is_const { + write!(f, "const ")?; + } + + if self.qualifier.is_unsafe { + write!(f, "unsafe ")?; + } + + if let Some(extern_abi) = &self.qualifier.extern_abi { + // Keyword `extern` is included in the string. + write!(f, "{} ", extern_abi)?; + } + if let Some(name) = &self.name { match self.kind { CallableKind::Function => write!(f, "fn {}", name)?, -- cgit v1.2.3 From 8c2670026a4c864a67a06bab654e203ed068f021 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 28 Apr 2020 00:40:32 +0200 Subject: Complete assoc. items on type parameters --- .../src/completion/complete_qualified_path.rs | 273 ++++++++++++++++++++- 1 file changed, 262 insertions(+), 11 deletions(-) (limited to 'crates/ra_ide/src') diff --git a/crates/ra_ide/src/completion/complete_qualified_path.rs b/crates/ra_ide/src/completion/complete_qualified_path.rs index dd10f74e6..69e789a49 100644 --- a/crates/ra_ide/src/completion/complete_qualified_path.rs +++ b/crates/ra_ide/src/completion/complete_qualified_path.rs @@ -5,19 +5,30 @@ use ra_syntax::AstNode; use test_utils::tested_by; use crate::completion::{CompletionContext, Completions}; +use rustc_hash::FxHashSet; pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext) { let path = match &ctx.path_prefix { Some(path) => path.clone(), _ => return, }; - let def = match ctx.scope().resolve_hir_path(&path) { - Some(PathResolution::Def(def)) => def, - _ => return, + let scope = ctx.scope(); + let context_module = scope.module(); + + let res = if let Some(res) = scope.resolve_hir_path(&path) { + res + } else { + return; }; - let context_module = ctx.scope().module(); - match def { - hir::ModuleDef::Module(module) => { + + // Add associated types on type parameters and `Self`. + res.assoc_type_shorthand_candidates(ctx.db, |alias| { + acc.add_type_alias(ctx, alias); + None::<()> + }); + + match res { + PathResolution::Def(hir::ModuleDef::Module(module)) => { let module_scope = module.scope(ctx.db, context_module); for (name, def) in module_scope { if ctx.use_item_syntax.is_some() { @@ -35,7 +46,8 @@ pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon acc.add_resolution(ctx, name.to_string(), &def); } } - hir::ModuleDef::Adt(_) | hir::ModuleDef::TypeAlias(_) => { + PathResolution::Def(def @ hir::ModuleDef::Adt(_)) + | PathResolution::Def(def @ hir::ModuleDef::TypeAlias(_)) => { if let hir::ModuleDef::Adt(Adt::Enum(e)) = def { for variant in e.variants(ctx.db) { acc.add_enum_variant(ctx, variant, None); @@ -46,8 +58,10 @@ pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon hir::ModuleDef::TypeAlias(a) => a.ty(ctx.db), _ => unreachable!(), }; - // Iterate assoc types separately - // FIXME: complete T::AssocType + + // XXX: For parity with Rust bug #22519, this does not complete Ty::AssocType. + // (where AssocType is defined on a trait, not an inherent impl) + let krate = ctx.krate; if let Some(krate) = krate { let traits_in_scope = ctx.scope().traits_in_scope(); @@ -65,6 +79,7 @@ pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon None::<()> }); + // Iterate assoc types separately ty.iterate_impl_items(ctx.db, krate, |item| { if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) { return None; @@ -77,7 +92,8 @@ pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon }); } } - hir::ModuleDef::Trait(t) => { + PathResolution::Def(hir::ModuleDef::Trait(t)) => { + // Handles `Trait::assoc` as well as `::assoc`. for item in t.items(ctx.db) { if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) { continue; @@ -91,8 +107,38 @@ pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon } } } + PathResolution::TypeParam(_) | PathResolution::SelfType(_) => { + if let Some(krate) = ctx.krate { + let ty = match res { + PathResolution::TypeParam(param) => param.ty(ctx.db), + PathResolution::SelfType(impl_def) => impl_def.target_ty(ctx.db), + _ => return, + }; + + let traits_in_scope = ctx.scope().traits_in_scope(); + let mut seen = FxHashSet::default(); + ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| { + if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) { + return None; + } + + // We might iterate candidates of a trait multiple times here, so deduplicate + // them. + if seen.insert(item) { + match item { + hir::AssocItem::Function(func) => { + acc.add_function(ctx, func, None); + } + hir::AssocItem::Const(ct) => acc.add_const(ctx, ct), + hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty), + } + } + None::<()> + }); + } + } _ => {} - }; + } } #[cfg(test)] @@ -843,6 +889,211 @@ mod tests { ); } + #[test] + fn completes_ty_param_assoc_ty() { + assert_debug_snapshot!( + do_reference_completion( + " + //- /lib.rs + trait Super { + type Ty; + const CONST: u8; + fn func() {} + fn method(&self) {} + } + + trait Sub: Super { + type SubTy; + const C2: (); + fn subfunc() {} + fn submethod(&self) {} + } + + fn foo() { + T::<|> + } + " + ), + @r###" + [ + CompletionItem { + label: "C2", + source_range: 219..219, + delete: 219..219, + insert: "C2", + kind: Const, + detail: "const C2: ();", + }, + CompletionItem { + label: "CONST", + source_range: 219..219, + delete: 219..219, + insert: "CONST", + kind: Const, + detail: "const CONST: u8;", + }, + CompletionItem { + label: "SubTy", + source_range: 219..219, + delete: 219..219, + insert: "SubTy", + kind: TypeAlias, + detail: "type SubTy;", + }, + CompletionItem { + label: "Ty", + source_range: 219..219, + delete: 219..219, + insert: "Ty", + kind: TypeAlias, + detail: "type Ty;", + }, + CompletionItem { + label: "func()", + source_range: 219..219, + delete: 219..219, + insert: "func()$0", + kind: Function, + lookup: "func", + detail: "fn func()", + }, + CompletionItem { + label: "method()", + source_range: 219..219, + delete: 219..219, + insert: "method()$0", + kind: Method, + lookup: "method", + detail: "fn method(&self)", + }, + CompletionItem { + label: "subfunc()", + source_range: 219..219, + delete: 219..219, + insert: "subfunc()$0", + kind: Function, + lookup: "subfunc", + detail: "fn subfunc()", + }, + CompletionItem { + label: "submethod()", + source_range: 219..219, + delete: 219..219, + insert: "submethod()$0", + kind: Method, + lookup: "submethod", + detail: "fn submethod(&self)", + }, + ] + "### + ); + } + + #[test] + fn completes_self_param_assoc_ty() { + assert_debug_snapshot!( + do_reference_completion( + " + //- /lib.rs + trait Super { + type Ty; + const CONST: u8 = 0; + fn func() {} + fn method(&self) {} + } + + trait Sub: Super { + type SubTy; + const C2: () = (); + fn subfunc() {} + fn submethod(&self) {} + } + + struct Wrap(T); + impl Super for Wrap {} + impl Sub for Wrap { + fn subfunc() { + // Should be able to assume `Self: Sub + Super` + Self::<|> + } + } + " + ), + @r###" + [ + CompletionItem { + label: "C2", + source_range: 365..365, + delete: 365..365, + insert: "C2", + kind: Const, + detail: "const C2: () = ();", + }, + CompletionItem { + label: "CONST", + source_range: 365..365, + delete: 365..365, + insert: "CONST", + kind: Const, + detail: "const CONST: u8 = 0;", + }, + CompletionItem { + label: "SubTy", + source_range: 365..365, + delete: 365..365, + insert: "SubTy", + kind: TypeAlias, + detail: "type SubTy;", + }, + CompletionItem { + label: "Ty", + source_range: 365..365, + delete: 365..365, + insert: "Ty", + kind: TypeAlias, + detail: "type Ty;", + }, + CompletionItem { + label: "func()", + source_range: 365..365, + delete: 365..365, + insert: "func()$0", + kind: Function, + lookup: "func", + detail: "fn func()", + }, + CompletionItem { + label: "method()", + source_range: 365..365, + delete: 365..365, + insert: "method()$0", + kind: Method, + lookup: "method", + detail: "fn method(&self)", + }, + CompletionItem { + label: "subfunc()", + source_range: 365..365, + delete: 365..365, + insert: "subfunc()$0", + kind: Function, + lookup: "subfunc", + detail: "fn subfunc()", + }, + CompletionItem { + label: "submethod()", + source_range: 365..365, + delete: 365..365, + insert: "submethod()$0", + kind: Method, + lookup: "submethod", + detail: "fn submethod(&self)", + }, + ] + "### + ); + } + #[test] fn completes_type_alias() { assert_debug_snapshot!( -- cgit v1.2.3 From 0cd6a88cf6f80d48669c6136f5fa814fcdafe8e2 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Thu, 30 Apr 2020 00:10:15 +0200 Subject: if let -> match --- crates/ra_ide/src/completion/complete_qualified_path.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'crates/ra_ide/src') diff --git a/crates/ra_ide/src/completion/complete_qualified_path.rs b/crates/ra_ide/src/completion/complete_qualified_path.rs index 69e789a49..aa56a5cd8 100644 --- a/crates/ra_ide/src/completion/complete_qualified_path.rs +++ b/crates/ra_ide/src/completion/complete_qualified_path.rs @@ -15,10 +15,9 @@ pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon let scope = ctx.scope(); let context_module = scope.module(); - let res = if let Some(res) = scope.resolve_hir_path(&path) { - res - } else { - return; + let res = match scope.resolve_hir_path(&path) { + Some(res) => res, + None => return, }; // Add associated types on type parameters and `Self`. -- cgit v1.2.3 From b9b342ff93ad3da659934ccb6dd3c15b6c2e9115 Mon Sep 17 00:00:00 2001 From: oxalica Date: Thu, 30 Apr 2020 12:54:12 +0800 Subject: Add tests of showing function qualifiers --- crates/ra_ide/src/hover.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'crates/ra_ide/src') diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs index 58c799eca..a62f598f0 100644 --- a/crates/ra_ide/src/hover.rs +++ b/crates/ra_ide/src/hover.rs @@ -844,4 +844,29 @@ fn func(foo: i32) { if true { <|>foo; }; } &["fn foo()\n```\n\n<- `\u{3000}` here"], ); } + + #[test] + fn test_hover_function_show_qualifiers() { + check_hover_result( + " + //- /lib.rs + async fn foo<|>() {} + ", + &["async fn foo()"], + ); + check_hover_result( + " + //- /lib.rs + pub const unsafe fn foo<|>() {} + ", + &["pub const unsafe fn foo()"], + ); + check_hover_result( + r#" + //- /lib.rs + pub(crate) async unsafe extern "C" fn foo<|>() {} + "#, + &[r#"pub(crate) async unsafe extern "C" fn foo()"#], + ); + } } -- cgit v1.2.3 From 15cfa9a808be820ceafc2e957ea8532e8ec68f00 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 30 Apr 2020 21:36:31 +0200 Subject: Fix a bunch of false-positives in join-lines --- crates/ra_ide/src/join_lines.rs | 66 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'crates/ra_ide/src') diff --git a/crates/ra_ide/src/join_lines.rs b/crates/ra_ide/src/join_lines.rs index fde0bfa98..d0def7eaa 100644 --- a/crates/ra_ide/src/join_lines.rs +++ b/crates/ra_ide/src/join_lines.rs @@ -131,6 +131,9 @@ fn has_comma_after(node: &SyntaxNode) -> bool { fn join_single_expr_block(edit: &mut TextEditBuilder, token: &SyntaxToken) -> Option<()> { let block = ast::Block::cast(token.parent())?; let block_expr = ast::BlockExpr::cast(block.syntax().parent()?)?; + if !block_expr.is_standalone() { + return None; + } let expr = extract_trivial_expression(&block_expr)?; let block_range = block_expr.syntax().text_range(); @@ -662,4 +665,67 @@ fn main() { ", ) } + + #[test] + fn join_lines_mandatory_blocks_block() { + check_join_lines( + r" +<|>fn foo() { + 92 +} + ", + r" +<|>fn foo() { 92 +} + ", + ); + + check_join_lines( + r" +fn foo() { + <|>if true { + 92 + } +} + ", + r" +fn foo() { + <|>if true { 92 + } +} + ", + ); + + check_join_lines( + r" +fn foo() { + <|>loop { + 92 + } +} + ", + r" +fn foo() { + <|>loop { 92 + } +} + ", + ); + + check_join_lines( + r" +fn foo() { + <|>unsafe { + 92 + } +} + ", + r" +fn foo() { + <|>unsafe { 92 + } +} + ", + ); + } } -- cgit v1.2.3 From 6833183ab45d5f0ad2e350d62c457eb8a4734b83 Mon Sep 17 00:00:00 2001 From: Diana <5275194+DianaNites@users.noreply.github.com> Date: Fri, 1 May 2020 11:49:41 -0400 Subject: Unsafe traits --- crates/ra_ide/src/display/short_label.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'crates/ra_ide/src') diff --git a/crates/ra_ide/src/display/short_label.rs b/crates/ra_ide/src/display/short_label.rs index 4b081bf6c..d37260e96 100644 --- a/crates/ra_ide/src/display/short_label.rs +++ b/crates/ra_ide/src/display/short_label.rs @@ -33,7 +33,11 @@ impl ShortLabel for ast::EnumDef { impl ShortLabel for ast::TraitDef { fn short_label(&self) -> Option { - short_label_from_node(self, "trait ") + if self.unsafe_token().is_some() { + short_label_from_node(self, "unsafe trait ") + } else { + short_label_from_node(self, "trait ") + } } } -- cgit v1.2.3 From ebff5762e9789ecd472564284994a9ac119b4166 Mon Sep 17 00:00:00 2001 From: Diana <5275194+DianaNites@users.noreply.github.com> Date: Fri, 1 May 2020 11:49:51 -0400 Subject: Test for unsafe trait --- crates/ra_ide/src/hover.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'crates/ra_ide/src') diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs index a62f598f0..54d318858 100644 --- a/crates/ra_ide/src/hover.rs +++ b/crates/ra_ide/src/hover.rs @@ -869,4 +869,15 @@ fn func(foo: i32) { if true { <|>foo; }; } &[r#"pub(crate) async unsafe extern "C" fn foo()"#], ); } + + #[test] + fn test_hover_trait_show_qualifiers() { + check_hover_result( + " + //- /lib.rs + unsafe trait foo<|>() {} + ", + &["unsafe trait foo"], + ); + } } -- cgit v1.2.3 From 4f2134cc33f07c09fe166cec42971828843bc0ef Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 2 May 2020 01:18:19 +0200 Subject: Introduce EffectExpr --- crates/ra_ide/src/completion/completion_context.rs | 2 +- crates/ra_ide/src/folding_ranges.rs | 2 +- crates/ra_ide/src/join_lines.rs | 3 +- crates/ra_ide/src/syntax_tree.rs | 77 ++++++++++------------ 4 files changed, 38 insertions(+), 46 deletions(-) (limited to 'crates/ra_ide/src') diff --git a/crates/ra_ide/src/completion/completion_context.rs b/crates/ra_ide/src/completion/completion_context.rs index 118fceb2e..c529752d4 100644 --- a/crates/ra_ide/src/completion/completion_context.rs +++ b/crates/ra_ide/src/completion/completion_context.rs @@ -344,7 +344,7 @@ impl<'a> CompletionContext<'a> { stmt.syntax().text_range() == name_ref.syntax().text_range(), ); } - if let Some(block) = ast::Block::cast(node) { + if let Some(block) = ast::BlockExpr::cast(node) { return Some( block.expr().map(|e| e.syntax().text_range()) == Some(name_ref.syntax().text_range()), diff --git a/crates/ra_ide/src/folding_ranges.rs b/crates/ra_ide/src/folding_ranges.rs index 4379005aa..8657377de 100644 --- a/crates/ra_ide/src/folding_ranges.rs +++ b/crates/ra_ide/src/folding_ranges.rs @@ -88,7 +88,7 @@ fn fold_kind(kind: SyntaxKind) -> Option { | ITEM_LIST | EXTERN_ITEM_LIST | USE_TREE_LIST - | BLOCK + | BLOCK_EXPR | MATCH_ARM_LIST | ENUM_VARIANT_LIST | TOKEN_TREE => Some(FoldKind::Block), diff --git a/crates/ra_ide/src/join_lines.rs b/crates/ra_ide/src/join_lines.rs index d0def7eaa..63fd6b3e4 100644 --- a/crates/ra_ide/src/join_lines.rs +++ b/crates/ra_ide/src/join_lines.rs @@ -129,8 +129,7 @@ fn has_comma_after(node: &SyntaxNode) -> bool { } fn join_single_expr_block(edit: &mut TextEditBuilder, token: &SyntaxToken) -> Option<()> { - let block = ast::Block::cast(token.parent())?; - let block_expr = ast::BlockExpr::cast(block.syntax().parent()?)?; + let block_expr = ast::BlockExpr::cast(token.parent())?; if !block_expr.is_standalone() { return None; } diff --git a/crates/ra_ide/src/syntax_tree.rs b/crates/ra_ide/src/syntax_tree.rs index bf97f8c56..86c70ff83 100644 --- a/crates/ra_ide/src/syntax_tree.rs +++ b/crates/ra_ide/src/syntax_tree.rs @@ -120,9 +120,8 @@ SOURCE_FILE@0..11 R_PAREN@7..8 ")" WHITESPACE@8..9 " " BLOCK_EXPR@9..11 - BLOCK@9..11 - L_CURLY@9..10 "{" - R_CURLY@10..11 "}" + L_CURLY@9..10 "{" + R_CURLY@10..11 "}" "# .trim() ); @@ -153,26 +152,25 @@ SOURCE_FILE@0..60 R_PAREN@8..9 ")" WHITESPACE@9..10 " " BLOCK_EXPR@10..60 - BLOCK@10..60 - L_CURLY@10..11 "{" - WHITESPACE@11..16 "\n " - EXPR_STMT@16..58 - MACRO_CALL@16..57 - PATH@16..22 - PATH_SEGMENT@16..22 - NAME_REF@16..22 - IDENT@16..22 "assert" - BANG@22..23 "!" - TOKEN_TREE@23..57 - L_PAREN@23..24 "(" - STRING@24..52 "\"\n fn foo() {\n ..." - COMMA@52..53 "," - WHITESPACE@53..54 " " - STRING@54..56 "\"\"" - R_PAREN@56..57 ")" - SEMICOLON@57..58 ";" - WHITESPACE@58..59 "\n" - R_CURLY@59..60 "}" + L_CURLY@10..11 "{" + WHITESPACE@11..16 "\n " + EXPR_STMT@16..58 + MACRO_CALL@16..57 + PATH@16..22 + PATH_SEGMENT@16..22 + NAME_REF@16..22 + IDENT@16..22 "assert" + BANG@22..23 "!" + TOKEN_TREE@23..57 + L_PAREN@23..24 "(" + STRING@24..52 "\"\n fn foo() {\n ..." + COMMA@52..53 "," + WHITESPACE@53..54 " " + STRING@54..56 "\"\"" + R_PAREN@56..57 ")" + SEMICOLON@57..58 ";" + WHITESPACE@58..59 "\n" + R_CURLY@59..60 "}" "# .trim() ); @@ -196,9 +194,8 @@ FN_DEF@0..11 R_PAREN@7..8 ")" WHITESPACE@8..9 " " BLOCK_EXPR@9..11 - BLOCK@9..11 - L_CURLY@9..10 "{" - R_CURLY@10..11 "}" + L_CURLY@9..10 "{" + R_CURLY@10..11 "}" "# .trim() ); @@ -265,10 +262,9 @@ SOURCE_FILE@0..12 R_PAREN@7..8 ")" WHITESPACE@8..9 " " BLOCK_EXPR@9..12 - BLOCK@9..12 - L_CURLY@9..10 "{" - WHITESPACE@10..11 "\n" - R_CURLY@11..12 "}" + L_CURLY@9..10 "{" + WHITESPACE@10..11 "\n" + R_CURLY@11..12 "}" "# .trim() ); @@ -300,10 +296,9 @@ SOURCE_FILE@0..12 R_PAREN@7..8 ")" WHITESPACE@8..9 " " BLOCK_EXPR@9..12 - BLOCK@9..12 - L_CURLY@9..10 "{" - WHITESPACE@10..11 "\n" - R_CURLY@11..12 "}" + L_CURLY@9..10 "{" + WHITESPACE@10..11 "\n" + R_CURLY@11..12 "}" "# .trim() ); @@ -334,10 +329,9 @@ SOURCE_FILE@0..25 R_PAREN@7..8 ")" WHITESPACE@8..9 " " BLOCK_EXPR@9..12 - BLOCK@9..12 - L_CURLY@9..10 "{" - WHITESPACE@10..11 "\n" - R_CURLY@11..12 "}" + L_CURLY@9..10 "{" + WHITESPACE@10..11 "\n" + R_CURLY@11..12 "}" WHITESPACE@12..13 "\n" FN_DEF@13..25 FN_KW@13..15 "fn" @@ -349,10 +343,9 @@ SOURCE_FILE@0..25 R_PAREN@20..21 ")" WHITESPACE@21..22 " " BLOCK_EXPR@22..25 - BLOCK@22..25 - L_CURLY@22..23 "{" - WHITESPACE@23..24 "\n" - R_CURLY@24..25 "}" + L_CURLY@22..23 "{" + WHITESPACE@23..24 "\n" + R_CURLY@24..25 "}" "# .trim() ); -- cgit v1.2.3