From 241807dbf9785748a76cb61358a68214fc24e013 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Wed, 31 Aug 2022 18:34:10 +0200 Subject: [PATCH 01/29] 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 e9034daefa8d4..4ad6aa0e04970 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 d61d69a090b33..0552330814aa4 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 d89f0f5a3cf45..3a661ddf063c8 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 102cd60295043..de151f0d92c1c 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/29] 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 9adf6381c1cbc..ee560c6193c40 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 a8c8622c1c1d8..227e2300f92a0 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/29] 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 96890ad51a6f9..9f51cdaf8b1eb 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 ee560c6193c40..4afe890c783e1 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/29] 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 4afe890c783e1..a7f1cf49e3a45 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/29] 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 a7f1cf49e3a45..95aeb09437f8f 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/29] 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 b16f6fe03ae8e..1a7919a5a104d 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 95aeb09437f8f..fc24659d1f1a0 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 7e102ceba891a..20abf5636312f 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 176a3bf5803fc..788fc22c87167 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 3ce028e930659..266275972810e 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 103e3259fa2ef..4ab6e2627fa75 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 c14182279d05e..9be1d36634934 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 8efd58e2c39aa..1e4bd2ef2574f 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/29] 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 fc24659d1f1a0..353d467ed19f3 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/29] 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 20abf5636312f..2bdbec93b1f96 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 788fc22c87167..1dd376ac3fd53 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 266275972810e..dac216b69b727 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 1e4bd2ef2574f..eadebbe8a212b 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/29] 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 d52adaee535f9..c5c50d88dd28a 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 685eb4521ebda..d49bc4f99cfde 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/29] 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 f54ae6c920229..8bc093a85a21b 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 d49bc4f99cfde..4b8b47783d126 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/29] 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 38e24ebc732d4..8e26d889f9b63 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 7303ef8b7bb58..7109c6fd188f5 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/29] 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 a9c124b42dc2c..4a5533c6487e4 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 4a37a7945330c..532544fee595c 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 e67c27aa2db97..21a86319763fc 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/29] 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 f23bbca638765..e47f70fff39e0 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/29] 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 4ad6aa0e04970..d1b1d2c331a51 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/29] 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 de151f0d92c1c..e083b9d0e3378 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/29] 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 9c975b9295337..950731eb4ca8c 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/29] 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 b0cfeec2931cfb3bc9f8b11510684fb2fedee731 Mon Sep 17 00:00:00 2001 From: Luis Cardoso <61982523+LuisCardosoOliveira@users.noreply.github.com> Date: Fri, 26 Aug 2022 16:06:27 +0200 Subject: [PATCH 18/29] translations(rustc_session): migrates session.rs and config.rs --- compiler/rustc_session/src/config.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 8bb3878fbbb47..0018346c72c49 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1,6 +1,7 @@ //! Contains infrastructure for configuring the compiler, including parsing //! command-line options. +use crate::errors::TargetDataLayoutParseError; pub use crate::options::*; use crate::search_paths::SearchPath; @@ -898,7 +899,7 @@ fn default_configuration(sess: &Session) -> CrateConfig { let max_atomic_width = sess.target.max_atomic_width(); let atomic_cas = sess.target.atomic_cas; let layout = TargetDataLayout::parse(&sess.target).unwrap_or_else(|err| { - sess.emit_fatal(err); + sess.emit_fatal(TargetDataLayoutParseError { err }); }); let mut ret = CrateConfig::default(); From 54fe5b7fc223677f4525886c58b1ae9767da8231 Mon Sep 17 00:00:00 2001 From: Spencer Sharkey Date: Thu, 8 Sep 2022 22:29:08 -0700 Subject: [PATCH 19/29] 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 303a10615bb7b..785eb6fc31cd9 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 329d5014b6a773d819e6cd56d5930a204bed7983 Mon Sep 17 00:00:00 2001 From: Luis Cardoso <61982523+LuisCardosoOliveira@users.noreply.github.com> Date: Thu, 1 Sep 2022 08:03:47 +0200 Subject: [PATCH 20/29] translations(rustc_session): migrate output.rs --- .../locales/en-US/session.ftl | 10 ++++ compiler/rustc_errors/Cargo.toml | 2 +- compiler/rustc_session/src/config.rs | 3 +- compiler/rustc_session/src/errors.rs | 51 ++++++++++++++++++- compiler/rustc_session/src/lib.rs | 2 + compiler/rustc_session/src/output.rs | 35 ++++--------- compiler/rustc_session/src/session.rs | 44 ++++++++++++++++ 7 files changed, 119 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/session.ftl b/compiler/rustc_error_messages/locales/en-US/session.ftl index d2a2958f62436..76cae3c81e451 100644 --- a/compiler/rustc_error_messages/locales/en-US/session.ftl +++ b/compiler/rustc_error_messages/locales/en-US/session.ftl @@ -56,3 +56,13 @@ session_target_invalid_bits_size = {$err} session_target_stack_protector_not_supported = `-Z stack-protector={$stack_protector}` is not supported for target {$target_triple} and will be ignored session_split_debuginfo_unstable_platform = `-Csplit-debuginfo={$debuginfo}` is unstable on this platform + +session_file_is_not_writeable = output file {$file} is not writeable -- check its permissions + +session_crate_name_does_not_match = `--crate-name` and `#[crate_name]` are required to match, but `{$s}` != `{$name}` + +session_crate_name_invalid = crate names cannot start with a `-`, but `{$s}` has a leading hyphen + +session_crate_name_empty = crate name must not be empty + +session_invalid_character_in_create_name = invalid character `{$character}` in crate name: `{$crate_name}` diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml index 4d207fd17fb2d..c36ca11fad6f2 100644 --- a/compiler/rustc_errors/Cargo.toml +++ b/compiler/rustc_errors/Cargo.toml @@ -13,9 +13,9 @@ rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } rustc_macros = { path = "../rustc_macros" } rustc_data_structures = { path = "../rustc_data_structures" } +rustc_target = { path = "../rustc_target" } rustc_hir = { path = "../rustc_hir" } rustc_lint_defs = { path = "../rustc_lint_defs" } -rustc_target = { path = "../rustc_target" } unicode-width = "0.1.4" atty = "0.2" termcolor = "1.0" diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 0018346c72c49..8bb3878fbbb47 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1,7 +1,6 @@ //! Contains infrastructure for configuring the compiler, including parsing //! command-line options. -use crate::errors::TargetDataLayoutParseError; pub use crate::options::*; use crate::search_paths::SearchPath; @@ -899,7 +898,7 @@ fn default_configuration(sess: &Session) -> CrateConfig { let max_atomic_width = sess.target.max_atomic_width(); let atomic_cas = sess.target.atomic_cas; let layout = TargetDataLayout::parse(&sess.target).unwrap_or_else(|err| { - sess.emit_fatal(TargetDataLayoutParseError { err }); + sess.emit_fatal(err); }); let mut ret = CrateConfig::default(); diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index 3c93cfab183d2..c6596ff249899 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -2,7 +2,7 @@ use std::num::NonZeroU32; use crate::cgu_reuse_tracker::CguReuse; use crate::{self as rustc_session, SessionDiagnostic}; -use rustc_errors::{fluent, DiagnosticBuilder, Handler, MultiSpan}; +use rustc_errors::{fluent, DiagnosticBuilder, ErrorGuaranteed, Handler, MultiSpan}; use rustc_macros::SessionDiagnostic; use rustc_span::{Span, Symbol}; use rustc_target::abi::TargetDataLayoutErrors; @@ -170,3 +170,52 @@ pub struct StackProtectorNotSupportedForTarget<'a> { pub struct SplitDebugInfoUnstablePlatform { pub debuginfo: SplitDebuginfo, } + +#[derive(SessionDiagnostic)] +#[diag(session::file_is_not_writeable)] +pub struct FileIsNotWriteable<'a> { + pub file: &'a std::path::Path, +} + +#[derive(SessionDiagnostic)] +#[diag(session::crate_name_does_not_match)] +pub struct CrateNameDoesNotMatch<'a> { + #[primary_span] + pub span: Span, + pub s: &'a str, + pub name: Symbol, +} + +#[derive(SessionDiagnostic)] +#[diag(session::crate_name_invalid)] +pub struct CrateNameInvalid<'a> { + pub s: &'a str, +} + +#[derive(SessionDiagnostic)] +#[diag(session::crate_name_empty)] +pub struct CrateNameEmpty { + #[primary_span] + pub span: Option, +} + +pub struct InvalidCharacterInCrateName<'a> { + pub span: Option, + pub character: char, + pub crate_name: &'a str, +} + +impl crate::SessionDiagnostic<'_> for InvalidCharacterInCrateName<'_> { + fn into_diagnostic( + self, + sess: &Handler, + ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { + let mut diag = sess.struct_err(fluent::session::invalid_character_in_create_name); + if let Some(sp) = self.span { + diag.set_span(sp); + } + diag.set_arg("character", self.character); + diag.set_arg("crate_name", self.crate_name); + diag + } +} diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index 02d5d33c8d5ba..b9b243f6f0840 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -9,6 +9,8 @@ #![feature(map_many_mut)] #![recursion_limit = "256"] #![allow(rustc::potential_query_instability)] +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] #[macro_use] extern crate rustc_macros; diff --git a/compiler/rustc_session/src/output.rs b/compiler/rustc_session/src/output.rs index e5e6579d75b10..2511bee46afeb 100644 --- a/compiler/rustc_session/src/output.rs +++ b/compiler/rustc_session/src/output.rs @@ -1,5 +1,9 @@ //! Related to out filenames of compilation (e.g. save analysis, binaries). use crate::config::{CrateType, Input, OutputFilenames, OutputType}; +use crate::errors::{ + CrateNameDoesNotMatch, CrateNameEmpty, CrateNameInvalid, FileIsNotWriteable, + InvalidCharacterInCrateName, +}; use crate::Session; use rustc_ast as ast; use rustc_span::symbol::sym; @@ -30,11 +34,7 @@ pub fn out_filename( /// read-only file. We should be consistent. pub fn check_file_is_writeable(file: &Path, sess: &Session) { if !is_writeable(file) { - sess.fatal(&format!( - "output file {} is not writeable -- check its \ - permissions", - file.display() - )); + sess.emit_fatal(FileIsNotWriteable { file }); } } @@ -61,11 +61,7 @@ pub fn find_crate_name(sess: &Session, attrs: &[ast::Attribute], input: &Input) if let Some(ref s) = sess.opts.crate_name { if let Some((attr, name)) = attr_crate_name { if name.as_str() != s { - let msg = format!( - "`--crate-name` and `#[crate_name]` are \ - required to match, but `{s}` != `{name}`" - ); - sess.span_err(attr.span, &msg); + sess.emit_err(CrateNameDoesNotMatch { span: attr.span, s, name }); } } return validate(s.clone(), None); @@ -77,11 +73,7 @@ pub fn find_crate_name(sess: &Session, attrs: &[ast::Attribute], input: &Input) if let Input::File(ref path) = *input { if let Some(s) = path.file_stem().and_then(|s| s.to_str()) { if s.starts_with('-') { - let msg = format!( - "crate names cannot start with a `-`, but \ - `{s}` has a leading hyphen" - ); - sess.err(&msg); + sess.emit_err(CrateNameInvalid { s }); } else { return validate(s.replace('-', "_"), None); } @@ -94,15 +86,9 @@ pub fn find_crate_name(sess: &Session, attrs: &[ast::Attribute], input: &Input) pub fn validate_crate_name(sess: &Session, s: &str, sp: Option) { let mut err_count = 0; { - let mut say = |s: &str| { - match sp { - Some(sp) => sess.span_err(sp, s), - None => sess.err(s), - }; - err_count += 1; - }; if s.is_empty() { - say("crate name must not be empty"); + err_count += 1; + sess.emit_err(CrateNameEmpty { span: sp }); } for c in s.chars() { if c.is_alphanumeric() { @@ -111,7 +97,8 @@ pub fn validate_crate_name(sess: &Session, s: &str, sp: Option) { if c == '_' { continue; } - say(&format!("invalid character `{c}` in crate name: `{s}`")); + err_count += 1; + sess.emit_err(InvalidCharacterInCrateName { span: sp, character: c, crate_name: s }); } } diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index caf9d582ab099..b1b4101af9e64 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -297,6 +297,8 @@ impl Session { } #[rustc_lint_diagnostics] + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] pub fn struct_span_warn>( &self, sp: S, @@ -305,6 +307,8 @@ impl Session { self.diagnostic().struct_span_warn(sp, msg) } #[rustc_lint_diagnostics] + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] pub fn struct_span_warn_with_expectation>( &self, sp: S, @@ -314,6 +318,8 @@ impl Session { self.diagnostic().struct_span_warn_with_expectation(sp, msg, id) } #[rustc_lint_diagnostics] + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] pub fn struct_span_warn_with_code>( &self, sp: S, @@ -323,10 +329,14 @@ impl Session { self.diagnostic().struct_span_warn_with_code(sp, msg, code) } #[rustc_lint_diagnostics] + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] pub fn struct_warn(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { self.diagnostic().struct_warn(msg) } #[rustc_lint_diagnostics] + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] pub fn struct_warn_with_expectation( &self, msg: impl Into, @@ -335,6 +345,8 @@ impl Session { self.diagnostic().struct_warn_with_expectation(msg, id) } #[rustc_lint_diagnostics] + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] pub fn struct_span_allow>( &self, sp: S, @@ -343,10 +355,14 @@ impl Session { self.diagnostic().struct_span_allow(sp, msg) } #[rustc_lint_diagnostics] + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] pub fn struct_allow(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { self.diagnostic().struct_allow(msg) } #[rustc_lint_diagnostics] + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] pub fn struct_expect( &self, msg: impl Into, @@ -355,6 +371,8 @@ impl Session { self.diagnostic().struct_expect(msg, id) } #[rustc_lint_diagnostics] + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] pub fn struct_span_err>( &self, sp: S, @@ -363,6 +381,8 @@ impl Session { self.diagnostic().struct_span_err(sp, msg) } #[rustc_lint_diagnostics] + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] pub fn struct_span_err_with_code>( &self, sp: S, @@ -373,6 +393,8 @@ impl Session { } // FIXME: This method should be removed (every error should have an associated error code). #[rustc_lint_diagnostics] + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] pub fn struct_err( &self, msg: impl Into, @@ -380,6 +402,8 @@ impl Session { self.parse_sess.struct_err(msg) } #[rustc_lint_diagnostics] + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] pub fn struct_err_with_code( &self, msg: impl Into, @@ -388,6 +412,8 @@ impl Session { self.diagnostic().struct_err_with_code(msg, code) } #[rustc_lint_diagnostics] + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] pub fn struct_warn_with_code( &self, msg: impl Into, @@ -396,6 +422,8 @@ impl Session { self.diagnostic().struct_warn_with_code(msg, code) } #[rustc_lint_diagnostics] + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] pub fn struct_span_fatal>( &self, sp: S, @@ -404,6 +432,8 @@ impl Session { self.diagnostic().struct_span_fatal(sp, msg) } #[rustc_lint_diagnostics] + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] pub fn struct_span_fatal_with_code>( &self, sp: S, @@ -413,15 +443,21 @@ impl Session { self.diagnostic().struct_span_fatal_with_code(sp, msg, code) } #[rustc_lint_diagnostics] + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] pub fn struct_fatal(&self, msg: impl Into) -> DiagnosticBuilder<'_, !> { self.diagnostic().struct_fatal(msg) } #[rustc_lint_diagnostics] + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] pub fn span_fatal>(&self, sp: S, msg: impl Into) -> ! { self.diagnostic().span_fatal(sp, msg) } #[rustc_lint_diagnostics] + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] pub fn span_fatal_with_code>( &self, sp: S, @@ -431,10 +467,14 @@ impl Session { self.diagnostic().span_fatal_with_code(sp, msg, code) } #[rustc_lint_diagnostics] + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] pub fn fatal(&self, msg: impl Into) -> ! { self.diagnostic().fatal(msg).raise() } #[rustc_lint_diagnostics] + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] pub fn span_err_or_warn>( &self, is_warning: bool, @@ -448,6 +488,8 @@ impl Session { } } #[rustc_lint_diagnostics] + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] pub fn span_err>( &self, sp: S, @@ -456,6 +498,8 @@ impl Session { self.diagnostic().span_err(sp, msg) } #[rustc_lint_diagnostics] + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] pub fn span_err_with_code>( &self, sp: S, From b843b8801d5cfe0a17e6d7fcc43f4fd98c613596 Mon Sep 17 00:00:00 2001 From: Spencer Date: Sat, 10 Sep 2022 18:10:56 -0700 Subject: [PATCH 21/29] 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 785eb6fc31cd9..312ea066ff3c1 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 22/29] 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 312ea066ff3c1..216a302846021 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 23/29] 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 216a302846021..e71b692e7f88b 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 24/29] 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 e71b692e7f88b..f4d472e3d5c1d 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 From c4559ebfde5d6cae587d4f099d758c1d7c74998f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 12 Sep 2022 21:18:59 +0200 Subject: [PATCH 25/29] Improve Attribute doc methods --- compiler/rustc_ast/src/attr/mod.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 6b0dac7c2f0b8..686a0d6a5c9d3 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -233,7 +233,8 @@ impl AttrItem { impl Attribute { /// Returns `true` if it is a sugared doc comment (`///` or `//!` for example). - /// So `#[doc = "doc"]` will return `false`. + /// So `#[doc = "doc"]` (which is a doc comment) and `#[doc(...)]` (which is not + /// a doc comment) will return `false`. pub fn is_doc_comment(&self) -> bool { match self.kind { AttrKind::Normal(..) => false, @@ -241,6 +242,11 @@ impl Attribute { } } + /// Returns the documentation and its kind if this is a doc comment or a sugared doc comment. + /// * `///doc` returns `Some(("doc", CommentKind::Line))`. + /// * `/** doc */` returns `Some(("doc", CommentKind::Block))`. + /// * `#[doc = "doc"]` returns `Some(("doc", CommentKind::Line))`. + /// * `#[doc(...)]` returns `None`. pub fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> { match self.kind { AttrKind::DocComment(kind, data) => Some((data, kind)), @@ -253,6 +259,10 @@ impl Attribute { } } + /// Returns the documentation if this is a doc comment or a sugared doc comment. + /// * `///doc` returns `Some("doc")`. + /// * `#[doc = "doc"]` returns `Some("doc")`. + /// * `#[doc(...)]` returns `None`. pub fn doc_str(&self) -> Option { match self.kind { AttrKind::DocComment(.., data) => Some(data), From b96322801e7ea1fa92a07bb06ba42b72d689bd90 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Mon, 12 Sep 2022 14:04:11 -0700 Subject: [PATCH 26/29] rustdoc: remove no-op CSS `.search-results .result-name > span` The rule `display: inline-block` was added in 5afa52bc7dee683f25f437dddf338dbc6ad32eb8. The `margin: 0` and `font-weight: normal` were added in c01bd560e2f87a9a960ed071213edd70f73171a8. Both seem to have been added to override class-based rules that were targetted at method sections. See for an example. The selectors that these were meant to override were changed in a8318e420d19c364b1eec33956a86164941f6df4 and 76a3b609d0b93c5d8da5e4e3db37bd03e5cb1c30 to be more specific, so they no longer need to be overridden. --- src/librustdoc/html/static/css/rustdoc.css | 6 ------ src/test/rustdoc-gui/search-result-display.goml | 3 +++ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 72e04decbe3e0..d159b48e37fce 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -987,12 +987,6 @@ so that we can apply CSS-filters to change the arrow color in themes */ padding-right: 1em; } -.search-results .result-name > span { - display: inline-block; - margin: 0; - font-weight: normal; -} - .popover { font-size: 1rem; position: absolute; diff --git a/src/test/rustdoc-gui/search-result-display.goml b/src/test/rustdoc-gui/search-result-display.goml index 54482005fa601..efbbfb925bd3b 100644 --- a/src/test/rustdoc-gui/search-result-display.goml +++ b/src/test/rustdoc-gui/search-result-display.goml @@ -13,6 +13,9 @@ size: (600, 100) // when computed it's larger. assert-css: (".search-results div.desc", {"width": "566px"}) +// The result set is all on one line. +assert-css: (".search-results .result-name > span", {"display": "inline"}) + // Check that the crate filter `