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 e9034daefa8..4ad6aa0e049 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 d61d69a090b..0552330814a 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 d89f0f5a3cf..3a661ddf063 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 102cd602950..de151f0d92c 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 9adf6381c1c..ee560c6193c 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 a8c8622c1c1..227e2300f92 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 96890ad51a6..9f51cdaf8b1 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 ee560c6193c..4afe890c783 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 4afe890c783..a7f1cf49e3a 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 a7f1cf49e3a..95aeb09437f 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 b16f6fe03ae..1a7919a5a10 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 95aeb09437f..fc24659d1f1 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 7e102ceba89..20abf563631 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 176a3bf5803..788fc22c871 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 3ce028e9306..26627597281 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 103e3259fa2..4ab6e2627fa 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 c14182279d0..9be1d366349 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 8efd58e2c39..1e4bd2ef257 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 fc24659d1f1..353d467ed19 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 20abf563631..2bdbec93b1f 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 788fc22c871..1dd376ac3fd 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 26627597281..dac216b69b7 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 1e4bd2ef257..eadebbe8a21 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 d52adaee535..c5c50d88dd2 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| it.value(db)), + 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::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 685eb4521eb..d49bc4f99cf 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 f54ae6c9202..8bc093a85a2 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 d49bc4f99cf..4b8b47783d1 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 38e24ebc732..8e26d889f9b 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 7303ef8b7bb..7109c6fd188 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 | 73 +++++++++++++++++++++---------- crates/hir-ty/src/tests/traits.rs | 28 ++++++++++++ 3 files changed, 81 insertions(+), 22 deletions(-) diff --git a/crates/hir-ty/src/chalk_ext.rs b/crates/hir-ty/src/chalk_ext.rs index a9c124b42dc..4a5533c6487 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 4a37a794533..532544fee59 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 bounds: Vec<_> = bounds + .iter() + .flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)) + .collect(); - 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 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 e67c27aa2db..21a86319763 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 f23bbca6387..e47f70fff39 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 4ad6aa0e049..d1b1d2c331a 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 de151f0d92c..e083b9d0e33 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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 C7_F`V literal 0 HcmV?d00001 diff --git a/crates/ide-completion/src/completions/mod_.rs b/crates/ide-completion/src/completions/mod_.rs index 9c975b92953..950731eb4ca 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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 C7_F`V 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 303a10615bb..785eb6fc31c 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 785eb6fc31c..312ea066ff3 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 312ea066ff3..216a3028460 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 216a3028460..e71b692e7f8 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 e71b692e7f8..f4d472e3d5c 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