From 241807dbf9785748a76cb61358a68214fc24e013 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Wed, 31 Aug 2022 18:34:10 +0200 Subject: [PATCH 01/22] Allow multi-part inlay hint labels with location links --- crates/ide/src/inlay_hints.rs | 162 ++++++++++++++++++++++----- crates/ide/src/lib.rs | 4 +- crates/rust-analyzer/src/handlers.rs | 2 +- crates/rust-analyzer/src/to_proto.rs | 57 +++++++--- 4 files changed, 179 insertions(+), 46 deletions(-) diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index e9034daefa8d..4ad6aa0e0497 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs @@ -1,3 +1,5 @@ +use std::fmt; + use either::Either; use hir::{known, Callable, HasVisibility, HirDisplay, Mutability, Semantics, TypeInfo}; use ide_db::{ @@ -69,7 +71,7 @@ pub enum InlayKind { pub struct InlayHint { pub range: TextRange, pub kind: InlayKind, - pub label: String, + pub label: InlayHintLabel, pub tooltip: Option, } @@ -80,6 +82,78 @@ pub enum InlayTooltip { HoverOffset(FileId, TextSize), } +pub struct InlayHintLabel { + pub parts: Vec, +} + +impl InlayHintLabel { + pub fn as_simple_str(&self) -> Option<&str> { + match &*self.parts { + [part] => part.as_simple_str(), + _ => None, + } + } + + pub fn prepend_str(&mut self, s: &str) { + match &mut *self.parts { + [part, ..] if part.as_simple_str().is_some() => part.text = format!("{s}{}", part.text), + _ => self.parts.insert(0, InlayHintLabelPart { text: s.into(), linked_location: None }), + } + } + + pub fn append_str(&mut self, s: &str) { + match &mut *self.parts { + [.., part] if part.as_simple_str().is_some() => part.text.push_str(s), + _ => self.parts.push(InlayHintLabelPart { text: s.into(), linked_location: None }), + } + } +} + +impl From for InlayHintLabel { + fn from(s: String) -> Self { + Self { parts: vec![InlayHintLabelPart { text: s, linked_location: None }] } + } +} + +impl fmt::Display for InlayHintLabel { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.parts.iter().map(|part| &part.text).format("")) + } +} + +impl fmt::Debug for InlayHintLabel { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_list().entries(&self.parts).finish() + } +} + +pub struct InlayHintLabelPart { + pub text: String, + pub linked_location: Option, +} + +impl InlayHintLabelPart { + pub fn as_simple_str(&self) -> Option<&str> { + match self { + Self { text, linked_location: None } => Some(text), + _ => None, + } + } +} + +impl fmt::Debug for InlayHintLabelPart { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.as_simple_str() { + Some(string) => string.fmt(f), + None => f + .debug_struct("InlayHintLabelPart") + .field("text", &self.text) + .field("linked_location", &self.linked_location) + .finish(), + } + } +} + // Feature: Inlay Hints // // rust-analyzer shows additional information inline with the source code. @@ -281,7 +355,7 @@ fn closing_brace_hints( acc.push(InlayHint { range: closing_token.text_range(), kind: InlayKind::ClosingBraceHint, - label, + label: label.into(), tooltip: name_offset.map(|it| InlayTooltip::HoverOffset(file_id, it)), }); @@ -311,7 +385,7 @@ fn implicit_static_hints( acc.push(InlayHint { range: t.text_range(), kind: InlayKind::LifetimeHint, - label: "'static".to_owned(), + label: "'static".to_owned().into(), tooltip: Some(InlayTooltip::String("Elided static lifetime".into())), }); } @@ -329,10 +403,10 @@ fn fn_lifetime_fn_hints( return None; } - let mk_lt_hint = |t: SyntaxToken, label| InlayHint { + let mk_lt_hint = |t: SyntaxToken, label: String| InlayHint { range: t.text_range(), kind: InlayKind::LifetimeHint, - label, + label: label.into(), tooltip: Some(InlayTooltip::String("Elided lifetime".into())), }; @@ -486,7 +560,8 @@ fn fn_lifetime_fn_hints( "{}{}", allocated_lifetimes.iter().format(", "), if is_empty { "" } else { ", " } - ), + ) + .into(), tooltip: Some(InlayTooltip::String("Elided lifetimes".into())), }); } @@ -535,7 +610,8 @@ fn closure_ret_hints( range: param_list.syntax().text_range(), kind: InlayKind::ClosureReturnTypeHint, label: hint_iterator(sema, &famous_defs, config, &ty) - .unwrap_or_else(|| ty.display_truncated(sema.db, config.max_length).to_string()), + .unwrap_or_else(|| ty.display_truncated(sema.db, config.max_length).to_string()) + .into(), tooltip: Some(InlayTooltip::HoverRanged(file_id, param_list.syntax().text_range())), }); Some(()) @@ -562,7 +638,7 @@ fn reborrow_hints( acc.push(InlayHint { range: expr.syntax().text_range(), kind: InlayKind::ImplicitReborrowHint, - label: label.to_string(), + label: label.to_string().into(), tooltip: Some(InlayTooltip::String("Compiler inserted reborrow".into())), }); Some(()) @@ -620,9 +696,9 @@ fn chaining_hints( acc.push(InlayHint { range: expr.syntax().text_range(), kind: InlayKind::ChainingHint, - label: hint_iterator(sema, &famous_defs, config, &ty).unwrap_or_else(|| { - ty.display_truncated(sema.db, config.max_length).to_string() - }), + label: hint_iterator(sema, &famous_defs, config, &ty) + .unwrap_or_else(|| ty.display_truncated(sema.db, config.max_length).to_string()) + .into(), tooltip: Some(InlayTooltip::HoverRanged(file_id, expr.syntax().text_range())), }); } @@ -674,7 +750,7 @@ fn param_name_hints( InlayHint { range, kind: InlayKind::ParameterHint, - label: param_name, + label: param_name.into(), tooltip: tooltip.map(|it| InlayTooltip::HoverOffset(it.file_id, it.range.start())), } }); @@ -705,7 +781,7 @@ fn binding_mode_hints( acc.push(InlayHint { range, kind: InlayKind::BindingModeHint, - label: r.to_string(), + label: r.to_string().into(), tooltip: Some(InlayTooltip::String("Inferred binding mode".into())), }); }); @@ -720,7 +796,7 @@ fn binding_mode_hints( acc.push(InlayHint { range, kind: InlayKind::BindingModeHint, - label: bm.to_string(), + label: bm.to_string().into(), tooltip: Some(InlayTooltip::String("Inferred binding mode".into())), }); } @@ -772,7 +848,7 @@ fn bind_pat_hints( None => pat.syntax().text_range(), }, kind: InlayKind::TypeHint, - label, + label: label.into(), tooltip: pat .name() .map(|it| it.syntax().text_range()) @@ -2223,7 +2299,9 @@ fn main() { InlayHint { range: 147..172, kind: ChainingHint, - label: "B", + label: [ + "B", + ], tooltip: Some( HoverRanged( FileId( @@ -2236,7 +2314,9 @@ fn main() { InlayHint { range: 147..154, kind: ChainingHint, - label: "A", + label: [ + "A", + ], tooltip: Some( HoverRanged( FileId( @@ -2294,7 +2374,9 @@ fn main() { InlayHint { range: 143..190, kind: ChainingHint, - label: "C", + label: [ + "C", + ], tooltip: Some( HoverRanged( FileId( @@ -2307,7 +2389,9 @@ fn main() { InlayHint { range: 143..179, kind: ChainingHint, - label: "B", + label: [ + "B", + ], tooltip: Some( HoverRanged( FileId( @@ -2350,7 +2434,9 @@ fn main() { InlayHint { range: 246..283, kind: ChainingHint, - label: "B>", + label: [ + "B>", + ], tooltip: Some( HoverRanged( FileId( @@ -2363,7 +2449,9 @@ fn main() { InlayHint { range: 246..265, kind: ChainingHint, - label: "A>", + label: [ + "A>", + ], tooltip: Some( HoverRanged( FileId( @@ -2408,7 +2496,9 @@ fn main() { InlayHint { range: 174..241, kind: ChainingHint, - label: "impl Iterator", + label: [ + "impl Iterator", + ], tooltip: Some( HoverRanged( FileId( @@ -2421,7 +2511,9 @@ fn main() { InlayHint { range: 174..224, kind: ChainingHint, - label: "impl Iterator", + label: [ + "impl Iterator", + ], tooltip: Some( HoverRanged( FileId( @@ -2434,7 +2526,9 @@ fn main() { InlayHint { range: 174..206, kind: ChainingHint, - label: "impl Iterator", + label: [ + "impl Iterator", + ], tooltip: Some( HoverRanged( FileId( @@ -2447,7 +2541,9 @@ fn main() { InlayHint { range: 174..189, kind: ChainingHint, - label: "&mut MyIter", + label: [ + "&mut MyIter", + ], tooltip: Some( HoverRanged( FileId( @@ -2489,7 +2585,9 @@ fn main() { InlayHint { range: 124..130, kind: TypeHint, - label: "Struct", + label: [ + "Struct", + ], tooltip: Some( HoverRanged( FileId( @@ -2502,7 +2600,9 @@ fn main() { InlayHint { range: 145..185, kind: ChainingHint, - label: "Struct", + label: [ + "Struct", + ], tooltip: Some( HoverRanged( FileId( @@ -2515,7 +2615,9 @@ fn main() { InlayHint { range: 145..168, kind: ChainingHint, - label: "Struct", + label: [ + "Struct", + ], tooltip: Some( HoverRanged( FileId( @@ -2528,7 +2630,9 @@ fn main() { InlayHint { range: 222..228, kind: ParameterHint, - label: "self", + label: [ + "self", + ], tooltip: Some( HoverOffset( FileId( diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index d61d69a090b3..0552330814aa 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs @@ -82,8 +82,8 @@ pub use crate::{ highlight_related::{HighlightRelatedConfig, HighlightedRange}, hover::{HoverAction, HoverConfig, HoverDocFormat, HoverGotoTypeData, HoverResult}, inlay_hints::{ - ClosureReturnTypeHints, InlayHint, InlayHintsConfig, InlayKind, InlayTooltip, - LifetimeElisionHints, ReborrowHints, + ClosureReturnTypeHints, InlayHint, InlayHintLabel, InlayHintsConfig, InlayKind, + InlayTooltip, LifetimeElisionHints, ReborrowHints, }, join_lines::JoinLinesConfig, markup::Markup, diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index d89f0f5a3cf4..3a661ddf063c 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs @@ -1362,7 +1362,7 @@ pub(crate) fn handle_inlay_hints( .map(|it| { to_proto::inlay_hint(&snap, &line_index, inlay_hints_config.render_colons, it) }) - .collect(), + .collect::>>()?, )) } diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 102cd6029504..de151f0d92c1 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs @@ -9,8 +9,9 @@ use ide::{ Annotation, AnnotationKind, Assist, AssistKind, Cancellable, CompletionItem, CompletionItemKind, CompletionRelevance, Documentation, FileId, FileRange, FileSystemEdit, Fold, FoldKind, Highlight, HlMod, HlOperator, HlPunct, HlRange, HlTag, Indel, InlayHint, - InlayKind, Markup, NavigationTarget, ReferenceCategory, RenameError, Runnable, Severity, - SignatureHelp, SourceChange, StructureNodeKind, SymbolKind, TextEdit, TextRange, TextSize, + InlayHintLabel, InlayKind, Markup, NavigationTarget, ReferenceCategory, RenameError, Runnable, + Severity, SignatureHelp, SourceChange, StructureNodeKind, SymbolKind, TextEdit, TextRange, + TextSize, }; use itertools::Itertools; use serde_json::to_value; @@ -426,9 +427,16 @@ pub(crate) fn inlay_hint( snap: &GlobalStateSnapshot, line_index: &LineIndex, render_colons: bool, - inlay_hint: InlayHint, -) -> lsp_types::InlayHint { - lsp_types::InlayHint { + mut inlay_hint: InlayHint, +) -> Result { + match inlay_hint.kind { + InlayKind::ParameterHint if render_colons => inlay_hint.label.append_str(":"), + InlayKind::TypeHint if render_colons => inlay_hint.label.prepend_str(": "), + InlayKind::ClosureReturnTypeHint => inlay_hint.label.prepend_str(" -> "), + _ => {} + } + + Ok(lsp_types::InlayHint { position: match inlay_hint.kind { // before annotated thing InlayKind::ParameterHint @@ -459,15 +467,9 @@ pub(crate) fn inlay_hint( | InlayKind::ImplicitReborrowHint | InlayKind::TypeHint | InlayKind::ClosingBraceHint => false, - InlayKind::BindingModeHint => inlay_hint.label != "&", + InlayKind::BindingModeHint => inlay_hint.label.to_string() != "&", InlayKind::ParameterHint | InlayKind::LifetimeHint => true, }), - label: lsp_types::InlayHintLabel::String(match inlay_hint.kind { - InlayKind::ParameterHint if render_colons => format!("{}:", inlay_hint.label), - InlayKind::TypeHint if render_colons => format!(": {}", inlay_hint.label), - InlayKind::ClosureReturnTypeHint => format!(" -> {}", inlay_hint.label), - _ => inlay_hint.label.clone(), - }), kind: match inlay_hint.kind { InlayKind::ParameterHint => Some(lsp_types::InlayHintKind::PARAMETER), InlayKind::ClosureReturnTypeHint | InlayKind::TypeHint | InlayKind::ChainingHint => { @@ -506,9 +508,36 @@ pub(crate) fn inlay_hint( })(), tooltip: Some(match inlay_hint.tooltip { Some(ide::InlayTooltip::String(s)) => lsp_types::InlayHintTooltip::String(s), - _ => lsp_types::InlayHintTooltip::String(inlay_hint.label), + _ => lsp_types::InlayHintTooltip::String(inlay_hint.label.to_string()), }), - } + label: inlay_hint_label(snap, inlay_hint.label)?, + }) +} + +fn inlay_hint_label( + snap: &GlobalStateSnapshot, + label: InlayHintLabel, +) -> Result { + Ok(match label.as_simple_str() { + Some(s) => lsp_types::InlayHintLabel::String(s.into()), + None => lsp_types::InlayHintLabel::LabelParts( + label + .parts + .into_iter() + .map(|part| { + Ok(lsp_types::InlayHintLabelPart { + value: part.text, + tooltip: None, + location: part + .linked_location + .map(|range| location(snap, range)) + .transpose()?, + command: None, + }) + }) + .collect::>>()?, + ), + }) } static TOKEN_RESULT_COUNTER: AtomicU32 = AtomicU32::new(1); From fcc61337a8e784d56b96d5dc2512464560b0ae58 Mon Sep 17 00:00:00 2001 From: ice1000 Date: Tue, 23 Aug 2022 04:59:41 +0000 Subject: [PATCH 02/22] Remove alias definition naively --- crates/ide-assists/src/handlers/inline_type_alias.rs | 9 ++++++--- crates/ide-assists/src/tests/generated.rs | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/crates/ide-assists/src/handlers/inline_type_alias.rs b/crates/ide-assists/src/handlers/inline_type_alias.rs index 9adf6381c1cb..ee560c6193c4 100644 --- a/crates/ide-assists/src/handlers/inline_type_alias.rs +++ b/crates/ide-assists/src/handlers/inline_type_alias.rs @@ -31,7 +31,7 @@ use crate::{ // ``` // -> // ``` -// type A = i32; +// // fn id(x: i32) -> i32 { // x // }; @@ -84,6 +84,9 @@ pub(crate) fn inline_type_alias_uses(acc: &mut Assists, ctx: &AssistContext<'_>) for (file_id, refs) in usages.into_iter() { inline_refs_for_file(file_id, refs); } + + builder.edit_file(ctx.file_id()); + builder.delete(ast_alias.syntax().text_range()); }, ) } @@ -929,7 +932,7 @@ fn foo() { } "#, r#" -type A = u32; + fn foo() { let _: u32 = 3; @@ -960,7 +963,7 @@ fn foo() { r#" //- /lib.rs mod foo; -type T = Vec; + fn f() -> Vec<&str> { vec!["hello"] } diff --git a/crates/ide-assists/src/tests/generated.rs b/crates/ide-assists/src/tests/generated.rs index a8c8622c1c1d..227e2300f92a 100644 --- a/crates/ide-assists/src/tests/generated.rs +++ b/crates/ide-assists/src/tests/generated.rs @@ -1390,7 +1390,7 @@ fn foo() { } "#####, r#####" -type A = i32; + fn id(x: i32) -> i32 { x }; From 79e5c366cda0f03cc9a087e43152f8631e61d356 Mon Sep 17 00:00:00 2001 From: ice1000 Date: Wed, 24 Aug 2022 04:50:12 +0000 Subject: [PATCH 03/22] Extract shared logic --- .../ide-assists/src/handlers/inline_call.rs | 37 ++++++++++--------- .../src/handlers/inline_type_alias.rs | 32 ++++++++++------ 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/crates/ide-assists/src/handlers/inline_call.rs b/crates/ide-assists/src/handlers/inline_call.rs index 96890ad51a6f..9f51cdaf8b1e 100644 --- a/crates/ide-assists/src/handlers/inline_call.rs +++ b/crates/ide-assists/src/handlers/inline_call.rs @@ -7,6 +7,7 @@ use ide_db::{ imports::insert_use::remove_path_if_in_use_stmt, path_transform::PathTransform, search::{FileReference, SearchScope}, + source_change::SourceChangeBuilder, syntax_helpers::{insert_whitespace_into_node::insert_ws_into, node_ext::expr_as_name_ref}, RootDatabase, }; @@ -100,18 +101,7 @@ pub(crate) fn inline_into_callers(acc: &mut Assists, ctx: &AssistContext<'_>) -> builder.edit_file(file_id); let count = refs.len(); // The collects are required as we are otherwise iterating while mutating 🙅‍♀️🙅‍♂️ - let (name_refs, name_refs_use): (Vec<_>, Vec<_>) = refs - .into_iter() - .filter_map(|file_ref| match file_ref.name { - ast::NameLike::NameRef(name_ref) => Some(name_ref), - _ => None, - }) - .partition_map(|name_ref| { - match name_ref.syntax().ancestors().find_map(ast::UseTree::cast) { - Some(use_tree) => Either::Right(builder.make_mut(use_tree)), - None => Either::Left(name_ref), - } - }); + let (name_refs, name_refs_use) = split_refs_and_uses(builder, refs, Some); let call_infos: Vec<_> = name_refs .into_iter() .filter_map(CallInfo::from_name_ref) @@ -130,11 +120,7 @@ pub(crate) fn inline_into_callers(acc: &mut Assists, ctx: &AssistContext<'_>) -> .count(); if replaced + name_refs_use.len() == count { // we replaced all usages in this file, so we can remove the imports - name_refs_use.into_iter().for_each(|use_tree| { - if let Some(path) = use_tree.path() { - remove_path_if_in_use_stmt(&path); - } - }) + name_refs_use.iter().for_each(remove_path_if_in_use_stmt); } else { remove_def = false; } @@ -153,6 +139,23 @@ pub(crate) fn inline_into_callers(acc: &mut Assists, ctx: &AssistContext<'_>) -> ) } +pub(super) fn split_refs_and_uses( + builder: &mut SourceChangeBuilder, + iter: impl IntoIterator, + mut map_ref: impl FnMut(ast::NameRef) -> Option, +) -> (Vec, Vec) { + iter.into_iter() + .filter_map(|file_ref| match file_ref.name { + ast::NameLike::NameRef(name_ref) => Some(name_ref), + _ => None, + }) + .filter_map(|name_ref| match name_ref.syntax().ancestors().find_map(ast::UseTree::cast) { + Some(use_tree) => builder.make_mut(use_tree).path().map(Either::Right), + None => map_ref(name_ref).map(Either::Left), + }) + .partition_map(|either| either) +} + // Assist: inline_call // // Inlines a function or method body creating a `let` statement per parameter unless the parameter diff --git a/crates/ide-assists/src/handlers/inline_type_alias.rs b/crates/ide-assists/src/handlers/inline_type_alias.rs index ee560c6193c4..4afe890c783e 100644 --- a/crates/ide-assists/src/handlers/inline_type_alias.rs +++ b/crates/ide-assists/src/handlers/inline_type_alias.rs @@ -3,7 +3,9 @@ // - Remove unused aliases if there are no longer any users, see inline_call.rs. use hir::{HasSource, PathResolution}; -use ide_db::{defs::Definition, search::FileReference}; +use ide_db::{ + defs::Definition, imports::insert_use::remove_path_if_in_use_stmt, search::FileReference, +}; use itertools::Itertools; use std::collections::HashMap; use syntax::{ @@ -16,6 +18,8 @@ use crate::{ AssistId, AssistKind, }; +use super::inline_call::split_refs_and_uses; + // Assist: inline_type_alias_uses // // Inline a type alias into all of its uses where possible. @@ -31,7 +35,7 @@ use crate::{ // ``` // -> // ``` -// +// // fn id(x: i32) -> i32 { // x // }; @@ -62,15 +66,10 @@ pub(crate) fn inline_type_alias_uses(acc: &mut Assists, ctx: &AssistContext<'_>) let mut inline_refs_for_file = |file_id, refs: Vec| { builder.edit_file(file_id); - let path_types: Vec = refs - .into_iter() - .filter_map(|file_ref| match file_ref.name { - ast::NameLike::NameRef(path_type) => { - path_type.syntax().ancestors().nth(3).and_then(ast::PathType::cast) - } - _ => None, - }) - .collect(); + let (path_types, path_type_uses) = + split_refs_and_uses(builder, refs, |path_type| { + path_type.syntax().ancestors().nth(3).and_then(ast::PathType::cast) + }); for (target, replacement) in path_types.into_iter().filter_map(|path_type| { let replacement = inline(&ast_alias, &path_type)?.to_text(&concrete_type); @@ -79,6 +78,10 @@ pub(crate) fn inline_type_alias_uses(acc: &mut Assists, ctx: &AssistContext<'_>) }) { builder.replace(target, replacement); } + if !path_type_uses.is_empty() { + builder.edit_file(file_id); + path_type_uses.iter().for_each(remove_path_if_in_use_stmt); + } }; for (file_id, refs) in usages.into_iter() { @@ -993,7 +996,12 @@ fn foo() { } "#, r#" -use super::I; +//- /lib.rs +mod foo; + + +//- /foo.rs + fn foo() { let _: i32 = 0; } From 277df02ff562e152baac5cba93844d7499d806b5 Mon Sep 17 00:00:00 2001 From: ice1000 Date: Wed, 24 Aug 2022 05:49:59 +0000 Subject: [PATCH 04/22] This should work, but I got mysterious errors --- crates/ide-assists/src/handlers/inline_type_alias.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/crates/ide-assists/src/handlers/inline_type_alias.rs b/crates/ide-assists/src/handlers/inline_type_alias.rs index 4afe890c783e..a7f1cf49e3a4 100644 --- a/crates/ide-assists/src/handlers/inline_type_alias.rs +++ b/crates/ide-assists/src/handlers/inline_type_alias.rs @@ -71,6 +71,7 @@ pub(crate) fn inline_type_alias_uses(acc: &mut Assists, ctx: &AssistContext<'_>) path_type.syntax().ancestors().nth(3).and_then(ast::PathType::cast) }); + path_type_uses.iter().for_each(remove_path_if_in_use_stmt); for (target, replacement) in path_types.into_iter().filter_map(|path_type| { let replacement = inline(&ast_alias, &path_type)?.to_text(&concrete_type); let target = path_type.syntax().text_range(); @@ -78,10 +79,6 @@ pub(crate) fn inline_type_alias_uses(acc: &mut Assists, ctx: &AssistContext<'_>) }) { builder.replace(target, replacement); } - if !path_type_uses.is_empty() { - builder.edit_file(file_id); - path_type_uses.iter().for_each(remove_path_if_in_use_stmt); - } }; for (file_id, refs) in usages.into_iter() { @@ -1001,7 +998,6 @@ mod foo; //- /foo.rs - fn foo() { let _: i32 = 0; } From 37e20decadb4aecbae3b88502d4c130c9d9f31f4 Mon Sep 17 00:00:00 2001 From: ice1000 Date: Mon, 29 Aug 2022 20:27:53 +0000 Subject: [PATCH 05/22] Address comments --- crates/ide-assists/src/handlers/inline_type_alias.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/crates/ide-assists/src/handlers/inline_type_alias.rs b/crates/ide-assists/src/handlers/inline_type_alias.rs index a7f1cf49e3a4..95aeb09437f8 100644 --- a/crates/ide-assists/src/handlers/inline_type_alias.rs +++ b/crates/ide-assists/src/handlers/inline_type_alias.rs @@ -62,6 +62,7 @@ pub(crate) fn inline_type_alias_uses(acc: &mut Assists, ctx: &AssistContext<'_>) name.syntax().text_range(), |builder| { let usages = usages.all(); + let mut definition_deleted = false; let mut inline_refs_for_file = |file_id, refs: Vec| { builder.edit_file(file_id); @@ -79,14 +80,19 @@ pub(crate) fn inline_type_alias_uses(acc: &mut Assists, ctx: &AssistContext<'_>) }) { builder.replace(target, replacement); } + + if file_id == ctx.file_id() { + builder.delete(ast_alias.syntax().text_range()); + definition_deleted = true; + } }; for (file_id, refs) in usages.into_iter() { inline_refs_for_file(file_id, refs); } - - builder.edit_file(ctx.file_id()); - builder.delete(ast_alias.syntax().text_range()); + if !definition_deleted { + builder.delete(ast_alias.syntax().text_range()); + } }, ) } From a695e900f6722088f1385ae5f174c8643cb54fdb Mon Sep 17 00:00:00 2001 From: ice1000 Date: Fri, 2 Sep 2022 05:06:51 +0000 Subject: [PATCH 06/22] Create `trait Removable`, replace `ted` APIs with builder APIs --- .../src/handlers/add_missing_match_arms.rs | 1 + .../src/handlers/inline_type_alias.rs | 8 +++-- .../ide-assists/src/handlers/merge_imports.rs | 4 +-- .../ide-assists/src/handlers/move_bounds.rs | 2 +- .../ide-assists/src/handlers/unmerge_use.rs | 2 +- crates/ide-assists/src/utils.rs | 2 +- crates/ide-db/src/imports/insert_use.rs | 31 ++++++++++++------- crates/syntax/src/ast/edit_in_place.rs | 22 ++++++++----- 8 files changed, 45 insertions(+), 27 deletions(-) diff --git a/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/crates/ide-assists/src/handlers/add_missing_match_arms.rs index b16f6fe03ae8..1a7919a5a104 100644 --- a/crates/ide-assists/src/handlers/add_missing_match_arms.rs +++ b/crates/ide-assists/src/handlers/add_missing_match_arms.rs @@ -5,6 +5,7 @@ use hir::{Adt, Crate, HasAttrs, HasSource, ModuleDef, Semantics}; use ide_db::RootDatabase; use ide_db::{famous_defs::FamousDefs, helpers::mod_path_to_ast}; use itertools::Itertools; +use syntax::ast::edit_in_place::Removable; use syntax::ast::{self, make, AstNode, HasName, MatchArmList, MatchExpr, Pat}; use crate::{ diff --git a/crates/ide-assists/src/handlers/inline_type_alias.rs b/crates/ide-assists/src/handlers/inline_type_alias.rs index 95aeb09437f8..fc24659d1f1a 100644 --- a/crates/ide-assists/src/handlers/inline_type_alias.rs +++ b/crates/ide-assists/src/handlers/inline_type_alias.rs @@ -4,7 +4,8 @@ use hir::{HasSource, PathResolution}; use ide_db::{ - defs::Definition, imports::insert_use::remove_path_if_in_use_stmt, search::FileReference, + defs::Definition, imports::insert_use::ast_to_remove_for_path_in_use_stmt, + search::FileReference, }; use itertools::Itertools; use std::collections::HashMap; @@ -72,7 +73,10 @@ pub(crate) fn inline_type_alias_uses(acc: &mut Assists, ctx: &AssistContext<'_>) path_type.syntax().ancestors().nth(3).and_then(ast::PathType::cast) }); - path_type_uses.iter().for_each(remove_path_if_in_use_stmt); + path_type_uses + .iter() + .flat_map(ast_to_remove_for_path_in_use_stmt) + .for_each(|x| builder.delete(x.syntax().text_range())); for (target, replacement) in path_types.into_iter().filter_map(|path_type| { let replacement = inline(&ast_alias, &path_type)?.to_text(&concrete_type); let target = path_type.syntax().text_range(); diff --git a/crates/ide-assists/src/handlers/merge_imports.rs b/crates/ide-assists/src/handlers/merge_imports.rs index 7e102ceba891..20abf5636312 100644 --- a/crates/ide-assists/src/handlers/merge_imports.rs +++ b/crates/ide-assists/src/handlers/merge_imports.rs @@ -1,6 +1,6 @@ use either::Either; use ide_db::imports::merge_imports::{try_merge_imports, try_merge_trees, MergeBehavior}; -use syntax::{algo::neighbor, ast, match_ast, ted, AstNode, SyntaxElement, SyntaxNode}; +use syntax::{algo::neighbor, ast::{self, edit_in_place::Removable}, match_ast, ted, AstNode, SyntaxElement, SyntaxNode}; use crate::{ assist_context::{AssistContext, Assists}, @@ -76,7 +76,7 @@ pub(crate) fn merge_imports(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio .collect(); for edit in edits_mut { match edit { - Remove(it) => it.as_ref().either(ast::Use::remove, ast::UseTree::remove), + Remove(it) => it.as_ref().either(Removable::remove, Removable::remove), Replace(old, new) => ted::replace(old, new), } } diff --git a/crates/ide-assists/src/handlers/move_bounds.rs b/crates/ide-assists/src/handlers/move_bounds.rs index 176a3bf5803f..788fc22c8716 100644 --- a/crates/ide-assists/src/handlers/move_bounds.rs +++ b/crates/ide-assists/src/handlers/move_bounds.rs @@ -1,5 +1,5 @@ use syntax::{ - ast::{self, edit_in_place::GenericParamsOwnerEdit, make, AstNode, HasName, HasTypeBounds}, + ast::{self, edit_in_place::{GenericParamsOwnerEdit, Removable}, make, AstNode, HasName, HasTypeBounds}, match_ast, }; diff --git a/crates/ide-assists/src/handlers/unmerge_use.rs b/crates/ide-assists/src/handlers/unmerge_use.rs index 3ce028e93065..266275972810 100644 --- a/crates/ide-assists/src/handlers/unmerge_use.rs +++ b/crates/ide-assists/src/handlers/unmerge_use.rs @@ -1,5 +1,5 @@ use syntax::{ - ast::{self, make, HasVisibility}, + ast::{self, make, HasVisibility, edit_in_place::Removable}, ted::{self, Position}, AstNode, SyntaxKind, }; diff --git a/crates/ide-assists/src/utils.rs b/crates/ide-assists/src/utils.rs index 103e3259fa2e..4ab6e2627fa7 100644 --- a/crates/ide-assists/src/utils.rs +++ b/crates/ide-assists/src/utils.rs @@ -12,7 +12,7 @@ use syntax::{ ast::{ self, edit::{self, AstNodeEdit}, - edit_in_place::AttrsOwnerEdit, + edit_in_place::{AttrsOwnerEdit, Removable}, make, HasArgList, HasAttrs, HasGenericParams, HasName, HasTypeBounds, Whitespace, }, ted, AstNode, AstToken, Direction, SmolStr, SourceFile, diff --git a/crates/ide-db/src/imports/insert_use.rs b/crates/ide-db/src/imports/insert_use.rs index c14182279d05..9be1d3663493 100644 --- a/crates/ide-db/src/imports/insert_use.rs +++ b/crates/ide-db/src/imports/insert_use.rs @@ -7,7 +7,10 @@ use std::cmp::Ordering; use hir::Semantics; use syntax::{ algo, - ast::{self, make, AstNode, HasAttrs, HasModuleItem, HasVisibility, PathSegmentKind}, + ast::{ + self, edit_in_place::Removable, make, AstNode, HasAttrs, HasModuleItem, HasVisibility, + PathSegmentKind, + }, ted, Direction, NodeOrToken, SyntaxKind, SyntaxNode, }; @@ -192,20 +195,24 @@ pub fn insert_use(scope: &ImportScope, path: ast::Path, cfg: &InsertUseConfig) { insert_use_(scope, &path, cfg.group, use_item); } -pub fn remove_path_if_in_use_stmt(path: &ast::Path) { +pub fn ast_to_remove_for_path_in_use_stmt(path: &ast::Path) -> Option> { // FIXME: improve this if path.parent_path().is_some() { - return; + return None; } - if let Some(use_tree) = path.syntax().parent().and_then(ast::UseTree::cast) { - if use_tree.use_tree_list().is_some() || use_tree.star_token().is_some() { - return; - } - if let Some(use_) = use_tree.syntax().parent().and_then(ast::Use::cast) { - use_.remove(); - return; - } - use_tree.remove(); + let use_tree = path.syntax().parent().and_then(ast::UseTree::cast)?; + if use_tree.use_tree_list().is_some() || use_tree.star_token().is_some() { + return None; + } + if let Some(use_) = use_tree.syntax().parent().and_then(ast::Use::cast) { + return Some(Box::new(use_)); + } + Some(Box::new(use_tree)) +} + +pub fn remove_path_if_in_use_stmt(path: &ast::Path) { + if let Some(node) = ast_to_remove_for_path_in_use_stmt(path) { + node.remove(); } } diff --git a/crates/syntax/src/ast/edit_in_place.rs b/crates/syntax/src/ast/edit_in_place.rs index 8efd58e2c39a..1e4bd2ef2574 100644 --- a/crates/syntax/src/ast/edit_in_place.rs +++ b/crates/syntax/src/ast/edit_in_place.rs @@ -248,8 +248,12 @@ impl ast::WhereClause { } } -impl ast::TypeBoundList { - pub fn remove(&self) { +pub trait Removable : AstNode { + fn remove(&self); +} + +impl Removable for ast::TypeBoundList { + fn remove(&self) { match self.syntax().siblings_with_tokens(Direction::Prev).find(|it| it.kind() == T![:]) { Some(colon) => ted::remove_all(colon..=self.syntax().clone().into()), None => ted::remove(self.syntax()), @@ -267,8 +271,8 @@ impl ast::PathSegment { } } -impl ast::UseTree { - pub fn remove(&self) { +impl Removable for ast::UseTree { + fn remove(&self) { for dir in [Direction::Next, Direction::Prev] { if let Some(next_use_tree) = neighbor(self, dir) { let separators = self @@ -282,7 +286,9 @@ impl ast::UseTree { } ted::remove(self.syntax()); } +} +impl ast::UseTree { pub fn get_or_create_use_tree_list(&self) -> ast::UseTreeList { match self.use_tree_list() { Some(it) => it, @@ -373,8 +379,8 @@ impl ast::UseTreeList { } } -impl ast::Use { - pub fn remove(&self) { +impl Removable for ast::Use { + fn remove(&self) { let next_ws = self .syntax() .next_sibling_or_token() @@ -444,8 +450,8 @@ impl ast::Fn { } } -impl ast::MatchArm { - pub fn remove(&self) { +impl Removable for ast::MatchArm { + fn remove(&self) { if let Some(sibling) = self.syntax().prev_sibling_or_token() { if sibling.kind() == SyntaxKind::WHITESPACE { ted::remove(sibling); From 68eabf1bf1f95afe2a0d4459dd8b7c748b6a54cc Mon Sep 17 00:00:00 2001 From: ice1000 Date: Fri, 2 Sep 2022 05:13:02 +0000 Subject: [PATCH 07/22] Fix test --- crates/ide-assists/src/handlers/inline_type_alias.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/ide-assists/src/handlers/inline_type_alias.rs b/crates/ide-assists/src/handlers/inline_type_alias.rs index fc24659d1f1a..353d467ed19f 100644 --- a/crates/ide-assists/src/handlers/inline_type_alias.rs +++ b/crates/ide-assists/src/handlers/inline_type_alias.rs @@ -95,6 +95,7 @@ pub(crate) fn inline_type_alias_uses(acc: &mut Assists, ctx: &AssistContext<'_>) inline_refs_for_file(file_id, refs); } if !definition_deleted { + builder.edit_file(ctx.file_id()); builder.delete(ast_alias.syntax().text_range()); } }, @@ -979,7 +980,7 @@ fn f() -> Vec<&str> { } //- /foo.rs -use super::T; + fn foo() { let _: Vec = Vec::new(); } @@ -1008,6 +1009,7 @@ mod foo; //- /foo.rs + fn foo() { let _: i32 = 0; } From 364d9c49103865c0f1f02c035f9da5c6377eaab7 Mon Sep 17 00:00:00 2001 From: ice1000 Date: Fri, 2 Sep 2022 05:13:33 +0000 Subject: [PATCH 08/22] Fmt --- crates/ide-assists/src/handlers/merge_imports.rs | 6 +++++- crates/ide-assists/src/handlers/move_bounds.rs | 6 +++++- crates/ide-assists/src/handlers/unmerge_use.rs | 2 +- crates/syntax/src/ast/edit_in_place.rs | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/crates/ide-assists/src/handlers/merge_imports.rs b/crates/ide-assists/src/handlers/merge_imports.rs index 20abf5636312..2bdbec93b1f9 100644 --- a/crates/ide-assists/src/handlers/merge_imports.rs +++ b/crates/ide-assists/src/handlers/merge_imports.rs @@ -1,6 +1,10 @@ use either::Either; use ide_db::imports::merge_imports::{try_merge_imports, try_merge_trees, MergeBehavior}; -use syntax::{algo::neighbor, ast::{self, edit_in_place::Removable}, match_ast, ted, AstNode, SyntaxElement, SyntaxNode}; +use syntax::{ + algo::neighbor, + ast::{self, edit_in_place::Removable}, + match_ast, ted, AstNode, SyntaxElement, SyntaxNode, +}; use crate::{ assist_context::{AssistContext, Assists}, diff --git a/crates/ide-assists/src/handlers/move_bounds.rs b/crates/ide-assists/src/handlers/move_bounds.rs index 788fc22c8716..1dd376ac3fd5 100644 --- a/crates/ide-assists/src/handlers/move_bounds.rs +++ b/crates/ide-assists/src/handlers/move_bounds.rs @@ -1,5 +1,9 @@ use syntax::{ - ast::{self, edit_in_place::{GenericParamsOwnerEdit, Removable}, make, AstNode, HasName, HasTypeBounds}, + ast::{ + self, + edit_in_place::{GenericParamsOwnerEdit, Removable}, + make, AstNode, HasName, HasTypeBounds, + }, match_ast, }; diff --git a/crates/ide-assists/src/handlers/unmerge_use.rs b/crates/ide-assists/src/handlers/unmerge_use.rs index 266275972810..dac216b69b72 100644 --- a/crates/ide-assists/src/handlers/unmerge_use.rs +++ b/crates/ide-assists/src/handlers/unmerge_use.rs @@ -1,5 +1,5 @@ use syntax::{ - ast::{self, make, HasVisibility, edit_in_place::Removable}, + ast::{self, edit_in_place::Removable, make, HasVisibility}, ted::{self, Position}, AstNode, SyntaxKind, }; diff --git a/crates/syntax/src/ast/edit_in_place.rs b/crates/syntax/src/ast/edit_in_place.rs index 1e4bd2ef2574..eadebbe8a212 100644 --- a/crates/syntax/src/ast/edit_in_place.rs +++ b/crates/syntax/src/ast/edit_in_place.rs @@ -248,7 +248,7 @@ impl ast::WhereClause { } } -pub trait Removable : AstNode { +pub trait Removable: AstNode { fn remove(&self); } From e295f0c29cc41be34fee364fe1fcf1a1b0bbd31a Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Sun, 4 Sep 2022 13:26:00 +0000 Subject: [PATCH 09/22] Insert whitespaces into static & const bodies if they are expanded from macro on hover Macro expansion erases whitespace information, and so we end with invalid Rust code. --- crates/ide/src/hover/render.rs | 21 ++++++++++-- crates/ide/src/hover/tests.rs | 59 ++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/crates/ide/src/hover/render.rs b/crates/ide/src/hover/render.rs index d52adaee535f..c5c50d88dd28 100644 --- a/crates/ide/src/hover/render.rs +++ b/crates/ide/src/hover/render.rs @@ -2,12 +2,13 @@ use std::fmt::Display; use either::Either; -use hir::{AsAssocItem, AttributeTemplate, HasAttrs, HirDisplay, Semantics, TypeInfo}; +use hir::{AsAssocItem, AttributeTemplate, HasAttrs, HasSource, HirDisplay, Semantics, TypeInfo}; use ide_db::{ base_db::SourceDatabase, defs::Definition, famous_defs::FamousDefs, generated::lints::{CLIPPY_LINTS, DEFAULT_LINTS, FEATURES}, + syntax_helpers::insert_whitespace_into_node, RootDatabase, }; use itertools::Itertools; @@ -350,10 +351,24 @@ pub(super) fn definition( let body = it.eval(db); match body { Ok(x) => Some(format!("{}", x)), - Err(_) => it.value(db).map(|x| format!("{}", x)), + Err(_) => { + let source = it.source(db)?; + let mut body = source.value.body()?.syntax().clone(); + if source.file_id.is_macro() { + body = insert_whitespace_into_node::insert_ws_into(body); + } + Some(body.to_string()) + } + } + }), + Definition::Static(it) => label_value_and_docs(db, it, |it| { + let source = it.source(db)?; + let mut body = source.value.body()?.syntax().clone(); + if source.file_id.is_macro() { + body = insert_whitespace_into_node::insert_ws_into(body); } + Some(body.to_string()) }), - Definition::Static(it) => label_value_and_docs(db, it, |it| it.value(db)), Definition::Trait(it) => label_and_docs(db, it), Definition::TypeAlias(it) => label_and_docs(db, it), Definition::BuiltinType(it) => { diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs index 685eb4521ebd..d49bc4f99cfd 100644 --- a/crates/ide/src/hover/tests.rs +++ b/crates/ide/src/hover/tests.rs @@ -5113,3 +5113,62 @@ fn f() { "#]], ); } + +#[test] +fn static_const_macro_expanded_body() { + check( + r#" +macro_rules! m { + () => { + pub const V: i8 = { + let e = 123; + f(e) // Prevent const eval from evaluating this constant, we want to print the body's code. + }; + }; +} +m!(); +fn main() { $0V; } +"#, + expect![[r#" + *V* + + ```rust + test + ``` + + ```rust + pub const V: i8 = { + let e = 123; + f(e) + } + ``` + "#]], + ); + check( + r#" +macro_rules! m { + () => { + pub static V: i8 = { + let e = 123; + }; + }; +} +m!(); +fn main() { $0V; } +"#, + expect![[r#" + *V* + + ```rust + test + ``` + + ```rust + pub static V: i8 = { + let e = 123; + + } + ``` + "#]], + ); +} From 26b5f1f92fa50215a2b70fb5211c300d56f290f2 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Sun, 4 Sep 2022 14:24:16 +0000 Subject: [PATCH 10/22] Do not insert a newline after `;` if the next token is a `}` This creates double newline. --- .../ide-db/src/syntax_helpers/insert_whitespace_into_node.rs | 2 +- crates/ide/src/hover/tests.rs | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/crates/ide-db/src/syntax_helpers/insert_whitespace_into_node.rs b/crates/ide-db/src/syntax_helpers/insert_whitespace_into_node.rs index f54ae6c92022..8bc093a85a21 100644 --- a/crates/ide-db/src/syntax_helpers/insert_whitespace_into_node.rs +++ b/crates/ide-db/src/syntax_helpers/insert_whitespace_into_node.rs @@ -95,7 +95,7 @@ pub fn insert_ws_into(syn: SyntaxNode) -> SyntaxNode { AS_KW | DYN_KW | IMPL_KW | CONST_KW => { mods.push(do_ws(after, tok)); } - T![;] => { + T![;] if is_next(|it| it != R_CURLY, true) => { if indent > 0 { mods.push(do_indent(after, tok, indent)); } diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs index d49bc4f99cfd..4b8b47783d12 100644 --- a/crates/ide/src/hover/tests.rs +++ b/crates/ide/src/hover/tests.rs @@ -5135,7 +5135,7 @@ fn main() { $0V; } ```rust test ``` - + ```rust pub const V: i8 = { let e = 123; @@ -5162,11 +5162,10 @@ fn main() { $0V; } ```rust test ``` - + ```rust pub static V: i8 = { let e = 123; - } ``` "#]], From 748567cba574e0b15359f11f74b649927d313d05 Mon Sep 17 00:00:00 2001 From: austaras Date: Sat, 3 Sep 2022 00:58:24 +0800 Subject: [PATCH 11/22] complete full struct in enum varaint --- crates/ide-completion/src/tests/expression.rs | 39 +++++++++++++++++++ crates/ide-db/src/active_parameter.rs | 8 ++-- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/crates/ide-completion/src/tests/expression.rs b/crates/ide-completion/src/tests/expression.rs index 38e24ebc732d..8e26d889f9b6 100644 --- a/crates/ide-completion/src/tests/expression.rs +++ b/crates/ide-completion/src/tests/expression.rs @@ -671,6 +671,45 @@ fn main() { ); } +#[test] +fn varaiant_with_struct() { + check_empty( + r#" +pub struct YoloVariant { + pub f: usize +} + +pub enum HH { + Yolo(YoloVariant), +} + +fn brr() { + let t = HH::Yolo(Y$0); +} +"#, + expect![[r#" + en HH + fn brr() fn() + st YoloVariant + st YoloVariant {…} YoloVariant { f: usize } + bt u32 + kw crate:: + kw false + kw for + kw if + kw if let + kw loop + kw match + kw return + kw self:: + kw true + kw unsafe + kw while + kw while let + "#]], + ); +} + #[test] fn return_unit_block() { cov_mark::check!(return_unit_block); diff --git a/crates/ide-db/src/active_parameter.rs b/crates/ide-db/src/active_parameter.rs index 7303ef8b7bb5..7109c6fd188f 100644 --- a/crates/ide-db/src/active_parameter.rs +++ b/crates/ide-db/src/active_parameter.rs @@ -12,7 +12,7 @@ use crate::RootDatabase; #[derive(Debug)] pub struct ActiveParameter { pub ty: Type, - pub pat: Either, + pub pat: Option>, } impl ActiveParameter { @@ -27,12 +27,12 @@ impl ActiveParameter { return None; } let (pat, ty) = params.swap_remove(idx); - pat.map(|pat| ActiveParameter { ty, pat }) + Some(ActiveParameter { ty, pat }) } pub fn ident(&self) -> Option { - self.pat.as_ref().right().and_then(|param| match param { - ast::Pat::IdentPat(ident) => ident.name(), + self.pat.as_ref().and_then(|param| match param { + Either::Right(ast::Pat::IdentPat(ident)) => ident.name(), _ => None, }) } From 265c75c53ffbc2c4cd13014e958af6e2f743e9bf Mon Sep 17 00:00:00 2001 From: Ryo Yoshida Date: Mon, 5 Sep 2022 18:35:50 +0900 Subject: [PATCH 12/22] fix: sort all bounds on trait object types --- crates/hir-ty/src/chalk_ext.rs | 2 + crates/hir-ty/src/lower.rs | 75 +++++++++++++++++++++---------- crates/hir-ty/src/tests/traits.rs | 28 ++++++++++++ 3 files changed, 82 insertions(+), 23 deletions(-) diff --git a/crates/hir-ty/src/chalk_ext.rs b/crates/hir-ty/src/chalk_ext.rs index a9c124b42dc2..4a5533c6487e 100644 --- a/crates/hir-ty/src/chalk_ext.rs +++ b/crates/hir-ty/src/chalk_ext.rs @@ -164,6 +164,8 @@ impl TyExt for Ty { fn dyn_trait(&self) -> Option { let trait_ref = match self.kind(Interner) { + // The principal trait bound should be the first element of the bounds. This is an + // invariant ensured by `TyLoweringContext::lower_dyn_trait()`. TyKind::Dyn(dyn_ty) => dyn_ty.bounds.skip_binders().interned().get(0).and_then(|b| { match b.skip_binders() { WhereClause::Implemented(trait_ref) => Some(trait_ref), diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs index 4a37a7945330..532544fee595 100644 --- a/crates/hir-ty/src/lower.rs +++ b/crates/hir-ty/src/lower.rs @@ -981,43 +981,72 @@ impl<'a> TyLoweringContext<'a> { fn lower_dyn_trait(&self, bounds: &[Interned]) -> Ty { let self_ty = TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner); + // INVARIANT: The principal trait bound must come first. Others may be in any order but + // should be in the same order for the same set but possibly different order of bounds in + // the input. + // This invariant is used by `TyExt::dyn_trait()` and chalk. let bounds = self.with_shifted_in(DebruijnIndex::ONE, |ctx| { - let bounds = - bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)); - - let mut auto_traits = SmallVec::<[_; 8]>::new(); - let mut regular_traits = SmallVec::<[_; 2]>::new(); - let mut other_bounds = SmallVec::<[_; 8]>::new(); - for bound in bounds { - if let Some(id) = bound.trait_id() { - if ctx.db.trait_data(from_chalk_trait_id(id)).is_auto { - auto_traits.push(bound); - } else { - regular_traits.push(bound); + let mut bounds: Vec<_> = bounds + .iter() + .flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)) + .collect(); + + let mut multiple_regular_traits = false; + let mut multiple_same_projection = false; + bounds.sort_unstable_by(|lhs, rhs| { + use std::cmp::Ordering; + match (lhs.skip_binders(), rhs.skip_binders()) { + (WhereClause::Implemented(lhs), WhereClause::Implemented(rhs)) => { + let lhs_id = lhs.trait_id; + let lhs_is_auto = ctx.db.trait_data(from_chalk_trait_id(lhs_id)).is_auto; + let rhs_id = rhs.trait_id; + let rhs_is_auto = ctx.db.trait_data(from_chalk_trait_id(rhs_id)).is_auto; + + if !lhs_is_auto && !rhs_is_auto { + multiple_regular_traits = true; + } + // Note that the ordering here is important; this ensures the invariant + // mentioned above. + (lhs_is_auto, lhs_id).cmp(&(rhs_is_auto, rhs_id)) } - } else { - other_bounds.push(bound); + (WhereClause::Implemented(_), _) => Ordering::Less, + (_, WhereClause::Implemented(_)) => Ordering::Greater, + (WhereClause::AliasEq(lhs), WhereClause::AliasEq(rhs)) => { + match (&lhs.alias, &rhs.alias) { + (AliasTy::Projection(lhs_proj), AliasTy::Projection(rhs_proj)) => { + // We only compare the `associated_ty_id`s. We shouldn't have + // multiple bounds for an associated type in the correct Rust code, + // and if we do, we error out. + if lhs_proj.associated_ty_id == rhs_proj.associated_ty_id { + multiple_same_projection = true; + } + lhs_proj.associated_ty_id.cmp(&rhs_proj.associated_ty_id) + } + // We don't produce `AliasTy::Opaque`s yet. + _ => unreachable!(), + } + } + // We don't produce `WhereClause::{TypeOutlives, LifetimeOutlives}` yet. + _ => unreachable!(), } - } + }); - if regular_traits.len() > 1 { + if multiple_regular_traits || multiple_same_projection { return None; } - auto_traits.sort_unstable_by_key(|b| b.trait_id().unwrap()); - auto_traits.dedup(); + // As multiple occurrences of the same auto traits *are* permitted, we dedulicate the + // bounds. We shouldn't have repeated elements besides auto traits at this point. + bounds.dedup(); - Some(QuantifiedWhereClauses::from_iter( - Interner, - regular_traits.into_iter().chain(other_bounds).chain(auto_traits), - )) + Some(QuantifiedWhereClauses::from_iter(Interner, bounds)) }); if let Some(bounds) = bounds { let bounds = crate::make_single_type_binders(bounds); TyKind::Dyn(DynTy { bounds, lifetime: static_lifetime() }).intern(Interner) } else { - // FIXME: report error (additional non-auto traits) + // FIXME: report error (additional non-auto traits or associated type rebound) TyKind::Error.intern(Interner) } } diff --git a/crates/hir-ty/src/tests/traits.rs b/crates/hir-ty/src/tests/traits.rs index e67c27aa2db9..21a86319763f 100644 --- a/crates/hir-ty/src/tests/traits.rs +++ b/crates/hir-ty/src/tests/traits.rs @@ -3900,6 +3900,34 @@ fn g(t: &(dyn Sync + T + Send)) { ); } +#[test] +fn dyn_multiple_projection_bounds() { + check_no_mismatches( + r#" +trait Trait { + type T; + type U; +} + +fn f(t: &dyn Trait) {} +fn g(t: &dyn Trait) { + f(t); +} + "#, + ); + + check_types( + r#" +trait Trait { + type T; +} + +fn f(t: &dyn Trait) {} + //^&{unknown} + "#, + ); +} + #[test] fn dyn_duplicate_auto_trait() { check_no_mismatches( From 5d126a18b4cb779644bace0dfdadb31b058fb618 Mon Sep 17 00:00:00 2001 From: Joseph Ryan Date: Tue, 6 Sep 2022 18:27:17 -0700 Subject: [PATCH 13/22] Use proc-macro-srv from sysroot in rust-project.json --- crates/rust-analyzer/src/reload.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index f23bbca63876..e47f70fff39e 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs @@ -314,7 +314,9 @@ impl GlobalState { let mut args = args.clone(); let mut path = path.clone(); - if let ProjectWorkspace::Cargo { sysroot, .. } = ws { + if let ProjectWorkspace::Cargo { sysroot, .. } + | ProjectWorkspace::Json { sysroot, .. } = ws + { tracing::debug!("Found a cargo workspace..."); if let Some(sysroot) = sysroot.as_ref() { tracing::debug!("Found a cargo workspace with a sysroot..."); From 064c9ef9e27ed9c427dedd6b4a1a042cb5cdc3e7 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Wed, 31 Aug 2022 18:54:19 +0200 Subject: [PATCH 14/22] Make clicking closing brace hint go to the opening brace --- crates/ide/src/inlay_hints.rs | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index 4ad6aa0e0497..d1b1d2c331a5 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs @@ -129,6 +129,11 @@ impl fmt::Debug for InlayHintLabel { pub struct InlayHintLabelPart { pub text: String, + /// Source location represented by this label part. The client will use this to fetch the part's + /// hover tooltip, and Ctrl+Clicking the label part will navigate to the definition the location + /// refers to (not necessarily the location itself). + /// When setting this, no tooltip must be set on the containing hint, or VS Code will display + /// them both. pub linked_location: Option, } @@ -266,10 +271,10 @@ fn closing_brace_hints( ) -> Option<()> { let min_lines = config.closing_brace_hints_min_lines?; - let name = |it: ast::Name| it.syntax().text_range().start(); + let name = |it: ast::Name| it.syntax().text_range(); let mut closing_token; - let (label, name_offset) = if let Some(item_list) = ast::AssocItemList::cast(node.clone()) { + let (label, name_range) = if let Some(item_list) = ast::AssocItemList::cast(node.clone()) { closing_token = item_list.r_curly_token()?; let parent = item_list.syntax().parent()?; @@ -279,11 +284,11 @@ fn closing_brace_hints( let imp = sema.to_def(&imp)?; let ty = imp.self_ty(sema.db); let trait_ = imp.trait_(sema.db); - - (match trait_ { + let hint_text = match trait_ { Some(tr) => format!("impl {} for {}", tr.name(sema.db), ty.display_truncated(sema.db, config.max_length)), None => format!("impl {}", ty.display_truncated(sema.db, config.max_length)), - }, None) + }; + (hint_text, None) }, ast::Trait(tr) => { (format!("trait {}", tr.name()?), tr.name().map(name)) @@ -327,7 +332,7 @@ fn closing_brace_hints( ( format!("{}!", mac.path()?), - mac.path().and_then(|it| it.segment()).map(|it| it.syntax().text_range().start()), + mac.path().and_then(|it| it.segment()).map(|it| it.syntax().text_range()), ) } else { return None; @@ -352,11 +357,12 @@ fn closing_brace_hints( return None; } + let linked_location = name_range.map(|range| FileRange { file_id, range }); acc.push(InlayHint { range: closing_token.text_range(), kind: InlayKind::ClosingBraceHint, - label: label.into(), - tooltip: name_offset.map(|it| InlayTooltip::HoverOffset(file_id, it)), + label: InlayHintLabel { parts: vec![InlayHintLabelPart { text: label, linked_location }] }, + tooltip: None, // provided by label part location }); None From c4eadab016cf16bd32b90ba7ecc71361592a4f28 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Thu, 8 Sep 2022 18:33:53 +0200 Subject: [PATCH 15/22] Update crates/rust-analyzer/src/to_proto.rs Co-authored-by: Lukas Wirth --- crates/rust-analyzer/src/to_proto.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index de151f0d92c1..e083b9d0e337 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs @@ -467,7 +467,7 @@ pub(crate) fn inlay_hint( | InlayKind::ImplicitReborrowHint | InlayKind::TypeHint | InlayKind::ClosingBraceHint => false, - InlayKind::BindingModeHint => inlay_hint.label.to_string() != "&", + InlayKind::BindingModeHint => inlay_hint.label.as_simple_str() != Some("&"), InlayKind::ParameterHint | InlayKind::LifetimeHint => true, }), kind: match inlay_hint.kind { From c7fefd522347a57460058c78d0c96b78eac535f7 Mon Sep 17 00:00:00 2001 From: Peh <20146907+randomicon00@users.noreply.github.com> Date: Thu, 8 Sep 2022 22:37:31 +0100 Subject: [PATCH 16/22] fix: add semicolon completion to mod --- .../src/completions/.mod_.rs.swp | Bin 0 -> 24576 bytes crates/ide-completion/src/completions/mod_.rs | 20 ++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 crates/ide-completion/src/completions/.mod_.rs.swp diff --git a/crates/ide-completion/src/completions/.mod_.rs.swp b/crates/ide-completion/src/completions/.mod_.rs.swp new file mode 100644 index 0000000000000000000000000000000000000000..52d5cea48b2a7a54bbe6a0cd34a00d38a14829f6 GIT binary patch literal 24576 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 literal 0 HcmV?d00001 diff --git a/crates/ide-completion/src/completions/mod_.rs b/crates/ide-completion/src/completions/mod_.rs index 9c975b929533..950731eb4ca8 100644 --- a/crates/ide-completion/src/completions/mod_.rs +++ b/crates/ide-completion/src/completions/mod_.rs @@ -53,6 +53,7 @@ pub(crate) fn complete_mod( let existing_mod_declarations = current_module .children(ctx.db) .filter_map(|module| Some(module.name(ctx.db)?.to_string())) + .filter(|module| module != ctx.original_token.text()) .collect::>(); let module_declaration_file = @@ -351,4 +352,23 @@ fn ignored_bar() {} "#]], ); } + + #[test] + fn semi_colon_completion() { + check( + r#" +//- /lib.rs +mod foo; +//- /foo.rs +mod bar { + mod baz$0 +} +//- /foo/bar/baz.rs +fn baz() {} +"#, + expect![[r#" + md baz; + "#]], + ); + } } From bd3feea8bc90745fceca0a259b58e301f1d6df51 Mon Sep 17 00:00:00 2001 From: Peh <20146907+randomicon00@users.noreply.github.com> Date: Thu, 8 Sep 2022 22:44:10 +0100 Subject: [PATCH 17/22] fix: removed swap file --- .../ide-completion/src/completions/.mod_.rs.swp | Bin 24576 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 crates/ide-completion/src/completions/.mod_.rs.swp diff --git a/crates/ide-completion/src/completions/.mod_.rs.swp b/crates/ide-completion/src/completions/.mod_.rs.swp deleted file mode 100644 index 52d5cea48b2a7a54bbe6a0cd34a00d38a14829f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24576 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 From 54fe5b7fc223677f4525886c58b1ae9767da8231 Mon Sep 17 00:00:00 2001 From: Spencer Sharkey Date: Thu, 8 Sep 2022 22:29:08 -0700 Subject: [PATCH 18/22] use ubuntu 18.04 container for release --- .github/workflows/release.yaml | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 303a10615bb7..785eb6fc31cd 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -34,6 +34,7 @@ jobs: - os: ubuntu-20.04 target: x86_64-unknown-linux-gnu code-target: linux-x64 + container: ubuntu:18.04 - os: ubuntu-20.04 target: aarch64-unknown-linux-gnu code-target: linux-arm64 @@ -49,6 +50,7 @@ jobs: name: dist (${{ matrix.target }}) runs-on: ${{ matrix.os }} + container: ${{ matrix.container }} env: RA_TARGET: ${{ matrix.target }} @@ -59,11 +61,17 @@ jobs: with: fetch-depth: ${{ env.FETCH_DEPTH }} + - name: Install toolchain dependencies + if: matrix.container == 'ubuntu:18.04' + run: apt-get update && apt-get install -y build-essential curl + - name: Install Rust toolchain - run: | - rustup update --no-self-update stable - rustup target add ${{ matrix.target }} - rustup component add rust-src + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + target: ${{ matrix.target }} + components: rust-src + override: true - name: Install Node.js uses: actions/setup-node@v1 @@ -71,7 +79,7 @@ jobs: node-version: 16.x - name: Update apt repositories - if: matrix.target == 'aarch64-unknown-linux-gnu' || matrix.target == 'arm-unknown-linux-gnueabihf' + if: "!matrix.container && (matrix.target == 'aarch64-unknown-linux-gnu' || matrix.target == 'arm-unknown-linux-gnueabihf')" run: sudo apt-get update - name: Install AArch64 target toolchain From b843b8801d5cfe0a17e6d7fcc43f4fd98c613596 Mon Sep 17 00:00:00 2001 From: Spencer Date: Sat, 10 Sep 2022 18:10:56 -0700 Subject: [PATCH 19/22] revert conditional logic for apt update step --- .github/workflows/release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 785eb6fc31cd..312ea066ff3c 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -79,7 +79,7 @@ jobs: node-version: 16.x - name: Update apt repositories - if: "!matrix.container && (matrix.target == 'aarch64-unknown-linux-gnu' || matrix.target == 'arm-unknown-linux-gnueabihf')" + if: matrix.target == 'aarch64-unknown-linux-gnu' || matrix.target == 'arm-unknown-linux-gnueabihf' run: sudo apt-get update - name: Install AArch64 target toolchain From dd65588c51947111af1b62011023d7a16e9e01ca Mon Sep 17 00:00:00 2001 From: Spencer Date: Sat, 10 Sep 2022 23:25:30 -0700 Subject: [PATCH 20/22] install rustup directly --- .github/workflows/release.yaml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 312ea066ff3c..216a30284602 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -63,15 +63,16 @@ jobs: - name: Install toolchain dependencies if: matrix.container == 'ubuntu:18.04' - run: apt-get update && apt-get install -y build-essential curl + shell: bash + run: | + apt-get update && apt-get install -y build-essential curl + curl --proto '=https' --tlsv1.2 "https://sh.rustup.rs" | sh -s -- --default-toolchain none -y - name: Install Rust toolchain - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - target: ${{ matrix.target }} - components: rust-src - override: true + run: | + rustup update --no-self-update stable + rustup target add ${{ matrix.target }} + rustup component add rust-src - name: Install Node.js uses: actions/setup-node@v1 From ae57150d0d2e3171ee1954f2739956ee1621737f Mon Sep 17 00:00:00 2001 From: Spencer Date: Sat, 10 Sep 2022 23:29:15 -0700 Subject: [PATCH 21/22] add rustup bin to path --- .github/workflows/release.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 216a30284602..e71b692e7f88 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -67,6 +67,7 @@ jobs: run: | apt-get update && apt-get install -y build-essential curl curl --proto '=https' --tlsv1.2 "https://sh.rustup.rs" | sh -s -- --default-toolchain none -y + echo "${CARGO_HOME:-$HOME/.cargo}/bin" >> $GITHUB_PATH - name: Install Rust toolchain run: | From 73d759955f7f0e9a104346ac89174e15467c67bb Mon Sep 17 00:00:00 2001 From: Spencer Date: Sat, 10 Sep 2022 23:43:33 -0700 Subject: [PATCH 22/22] use rustup minimal profile and add curl retries --- .github/workflows/release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index e71b692e7f88..f4d472e3d5c1 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -66,7 +66,7 @@ jobs: shell: bash run: | apt-get update && apt-get install -y build-essential curl - curl --proto '=https' --tlsv1.2 "https://sh.rustup.rs" | sh -s -- --default-toolchain none -y + curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused -fsSL "https://sh.rustup.rs" | sh -s -- --profile minimal --default-toolchain none -y echo "${CARGO_HOME:-$HOME/.cargo}/bin" >> $GITHUB_PATH - name: Install Rust toolchain