From c7ef6c25b7c2a41f0fef8b9de5827b7b074586bd Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 24 May 2023 18:04:29 +0200 Subject: [PATCH] internal: Replace Display impl for `Name` --- crates/hir-def/src/body/pretty.rs | 50 +++++--- crates/hir-def/src/builtin_type.rs | 10 +- crates/hir-def/src/hir/type_ref.rs | 24 ++-- crates/hir-def/src/import_map.rs | 89 ++++++++++---- crates/hir-def/src/item_scope.rs | 10 +- crates/hir-def/src/item_tree.rs | 4 +- crates/hir-def/src/item_tree/pretty.rs | 74 ++++++----- crates/hir-def/src/item_tree/tests.rs | 2 +- crates/hir-def/src/nameres.rs | 18 ++- crates/hir-def/src/nameres/collector.rs | 14 ++- crates/hir-def/src/nameres/mod_resolution.rs | 18 ++- crates/hir-def/src/nameres/path_resolution.rs | 11 +- crates/hir-def/src/nameres/tests/macros.rs | 17 ++- crates/hir-def/src/pretty.rs | 77 +++++++----- crates/hir-expand/src/mod_path.rs | 102 +++++++++------ crates/hir-expand/src/name.rs | 60 +++++---- crates/hir-ty/src/chalk_db.rs | 16 ++- crates/hir-ty/src/consteval/tests.rs | 2 +- crates/hir-ty/src/db.rs | 16 ++- crates/hir-ty/src/diagnostics/decl_check.rs | 39 +++--- crates/hir-ty/src/diagnostics/match_check.rs | 20 ++- crates/hir-ty/src/display.rs | 92 +++++++++----- crates/hir-ty/src/infer/closure.rs | 2 +- crates/hir-ty/src/mir/eval.rs | 18 ++- crates/hir-ty/src/mir/eval/tests.rs | 2 +- crates/hir-ty/src/mir/lower.rs | 24 ++-- crates/hir-ty/src/mir/pretty.rs | 47 ++++--- crates/hir-ty/src/tls.rs | 22 ++-- crates/hir-ty/src/traits.rs | 2 +- crates/hir/src/display.rs | 57 +++++---- crates/hir/src/lib.rs | 8 +- .../src/handlers/add_missing_impl_members.rs | 3 +- .../ide-assists/src/handlers/auto_import.rs | 2 +- .../src/handlers/convert_bool_then.rs | 2 +- .../handlers/convert_iter_for_each_to_for.rs | 2 +- .../src/handlers/expand_glob_import.rs | 2 +- .../src/handlers/extract_function.rs | 16 ++- .../src/handlers/extract_module.rs | 2 +- .../extract_struct_from_enum_variant.rs | 2 +- .../src/handlers/fix_visibility.rs | 11 +- .../src/handlers/generate_delegate_methods.rs | 11 +- .../src/handlers/generate_deref.rs | 6 +- .../src/handlers/generate_function.rs | 2 +- .../src/handlers/move_const_to_impl.rs | 2 +- .../src/handlers/move_from_mod_rs.rs | 2 +- .../src/handlers/move_module_to_file.rs | 2 +- .../src/handlers/move_to_mod_rs.rs | 2 +- .../ide-assists/src/handlers/qualify_path.rs | 10 +- .../src/handlers/reorder_fields.rs | 2 +- .../src/handlers/reorder_impl_items.rs | 2 +- crates/ide-assists/src/utils/suggest_name.rs | 4 +- crates/ide-completion/src/completions.rs | 35 +++--- .../src/completions/attribute.rs | 2 +- .../src/completions/attribute/cfg.rs | 6 +- .../src/completions/attribute/derive.rs | 2 +- .../src/completions/attribute/lint.rs | 2 +- .../src/completions/attribute/repr.rs | 2 +- crates/ide-completion/src/completions/dot.rs | 2 +- .../src/completions/env_vars.rs | 2 +- .../src/completions/extern_abi.rs | 4 +- .../src/completions/flyimport.rs | 4 +- .../src/completions/fn_param.rs | 8 +- .../src/completions/format_string.rs | 2 +- .../src/completions/item_list/trait_impl.rs | 10 +- crates/ide-completion/src/completions/mod_.rs | 4 +- .../ide-completion/src/completions/postfix.rs | 47 +++---- .../src/completions/postfix/format_like.rs | 2 +- .../ide-completion/src/completions/record.rs | 4 +- .../ide-completion/src/completions/snippet.rs | 14 +-- crates/ide-completion/src/completions/use_.rs | 6 +- crates/ide-completion/src/context/analysis.rs | 2 +- crates/ide-completion/src/item.rs | 22 +++- crates/ide-completion/src/lib.rs | 2 +- crates/ide-completion/src/render.rs | 32 +++-- crates/ide-completion/src/render/const_.rs | 2 +- crates/ide-completion/src/render/function.rs | 9 +- crates/ide-completion/src/render/literal.rs | 8 +- crates/ide-completion/src/render/pattern.rs | 9 +- .../ide-completion/src/render/type_alias.rs | 2 +- .../src/render/union_literal.rs | 20 +-- crates/ide-completion/src/render/variant.rs | 6 +- crates/ide-completion/src/tests.rs | 10 +- crates/ide-db/src/imports/import_assets.rs | 4 +- crates/ide-db/src/rename.rs | 9 +- crates/ide-db/src/traits.rs | 18 +-- .../src/handlers/missing_fields.rs | 4 +- .../src/handlers/mutability_errors.rs | 5 +- .../src/handlers/private_assoc_item.rs | 6 +- .../src/handlers/private_field.rs | 4 +- .../src/handlers/undeclared_label.rs | 2 +- .../src/handlers/unreachable_label.rs | 2 +- .../src/handlers/unresolved_field.rs | 2 +- .../src/handlers/unresolved_macro_call.rs | 2 +- .../src/handlers/unresolved_method.rs | 2 +- crates/ide-ssr/src/lib.rs | 1 + crates/ide-ssr/src/replacing.rs | 18 ++- crates/ide/src/doc_links.rs | 48 +++++--- crates/ide/src/expand_macro.rs | 2 +- crates/ide/src/hover.rs | 2 +- crates/ide/src/hover/render.rs | 24 ++-- crates/ide/src/inlay_hints/closing_brace.rs | 2 +- crates/ide/src/moniker.rs | 116 ++++++++++-------- crates/ide/src/runnables.rs | 28 +++-- crates/ide/src/signature_help.rs | 48 +++++--- crates/ide/src/view_item_tree.rs | 2 +- .../rust-analyzer/src/cli/analysis_stats.rs | 14 ++- crates/rust-analyzer/src/cli/scip.rs | 12 +- crates/rust-analyzer/src/to_proto.rs | 8 +- 108 files changed, 1045 insertions(+), 656 deletions(-) diff --git a/crates/hir-def/src/body/pretty.rs b/crates/hir-def/src/body/pretty.rs index bdc84fefe6..7390a8f1f2 100644 --- a/crates/hir-def/src/body/pretty.rs +++ b/crates/hir-def/src/body/pretty.rs @@ -2,6 +2,7 @@ use std::fmt::{self, Write}; +use hir_expand::db::ExpandDatabase; use syntax::ast::HasName; use crate::{ @@ -18,16 +19,22 @@ pub(super) fn print_body_hir(db: &dyn DefDatabase, body: &Body, owner: DefWithBo let header = match owner { DefWithBodyId::FunctionId(it) => { let item_tree_id = it.lookup(db).id; - format!("fn {}", item_tree_id.item_tree(db)[item_tree_id.value].name) + format!( + "fn {}", + item_tree_id.item_tree(db)[item_tree_id.value].name.display(db.upcast()) + ) } DefWithBodyId::StaticId(it) => { let item_tree_id = it.lookup(db).id; - format!("static {} = ", item_tree_id.item_tree(db)[item_tree_id.value].name) + format!( + "static {} = ", + item_tree_id.item_tree(db)[item_tree_id.value].name.display(db.upcast()) + ) } DefWithBodyId::ConstId(it) => { let item_tree_id = it.lookup(db).id; let name = match &item_tree_id.item_tree(db)[item_tree_id.value].name { - Some(name) => name.to_string(), + Some(name) => name.display(db.upcast()).to_string(), None => "_".to_string(), }; format!("const {name} = ") @@ -42,7 +49,8 @@ pub(super) fn print_body_hir(db: &dyn DefDatabase, body: &Body, owner: DefWithBo } }; - let mut p = Printer { body, buf: header, indent_level: 0, needs_indent: false }; + let mut p = + Printer { db: db.upcast(), body, buf: header, indent_level: 0, needs_indent: false }; if let DefWithBodyId::FunctionId(it) = owner { p.buf.push('('); body.params.iter().zip(&db.function_data(it).params).for_each(|(¶m, ty)| { @@ -61,12 +69,13 @@ pub(super) fn print_body_hir(db: &dyn DefDatabase, body: &Body, owner: DefWithBo } pub(super) fn print_expr_hir( - _db: &dyn DefDatabase, + db: &dyn DefDatabase, body: &Body, _owner: DefWithBodyId, expr: ExprId, ) -> String { - let mut p = Printer { body, buf: String::new(), indent_level: 0, needs_indent: false }; + let mut p = + Printer { db: db.upcast(), body, buf: String::new(), indent_level: 0, needs_indent: false }; p.print_expr(expr); p.buf } @@ -87,6 +96,7 @@ macro_rules! wln { } struct Printer<'a> { + db: &'a dyn ExpandDatabase, body: &'a Body, buf: String, indent_level: usize, @@ -161,14 +171,14 @@ impl<'a> Printer<'a> { } Expr::Loop { body, label } => { if let Some(lbl) = label { - w!(self, "{}: ", self.body[*lbl].name); + w!(self, "{}: ", self.body[*lbl].name.display(self.db)); } w!(self, "loop "); self.print_expr(*body); } Expr::While { condition, body, label } => { if let Some(lbl) = label { - w!(self, "{}: ", self.body[*lbl].name); + w!(self, "{}: ", self.body[*lbl].name.display(self.db)); } w!(self, "while "); self.print_expr(*condition); @@ -176,7 +186,7 @@ impl<'a> Printer<'a> { } Expr::For { iterable, pat, body, label } => { if let Some(lbl) = label { - w!(self, "{}: ", self.body[*lbl].name); + w!(self, "{}: ", self.body[*lbl].name.display(self.db)); } w!(self, "for "); self.print_pat(*pat); @@ -199,10 +209,10 @@ impl<'a> Printer<'a> { } Expr::MethodCall { receiver, method_name, args, generic_args } => { self.print_expr(*receiver); - w!(self, ".{}", method_name); + w!(self, ".{}", method_name.display(self.db)); if let Some(args) = generic_args { w!(self, "::<"); - print_generic_args(args, self).unwrap(); + print_generic_args(self.db, args, self).unwrap(); w!(self, ">"); } w!(self, "("); @@ -237,13 +247,13 @@ impl<'a> Printer<'a> { Expr::Continue { label } => { w!(self, "continue"); if let Some(lbl) = label { - w!(self, " {}", self.body[*lbl].name); + w!(self, " {}", self.body[*lbl].name.display(self.db)); } } Expr::Break { expr, label } => { w!(self, "break"); if let Some(lbl) = label { - w!(self, " {}", self.body[*lbl].name); + w!(self, " {}", self.body[*lbl].name.display(self.db)); } if let Some(expr) = expr { self.whitespace(); @@ -282,7 +292,7 @@ impl<'a> Printer<'a> { w!(self, "{{"); self.indented(|p| { for field in &**fields { - w!(p, "{}: ", field.name); + w!(p, "{}: ", field.name.display(self.db)); p.print_expr(field.expr); wln!(p, ","); } @@ -299,7 +309,7 @@ impl<'a> Printer<'a> { } Expr::Field { expr, name } => { self.print_expr(*expr); - w!(self, ".{}", name); + w!(self, ".{}", name.display(self.db)); } Expr::Await { expr } => { self.print_expr(*expr); @@ -437,7 +447,7 @@ impl<'a> Printer<'a> { } Expr::Literal(lit) => self.print_literal(lit), Expr::Block { id: _, statements, tail, label } => { - let label = label.map(|lbl| format!("{}: ", self.body[lbl].name)); + let label = label.map(|lbl| format!("{}: ", self.body[lbl].name.display(self.db))); self.print_block(label.as_deref(), statements, tail); } Expr::Unsafe { id: _, statements, tail } => { @@ -513,7 +523,7 @@ impl<'a> Printer<'a> { w!(self, " {{"); self.indented(|p| { for arg in args.iter() { - w!(p, "{}: ", arg.name); + w!(p, "{}: ", arg.name.display(self.db)); p.print_pat(arg.pat); wln!(p, ","); } @@ -646,11 +656,11 @@ impl<'a> Printer<'a> { } fn print_type_ref(&mut self, ty: &TypeRef) { - print_type_ref(ty, self).unwrap(); + print_type_ref(self.db, ty, self).unwrap(); } fn print_path(&mut self, path: &Path) { - print_path(path, self).unwrap(); + print_path(self.db, path, self).unwrap(); } fn print_binding(&mut self, id: BindingId) { @@ -661,6 +671,6 @@ impl<'a> Printer<'a> { BindingAnnotation::Ref => "ref ", BindingAnnotation::RefMut => "ref mut ", }; - w!(self, "{}{}", mode, name); + w!(self, "{}{}", mode, name.display(self.db)); } } diff --git a/crates/hir-def/src/builtin_type.rs b/crates/hir-def/src/builtin_type.rs index dd69c3ab47..61b2481978 100644 --- a/crates/hir-def/src/builtin_type.rs +++ b/crates/hir-def/src/builtin_type.rs @@ -106,8 +106,14 @@ impl AsName for BuiltinType { impl fmt::Display for BuiltinType { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let type_name = self.as_name(); - type_name.fmt(f) + match self { + BuiltinType::Char => f.write_str("char"), + BuiltinType::Bool => f.write_str("bool"), + BuiltinType::Str => f.write_str("str"), + BuiltinType::Int(it) => it.fmt(f), + BuiltinType::Uint(it) => it.fmt(f), + BuiltinType::Float(it) => it.fmt(f), + } } } diff --git a/crates/hir-def/src/hir/type_ref.rs b/crates/hir-def/src/hir/type_ref.rs index 06e6be66ba..0573c9a6f8 100644 --- a/crates/hir-def/src/hir/type_ref.rs +++ b/crates/hir-def/src/hir/type_ref.rs @@ -1,9 +1,11 @@ //! HIR for references to types. Paths in these are not yet resolved. They can //! be directly created from an ast::TypeRef, without further queries. +use core::fmt; use std::fmt::Write; use hir_expand::{ + db::ExpandDatabase, name::{AsName, Name}, AstId, }; @@ -383,15 +385,6 @@ pub enum ConstRefOrPath { Path(Name), } -impl std::fmt::Display for ConstRefOrPath { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - ConstRefOrPath::Scalar(s) => s.fmt(f), - ConstRefOrPath::Path(n) => n.fmt(f), - } - } -} - impl ConstRefOrPath { pub(crate) fn from_expr_opt(expr: Option) -> Self { match expr { @@ -400,6 +393,19 @@ impl ConstRefOrPath { } } + pub fn display<'a>(&'a self, db: &'a dyn ExpandDatabase) -> impl fmt::Display + 'a { + struct Display<'a>(&'a dyn ExpandDatabase, &'a ConstRefOrPath); + impl fmt::Display for Display<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.1 { + ConstRefOrPath::Scalar(s) => s.fmt(f), + ConstRefOrPath::Path(n) => n.display(self.0).fmt(f), + } + } + } + Display(db, self) + } + // FIXME: as per the comments on `TypeRef::Array`, this evaluation should not happen at this // parse stage. fn from_expr(expr: ast::Expr) -> Self { diff --git a/crates/hir-def/src/import_map.rs b/crates/hir-def/src/import_map.rs index 4ea807e7d5..6ef2949ef5 100644 --- a/crates/hir-def/src/import_map.rs +++ b/crates/hir-def/src/import_map.rs @@ -33,13 +33,23 @@ pub struct ImportPath { pub segments: Vec, } -impl fmt::Display for ImportPath { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(&self.segments.iter().format("::"), f) - } -} - impl ImportPath { + pub fn display<'a>(&'a self, db: &'a dyn DefDatabase) -> impl fmt::Display + 'a { + struct Display<'a> { + db: &'a dyn DefDatabase, + path: &'a ImportPath, + } + impl fmt::Display for Display<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt( + &self.path.segments.iter().map(|it| it.display(self.db.upcast())).format("::"), + f, + ) + } + } + Display { db, path: self } + } + fn len(&self) -> usize { self.segments.len() } @@ -76,7 +86,7 @@ impl ImportMap { let mut importables = import_map .map .iter() - .map(|(item, info)| (item, fst_path(&info.path))) + .map(|(item, info)| (item, fst_path(db, &info.path))) .collect::>(); importables.sort_by(|(_, fst_path), (_, fst_path2)| fst_path.cmp(fst_path2)); @@ -113,6 +123,25 @@ impl ImportMap { self.map.get(&item) } + #[cfg(test)] + fn fmt_for_test(&self, db: &dyn DefDatabase) -> String { + let mut importable_paths: Vec<_> = self + .map + .iter() + .map(|(item, info)| { + let ns = match item { + ItemInNs::Types(_) => "t", + ItemInNs::Values(_) => "v", + ItemInNs::Macros(_) => "m", + }; + format!("- {} ({ns})", info.path.display(db)) + }) + .collect(); + + importable_paths.sort(); + importable_paths.join("\n") + } + fn collect_trait_assoc_items( &mut self, db: &dyn DefDatabase, @@ -238,13 +267,10 @@ impl fmt::Debug for ImportMap { let mut importable_paths: Vec<_> = self .map .iter() - .map(|(item, info)| { - let ns = match item { - ItemInNs::Types(_) => "t", - ItemInNs::Values(_) => "v", - ItemInNs::Macros(_) => "m", - }; - format!("- {} ({ns})", info.path) + .map(|(item, _)| match item { + ItemInNs::Types(it) => format!("- {it:?} (t)",), + ItemInNs::Values(it) => format!("- {it:?} (v)",), + ItemInNs::Macros(it) => format!("- {it:?} (m)",), }) .collect(); @@ -253,9 +279,9 @@ impl fmt::Debug for ImportMap { } } -fn fst_path(path: &ImportPath) -> String { +fn fst_path(db: &dyn DefDatabase, path: &ImportPath) -> String { let _p = profile::span("fst_path"); - let mut s = path.to_string(); + let mut s = path.display(db).to_string(); s.make_ascii_lowercase(); s } @@ -348,7 +374,12 @@ impl Query { self } - fn import_matches(&self, import: &ImportInfo, enforce_lowercase: bool) -> bool { + fn import_matches( + &self, + db: &dyn DefDatabase, + import: &ImportInfo, + enforce_lowercase: bool, + ) -> bool { let _p = profile::span("import_map::Query::import_matches"); if import.is_trait_assoc_item { if self.exclude_import_kinds.contains(&ImportKind::AssociatedItem) { @@ -359,9 +390,9 @@ impl Query { } let mut input = if import.is_trait_assoc_item || self.name_only { - import.path.segments.last().unwrap().to_string() + import.path.segments.last().unwrap().display(db.upcast()).to_string() } else { - import.path.to_string() + import.path.display(db).to_string() }; if enforce_lowercase || !self.case_sensitive { input.make_ascii_lowercase(); @@ -426,25 +457,27 @@ pub fn search_dependencies( let importables = &import_map.importables[indexed_value.value as usize..]; let common_importable_data = &import_map.map[&importables[0]]; - if !query.import_matches(common_importable_data, true) { + if !query.import_matches(db, common_importable_data, true) { continue; } // Path shared by the importable items in this group. - let common_importables_path_fst = fst_path(&common_importable_data.path); + let common_importables_path_fst = fst_path(db, &common_importable_data.path); // Add the items from this `ModPath` group. Those are all subsequent items in // `importables` whose paths match `path`. let iter = importables .iter() .copied() - .take_while(|item| common_importables_path_fst == fst_path(&import_map.map[item].path)) + .take_while(|item| { + common_importables_path_fst == fst_path(db, &import_map.map[item].path) + }) .filter(|&item| match item_import_kind(item) { Some(import_kind) => !query.exclude_import_kinds.contains(&import_kind), None => true, }) .filter(|item| { !query.case_sensitive // we've already checked the common importables path case-insensitively - || query.import_matches(&import_map.map[item], false) + || query.import_matches(db, &import_map.map[item], false) }); res.extend(iter); @@ -501,7 +534,7 @@ mod tests { let (path, mark) = match assoc_item_path(&db, &dependency_imports, dependency) { Some(assoc_item_path) => (assoc_item_path, "a"), None => ( - dependency_imports.path_of(dependency)?.to_string(), + dependency_imports.path_of(dependency)?.display(&db).to_string(), match dependency { ItemInNs::Types(ModuleDefId::FunctionId(_)) | ItemInNs::Values(ModuleDefId::FunctionId(_)) => "f", @@ -552,7 +585,11 @@ mod tests { None } })?; - return Some(format!("{}::{assoc_item_name}", dependency_imports.path_of(trait_)?)); + return Some(format!( + "{}::{}", + dependency_imports.path_of(trait_)?.display(db), + assoc_item_name.display(db.upcast()) + )); } None } @@ -592,7 +629,7 @@ mod tests { let map = db.import_map(krate); - Some(format!("{name}:\n{map:?}\n")) + Some(format!("{name}:\n{}\n", map.fmt_for_test(db.upcast()))) }) .sorted() .collect::(); diff --git a/crates/hir-def/src/item_scope.rs b/crates/hir-def/src/item_scope.rs index 991e447033..3ed321d189 100644 --- a/crates/hir-def/src/item_scope.rs +++ b/crates/hir-def/src/item_scope.rs @@ -4,7 +4,7 @@ use std::collections::hash_map::Entry; use base_db::CrateId; -use hir_expand::{attrs::AttrId, name::Name, AstId, MacroCallId}; +use hir_expand::{attrs::AttrId, db::ExpandDatabase, name::Name, AstId, MacroCallId}; use itertools::Itertools; use once_cell::sync::Lazy; use profile::Count; @@ -358,12 +358,16 @@ impl ItemScope { } } - pub(crate) fn dump(&self, buf: &mut String) { + pub(crate) fn dump(&self, db: &dyn ExpandDatabase, buf: &mut String) { let mut entries: Vec<_> = self.resolutions().collect(); entries.sort_by_key(|(name, _)| name.clone()); for (name, def) in entries { - format_to!(buf, "{}:", name.map_or("_".to_string(), |name| name.to_string())); + format_to!( + buf, + "{}:", + name.map_or("_".to_string(), |name| name.display(db).to_string()) + ); if def.types.is_some() { buf.push_str(" t"); diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs index c332cc28c3..590ed64af5 100644 --- a/crates/hir-def/src/item_tree.rs +++ b/crates/hir-def/src/item_tree.rs @@ -167,8 +167,8 @@ impl ItemTree { Attrs::filter(db, krate, self.raw_attrs(of).clone()) } - pub fn pretty_print(&self) -> String { - pretty::print_item_tree(self) + pub fn pretty_print(&self, db: &dyn DefDatabase) -> String { + pretty::print_item_tree(db.upcast(), self) } fn data(&self) -> &ItemTreeData { diff --git a/crates/hir-def/src/item_tree/pretty.rs b/crates/hir-def/src/item_tree/pretty.rs index 94c5157386..e873316a57 100644 --- a/crates/hir-def/src/item_tree/pretty.rs +++ b/crates/hir-def/src/item_tree/pretty.rs @@ -2,6 +2,8 @@ use std::fmt::{self, Write}; +use hir_expand::db::ExpandDatabase; + use crate::{ generics::{TypeOrConstParamData, WherePredicate, WherePredicateTypeTarget}, pretty::{print_path, print_type_bounds, print_type_ref}, @@ -10,8 +12,8 @@ use crate::{ use super::*; -pub(super) fn print_item_tree(tree: &ItemTree) -> String { - let mut p = Printer { tree, buf: String::new(), indent_level: 0, needs_indent: true }; +pub(super) fn print_item_tree(db: &dyn ExpandDatabase, tree: &ItemTree) -> String { + let mut p = Printer { db, tree, buf: String::new(), indent_level: 0, needs_indent: true }; if let Some(attrs) = tree.attrs.get(&AttrOwner::TopLevel) { p.print_attrs(attrs, true); @@ -43,6 +45,7 @@ macro_rules! wln { } struct Printer<'a> { + db: &'a dyn ExpandDatabase, tree: &'a ItemTree, buf: String, indent_level: usize, @@ -88,7 +91,7 @@ impl<'a> Printer<'a> { self, "#{}[{}{}]", inner, - attr.path, + attr.path.display(self.db), attr.input.as_ref().map(|it| it.to_string()).unwrap_or_default(), ); } @@ -102,7 +105,7 @@ impl<'a> Printer<'a> { fn print_visibility(&mut self, vis: RawVisibilityId) { match &self.tree[vis] { - RawVisibility::Module(path) => w!(self, "pub({}) ", path), + RawVisibility::Module(path) => w!(self, "pub({}) ", path.display(self.db)), RawVisibility::Public => w!(self, "pub "), }; } @@ -117,7 +120,7 @@ impl<'a> Printer<'a> { let Field { visibility, name, type_ref, ast_id: _ } = &this.tree[field]; this.print_attrs_of(field); this.print_visibility(*visibility); - w!(this, "{}: ", name); + w!(this, "{}: ", name.display(self.db)); this.print_type_ref(type_ref); wln!(this, ","); } @@ -131,7 +134,7 @@ impl<'a> Printer<'a> { let Field { visibility, name, type_ref, ast_id: _ } = &this.tree[field]; this.print_attrs_of(field); this.print_visibility(*visibility); - w!(this, "{}: ", name); + w!(this, "{}: ", name.display(self.db)); this.print_type_ref(type_ref); wln!(this, ","); } @@ -164,20 +167,20 @@ impl<'a> Printer<'a> { fn print_use_tree(&mut self, use_tree: &UseTree) { match &use_tree.kind { UseTreeKind::Single { path, alias } => { - w!(self, "{}", path); + w!(self, "{}", path.display(self.db)); if let Some(alias) = alias { w!(self, " as {}", alias); } } UseTreeKind::Glob { path } => { if let Some(path) = path { - w!(self, "{}::", path); + w!(self, "{}::", path.display(self.db)); } w!(self, "*"); } UseTreeKind::Prefixed { prefix, list } => { if let Some(prefix) = prefix { - w!(self, "{}::", prefix); + w!(self, "{}::", prefix.display(self.db)); } w!(self, "{{"); for (i, tree) in list.iter().enumerate() { @@ -205,7 +208,7 @@ impl<'a> Printer<'a> { ModItem::ExternCrate(it) => { let ExternCrate { name, alias, visibility, ast_id: _ } = &self.tree[it]; self.print_visibility(*visibility); - w!(self, "extern crate {}", name); + w!(self, "extern crate {}", name.display(self.db)); if let Some(alias) = alias { w!(self, " as {}", alias); } @@ -252,7 +255,7 @@ impl<'a> Printer<'a> { if let Some(abi) = abi { w!(self, "extern \"{}\" ", abi); } - w!(self, "fn {}", name); + w!(self, "fn {}", name.display(self.db)); self.print_generic_params(explicit_generic_params); w!(self, "("); if !params.is_empty() { @@ -286,7 +289,7 @@ impl<'a> Printer<'a> { ModItem::Struct(it) => { let Struct { visibility, name, fields, generic_params, ast_id: _ } = &self.tree[it]; self.print_visibility(*visibility); - w!(self, "struct {}", name); + w!(self, "struct {}", name.display(self.db)); self.print_generic_params(generic_params); self.print_fields_and_where_clause(fields, generic_params); if matches!(fields, Fields::Record(_)) { @@ -298,7 +301,7 @@ impl<'a> Printer<'a> { ModItem::Union(it) => { let Union { name, visibility, fields, generic_params, ast_id: _ } = &self.tree[it]; self.print_visibility(*visibility); - w!(self, "union {}", name); + w!(self, "union {}", name.display(self.db)); self.print_generic_params(generic_params); self.print_fields_and_where_clause(fields, generic_params); if matches!(fields, Fields::Record(_)) { @@ -310,14 +313,14 @@ impl<'a> Printer<'a> { ModItem::Enum(it) => { let Enum { name, visibility, variants, generic_params, ast_id: _ } = &self.tree[it]; self.print_visibility(*visibility); - w!(self, "enum {}", name); + w!(self, "enum {}", name.display(self.db)); self.print_generic_params(generic_params); self.print_where_clause_and_opening_brace(generic_params); self.indented(|this| { for variant in variants.clone() { let Variant { name, fields, ast_id: _ } = &this.tree[variant]; this.print_attrs_of(variant); - w!(this, "{}", name); + w!(this, "{}", name.display(self.db)); this.print_fields(fields); wln!(this, ","); } @@ -329,7 +332,7 @@ impl<'a> Printer<'a> { self.print_visibility(*visibility); w!(self, "const "); match name { - Some(name) => w!(self, "{}", name), + Some(name) => w!(self, "{}", name.display(self.db)), None => w!(self, "_"), } w!(self, ": "); @@ -343,7 +346,7 @@ impl<'a> Printer<'a> { if *mutable { w!(self, "mut "); } - w!(self, "{}: ", name); + w!(self, "{}: ", name.display(self.db)); self.print_type_ref(type_ref); w!(self, " = _;"); wln!(self); @@ -365,7 +368,7 @@ impl<'a> Printer<'a> { if *is_auto { w!(self, "auto "); } - w!(self, "trait {}", name); + w!(self, "trait {}", name.display(self.db)); self.print_generic_params(generic_params); self.print_where_clause_and_opening_brace(generic_params); self.indented(|this| { @@ -378,7 +381,7 @@ impl<'a> Printer<'a> { ModItem::TraitAlias(it) => { let TraitAlias { name, visibility, generic_params, ast_id: _ } = &self.tree[it]; self.print_visibility(*visibility); - w!(self, "trait {}", name); + w!(self, "trait {}", name.display(self.db)); self.print_generic_params(generic_params); w!(self, " = "); self.print_where_clause(generic_params); @@ -411,7 +414,7 @@ impl<'a> Printer<'a> { let TypeAlias { name, visibility, bounds, type_ref, generic_params, ast_id: _ } = &self.tree[it]; self.print_visibility(*visibility); - w!(self, "type {}", name); + w!(self, "type {}", name.display(self.db)); self.print_generic_params(generic_params); if !bounds.is_empty() { w!(self, ": "); @@ -428,7 +431,7 @@ impl<'a> Printer<'a> { ModItem::Mod(it) => { let Mod { name, visibility, kind, ast_id: _ } = &self.tree[it]; self.print_visibility(*visibility); - w!(self, "mod {}", name); + w!(self, "mod {}", name.display(self.db)); match kind { ModKind::Inline { items } => { w!(self, " {{"); @@ -446,16 +449,16 @@ impl<'a> Printer<'a> { } ModItem::MacroCall(it) => { let MacroCall { path, ast_id: _, expand_to: _ } = &self.tree[it]; - wln!(self, "{}!(...);", path); + wln!(self, "{}!(...);", path.display(self.db)); } ModItem::MacroRules(it) => { let MacroRules { name, ast_id: _ } = &self.tree[it]; - wln!(self, "macro_rules! {} {{ ... }}", name); + wln!(self, "macro_rules! {} {{ ... }}", name.display(self.db)); } ModItem::MacroDef(it) => { let MacroDef { name, visibility, ast_id: _ } = &self.tree[it]; self.print_visibility(*visibility); - wln!(self, "macro {} {{ ... }}", name); + wln!(self, "macro {} {{ ... }}", name.display(self.db)); } } @@ -463,15 +466,15 @@ impl<'a> Printer<'a> { } fn print_type_ref(&mut self, type_ref: &TypeRef) { - print_type_ref(type_ref, self).unwrap(); + print_type_ref(self.db, type_ref, self).unwrap(); } fn print_type_bounds(&mut self, bounds: &[Interned]) { - print_type_bounds(bounds, self).unwrap(); + print_type_bounds(self.db, bounds, self).unwrap(); } fn print_path(&mut self, path: &Path) { - print_path(path, self).unwrap(); + print_path(self.db, path, self).unwrap(); } fn print_generic_params(&mut self, params: &GenericParams) { @@ -486,7 +489,7 @@ impl<'a> Printer<'a> { w!(self, ", "); } first = false; - w!(self, "{}", lt.name); + w!(self, "{}", lt.name.display(self.db)); } for (idx, x) in params.type_or_consts.iter() { if !first { @@ -495,11 +498,11 @@ impl<'a> Printer<'a> { first = false; match x { TypeOrConstParamData::TypeParamData(ty) => match &ty.name { - Some(name) => w!(self, "{}", name), + Some(name) => w!(self, "{}", name.display(self.db)), None => w!(self, "_anon_{}", idx.into_raw()), }, TypeOrConstParamData::ConstParamData(konst) => { - w!(self, "const {}: ", konst.name); + w!(self, "const {}: ", konst.name.display(self.db)); self.print_type_ref(&konst.ty); } } @@ -531,7 +534,12 @@ impl<'a> Printer<'a> { let (target, bound) = match pred { WherePredicate::TypeBound { target, bound } => (target, bound), WherePredicate::Lifetime { target, bound } => { - wln!(this, "{}: {},", target.name, bound.name); + wln!( + this, + "{}: {},", + target.name.display(self.db), + bound.name.display(self.db) + ); continue; } WherePredicate::ForLifetime { lifetimes, target, bound } => { @@ -540,7 +548,7 @@ impl<'a> Printer<'a> { if i != 0 { w!(this, ", "); } - w!(this, "{}", lt); + w!(this, "{}", lt.display(self.db)); } w!(this, "> "); (target, bound) @@ -551,7 +559,7 @@ impl<'a> Printer<'a> { WherePredicateTypeTarget::TypeRef(ty) => this.print_type_ref(ty), WherePredicateTypeTarget::TypeOrConstParam(id) => { match ¶ms.type_or_consts[*id].name() { - Some(name) => w!(this, "{}", name), + Some(name) => w!(this, "{}", name.display(self.db)), None => w!(this, "_anon_{}", id.into_raw()), } } diff --git a/crates/hir-def/src/item_tree/tests.rs b/crates/hir-def/src/item_tree/tests.rs index 1b7564f7a9..5ded4b6b27 100644 --- a/crates/hir-def/src/item_tree/tests.rs +++ b/crates/hir-def/src/item_tree/tests.rs @@ -6,7 +6,7 @@ use crate::{db::DefDatabase, test_db::TestDB}; fn check(ra_fixture: &str, expect: Expect) { let (db, file_id) = TestDB::with_single_file(ra_fixture); let item_tree = db.file_item_tree(file_id.into()); - let pretty = item_tree.pretty_print(); + let pretty = item_tree.pretty_print(&db); expect.assert_eq(&pretty); } diff --git a/crates/hir-def/src/nameres.rs b/crates/hir-def/src/nameres.rs index 176637f9d0..8aceb4952a 100644 --- a/crates/hir-def/src/nameres.rs +++ b/crates/hir-def/src/nameres.rs @@ -463,25 +463,31 @@ impl DefMap { let mut arc; let mut current_map = self; while let Some(block) = current_map.block { - go(&mut buf, current_map, "block scope", current_map.root); + go(&mut buf, db, current_map, "block scope", current_map.root); buf.push('\n'); arc = block.parent.def_map(db); current_map = &arc; } - go(&mut buf, current_map, "crate", current_map.root); + go(&mut buf, db, current_map, "crate", current_map.root); return buf; - fn go(buf: &mut String, map: &DefMap, path: &str, module: LocalModuleId) { + fn go( + buf: &mut String, + db: &dyn DefDatabase, + map: &DefMap, + path: &str, + module: LocalModuleId, + ) { format_to!(buf, "{}\n", path); - map.modules[module].scope.dump(buf); + map.modules[module].scope.dump(db.upcast(), buf); for (name, child) in map.modules[module].children.iter().sorted_by(|a, b| Ord::cmp(&a.0, &b.0)) { - let path = format!("{path}::{name}"); + let path = format!("{path}::{}", name.display(db.upcast())); buf.push('\n'); - go(buf, map, &path, *child); + go(buf, db, map, &path, *child); } } } diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs index a528d238e3..c49bb248a7 100644 --- a/crates/hir-def/src/nameres/collector.rs +++ b/crates/hir-def/src/nameres/collector.rs @@ -565,7 +565,7 @@ impl DefCollector<'_> { types => { tracing::debug!( "could not resolve prelude path `{}` to module (resolved to {:?})", - path, + path.display(self.db.upcast()), types ); } @@ -766,7 +766,8 @@ impl DefCollector<'_> { } fn resolve_import(&self, module_id: LocalModuleId, import: &Import) -> PartialResolvedImport { - let _p = profile::span("resolve_import").detail(|| format!("{}", import.path)); + let _p = profile::span("resolve_import") + .detail(|| format!("{}", import.path.display(self.db.upcast()))); tracing::debug!("resolving import: {:?} ({:?})", import, self.def_map.edition); if import.is_extern_crate { let name = import @@ -1985,7 +1986,10 @@ impl ModCollector<'_, '_> { if self.def_collector.def_map.is_builtin_or_registered_attr(&attr.path) { continue; } - tracing::debug!("non-builtin attribute {}", attr.path); + tracing::debug!( + "non-builtin attribute {}", + attr.path.display(self.def_collector.db.upcast()) + ); let ast_id = AstIdWithPath::new( self.file_id(), @@ -2119,8 +2123,8 @@ impl ModCollector<'_, '_> { stdx::always!( name == mac.name, "built-in macro {} has #[rustc_builtin_macro] which declares different name {}", - mac.name, - name + mac.name.display(self.def_collector.db.upcast()), + name.display(self.def_collector.db.upcast()) ); helpers_opt = Some(helpers); } diff --git a/crates/hir-def/src/nameres/mod_resolution.rs b/crates/hir-def/src/nameres/mod_resolution.rs index 51c565fe12..2dcc2c30fe 100644 --- a/crates/hir-def/src/nameres/mod_resolution.rs +++ b/crates/hir-def/src/nameres/mod_resolution.rs @@ -74,12 +74,20 @@ impl ModDir { candidate_files.push(self.dir_path.join_attr(attr_path, self.root_non_dir_owner)) } None if file_id.is_include_macro(db.upcast()) => { - candidate_files.push(format!("{name}.rs")); - candidate_files.push(format!("{name}/mod.rs")); + candidate_files.push(format!("{}.rs", name.display(db.upcast()))); + candidate_files.push(format!("{}/mod.rs", name.display(db.upcast()))); } None => { - candidate_files.push(format!("{}{name}.rs", self.dir_path.0)); - candidate_files.push(format!("{}{name}/mod.rs", self.dir_path.0)); + candidate_files.push(format!( + "{}{}.rs", + self.dir_path.0, + name.display(db.upcast()) + )); + candidate_files.push(format!( + "{}{}/mod.rs", + self.dir_path.0, + name.display(db.upcast()) + )); } }; @@ -91,7 +99,7 @@ impl ModDir { let (dir_path, root_non_dir_owner) = if is_mod_rs || attr_path.is_some() { (DirPath::empty(), false) } else { - (DirPath::new(format!("{name}/")), true) + (DirPath::new(format!("{}/", name.display(db.upcast()))), true) }; if let Some(mod_dir) = self.child(dir_path, root_non_dir_owner) { return Ok((file_id, is_mod_rs, mod_dir)); diff --git a/crates/hir-def/src/nameres/path_resolution.rs b/crates/hir-def/src/nameres/path_resolution.rs index 981171013a..24dc4e243b 100644 --- a/crates/hir-def/src/nameres/path_resolution.rs +++ b/crates/hir-def/src/nameres/path_resolution.rs @@ -192,8 +192,11 @@ impl DefMap { ) -> ResolvePathResult { let graph = db.crate_graph(); let _cx = stdx::panic_context::enter(format!( - "DefMap {:?} crate_name={:?} block={:?} path={path}", - self.krate, graph[self.krate].display_name, self.block + "DefMap {:?} crate_name={:?} block={:?} path={}", + self.krate, + graph[self.krate].display_name, + self.block, + path.display(db.upcast()) )); let mut segments = path.segments().iter().enumerate(); @@ -262,8 +265,8 @@ impl DefMap { ); tracing::debug!( "`super` path: {} -> {} in parent map", - path, - new_path + path.display(db.upcast()), + new_path.display(db.upcast()) ); return block.parent.def_map(db).resolve_path_fp_with_macro( db, diff --git a/crates/hir-def/src/nameres/tests/macros.rs b/crates/hir-def/src/nameres/tests/macros.rs index 56059f7cb3..57f0233607 100644 --- a/crates/hir-def/src/nameres/tests/macros.rs +++ b/crates/hir-def/src/nameres/tests/macros.rs @@ -1080,7 +1080,7 @@ macro_rules! mbe { #[test] fn collects_derive_helpers() { - let def_map = compute_crate_def_map( + let db = TestDB::with_files( r#" #![crate_type="proc-macro"] struct TokenStream; @@ -1091,11 +1091,13 @@ pub fn derive_macro_2(_item: TokenStream) -> TokenStream { } "#, ); + let krate = db.crate_graph().iter().next().unwrap(); + let def_map = db.crate_def_map(krate); assert_eq!(def_map.exported_derives.len(), 1); match def_map.exported_derives.values().next() { Some(helpers) => match &**helpers { - [attr] => assert_eq!(attr.to_string(), "helper_attr"), + [attr] => assert_eq!(attr.display(&db).to_string(), "helper_attr"), _ => unreachable!(), }, _ => unreachable!(), @@ -1258,7 +1260,7 @@ struct A; #[test] fn macro_use_imports_all_macro_types() { - let def_map = compute_crate_def_map( + let db = TestDB::with_files( r#" //- /main.rs crate:main deps:lib #[macro_use] @@ -1281,6 +1283,8 @@ struct TokenStream; fn proc_attr(a: TokenStream, b: TokenStream) -> TokenStream { a } "#, ); + let krate = db.crate_graph().iter().next().unwrap(); + let def_map = db.crate_def_map(krate); let root_module = &def_map[def_map.root()].scope; assert!( @@ -1288,7 +1292,12 @@ fn proc_attr(a: TokenStream, b: TokenStream) -> TokenStream { a } "`#[macro_use]` shouldn't bring macros into textual macro scope", ); - let actual = def_map.macro_use_prelude.iter().map(|(name, _)| name).sorted().join("\n"); + let actual = def_map + .macro_use_prelude + .iter() + .map(|(name, _)| name.display(&db).to_string()) + .sorted() + .join("\n"); expect![[r#" legacy diff --git a/crates/hir-def/src/pretty.rs b/crates/hir-def/src/pretty.rs index 026750b62f..0aead6f37f 100644 --- a/crates/hir-def/src/pretty.rs +++ b/crates/hir-def/src/pretty.rs @@ -2,7 +2,7 @@ use std::fmt::{self, Write}; -use hir_expand::mod_path::PathKind; +use hir_expand::{db::ExpandDatabase, mod_path::PathKind}; use intern::Interned; use itertools::Itertools; @@ -11,14 +11,14 @@ use crate::{ type_ref::{Mutability, TraitBoundModifier, TypeBound, TypeRef}, }; -pub(crate) fn print_path(path: &Path, buf: &mut dyn Write) -> fmt::Result { +pub(crate) fn print_path(db: &dyn ExpandDatabase, path: &Path, buf: &mut dyn Write) -> fmt::Result { if let Path::LangItem(x) = path { return write!(buf, "$lang_item::{x:?}"); } match path.type_anchor() { Some(anchor) => { write!(buf, "<")?; - print_type_ref(anchor, buf)?; + print_type_ref(db, anchor, buf)?; write!(buf, ">::")?; } None => match path.kind() { @@ -44,10 +44,10 @@ pub(crate) fn print_path(path: &Path, buf: &mut dyn Write) -> fmt::Result { write!(buf, "::")?; } - write!(buf, "{}", segment.name)?; + write!(buf, "{}", segment.name.display(db))?; if let Some(generics) = segment.args_and_bindings { write!(buf, "::<")?; - print_generic_args(generics, buf)?; + print_generic_args(db, generics, buf)?; write!(buf, ">")?; } @@ -56,12 +56,16 @@ pub(crate) fn print_path(path: &Path, buf: &mut dyn Write) -> fmt::Result { Ok(()) } -pub(crate) fn print_generic_args(generics: &GenericArgs, buf: &mut dyn Write) -> fmt::Result { +pub(crate) fn print_generic_args( + db: &dyn ExpandDatabase, + generics: &GenericArgs, + buf: &mut dyn Write, +) -> fmt::Result { let mut first = true; let args = if generics.has_self_type { let (self_ty, args) = generics.args.split_first().unwrap(); write!(buf, "Self=")?; - print_generic_arg(self_ty, buf)?; + print_generic_arg(db, self_ty, buf)?; first = false; args } else { @@ -72,35 +76,43 @@ pub(crate) fn print_generic_args(generics: &GenericArgs, buf: &mut dyn Write) -> write!(buf, ", ")?; } first = false; - print_generic_arg(arg, buf)?; + print_generic_arg(db, arg, buf)?; } for binding in generics.bindings.iter() { if !first { write!(buf, ", ")?; } first = false; - write!(buf, "{}", binding.name)?; + write!(buf, "{}", binding.name.display(db))?; if !binding.bounds.is_empty() { write!(buf, ": ")?; - print_type_bounds(&binding.bounds, buf)?; + print_type_bounds(db, &binding.bounds, buf)?; } if let Some(ty) = &binding.type_ref { write!(buf, " = ")?; - print_type_ref(ty, buf)?; + print_type_ref(db, ty, buf)?; } } Ok(()) } -pub(crate) fn print_generic_arg(arg: &GenericArg, buf: &mut dyn Write) -> fmt::Result { +pub(crate) fn print_generic_arg( + db: &dyn ExpandDatabase, + arg: &GenericArg, + buf: &mut dyn Write, +) -> fmt::Result { match arg { - GenericArg::Type(ty) => print_type_ref(ty, buf), - GenericArg::Const(c) => write!(buf, "{c}"), - GenericArg::Lifetime(lt) => write!(buf, "{}", lt.name), + GenericArg::Type(ty) => print_type_ref(db, ty, buf), + GenericArg::Const(c) => write!(buf, "{}", c.display(db)), + GenericArg::Lifetime(lt) => write!(buf, "{}", lt.name.display(db)), } } -pub(crate) fn print_type_ref(type_ref: &TypeRef, buf: &mut dyn Write) -> fmt::Result { +pub(crate) fn print_type_ref( + db: &dyn ExpandDatabase, + type_ref: &TypeRef, + buf: &mut dyn Write, +) -> fmt::Result { // FIXME: deduplicate with `HirDisplay` impl match type_ref { TypeRef::Never => write!(buf, "!")?, @@ -111,18 +123,18 @@ pub(crate) fn print_type_ref(type_ref: &TypeRef, buf: &mut dyn Write) -> fmt::Re if i != 0 { write!(buf, ", ")?; } - print_type_ref(field, buf)?; + print_type_ref(db, field, buf)?; } write!(buf, ")")?; } - TypeRef::Path(path) => print_path(path, buf)?, + TypeRef::Path(path) => print_path(db, path, buf)?, TypeRef::RawPtr(pointee, mtbl) => { let mtbl = match mtbl { Mutability::Shared => "*const", Mutability::Mut => "*mut", }; write!(buf, "{mtbl} ")?; - print_type_ref(pointee, buf)?; + print_type_ref(db, pointee, buf)?; } TypeRef::Reference(pointee, lt, mtbl) => { let mtbl = match mtbl { @@ -131,19 +143,19 @@ pub(crate) fn print_type_ref(type_ref: &TypeRef, buf: &mut dyn Write) -> fmt::Re }; write!(buf, "&")?; if let Some(lt) = lt { - write!(buf, "{} ", lt.name)?; + write!(buf, "{} ", lt.name.display(db))?; } write!(buf, "{mtbl}")?; - print_type_ref(pointee, buf)?; + print_type_ref(db, pointee, buf)?; } TypeRef::Array(elem, len) => { write!(buf, "[")?; - print_type_ref(elem, buf)?; - write!(buf, "; {len}]")?; + print_type_ref(db, elem, buf)?; + write!(buf, "; {}]", len.display(db))?; } TypeRef::Slice(elem) => { write!(buf, "[")?; - print_type_ref(elem, buf)?; + print_type_ref(db, elem, buf)?; write!(buf, "]")?; } TypeRef::Fn(args_and_ret, varargs, is_unsafe) => { @@ -157,7 +169,7 @@ pub(crate) fn print_type_ref(type_ref: &TypeRef, buf: &mut dyn Write) -> fmt::Re if i != 0 { write!(buf, ", ")?; } - print_type_ref(typeref, buf)?; + print_type_ref(db, typeref, buf)?; } if *varargs { if !args.is_empty() { @@ -166,7 +178,7 @@ pub(crate) fn print_type_ref(type_ref: &TypeRef, buf: &mut dyn Write) -> fmt::Re write!(buf, "...")?; } write!(buf, ") -> ")?; - print_type_ref(return_type, buf)?; + print_type_ref(db, return_type, buf)?; } TypeRef::Macro(_ast_id) => { write!(buf, "")?; @@ -174,11 +186,11 @@ pub(crate) fn print_type_ref(type_ref: &TypeRef, buf: &mut dyn Write) -> fmt::Re TypeRef::Error => write!(buf, "{{unknown}}")?, TypeRef::ImplTrait(bounds) => { write!(buf, "impl ")?; - print_type_bounds(bounds, buf)?; + print_type_bounds(db, bounds, buf)?; } TypeRef::DynTrait(bounds) => { write!(buf, "dyn ")?; - print_type_bounds(bounds, buf)?; + print_type_bounds(db, bounds, buf)?; } } @@ -186,6 +198,7 @@ pub(crate) fn print_type_ref(type_ref: &TypeRef, buf: &mut dyn Write) -> fmt::Re } pub(crate) fn print_type_bounds( + db: &dyn ExpandDatabase, bounds: &[Interned], buf: &mut dyn Write, ) -> fmt::Result { @@ -200,13 +213,13 @@ pub(crate) fn print_type_bounds( TraitBoundModifier::None => (), TraitBoundModifier::Maybe => write!(buf, "?")?, } - print_path(path, buf)?; + print_path(db, path, buf)?; } TypeBound::ForLifetime(lifetimes, path) => { - write!(buf, "for<{}> ", lifetimes.iter().format(", "))?; - print_path(path, buf)?; + write!(buf, "for<{}> ", lifetimes.iter().map(|it| it.display(db)).format(", "))?; + print_path(db, path, buf)?; } - TypeBound::Lifetime(lt) => write!(buf, "{}", lt.name)?, + TypeBound::Lifetime(lt) => write!(buf, "{}", lt.name.display(db))?, TypeBound::Error => write!(buf, "{{unknown}}")?, } } diff --git a/crates/hir-expand/src/mod_path.rs b/crates/hir-expand/src/mod_path.rs index e9393cc89a..47a8ab7de7 100644 --- a/crates/hir-expand/src/mod_path.rs +++ b/crates/hir-expand/src/mod_path.rs @@ -1,7 +1,7 @@ //! A lowering for `use`-paths (more generally, paths without angle-bracketed segments). use std::{ - fmt::{self, Display}, + fmt::{self, Display as _}, iter, }; @@ -24,6 +24,12 @@ pub struct ModPath { #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct UnescapedModPath<'a>(&'a ModPath); +impl<'a> UnescapedModPath<'a> { + pub fn display(&'a self, db: &'a dyn crate::db::ExpandDatabase) -> impl fmt::Display + 'a { + UnescapedDisplay { db, path: self } + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum PathKind { Plain, @@ -110,52 +116,30 @@ impl ModPath { UnescapedModPath(self) } - fn _fmt(&self, f: &mut fmt::Formatter<'_>, escaped: bool) -> fmt::Result { - let mut first_segment = true; - let mut add_segment = |s| -> fmt::Result { - if !first_segment { - f.write_str("::")?; - } - first_segment = false; - f.write_str(s)?; - Ok(()) - }; - match self.kind { - PathKind::Plain => {} - PathKind::Super(0) => add_segment("self")?, - PathKind::Super(n) => { - for _ in 0..n { - add_segment("super")?; - } - } - PathKind::Crate => add_segment("crate")?, - PathKind::Abs => add_segment("")?, - PathKind::DollarCrate(_) => add_segment("$crate")?, - } - for segment in &self.segments { - if !first_segment { - f.write_str("::")?; - } - first_segment = false; - if escaped { - segment.fmt(f)? - } else { - segment.unescaped().fmt(f)? - }; - } - Ok(()) + pub fn display<'a>(&'a self, db: &'a dyn crate::db::ExpandDatabase) -> impl fmt::Display + 'a { + Display { db, path: self } } } -impl Display for ModPath { +struct Display<'a> { + db: &'a dyn ExpandDatabase, + path: &'a ModPath, +} + +impl<'a> fmt::Display for Display<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self._fmt(f, true) + display_fmt_path(self.db, self.path, f, true) } } -impl<'a> Display for UnescapedModPath<'a> { +struct UnescapedDisplay<'a> { + db: &'a dyn ExpandDatabase, + path: &'a UnescapedModPath<'a>, +} + +impl<'a> fmt::Display for UnescapedDisplay<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0._fmt(f, false) + display_fmt_path(self.db, self.path.0, f, false) } } @@ -164,6 +148,46 @@ impl From for ModPath { ModPath::from_segments(PathKind::Plain, iter::once(name)) } } +fn display_fmt_path( + db: &dyn ExpandDatabase, + path: &ModPath, + f: &mut fmt::Formatter<'_>, + escaped: bool, +) -> fmt::Result { + let mut first_segment = true; + let mut add_segment = |s| -> fmt::Result { + if !first_segment { + f.write_str("::")?; + } + first_segment = false; + f.write_str(s)?; + Ok(()) + }; + match path.kind { + PathKind::Plain => {} + PathKind::Super(0) => add_segment("self")?, + PathKind::Super(n) => { + for _ in 0..n { + add_segment("super")?; + } + } + PathKind::Crate => add_segment("crate")?, + PathKind::Abs => add_segment("")?, + PathKind::DollarCrate(_) => add_segment("$crate")?, + } + for segment in &path.segments { + if !first_segment { + f.write_str("::")?; + } + first_segment = false; + if escaped { + segment.display(db).fmt(f)?; + } else { + segment.unescaped().display(db).fmt(f)?; + } + } + Ok(()) +} fn convert_path( db: &dyn ExpandDatabase, diff --git a/crates/hir-expand/src/name.rs b/crates/hir-expand/src/name.rs index 10a251ba78..0e95673dbd 100644 --- a/crates/hir-expand/src/name.rs +++ b/crates/hir-expand/src/name.rs @@ -24,27 +24,6 @@ enum Repr { TupleField(usize), } -impl fmt::Display for Name { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match &self.0 { - Repr::Text(text) => fmt::Display::fmt(&text, f), - Repr::TupleField(idx) => fmt::Display::fmt(&idx, f), - } - } -} - -impl<'a> fmt::Display for UnescapedName<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match &self.0 .0 { - Repr::Text(text) => { - let text = text.strip_prefix("r#").unwrap_or(text); - fmt::Display::fmt(&text, f) - } - Repr::TupleField(idx) => fmt::Display::fmt(&idx, f), - } - } -} - impl<'a> UnescapedName<'a> { /// Returns the textual representation of this name as a [`SmolStr`]. Prefer using this over /// [`ToString::to_string`] if possible as this conversion is cheaper in the general case. @@ -60,6 +39,11 @@ impl<'a> UnescapedName<'a> { Repr::TupleField(it) => SmolStr::new(it.to_string()), } } + + pub fn display(&'a self, db: &dyn crate::db::ExpandDatabase) -> impl fmt::Display + 'a { + _ = db; + UnescapedDisplay { name: self } + } } impl Name { @@ -167,6 +151,40 @@ impl Name { Repr::TupleField(_) => false, } } + + pub fn display<'a>(&'a self, db: &dyn crate::db::ExpandDatabase) -> impl fmt::Display + 'a { + _ = db; + Display { name: self } + } +} + +struct Display<'a> { + name: &'a Name, +} + +impl<'a> fmt::Display for Display<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match &self.name.0 { + Repr::Text(text) => fmt::Display::fmt(&text, f), + Repr::TupleField(idx) => fmt::Display::fmt(&idx, f), + } + } +} + +struct UnescapedDisplay<'a> { + name: &'a UnescapedName<'a>, +} + +impl<'a> fmt::Display for UnescapedDisplay<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match &self.name.0 .0 { + Repr::Text(text) => { + let text = text.strip_prefix("r#").unwrap_or(text); + fmt::Display::fmt(&text, f) + } + Repr::TupleField(idx) => fmt::Display::fmt(&idx, f), + } + } } pub trait AsName { diff --git a/crates/hir-ty/src/chalk_db.rs b/crates/hir-ty/src/chalk_db.rs index 983cc22212..ac962c9e3e 100644 --- a/crates/hir-ty/src/chalk_db.rs +++ b/crates/hir-ty/src/chalk_db.rs @@ -365,13 +365,19 @@ impl<'a> chalk_solve::RustIrDatabase for ChalkContext<'a> { fn trait_name(&self, trait_id: chalk_ir::TraitId) -> String { let id = from_chalk_trait_id(trait_id); - self.db.trait_data(id).name.to_string() + self.db.trait_data(id).name.display(self.db.upcast()).to_string() } fn adt_name(&self, chalk_ir::AdtId(adt_id): AdtId) -> String { match adt_id { - hir_def::AdtId::StructId(id) => self.db.struct_data(id).name.to_string(), - hir_def::AdtId::EnumId(id) => self.db.enum_data(id).name.to_string(), - hir_def::AdtId::UnionId(id) => self.db.union_data(id).name.to_string(), + hir_def::AdtId::StructId(id) => { + self.db.struct_data(id).name.display(self.db.upcast()).to_string() + } + hir_def::AdtId::EnumId(id) => { + self.db.enum_data(id).name.display(self.db.upcast()).to_string() + } + hir_def::AdtId::UnionId(id) => { + self.db.union_data(id).name.display(self.db.upcast()).to_string() + } } } fn adt_size_align(&self, _id: chalk_ir::AdtId) -> Arc { @@ -380,7 +386,7 @@ impl<'a> chalk_solve::RustIrDatabase for ChalkContext<'a> { } fn assoc_type_name(&self, assoc_ty_id: chalk_ir::AssocTypeId) -> String { let id = self.db.associated_ty_data(assoc_ty_id).name; - self.db.type_alias_data(id).name.to_string() + self.db.type_alias_data(id).name.display(self.db.upcast()).to_string() } fn opaque_type_name(&self, opaque_ty_id: chalk_ir::OpaqueTyId) -> String { format!("Opaque_{}", opaque_ty_id.0) diff --git a/crates/hir-ty/src/consteval/tests.rs b/crates/hir-ty/src/consteval/tests.rs index b336fa5f0f..6ff8e2de67 100644 --- a/crates/hir-ty/src/consteval/tests.rs +++ b/crates/hir-ty/src/consteval/tests.rs @@ -79,7 +79,7 @@ fn eval_goal(db: &TestDB, file_id: FileId) -> Result { .declarations() .find_map(|x| match x { hir_def::ModuleDefId::ConstId(x) => { - if db.const_data(x).name.as_ref()?.to_string() == "GOAL" { + if db.const_data(x).name.as_ref()?.display(db).to_string() == "GOAL" { Some(x) } else { None diff --git a/crates/hir-ty/src/db.rs b/crates/hir-ty/src/db.rs index 5be1d0b1fd..3aa43dedcd 100644 --- a/crates/hir-ty/src/db.rs +++ b/crates/hir-ty/src/db.rs @@ -243,13 +243,19 @@ pub trait HirDatabase: DefDatabase + Upcast { fn infer_wait(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc { let _p = profile::span("infer:wait").detail(|| match def { - DefWithBodyId::FunctionId(it) => db.function_data(it).name.to_string(), - DefWithBodyId::StaticId(it) => db.static_data(it).name.clone().to_string(), - DefWithBodyId::ConstId(it) => { - db.const_data(it).name.clone().unwrap_or_else(Name::missing).to_string() + DefWithBodyId::FunctionId(it) => db.function_data(it).name.display(db.upcast()).to_string(), + DefWithBodyId::StaticId(it) => { + db.static_data(it).name.clone().display(db.upcast()).to_string() } + DefWithBodyId::ConstId(it) => db + .const_data(it) + .name + .clone() + .unwrap_or_else(Name::missing) + .display(db.upcast()) + .to_string(), DefWithBodyId::VariantId(it) => { - db.enum_data(it.parent).variants[it.local_id].name.to_string() + db.enum_data(it.parent).variants[it.local_id].name.display(db.upcast()).to_string() } }); db.infer_query(def) diff --git a/crates/hir-ty/src/diagnostics/decl_check.rs b/crates/hir-ty/src/diagnostics/decl_check.rs index b3a699e2d1..1233469b94 100644 --- a/crates/hir-ty/src/diagnostics/decl_check.rs +++ b/crates/hir-ty/src/diagnostics/decl_check.rs @@ -223,7 +223,7 @@ impl<'a> DeclValidator<'a> { } // Check the function name. - let function_name = data.name.to_string(); + let function_name = data.name.display(self.db.upcast()).to_string(); let fn_name_replacement = to_lower_snake_case(&function_name).map(|new_name| Replacement { current_name: data.name.clone(), suggested_text: new_name, @@ -244,7 +244,9 @@ impl<'a> DeclValidator<'a> { id, Replacement { current_name: bind_name.clone(), - suggested_text: to_lower_snake_case(&bind_name.to_string())?, + suggested_text: to_lower_snake_case( + &bind_name.display(self.db.upcast()).to_string(), + )?, expected_case: CaseType::LowerSnakeCase, }, )) @@ -287,7 +289,7 @@ impl<'a> DeclValidator<'a> { ident_type: IdentType::Function, ident: AstPtr::new(&ast_ptr), expected_case: fn_name_replacement.expected_case, - ident_text: fn_name_replacement.current_name.to_string(), + ident_text: fn_name_replacement.current_name.display(self.db.upcast()).to_string(), suggested_text: fn_name_replacement.suggested_text, }; @@ -343,7 +345,10 @@ impl<'a> DeclValidator<'a> { ident_type, ident: AstPtr::new(&name_ast), expected_case: replacement.expected_case, - ident_text: replacement.current_name.to_string(), + ident_text: replacement + .current_name + .display(self.db.upcast()) + .to_string(), suggested_text: replacement.suggested_text, }; @@ -362,7 +367,7 @@ impl<'a> DeclValidator<'a> { let non_snake_case_allowed = self.allowed(struct_id.into(), allow::NON_SNAKE_CASE, false); // Check the structure name. - let struct_name = data.name.to_string(); + let struct_name = data.name.display(self.db.upcast()).to_string(); let struct_name_replacement = if !non_camel_case_allowed { to_camel_case(&struct_name).map(|new_name| Replacement { current_name: data.name.clone(), @@ -379,7 +384,7 @@ impl<'a> DeclValidator<'a> { if !non_snake_case_allowed { if let VariantData::Record(fields) = data.variant_data.as_ref() { for (_, field) in fields.iter() { - let field_name = field.name.to_string(); + let field_name = field.name.display(self.db.upcast()).to_string(); if let Some(new_name) = to_lower_snake_case(&field_name) { let replacement = Replacement { current_name: field.name.clone(), @@ -434,7 +439,7 @@ impl<'a> DeclValidator<'a> { ident_type: IdentType::Structure, ident: AstPtr::new(&ast_ptr), expected_case: replacement.expected_case, - ident_text: replacement.current_name.to_string(), + ident_text: replacement.current_name.display(self.db.upcast()).to_string(), suggested_text: replacement.suggested_text, }; @@ -479,7 +484,7 @@ impl<'a> DeclValidator<'a> { ident_type: IdentType::Field, ident: AstPtr::new(&ast_ptr), expected_case: field_to_rename.expected_case, - ident_text: field_to_rename.current_name.to_string(), + ident_text: field_to_rename.current_name.display(self.db.upcast()).to_string(), suggested_text: field_to_rename.suggested_text, }; @@ -496,7 +501,7 @@ impl<'a> DeclValidator<'a> { } // Check the enum name. - let enum_name = data.name.to_string(); + let enum_name = data.name.display(self.db.upcast()).to_string(); let enum_name_replacement = to_camel_case(&enum_name).map(|new_name| Replacement { current_name: data.name.clone(), suggested_text: new_name, @@ -510,7 +515,9 @@ impl<'a> DeclValidator<'a> { .filter_map(|(_, variant)| { Some(Replacement { current_name: variant.name.clone(), - suggested_text: to_camel_case(&variant.name.to_string())?, + suggested_text: to_camel_case( + &variant.name.display(self.db.upcast()).to_string(), + )?, expected_case: CaseType::UpperCamelCase, }) }) @@ -558,7 +565,7 @@ impl<'a> DeclValidator<'a> { ident_type: IdentType::Enum, ident: AstPtr::new(&ast_ptr), expected_case: replacement.expected_case, - ident_text: replacement.current_name.to_string(), + ident_text: replacement.current_name.display(self.db.upcast()).to_string(), suggested_text: replacement.suggested_text, }; @@ -603,7 +610,7 @@ impl<'a> DeclValidator<'a> { ident_type: IdentType::Variant, ident: AstPtr::new(&ast_ptr), expected_case: variant_to_rename.expected_case, - ident_text: variant_to_rename.current_name.to_string(), + ident_text: variant_to_rename.current_name.display(self.db.upcast()).to_string(), suggested_text: variant_to_rename.suggested_text, }; @@ -623,7 +630,7 @@ impl<'a> DeclValidator<'a> { None => return, }; - let const_name = name.to_string(); + let const_name = name.display(self.db.upcast()).to_string(); let replacement = if let Some(new_name) = to_upper_snake_case(&const_name) { Replacement { current_name: name.clone(), @@ -648,7 +655,7 @@ impl<'a> DeclValidator<'a> { ident_type: IdentType::Constant, ident: AstPtr::new(&ast_ptr), expected_case: replacement.expected_case, - ident_text: replacement.current_name.to_string(), + ident_text: replacement.current_name.display(self.db.upcast()).to_string(), suggested_text: replacement.suggested_text, }; @@ -668,7 +675,7 @@ impl<'a> DeclValidator<'a> { let name = &data.name; - let static_name = name.to_string(); + let static_name = name.display(self.db.upcast()).to_string(); let replacement = if let Some(new_name) = to_upper_snake_case(&static_name) { Replacement { current_name: name.clone(), @@ -693,7 +700,7 @@ impl<'a> DeclValidator<'a> { ident_type: IdentType::StaticVariable, ident: AstPtr::new(&ast_ptr), expected_case: replacement.expected_case, - ident_text: replacement.current_name.to_string(), + ident_text: replacement.current_name.display(self.db.upcast()).to_string(), suggested_text: replacement.suggested_text, }; diff --git a/crates/hir-ty/src/diagnostics/match_check.rs b/crates/hir-ty/src/diagnostics/match_check.rs index 2b78e7e14f..f8cdeaa5e3 100644 --- a/crates/hir-ty/src/diagnostics/match_check.rs +++ b/crates/hir-ty/src/diagnostics/match_check.rs @@ -153,7 +153,7 @@ impl<'a> PatCtxt<'a> { match (bm, ty.kind(Interner)) { (BindingMode::Ref(_), TyKind::Ref(.., rty)) => ty = rty, (BindingMode::Ref(_), _) => { - never!("`ref {}` has wrong type {:?}", name, ty); + never!("`ref {}` has wrong type {:?}", name.display(self.db.upcast()), ty); self.errors.push(PatternError::UnexpectedType); return Pat { ty: ty.clone(), kind: PatKind::Wild.into() }; } @@ -298,7 +298,7 @@ impl HirDisplay for Pat { match &*self.kind { PatKind::Wild => write!(f, "_"), PatKind::Binding { name, subpattern } => { - write!(f, "{name}")?; + write!(f, "{}", name.display(f.db.upcast()))?; if let Some(subpattern) = subpattern { write!(f, " @ ")?; subpattern.hir_fmt(f)?; @@ -319,10 +319,14 @@ impl HirDisplay for Pat { match variant { VariantId::EnumVariantId(v) => { let data = f.db.enum_data(v.parent); - write!(f, "{}", data.variants[v.local_id].name)?; + write!(f, "{}", data.variants[v.local_id].name.display(f.db.upcast()))?; + } + VariantId::StructId(s) => { + write!(f, "{}", f.db.struct_data(s).name.display(f.db.upcast()))? + } + VariantId::UnionId(u) => { + write!(f, "{}", f.db.union_data(u).name.display(f.db.upcast()))? } - VariantId::StructId(s) => write!(f, "{}", f.db.struct_data(s).name)?, - VariantId::UnionId(u) => write!(f, "{}", f.db.union_data(u).name)?, }; let variant_data = variant.variant_data(f.db.upcast()); @@ -336,7 +340,11 @@ impl HirDisplay for Pat { .map(|p| { printed += 1; WriteWith(move |f| { - write!(f, "{}: ", rec_fields[p.field].name)?; + write!( + f, + "{}: ", + rec_fields[p.field].name.display(f.db.upcast()) + )?; p.pattern.hir_fmt(f) }) }); diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs index 39e3de6717..3a34485adc 100644 --- a/crates/hir-ty/src/display.rs +++ b/crates/hir-ty/src/display.rs @@ -372,7 +372,13 @@ impl HirDisplay for ProjectionTy { let trait_ref = self.trait_ref(f.db); write!(f, "<")?; fmt_trait_ref(f, &trait_ref, true)?; - write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)).name)?; + write!( + f, + ">::{}", + f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)) + .name + .display(f.db.upcast()) + )?; let proj_params_count = self.substitution.len(Interner) - trait_ref.substitution.len(Interner); let proj_params = &self.substitution.as_slice(Interner)[..proj_params_count]; @@ -415,7 +421,8 @@ impl HirDisplay for Const { let id = from_placeholder_idx(f.db, *idx); let generics = generics(f.db.upcast(), id.parent); let param_data = &generics.params.type_or_consts[id.local_id]; - write!(f, "{}", param_data.name().unwrap()) + write!(f, "{}", param_data.name().unwrap().display(f.db.upcast()))?; + Ok(()) } ConstValue::Concrete(c) => match &c.interned { ConstScalar::Bytes(b, m) => render_const_scalar(f, &b, m, &data.ty), @@ -546,19 +553,19 @@ fn render_const_scalar( }; let mut it = fields.iter(); if matches!(data.variant_data.as_ref(), VariantData::Record(_)) { - write!(f, "{} {{", data.name)?; + write!(f, "{} {{", data.name.display(f.db.upcast()))?; if let Some((id, data)) = it.next() { - write!(f, " {}: ", data.name)?; + write!(f, " {}: ", data.name.display(f.db.upcast()))?; render_field(f, id)?; } for (id, data) in it { - write!(f, ", {}: ", data.name)?; + write!(f, ", {}: ", data.name.display(f.db.upcast()))?; render_field(f, id)?; } write!(f, " }}")?; } else { let mut it = it.map(|x| x.0); - write!(f, "{}(", data.name)?; + write!(f, "{}(", data.name.display(f.db.upcast()))?; if let Some(id) = it.next() { render_field(f, id)?; } @@ -570,10 +577,12 @@ fn render_const_scalar( } return Ok(()); } - VariantData::Unit => write!(f, "{}", data.name), + VariantData::Unit => write!(f, "{}", data.name.display(f.db.upcast())), } } - hir_def::AdtId::UnionId(u) => write!(f, "{}", f.db.union_data(u).name), + hir_def::AdtId::UnionId(u) => { + write!(f, "{}", f.db.union_data(u).name.display(f.db.upcast())) + } hir_def::AdtId::EnumId(_) => f.write_str(""), }, chalk_ir::TyKind::FnDef(..) => ty.hir_fmt(f), @@ -739,11 +748,17 @@ impl HirDisplay for Ty { let sig = db.callable_item_signature(def).substitute(Interner, parameters); f.start_location_link(def.into()); match def { - CallableDefId::FunctionId(ff) => write!(f, "fn {}", db.function_data(ff).name)?, - CallableDefId::StructId(s) => write!(f, "{}", db.struct_data(s).name)?, - CallableDefId::EnumVariantId(e) => { - write!(f, "{}", db.enum_data(e.parent).variants[e.local_id].name)? + CallableDefId::FunctionId(ff) => { + write!(f, "fn {}", db.function_data(ff).name.display(f.db.upcast()))? } + CallableDefId::StructId(s) => { + write!(f, "{}", db.struct_data(s).name.display(f.db.upcast()))? + } + CallableDefId::EnumVariantId(e) => write!( + f, + "{}", + db.enum_data(e.parent).variants[e.local_id].name.display(f.db.upcast()) + )?, }; f.end_location_link(); if parameters.len(Interner) > 0 { @@ -783,7 +798,7 @@ impl HirDisplay for Ty { hir_def::AdtId::UnionId(it) => db.union_data(it).name.clone(), hir_def::AdtId::EnumId(it) => db.enum_data(it).name.clone(), }; - write!(f, "{name}")?; + write!(f, "{}", name.display(f.db.upcast()))?; } DisplayTarget::SourceCode { module_id, allow_opaque: _ } => { if let Some(path) = find_path::find_path( @@ -792,7 +807,7 @@ impl HirDisplay for Ty { module_id, false, ) { - write!(f, "{path}")?; + write!(f, "{}", path.display(f.db.upcast()))?; } else { return Err(HirDisplayError::DisplaySourceCodeError( DisplaySourceCodeError::PathNotFound, @@ -818,12 +833,12 @@ impl HirDisplay for Ty { // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types) if f.display_target.is_test() { f.start_location_link(trait_.into()); - write!(f, "{}", trait_data.name)?; + write!(f, "{}", trait_data.name.display(f.db.upcast()))?; f.end_location_link(); write!(f, "::")?; f.start_location_link(type_alias.into()); - write!(f, "{}", type_alias_data.name)?; + write!(f, "{}", type_alias_data.name.display(f.db.upcast()))?; f.end_location_link(); // Note that the generic args for the associated type come before those for the // trait (including the self type). @@ -846,7 +861,7 @@ impl HirDisplay for Ty { let alias = from_foreign_def_id(*type_alias); let type_alias = db.type_alias_data(alias); f.start_location_link(alias.into()); - write!(f, "{}", type_alias.name)?; + write!(f, "{}", type_alias.name.display(f.db.upcast()))?; f.end_location_link(); } TyKind::OpaqueType(opaque_ty_id, parameters) => { @@ -954,7 +969,11 @@ impl HirDisplay for Ty { match param_data { TypeOrConstParamData::TypeParamData(p) => match p.provenance { TypeParamProvenance::TypeParamList | TypeParamProvenance::TraitSelf => { - write!(f, "{}", p.name.clone().unwrap_or_else(Name::missing))? + write!( + f, + "{}", + p.name.clone().unwrap_or_else(Name::missing).display(f.db.upcast()) + )? } TypeParamProvenance::ArgumentImplTrait => { let substs = generics.placeholder_subst(db); @@ -983,7 +1002,7 @@ impl HirDisplay for Ty { } }, TypeOrConstParamData::ConstParamData(p) => { - write!(f, "{}", p.name)?; + write!(f, "{}", p.name.display(f.db.upcast()))?; } } } @@ -1258,7 +1277,7 @@ fn write_bounds_like_dyn_trait( // existential) here, which is the only thing that's // possible in actual Rust, and hence don't print it f.start_location_link(trait_.into()); - write!(f, "{}", f.db.trait_data(trait_).name)?; + write!(f, "{}", f.db.trait_data(trait_).name.display(f.db.upcast()))?; f.end_location_link(); if let [_, params @ ..] = &*trait_ref.substitution.as_slice(Interner) { if is_fn_trait { @@ -1297,7 +1316,7 @@ fn write_bounds_like_dyn_trait( let assoc_ty_id = from_assoc_type_id(proj.associated_ty_id); let type_alias = f.db.type_alias_data(assoc_ty_id); f.start_location_link(assoc_ty_id.into()); - write!(f, "{}", type_alias.name)?; + write!(f, "{}", type_alias.name.display(f.db.upcast()))?; f.end_location_link(); let proj_arg_count = generics(f.db.upcast(), assoc_ty_id.into()).len_self(); @@ -1364,7 +1383,7 @@ fn fmt_trait_ref( } let trait_ = tr.hir_trait_id(); f.start_location_link(trait_.into()); - write!(f, "{}", f.db.trait_data(trait_).name)?; + write!(f, "{}", f.db.trait_data(trait_).name.display(f.db.upcast()))?; f.end_location_link(); if tr.substitution.len(Interner) > 1 { write!(f, "<")?; @@ -1394,7 +1413,7 @@ impl HirDisplay for WhereClause { write!(f, ">::",)?; let type_alias = from_assoc_type_id(projection_ty.associated_ty_id); f.start_location_link(type_alias.into()); - write!(f, "{}", f.db.type_alias_data(type_alias).name,)?; + write!(f, "{}", f.db.type_alias_data(type_alias).name.display(f.db.upcast()),)?; f.end_location_link(); write!(f, " = ")?; ty.hir_fmt(f)?; @@ -1432,7 +1451,8 @@ impl HirDisplay for LifetimeData { let id = lt_from_placeholder_idx(f.db, *idx); let generics = generics(f.db.upcast(), id.parent); let param_data = &generics.params.lifetimes[id.local_id]; - write!(f, "{}", param_data.name) + write!(f, "{}", param_data.name.display(f.db.upcast()))?; + Ok(()) } LifetimeData::Static => write!(f, "'static"), LifetimeData::Erased => Ok(()), @@ -1508,7 +1528,7 @@ impl HirDisplay for TypeRef { }; write!(f, "&")?; if let Some(lifetime) = lifetime { - write!(f, "{} ", lifetime.name)?; + write!(f, "{} ", lifetime.name.display(f.db.upcast()))?; } write!(f, "{mutability}")?; inner.hir_fmt(f)?; @@ -1516,7 +1536,7 @@ impl HirDisplay for TypeRef { TypeRef::Array(inner, len) => { write!(f, "[")?; inner.hir_fmt(f)?; - write!(f, "; {len}]")?; + write!(f, "; {}]", len.display(f.db.upcast()))?; } TypeRef::Slice(inner) => { write!(f, "[")?; @@ -1533,7 +1553,7 @@ impl HirDisplay for TypeRef { for index in 0..function_parameters.len() { let (param_name, param_type) = &function_parameters[index]; if let Some(name) = param_name { - write!(f, "{name}: ")?; + write!(f, "{}: ", name.display(f.db.upcast()))?; } param_type.hir_fmt(f)?; @@ -1594,9 +1614,13 @@ impl HirDisplay for TypeBound { } path.hir_fmt(f) } - TypeBound::Lifetime(lifetime) => write!(f, "{}", lifetime.name), + TypeBound::Lifetime(lifetime) => write!(f, "{}", lifetime.name.display(f.db.upcast())), TypeBound::ForLifetime(lifetimes, path) => { - write!(f, "for<{}> ", lifetimes.iter().format(", "))?; + write!( + f, + "for<{}> ", + lifetimes.iter().map(|it| it.display(f.db.upcast())).format(", ") + )?; path.hir_fmt(f) } TypeBound::Error => write!(f, "{{error}}"), @@ -1642,7 +1666,7 @@ impl HirDisplay for Path { if !matches!(self.kind(), PathKind::Plain) || seg_idx > 0 { write!(f, "::")?; } - write!(f, "{}", segment.name)?; + write!(f, "{}", segment.name.display(f.db.upcast()))?; if let Some(generic_args) = segment.args_and_bindings { // We should be in type context, so format as `Foo` instead of `Foo::`. // Do we actually format expressions? @@ -1689,7 +1713,7 @@ impl HirDisplay for Path { } else { write!(f, ", ")?; } - write!(f, "{}", binding.name)?; + write!(f, "{}", binding.name.display(f.db.upcast()))?; match &binding.type_ref { Some(ty) => { write!(f, " = ")?; @@ -1712,8 +1736,10 @@ impl HirDisplay for hir_def::path::GenericArg { fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> { match self { hir_def::path::GenericArg::Type(ty) => ty.hir_fmt(f), - hir_def::path::GenericArg::Const(c) => write!(f, "{c}"), - hir_def::path::GenericArg::Lifetime(lifetime) => write!(f, "{}", lifetime.name), + hir_def::path::GenericArg::Const(c) => write!(f, "{}", c.display(f.db.upcast())), + hir_def::path::GenericArg::Lifetime(lifetime) => { + write!(f, "{}", lifetime.name.display(f.db.upcast())) + } } } } diff --git a/crates/hir-ty/src/infer/closure.rs b/crates/hir-ty/src/infer/closure.rs index a7d9246b7c..7878ebcc58 100644 --- a/crates/hir-ty/src/infer/closure.rs +++ b/crates/hir-ty/src/infer/closure.rs @@ -181,7 +181,7 @@ impl CapturedItem { pub fn display_place(&self, owner: DefWithBodyId, db: &dyn HirDatabase) -> String { let body = db.body(owner); - let mut result = body[self.place.local].name.to_string(); + let mut result = body[self.place.local].name.display(db.upcast()).to_string(); let mut field_need_paren = false; for proj in &self.place.projections { match proj { diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs index e4acd10aa9..a1f69b1f28 100644 --- a/crates/hir-ty/src/mir/eval.rs +++ b/crates/hir-ty/src/mir/eval.rs @@ -309,7 +309,12 @@ impl MirEvalError { match func { Either::Left(func) => { let function_name = db.function_data(*func); - writeln!(f, "In function {} ({:?})", function_name.name, func)?; + writeln!( + f, + "In function {} ({:?})", + function_name.name.display(db.upcast()), + func + )?; } Either::Right(clos) => { writeln!(f, "In {:?}", clos)?; @@ -349,7 +354,7 @@ impl MirEvalError { writeln!( f, "Generic arg not provided for {}", - param.name().unwrap_or(&Name::missing()) + param.name().unwrap_or(&Name::missing()).display(db.upcast()) )?; writeln!(f, "Provided args: [")?; for g in subst.iter(Interner) { @@ -362,7 +367,8 @@ impl MirEvalError { writeln!( f, "MIR lowering for function `{}` ({:?}) failed due:", - function_name.name, func + function_name.name.display(db.upcast()), + func )?; err.pretty_print(f, db, span_formatter)?; } @@ -2070,7 +2076,11 @@ impl Evaluator<'_> { Ok(r) => Ok(r), Err(e) => { let data = self.db.enum_data(variant.parent); - let name = format!("{}::{}", data.name, data.variants[variant.local_id].name); + let name = format!( + "{}::{}", + data.name.display(self.db.upcast()), + data.variants[variant.local_id].name.display(self.db.upcast()) + ); Err(MirEvalError::ConstEvalError(name, Box::new(e))) } } diff --git a/crates/hir-ty/src/mir/eval/tests.rs b/crates/hir-ty/src/mir/eval/tests.rs index 0685159f1c..6a9d3c5b4f 100644 --- a/crates/hir-ty/src/mir/eval/tests.rs +++ b/crates/hir-ty/src/mir/eval/tests.rs @@ -13,7 +13,7 @@ fn eval_main(db: &TestDB, file_id: FileId) -> Result<(String, String), MirEvalEr .declarations() .find_map(|x| match x { hir_def::ModuleDefId::FunctionId(x) => { - if db.function_data(x).name.to_string() == "main" { + if db.function_data(x).name.display(db).to_string() == "main" { Some(x) } else { None diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs index f73b25d83f..b77e2c1c80 100644 --- a/crates/hir-ty/src/mir/lower.rs +++ b/crates/hir-ty/src/mir/lower.rs @@ -619,7 +619,7 @@ impl<'ctx> MirLowerCtx<'ctx> { } Expr::MethodCall { receiver, args, method_name, .. } => { let (func_id, generic_args) = - self.infer.method_resolution(expr_id).ok_or_else(|| MirLowerError::UnresolvedMethod(format!("{}", method_name)))?; + self.infer.method_resolution(expr_id).ok_or_else(|| MirLowerError::UnresolvedMethod(method_name.display(self.db.upcast()).to_string()))?; let func = Operand::from_fn(self.db, func_id, generic_args); self.lower_call_and_args( func, @@ -1614,7 +1614,11 @@ impl<'ctx> MirLowerCtx<'ctx> { Ok(r) => Ok(r), Err(e) => { let data = self.db.enum_data(variant.parent); - let name = format!("{}::{}", data.name, data.variants[variant.local_id].name); + let name = format!( + "{}::{}", + data.name.display(self.db.upcast()), + data.variants[variant.local_id].name.display(self.db.upcast()) + ); Err(MirLowerError::ConstEvalError(name, Box::new(e))) } } @@ -1766,13 +1770,17 @@ pub fn mir_body_for_closure_query( pub fn mir_body_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Result> { let _p = profile::span("mir_body_query").detail(|| match def { - DefWithBodyId::FunctionId(it) => db.function_data(it).name.to_string(), - DefWithBodyId::StaticId(it) => db.static_data(it).name.clone().to_string(), - DefWithBodyId::ConstId(it) => { - db.const_data(it).name.clone().unwrap_or_else(Name::missing).to_string() - } + DefWithBodyId::FunctionId(it) => db.function_data(it).name.display(db.upcast()).to_string(), + DefWithBodyId::StaticId(it) => db.static_data(it).name.display(db.upcast()).to_string(), + DefWithBodyId::ConstId(it) => db + .const_data(it) + .name + .clone() + .unwrap_or_else(Name::missing) + .display(db.upcast()) + .to_string(), DefWithBodyId::VariantId(it) => { - db.enum_data(it.parent).variants[it.local_id].name.to_string() + db.enum_data(it.parent).variants[it.local_id].name.display(db.upcast()).to_string() } }); let body = db.body(def); diff --git a/crates/hir-ty/src/mir/pretty.rs b/crates/hir-ty/src/mir/pretty.rs index 257860968c..3821e6a59c 100644 --- a/crates/hir-ty/src/mir/pretty.rs +++ b/crates/hir-ty/src/mir/pretty.rs @@ -42,19 +42,23 @@ impl MirBody { ctx.for_body(|this| match ctx.body.owner { hir_def::DefWithBodyId::FunctionId(id) => { let data = db.function_data(id); - w!(this, "fn {}() ", data.name); + w!(this, "fn {}() ", data.name.display(db.upcast())); } hir_def::DefWithBodyId::StaticId(id) => { let data = db.static_data(id); - w!(this, "static {}: _ = ", data.name); + w!(this, "static {}: _ = ", data.name.display(db.upcast())); } hir_def::DefWithBodyId::ConstId(id) => { let data = db.const_data(id); - w!(this, "const {}: _ = ", data.name.as_ref().unwrap_or(&Name::missing())); + w!( + this, + "const {}: _ = ", + data.name.as_ref().unwrap_or(&Name::missing()).display(db.upcast()) + ); } hir_def::DefWithBodyId::VariantId(id) => { let data = db.enum_data(id.parent); - w!(this, "enum {} = ", data.name); + w!(this, "enum {} = ", data.name.display(db.upcast())); } }); ctx.result @@ -99,11 +103,16 @@ enum LocalName { Binding(Name, LocalId), } -impl Display for LocalName { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl HirDisplay for LocalName { + fn hir_fmt( + &self, + f: &mut crate::display::HirFormatter<'_>, + ) -> Result<(), crate::display::HirDisplayError> { match self { LocalName::Unknown(l) => write!(f, "_{}", u32::from(l.into_raw())), - LocalName::Binding(n, l) => write!(f, "{n}_{}", u32::from(l.into_raw())), + LocalName::Binding(n, l) => { + write!(f, "{}_{}", n.display(f.db.upcast()), u32::from(l.into_raw())) + } } } } @@ -177,7 +186,12 @@ impl<'a> MirPrettyCtx<'a> { fn locals(&mut self) { for (id, local) in self.body.locals.iter() { - wln!(self, "let {}: {};", self.local_name(id), self.hir_display(&local.ty)); + wln!( + self, + "let {}: {};", + self.local_name(id).display(self.db), + self.hir_display(&local.ty) + ); } } @@ -206,10 +220,10 @@ impl<'a> MirPrettyCtx<'a> { wln!(this, ";"); } StatementKind::StorageDead(p) => { - wln!(this, "StorageDead({})", this.local_name(*p)); + wln!(this, "StorageDead({})", this.local_name(*p).display(self.db)); } StatementKind::StorageLive(p) => { - wln!(this, "StorageLive({})", this.local_name(*p)); + wln!(this, "StorageLive({})", this.local_name(*p).display(self.db)); } StatementKind::Deinit(p) => { w!(this, "Deinit("); @@ -267,7 +281,7 @@ impl<'a> MirPrettyCtx<'a> { fn f(this: &mut MirPrettyCtx<'_>, local: LocalId, projections: &[PlaceElem]) { let Some((last, head)) = projections.split_last() else { // no projection - w!(this, "{}", this.local_name(local)); + w!(this, "{}", this.local_name(local).display(this.db)); return; }; match last { @@ -285,11 +299,16 @@ impl<'a> MirPrettyCtx<'a> { f(this, local, head); let variant_name = &this.db.enum_data(e.parent).variants[e.local_id].name; - w!(this, " as {}).{}", variant_name, name); + w!( + this, + " as {}).{}", + variant_name.display(this.db.upcast()), + name.display(this.db.upcast()) + ); } hir_def::VariantId::StructId(_) | hir_def::VariantId::UnionId(_) => { f(this, local, head); - w!(this, ".{name}"); + w!(this, ".{}", name.display(this.db.upcast())); } } } @@ -299,7 +318,7 @@ impl<'a> MirPrettyCtx<'a> { } ProjectionElem::Index(l) => { f(this, local, head); - w!(this, "[{}]", this.local_name(*l)); + w!(this, "[{}]", this.local_name(*l).display(this.db)); } x => { f(this, local, head); diff --git a/crates/hir-ty/src/tls.rs b/crates/hir-ty/src/tls.rs index b7e6ee6740..83814ed0ec 100644 --- a/crates/hir-ty/src/tls.rs +++ b/crates/hir-ty/src/tls.rs @@ -24,7 +24,8 @@ impl DebugContext<'_> { AdtId::UnionId(it) => self.0.union_data(it).name.clone(), AdtId::EnumId(it) => self.0.enum_data(it).name.clone(), }; - name.fmt(f) + name.display(self.0.upcast()).fmt(f)?; + Ok(()) } pub(crate) fn debug_trait_id( @@ -34,7 +35,8 @@ impl DebugContext<'_> { ) -> Result<(), fmt::Error> { let trait_: hir_def::TraitId = from_chalk_trait_id(id); let trait_data = self.0.trait_data(trait_); - trait_data.name.fmt(f) + trait_data.name.display(self.0.upcast()).fmt(f)?; + Ok(()) } pub(crate) fn debug_assoc_type_id( @@ -49,7 +51,13 @@ impl DebugContext<'_> { _ => panic!("associated type not in trait"), }; let trait_data = self.0.trait_data(trait_); - write!(fmt, "{}::{}", trait_data.name, type_alias_data.name) + write!( + fmt, + "{}::{}", + trait_data.name.display(self.0.upcast()), + type_alias_data.name.display(self.0.upcast()) + )?; + Ok(()) } pub(crate) fn debug_projection_ty( @@ -67,7 +75,7 @@ impl DebugContext<'_> { let trait_ref = projection_ty.trait_ref(self.0); let trait_params = trait_ref.substitution.as_slice(Interner); let self_ty = trait_ref.self_type_parameter(Interner); - write!(fmt, "<{self_ty:?} as {trait_name}")?; + write!(fmt, "<{self_ty:?} as {}", trait_name.display(self.0.upcast()))?; if trait_params.len() > 1 { write!( fmt, @@ -75,7 +83,7 @@ impl DebugContext<'_> { trait_params[1..].iter().format_with(", ", |x, f| f(&format_args!("{x:?}"))), )?; } - write!(fmt, ">::{}", type_alias_data.name)?; + write!(fmt, ">::{}", type_alias_data.name.display(self.0.upcast()))?; let proj_params_count = projection_ty.substitution.len(Interner) - trait_params.len(); let proj_params = &projection_ty.substitution.as_slice(Interner)[..proj_params_count]; @@ -105,9 +113,9 @@ impl DebugContext<'_> { } }; match def { - CallableDefId::FunctionId(_) => write!(fmt, "{{fn {name}}}"), + CallableDefId::FunctionId(_) => write!(fmt, "{{fn {}}}", name.display(self.0.upcast())), CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => { - write!(fmt, "{{ctor {name}}}") + write!(fmt, "{{ctor {}}}", name.display(self.0.upcast())) } } } diff --git a/crates/hir-ty/src/traits.rs b/crates/hir-ty/src/traits.rs index 2808fe6435..d2ca6e5ed7 100644 --- a/crates/hir-ty/src/traits.rs +++ b/crates/hir-ty/src/traits.rs @@ -88,7 +88,7 @@ pub(crate) fn trait_solve_query( ) -> Option { let _p = profile::span("trait_solve_query").detail(|| match &goal.value.goal.data(Interner) { GoalData::DomainGoal(DomainGoal::Holds(WhereClause::Implemented(it))) => { - db.trait_data(it.hir_trait_id()).name.to_string() + db.trait_data(it.hir_trait_id()).name.display(db.upcast()).to_string() } GoalData::DomainGoal(DomainGoal::Holds(WhereClause::AliasEq(_))) => "alias_eq".to_string(), _ => "??".to_string(), diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs index 49165ca70e..0c8793c6df 100644 --- a/crates/hir/src/display.rs +++ b/crates/hir/src/display.rs @@ -51,7 +51,7 @@ impl HirDisplay for Function { // FIXME: String escape? write!(f, "extern \"{}\" ", &**abi)?; } - write!(f, "fn {}", data.name)?; + write!(f, "fn {}", data.name.display(f.db.upcast()))?; write_generic_params(GenericDefId::FunctionId(self.id), f)?; @@ -63,7 +63,7 @@ impl HirDisplay for Function { { f.write_char('&')?; if let Some(lifetime) = lifetime { - write!(f, "{} ", lifetime.name)?; + write!(f, "{} ", lifetime.name.display(f.db.upcast()))?; } if let hir_def::type_ref::Mutability::Mut = mut_ { f.write_str("mut ")?; @@ -90,7 +90,7 @@ impl HirDisplay for Function { } } match local { - Some(name) => write!(f, "{name}: ")?, + Some(name) => write!(f, "{}: ", name.display(f.db.upcast()))?, None => f.write_str("_: ")?, } type_ref.hir_fmt(f)?; @@ -151,7 +151,7 @@ impl HirDisplay for Struct { fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> { write_visibility(self.module(f.db).id, self.visibility(f.db), f)?; f.write_str("struct ")?; - write!(f, "{}", self.name(f.db))?; + write!(f, "{}", self.name(f.db).display(f.db.upcast()))?; let def_id = GenericDefId::AdtId(AdtId::StructId(self.id)); write_generic_params(def_id, f)?; write_where_clause(def_id, f)?; @@ -163,7 +163,7 @@ impl HirDisplay for Enum { fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> { write_visibility(self.module(f.db).id, self.visibility(f.db), f)?; f.write_str("enum ")?; - write!(f, "{}", self.name(f.db))?; + write!(f, "{}", self.name(f.db).display(f.db.upcast()))?; let def_id = GenericDefId::AdtId(AdtId::EnumId(self.id)); write_generic_params(def_id, f)?; write_where_clause(def_id, f)?; @@ -175,7 +175,7 @@ impl HirDisplay for Union { fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> { write_visibility(self.module(f.db).id, self.visibility(f.db), f)?; f.write_str("union ")?; - write!(f, "{}", self.name(f.db))?; + write!(f, "{}", self.name(f.db).display(f.db.upcast()))?; let def_id = GenericDefId::AdtId(AdtId::UnionId(self.id)); write_generic_params(def_id, f)?; write_where_clause(def_id, f)?; @@ -186,14 +186,14 @@ impl HirDisplay for Union { impl HirDisplay for Field { fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> { write_visibility(self.parent.module(f.db).id, self.visibility(f.db), f)?; - write!(f, "{}: ", self.name(f.db))?; + write!(f, "{}: ", self.name(f.db).display(f.db.upcast()))?; self.ty(f.db).hir_fmt(f) } } impl HirDisplay for Variant { fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> { - write!(f, "{}", self.name(f.db))?; + write!(f, "{}", self.name(f.db).display(f.db.upcast()))?; let data = self.variant_data(f.db); match &*data { VariantData::Unit => {} @@ -222,7 +222,7 @@ impl HirDisplay for Variant { f.write_str(", ")?; } // Enum variant fields must be pub. - write!(f, "{}: ", field.name)?; + write!(f, "{}: ", field.name.display(f.db.upcast()))?; field.type_ref.hir_fmt(f)?; } f.write_str(" }")?; @@ -259,7 +259,7 @@ impl HirDisplay for TypeOrConstParam { impl HirDisplay for TypeParam { fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> { - write!(f, "{}", self.name(f.db))?; + write!(f, "{}", self.name(f.db).display(f.db.upcast()))?; if f.omit_verbose_types() { return Ok(()); } @@ -286,13 +286,13 @@ impl HirDisplay for TypeParam { impl HirDisplay for LifetimeParam { fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> { - write!(f, "{}", self.name(f.db)) + write!(f, "{}", self.name(f.db).display(f.db.upcast())) } } impl HirDisplay for ConstParam { fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> { - write!(f, "const {}: ", self.name(f.db))?; + write!(f, "const {}: ", self.name(f.db).display(f.db.upcast()))?; self.ty(f.db).hir_fmt(f) } } @@ -325,7 +325,7 @@ fn write_generic_params( }; for (_, lifetime) in params.lifetimes.iter() { delim(f)?; - write!(f, "{}", lifetime.name)?; + write!(f, "{}", lifetime.name.display(f.db.upcast()))?; } for (_, ty) in params.type_or_consts.iter() { if let Some(name) = &ty.name() { @@ -335,7 +335,7 @@ fn write_generic_params( continue; } delim(f)?; - write!(f, "{name}")?; + write!(f, "{}", name.display(f.db.upcast()))?; if let Some(default) = &ty.default { f.write_str(" = ")?; default.hir_fmt(f)?; @@ -343,7 +343,7 @@ fn write_generic_params( } TypeOrConstParamData::ConstParamData(c) => { delim(f)?; - write!(f, "const {name}: ")?; + write!(f, "const {}: ", name.display(f.db.upcast()))?; c.ty.hir_fmt(f)?; } } @@ -380,7 +380,7 @@ fn write_where_clause(def: GenericDefId, f: &mut HirFormatter<'_>) -> Result<(), WherePredicateTypeTarget::TypeRef(ty) => ty.hir_fmt(f), WherePredicateTypeTarget::TypeOrConstParam(id) => { match ¶ms.type_or_consts[*id].name() { - Some(name) => write!(f, "{name}"), + Some(name) => write!(f, "{}", name.display(f.db.upcast())), None => f.write_str("{unnamed}"), } } @@ -412,10 +412,15 @@ fn write_where_clause(def: GenericDefId, f: &mut HirFormatter<'_>) -> Result<(), WherePredicate::Lifetime { target, bound } => { if matches!(prev_pred, Some(WherePredicate::Lifetime { target: target_, .. }) if target_ == target) { - write!(f, " + {}", bound.name)?; + write!(f, " + {}", bound.name.display(f.db.upcast()))?; } else { new_predicate(f)?; - write!(f, "{}: {}", target.name, bound.name)?; + write!( + f, + "{}: {}", + target.name.display(f.db.upcast()), + bound.name.display(f.db.upcast()) + )?; } } WherePredicate::ForLifetime { lifetimes, target, bound } => { @@ -432,7 +437,7 @@ fn write_where_clause(def: GenericDefId, f: &mut HirFormatter<'_>) -> Result<(), if idx != 0 { f.write_str(", ")?; } - write!(f, "{lifetime}")?; + write!(f, "{}", lifetime.display(f.db.upcast()))?; } f.write_str("> ")?; write_target(target, f)?; @@ -462,7 +467,7 @@ impl HirDisplay for Const { let data = db.const_data(self.id); f.write_str("const ")?; match &data.name { - Some(name) => write!(f, "{name}: ")?, + Some(name) => write!(f, "{}: ", name.display(f.db.upcast()))?, None => f.write_str("_: ")?, } data.type_ref.hir_fmt(f)?; @@ -478,7 +483,7 @@ impl HirDisplay for Static { if data.mutable { f.write_str("mut ")?; } - write!(f, "{}: ", &data.name)?; + write!(f, "{}: ", data.name.display(f.db.upcast()))?; data.type_ref.hir_fmt(f)?; Ok(()) } @@ -494,7 +499,7 @@ impl HirDisplay for Trait { if data.is_auto { f.write_str("auto ")?; } - write!(f, "trait {}", data.name)?; + write!(f, "trait {}", data.name.display(f.db.upcast()))?; let def_id = GenericDefId::TraitId(self.id); write_generic_params(def_id, f)?; write_where_clause(def_id, f)?; @@ -506,7 +511,7 @@ impl HirDisplay for TraitAlias { fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> { write_visibility(self.module(f.db).id, self.visibility(f.db), f)?; let data = f.db.trait_alias_data(self.id); - write!(f, "trait {}", data.name)?; + write!(f, "trait {}", data.name.display(f.db.upcast()))?; let def_id = GenericDefId::TraitAliasId(self.id); write_generic_params(def_id, f)?; f.write_str(" = ")?; @@ -522,7 +527,7 @@ impl HirDisplay for TypeAlias { fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> { write_visibility(self.module(f.db).id, self.visibility(f.db), f)?; let data = f.db.type_alias_data(self.id); - write!(f, "type {}", data.name)?; + write!(f, "type {}", data.name.display(f.db.upcast()))?; let def_id = GenericDefId::TypeAliasId(self.id); write_generic_params(def_id, f)?; write_where_clause(def_id, f)?; @@ -542,7 +547,7 @@ impl HirDisplay for Module { fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> { // FIXME: Module doesn't have visibility saved in data. match self.name(f.db) { - Some(name) => write!(f, "mod {name}"), + Some(name) => write!(f, "mod {}", name.display(f.db.upcast())), None if self.is_crate_root(f.db) => match self.krate(f.db).display_name(f.db) { Some(name) => write!(f, "extern crate {name}"), None => f.write_str("extern crate {unknown}"), @@ -559,6 +564,6 @@ impl HirDisplay for Macro { hir_def::MacroId::MacroRulesId(_) => f.write_str("macro_rules!"), hir_def::MacroId::ProcMacroId(_) => f.write_str("proc_macro"), }?; - write!(f, " {}", self.name(f.db)) + write!(f, " {}", self.name(f.db).display(f.db.upcast())) } } diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 8fac7fcd87..64f9745276 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -329,7 +329,7 @@ impl ModuleDef { segments.extend(m.name(db)) } segments.reverse(); - Some(segments.into_iter().join("::")) + Some(segments.iter().map(|it| it.display(db.upcast())).join("::")) } pub fn canonical_module_path( @@ -555,7 +555,11 @@ impl Module { /// Fills `acc` with the module's diagnostics. pub fn diagnostics(self, db: &dyn HirDatabase, acc: &mut Vec) { let _p = profile::span("Module::diagnostics").detail(|| { - format!("{:?}", self.name(db).map_or("".into(), |name| name.to_string())) + format!( + "{:?}", + self.name(db) + .map_or("".into(), |name| name.display(db.upcast()).to_string()) + ) }); let def_map = self.id.def_map(db.upcast()); for diag in def_map.diagnostics() { diff --git a/crates/ide-assists/src/handlers/add_missing_impl_members.rs b/crates/ide-assists/src/handlers/add_missing_impl_members.rs index 9e4e6c1daf..a35a62b8b3 100644 --- a/crates/ide-assists/src/handlers/add_missing_impl_members.rs +++ b/crates/ide-assists/src/handlers/add_missing_impl_members.rs @@ -184,7 +184,8 @@ fn try_gen_trait_body( trait_ref: hir::TraitRef, impl_def: &ast::Impl, ) -> Option<()> { - let trait_path = make::ext::ident_path(&trait_ref.trait_().name(ctx.db()).to_string()); + let trait_path = + make::ext::ident_path(&trait_ref.trait_().name(ctx.db()).display(ctx.db()).to_string()); let hir_ty = ctx.sema.resolve_type(&impl_def.self_ty()?)?; let adt = hir_ty.as_adt()?.source(ctx.db())?; gen_trait_fn_body(func, &trait_path, &adt.value, Some(trait_ref)) diff --git a/crates/ide-assists/src/handlers/auto_import.rs b/crates/ide-assists/src/handlers/auto_import.rs index 17ffb861fd..7acf2ea0a0 100644 --- a/crates/ide-assists/src/handlers/auto_import.rs +++ b/crates/ide-assists/src/handlers/auto_import.rs @@ -132,7 +132,7 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option< acc.add_group( &group_label, AssistId("auto_import", AssistKind::QuickFix), - format!("Import `{import_path}`"), + format!("Import `{}`", import_path.display(ctx.db())), range, |builder| { let scope = match scope.clone() { diff --git a/crates/ide-assists/src/handlers/convert_bool_then.rs b/crates/ide-assists/src/handlers/convert_bool_then.rs index db96ad3304..1af52c5921 100644 --- a/crates/ide-assists/src/handlers/convert_bool_then.rs +++ b/crates/ide-assists/src/handlers/convert_bool_then.rs @@ -160,7 +160,7 @@ pub(crate) fn convert_bool_then_to_if(acc: &mut Assists, ctx: &AssistContext<'_> }; // Verify this is `bool::then` that is being called. let func = ctx.sema.resolve_method_call(&mcall)?; - if func.name(ctx.sema.db).to_string() != "then" { + if func.name(ctx.sema.db).display(ctx.db()).to_string() != "then" { return None; } let assoc = func.as_assoc_item(ctx.sema.db)?; diff --git a/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs b/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs index 9e1d9a702a..db96c8fe40 100644 --- a/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs +++ b/crates/ide-assists/src/handlers/convert_iter_for_each_to_for.rs @@ -119,7 +119,7 @@ pub(crate) fn convert_for_loop_with_for_each( { // We have either "for x in &col" and col implements a method called iter // or "for x in &mut col" and col implements a method called iter_mut - format_to!(buf, "{expr_behind_ref}.{method}()"); + format_to!(buf, "{expr_behind_ref}.{}()", method.display(ctx.db())); } else if let ast::Expr::RangeExpr(..) = iterable { // range expressions need to be parenthesized for the syntax to be correct format_to!(buf, "({iterable})"); diff --git a/crates/ide-assists/src/handlers/expand_glob_import.rs b/crates/ide-assists/src/handlers/expand_glob_import.rs index 87f5018fb6..5c435dd9c2 100644 --- a/crates/ide-assists/src/handlers/expand_glob_import.rs +++ b/crates/ide-assists/src/handlers/expand_glob_import.rs @@ -65,7 +65,7 @@ pub(crate) fn expand_glob_import(acc: &mut Assists, ctx: &AssistContext<'_>) -> let names_to_import = find_names_to_import(ctx, refs_in_target, imported_defs); let expanded = make::use_tree_list(names_to_import.iter().map(|n| { - let path = make::ext::ident_path(&n.to_string()); + let path = make::ext::ident_path(&n.display(ctx.db()).to_string()); make::use_tree(path, None, None, false) })) .clone_for_update(); diff --git a/crates/ide-assists/src/handlers/extract_function.rs b/crates/ide-assists/src/handlers/extract_function.rs index c29721b464..62cc748829 100644 --- a/crates/ide-assists/src/handlers/extract_function.rs +++ b/crates/ide-assists/src/handlers/extract_function.rs @@ -183,7 +183,9 @@ pub(crate) fn extract_function(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op fn make_function_name(semantics_scope: &hir::SemanticsScope<'_>) -> ast::NameRef { let mut names_in_scope = vec![]; - semantics_scope.process_all_names(&mut |name, _| names_in_scope.push(name.to_string())); + semantics_scope.process_all_names(&mut |name, _| { + names_in_scope.push(name.display(semantics_scope.db.upcast()).to_string()) + }); let default_name = "fun_name"; @@ -443,7 +445,7 @@ impl Param { } fn to_param(&self, ctx: &AssistContext<'_>, module: hir::Module) -> ast::Param { - let var = self.var.name(ctx.db()).to_string(); + let var = self.var.name(ctx.db()).display(ctx.db()).to_string(); let var_name = make::name(&var); let pat = match self.kind() { ParamKind::MutValue => make::ident_pat(false, true, var_name), @@ -473,7 +475,8 @@ impl TryKind { let name = adt.name(ctx.db()); // FIXME: use lang items to determine if it is std type or user defined // E.g. if user happens to define type named `Option`, we would have false positive - match name.to_string().as_str() { + let name = &name.display(ctx.db()).to_string(); + match name.as_str() { "Option" => Some(TryKind::Option), "Result" => Some(TryKind::Result { ty }), _ => None, @@ -1341,14 +1344,15 @@ fn make_call(ctx: &AssistContext<'_>, fun: &Function, indent: IndentLevel) -> St [var] => { let modifier = mut_modifier(var); let name = var.local.name(ctx.db()); - format_to!(buf, "let {modifier}{name} = ") + format_to!(buf, "let {modifier}{} = ", name.display(ctx.db())) } vars => { buf.push_str("let ("); let bindings = vars.iter().format_with(", ", |local, f| { let modifier = mut_modifier(local); let name = local.local.name(ctx.db()); - f(&format_args!("{modifier}{name}")) + f(&format_args!("{modifier}{}", name.display(ctx.db())))?; + Ok(()) }); format_to!(buf, "{bindings}"); buf.push_str(") = "); @@ -1487,7 +1491,7 @@ impl FlowHandler { } fn path_expr_from_local(ctx: &AssistContext<'_>, var: Local) -> ast::Expr { - let name = var.name(ctx.db()).to_string(); + let name = var.name(ctx.db()).display(ctx.db()).to_string(); make::expr_path(make::ext::ident_path(&name)) } diff --git a/crates/ide-assists/src/handlers/extract_module.rs b/crates/ide-assists/src/handlers/extract_module.rs index 795691d73e..de37f5f130 100644 --- a/crates/ide-assists/src/handlers/extract_module.rs +++ b/crates/ide-assists/src/handlers/extract_module.rs @@ -904,7 +904,7 @@ fn compare_hir_and_ast_module( ) -> Option<()> { let hir_mod_name = hir_module.name(ctx.db())?; let ast_mod_name = ast_module.name()?; - if hir_mod_name.to_string() != ast_mod_name.to_string() { + if hir_mod_name.display(ctx.db()).to_string() != ast_mod_name.to_string() { return None; } diff --git a/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs b/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs index f75df28786..e4f64ccc75 100644 --- a/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs +++ b/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs @@ -158,7 +158,7 @@ fn existing_definition(db: &RootDatabase, variant_name: &ast::Name, variant: &Va ), _ => false, }) - .any(|(name, _)| name.to_string() == variant_name.to_string()) + .any(|(name, _)| name.display(db).to_string() == variant_name.to_string()) } fn extract_generic_params( diff --git a/crates/ide-assists/src/handlers/fix_visibility.rs b/crates/ide-assists/src/handlers/fix_visibility.rs index 4c61678eab..d6c59a9c82 100644 --- a/crates/ide-assists/src/handlers/fix_visibility.rs +++ b/crates/ide-assists/src/handlers/fix_visibility.rs @@ -62,7 +62,9 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext<'_>) let assist_label = match target_name { None => format!("Change visibility to {missing_visibility}"), - Some(name) => format!("Change visibility of {name} to {missing_visibility}"), + Some(name) => { + format!("Change visibility of {} to {missing_visibility}", name.display(ctx.db())) + } }; acc.add(AssistId("fix_visibility", AssistKind::QuickFix), assist_label, target, |builder| { @@ -117,8 +119,11 @@ fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext<'_> let target_file = in_file_source.file_id.original_file(ctx.db()); let target_name = record_field_def.name(ctx.db()); - let assist_label = - format!("Change visibility of {parent_name}.{target_name} to {missing_visibility}"); + let assist_label = format!( + "Change visibility of {}.{} to {missing_visibility}", + parent_name.display(ctx.db()), + target_name.display(ctx.db()) + ); acc.add(AssistId("fix_visibility", AssistKind::QuickFix), assist_label, target, |builder| { builder.edit_file(target_file); diff --git a/crates/ide-assists/src/handlers/generate_delegate_methods.rs b/crates/ide-assists/src/handlers/generate_delegate_methods.rs index a0813c9115..c6d0ebd702 100644 --- a/crates/ide-assists/src/handlers/generate_delegate_methods.rs +++ b/crates/ide-assists/src/handlers/generate_delegate_methods.rs @@ -85,13 +85,16 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<' for method in methods { let adt = ast::Adt::Struct(strukt.clone()); - let name = method.name(ctx.db()).to_string(); + let name = method.name(ctx.db()).display(ctx.db()).to_string(); // if `find_struct_impl` returns None, that means that a function named `name` already exists. let Some(impl_def) = find_struct_impl(ctx, &adt, &[name]) else { continue; }; acc.add_group( &GroupLabel("Generate delegate methods…".to_owned()), AssistId("generate_delegate_methods", AssistKind::Generate), - format!("Generate delegate for `{field_name}.{}()`", method.name(ctx.db())), + format!( + "Generate delegate for `{field_name}.{}()`", + method.name(ctx.db()).display(ctx.db()) + ), target, |builder| { // Create the function @@ -101,7 +104,7 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<' }; let method_name = method.name(ctx.db()); let vis = method_source.visibility(); - let name = make::name(&method.name(ctx.db()).to_string()); + let name = make::name(&method.name(ctx.db()).display(ctx.db()).to_string()); let params = method_source.param_list().unwrap_or_else(|| make::param_list(None, [])); let type_params = method_source.generic_param_list(); @@ -111,7 +114,7 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<' }; let tail_expr = make::expr_method_call( make::ext::field_from_idents(["self", &field_name]).unwrap(), // This unwrap is ok because we have at least 1 arg in the list - make::name_ref(&method_name.to_string()), + make::name_ref(&method_name.display(ctx.db()).to_string()), arg_list, ); let ret_type = method_source.ret_type(); diff --git a/crates/ide-assists/src/handlers/generate_deref.rs b/crates/ide-assists/src/handlers/generate_deref.rs index b6958e2919..8154539617 100644 --- a/crates/ide-assists/src/handlers/generate_deref.rs +++ b/crates/ide-assists/src/handlers/generate_deref.rs @@ -70,6 +70,7 @@ fn generate_record_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<( target, |edit| { generate_edit( + ctx.db(), edit, strukt, field_type.syntax(), @@ -109,6 +110,7 @@ fn generate_tuple_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<() target, |edit| { generate_edit( + ctx.db(), edit, strukt, field_type.syntax(), @@ -121,6 +123,7 @@ fn generate_tuple_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<() } fn generate_edit( + db: &RootDatabase, edit: &mut SourceChangeBuilder, strukt: ast::Struct, field_type_syntax: &SyntaxNode, @@ -144,7 +147,8 @@ fn generate_edit( ), }; let strukt_adt = ast::Adt::Struct(strukt); - let deref_impl = generate_trait_impl_text(&strukt_adt, &trait_path.to_string(), &impl_code); + let deref_impl = + generate_trait_impl_text(&strukt_adt, &trait_path.display(db).to_string(), &impl_code); edit.insert(start_offset, deref_impl); } diff --git a/crates/ide-assists/src/handlers/generate_function.rs b/crates/ide-assists/src/handlers/generate_function.rs index 739b466b31..4634cfc189 100644 --- a/crates/ide-assists/src/handlers/generate_function.rs +++ b/crates/ide-assists/src/handlers/generate_function.rs @@ -196,7 +196,7 @@ fn add_func_to_accumulator( let mut func = function_template.to_string(ctx.config.snippet_cap); if let Some(name) = adt_name { // FIXME: adt may have generic params. - func = format!("\n{indent}impl {name} {{\n{func}\n{indent}}}"); + func = format!("\n{indent}impl {} {{\n{func}\n{indent}}}", name.display(ctx.db())); } builder.edit_file(file); match ctx.config.snippet_cap { diff --git a/crates/ide-assists/src/handlers/move_const_to_impl.rs b/crates/ide-assists/src/handlers/move_const_to_impl.rs index d848fce4be..b6027eac55 100644 --- a/crates/ide-assists/src/handlers/move_const_to_impl.rs +++ b/crates/ide-assists/src/handlers/move_const_to_impl.rs @@ -98,7 +98,7 @@ pub(crate) fn move_const_to_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> }; builder.delete(range_to_delete); - let const_ref = format!("Self::{name}"); + let const_ref = format!("Self::{}", name.display(ctx.db())); for range in usages.all().file_ranges().map(|it| it.range) { builder.replace(range, const_ref.clone()); } diff --git a/crates/ide-assists/src/handlers/move_from_mod_rs.rs b/crates/ide-assists/src/handlers/move_from_mod_rs.rs index 1728c03cd0..917d0b3671 100644 --- a/crates/ide-assists/src/handlers/move_from_mod_rs.rs +++ b/crates/ide-assists/src/handlers/move_from_mod_rs.rs @@ -39,7 +39,7 @@ pub(crate) fn move_from_mod_rs(acc: &mut Assists, ctx: &AssistContext<'_>) -> Op } let target = source_file.syntax().text_range(); - let module_name = module.name(ctx.db())?.to_string(); + let module_name = module.name(ctx.db())?.display(ctx.db()).to_string(); let path = format!("../{module_name}.rs"); let dst = AnchoredPathBuf { anchor: ctx.file_id(), path }; acc.add( diff --git a/crates/ide-assists/src/handlers/move_module_to_file.rs b/crates/ide-assists/src/handlers/move_module_to_file.rs index a7c605325e..166b25c69e 100644 --- a/crates/ide-assists/src/handlers/move_module_to_file.rs +++ b/crates/ide-assists/src/handlers/move_module_to_file.rs @@ -52,7 +52,7 @@ pub(crate) fn move_module_to_file(acc: &mut Assists, ctx: &AssistContext<'_>) -> let mut buf = String::from("./"); match parent_module.name(ctx.db()) { Some(name) if !parent_module.is_mod_rs(ctx.db()) => { - format_to!(buf, "{name}/") + format_to!(buf, "{}/", name.display(ctx.db())) } _ => (), } diff --git a/crates/ide-assists/src/handlers/move_to_mod_rs.rs b/crates/ide-assists/src/handlers/move_to_mod_rs.rs index 076d25411a..b73270cd05 100644 --- a/crates/ide-assists/src/handlers/move_to_mod_rs.rs +++ b/crates/ide-assists/src/handlers/move_to_mod_rs.rs @@ -39,7 +39,7 @@ pub(crate) fn move_to_mod_rs(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti } let target = source_file.syntax().text_range(); - let module_name = module.name(ctx.db())?.to_string(); + let module_name = module.name(ctx.db())?.display(ctx.db()).to_string(); let path = format!("./{module_name}/mod.rs"); let dst = AnchoredPathBuf { anchor: ctx.file_id(), path }; acc.add( diff --git a/crates/ide-assists/src/handlers/qualify_path.rs b/crates/ide-assists/src/handlers/qualify_path.rs index e759e1561c..239149dc41 100644 --- a/crates/ide-assists/src/handlers/qualify_path.rs +++ b/crates/ide-assists/src/handlers/qualify_path.rs @@ -86,7 +86,7 @@ pub(crate) fn qualify_path(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option acc.add_group( &group_label, AssistId("qualify_path", AssistKind::QuickFix), - label(candidate, &import), + label(ctx.db(), candidate, &import), range, |builder| { qualify_candidate.qualify( @@ -186,7 +186,7 @@ fn find_trait_method( if let Some(hir::AssocItem::Function(method)) = trait_.items(db).into_iter().find(|item: &hir::AssocItem| { item.name(db) - .map(|name| name.to_string() == trait_method_name.to_string()) + .map(|name| name.display(db).to_string() == trait_method_name.to_string()) .unwrap_or(false) }) { @@ -216,14 +216,14 @@ fn group_label(candidate: &ImportCandidate) -> GroupLabel { GroupLabel(format!("Qualify {name}")) } -fn label(candidate: &ImportCandidate, import: &LocatedImport) -> String { +fn label(db: &RootDatabase, candidate: &ImportCandidate, import: &LocatedImport) -> String { let import_path = &import.import_path; match candidate { ImportCandidate::Path(candidate) if candidate.qualifier.is_none() => { - format!("Qualify as `{import_path}`") + format!("Qualify as `{}`", import_path.display(db)) } - _ => format!("Qualify with `{import_path}`"), + _ => format!("Qualify with `{}`", import_path.display(db)), } } diff --git a/crates/ide-assists/src/handlers/reorder_fields.rs b/crates/ide-assists/src/handlers/reorder_fields.rs index cd977a68a6..0256256697 100644 --- a/crates/ide-assists/src/handlers/reorder_fields.rs +++ b/crates/ide-assists/src/handlers/reorder_fields.rs @@ -97,7 +97,7 @@ fn compute_fields_ranks( .fields(ctx.db()) .into_iter() .enumerate() - .map(|(idx, field)| (field.name(ctx.db()).to_string(), idx)) + .map(|(idx, field)| (field.name(ctx.db()).display(ctx.db()).to_string(), idx)) .collect(); Some(res) diff --git a/crates/ide-assists/src/handlers/reorder_impl_items.rs b/crates/ide-assists/src/handlers/reorder_impl_items.rs index af96950761..6666966231 100644 --- a/crates/ide-assists/src/handlers/reorder_impl_items.rs +++ b/crates/ide-assists/src/handlers/reorder_impl_items.rs @@ -114,7 +114,7 @@ fn compute_item_ranks( .iter() .flat_map(|i| i.name(ctx.db())) .enumerate() - .map(|(idx, name)| (name.to_string(), idx)) + .map(|(idx, name)| (name.display(ctx.db()).to_string(), idx)) .collect(), ) } diff --git a/crates/ide-assists/src/utils/suggest_name.rs b/crates/ide-assists/src/utils/suggest_name.rs index c521a10fcc..f74ebfae02 100644 --- a/crates/ide-assists/src/utils/suggest_name.rs +++ b/crates/ide-assists/src/utils/suggest_name.rs @@ -234,7 +234,7 @@ fn from_type(expr: &ast::Expr, sema: &Semantics<'_, RootDatabase>) -> Option Option { let name = if let Some(adt) = ty.as_adt() { - let name = adt.name(db).to_string(); + let name = adt.name(db).display(db).to_string(); if WRAPPER_TYPES.contains(&name.as_str()) { let inner_ty = ty.type_arguments().next()?; @@ -258,7 +258,7 @@ fn name_of_type(ty: &hir::Type, db: &RootDatabase) -> Option { } fn trait_name(trait_: &hir::Trait, db: &RootDatabase) -> Option { - let name = trait_.name(db).to_string(); + let name = trait_.name(db).display(db).to_string(); if USELESS_TRAITS.contains(&name.as_str()) { return None; } diff --git a/crates/ide-completion/src/completions.rs b/crates/ide-completion/src/completions.rs index 87346f501d..d53e9e2fa9 100644 --- a/crates/ide-completion/src/completions.rs +++ b/crates/ide-completion/src/completions.rs @@ -24,7 +24,7 @@ pub(crate) mod env_vars; use std::iter; use hir::{known, HasAttrs, ScopeDef, Variant}; -use ide_db::{imports::import_assets::LocatedImport, SymbolKind}; +use ide_db::{imports::import_assets::LocatedImport, RootDatabase, SymbolKind}; use syntax::ast; use crate::{ @@ -62,8 +62,8 @@ impl From for Vec { impl Builder { /// Convenience method, which allows to add a freshly created completion into accumulator /// without binding it to the variable. - pub(crate) fn add_to(self, acc: &mut Completions) { - acc.add(self.build()) + pub(crate) fn add_to(self, acc: &mut Completions, db: &RootDatabase) { + acc.add(self.build(db)) } } @@ -80,7 +80,7 @@ impl Completions { pub(crate) fn add_keyword(&mut self, ctx: &CompletionContext<'_>, keyword: &'static str) { let item = CompletionItem::new(CompletionItemKind::Keyword, ctx.source_range(), keyword); - item.add_to(self); + item.add_to(self, ctx.db); } pub(crate) fn add_nameref_keywords_with_colon(&mut self, ctx: &CompletionContext<'_>) { @@ -134,7 +134,7 @@ impl Completions { item.insert_text(if snippet.contains('$') { kw } else { snippet }); } }; - item.add_to(self); + item.add_to(self, ctx.db); } pub(crate) fn add_keyword_snippet( @@ -149,7 +149,7 @@ impl Completions { Some(cap) => item.insert_snippet(cap, snippet), None => item.insert_text(if snippet.contains('$') { kw } else { snippet }), }; - item.add_to(self); + item.add_to(self, ctx.db); } pub(crate) fn add_crate_roots( @@ -190,7 +190,7 @@ impl Completions { local_name, resolution, ) - .build(), + .build(ctx.db), ); } @@ -216,7 +216,7 @@ impl Completions { local_name, resolution, ) - .build(), + .build(ctx.db), ); } @@ -276,7 +276,7 @@ impl Completions { local_name, mac, ) - .build(), + .build(ctx.db), ); } @@ -305,7 +305,7 @@ impl Completions { local_name, func, ) - .build(), + .build(ctx.db), ); } @@ -336,7 +336,7 @@ impl Completions { local_name, func, ) - .build(), + .build(ctx.db), ); } @@ -367,7 +367,7 @@ impl Completions { None, func, ) - .build(), + .build(ctx.db), ); } @@ -429,7 +429,7 @@ impl Completions { if let Some(builder) = render_variant_lit(RenderContext::new(ctx), path_ctx, None, variant, Some(path)) { - self.add(builder.build()); + self.add(builder.build(ctx.db)); } } @@ -452,7 +452,7 @@ impl Completions { if let Some(builder) = render_variant_lit(RenderContext::new(ctx), path_ctx, local_name, variant, None) { - self.add(builder.build()); + self.add(builder.build(ctx.db)); } } @@ -497,7 +497,7 @@ impl Completions { if let Some(builder) = render_struct_literal(RenderContext::new(ctx), path_ctx, strukt, path, local_name) { - self.add(builder.build()); + self.add(builder.build(ctx.db)); } } @@ -530,11 +530,12 @@ impl Completions { pub(crate) fn add_lifetime(&mut self, ctx: &CompletionContext<'_>, name: hir::Name) { CompletionItem::new(SymbolKind::LifetimeParam, ctx.source_range(), name.to_smol_str()) - .add_to(self) + .add_to(self, ctx.db) } pub(crate) fn add_label(&mut self, ctx: &CompletionContext<'_>, name: hir::Name) { - CompletionItem::new(SymbolKind::Label, ctx.source_range(), name.to_smol_str()).add_to(self) + CompletionItem::new(SymbolKind::Label, ctx.source_range(), name.to_smol_str()) + .add_to(self, ctx.db) } pub(crate) fn add_variant_pat( diff --git a/crates/ide-completion/src/completions/attribute.rs b/crates/ide-completion/src/completions/attribute.rs index 13c5832a51..466f0b1fb7 100644 --- a/crates/ide-completion/src/completions/attribute.rs +++ b/crates/ide-completion/src/completions/attribute.rs @@ -139,7 +139,7 @@ pub(crate) fn complete_attribute_path( } if is_inner || !attr_completion.prefer_inner { - item.add_to(acc); + item.add_to(acc, ctx.db); } }; diff --git a/crates/ide-completion/src/completions/attribute/cfg.rs b/crates/ide-completion/src/completions/attribute/cfg.rs index 7ef4ff30b5..19bfd294b2 100644 --- a/crates/ide-completion/src/completions/attribute/cfg.rs +++ b/crates/ide-completion/src/completions/attribute/cfg.rs @@ -12,7 +12,7 @@ pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext<'_>) { let add_completion = |item: &str| { let mut completion = CompletionItem::new(SymbolKind::BuiltinAttr, ctx.source_range(), item); completion.insert_text(format!(r#""{item}""#)); - acc.add(completion.build()); + acc.add(completion.build(ctx.db)); }; let previous = iter::successors(ctx.original_token.prev_token(), |t| { @@ -33,11 +33,11 @@ pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext<'_>) { let mut item = CompletionItem::new(SymbolKind::BuiltinAttr, ctx.source_range(), s); item.insert_text(insert_text); - acc.add(item.build()); + acc.add(item.build(ctx.db)); }), None => ctx.krate.potential_cfg(ctx.db).get_cfg_keys().cloned().unique().for_each(|s| { let item = CompletionItem::new(SymbolKind::BuiltinAttr, ctx.source_range(), s); - acc.add(item.build()); + acc.add(item.build(ctx.db)); }), }; } diff --git a/crates/ide-completion/src/completions/attribute/derive.rs b/crates/ide-completion/src/completions/attribute/derive.rs index a92fe6c7bc..9447bc7db0 100644 --- a/crates/ide-completion/src/completions/attribute/derive.rs +++ b/crates/ide-completion/src/completions/attribute/derive.rs @@ -90,7 +90,7 @@ pub(crate) fn complete_derive_path( item.documentation(docs); } item.lookup_by(lookup); - item.add_to(acc); + item.add_to(acc, ctx.db); } None => acc.add_macro(ctx, path_ctx, mac, name), } diff --git a/crates/ide-completion/src/completions/attribute/lint.rs b/crates/ide-completion/src/completions/attribute/lint.rs index 818c3cfd5f..6bc6f34ed4 100644 --- a/crates/ide-completion/src/completions/attribute/lint.rs +++ b/crates/ide-completion/src/completions/attribute/lint.rs @@ -56,6 +56,6 @@ pub(super) fn complete_lint( }; let mut item = CompletionItem::new(SymbolKind::Attribute, ctx.source_range(), label); item.documentation(hir::Documentation::new(description.to_owned())); - item.add_to(acc) + item.add_to(acc, ctx.db) } } diff --git a/crates/ide-completion/src/completions/attribute/repr.rs b/crates/ide-completion/src/completions/attribute/repr.rs index a29417133e..14f464b775 100644 --- a/crates/ide-completion/src/completions/attribute/repr.rs +++ b/crates/ide-completion/src/completions/attribute/repr.rs @@ -37,7 +37,7 @@ pub(super) fn complete_repr( if let Some((snippet, cap)) = snippet.zip(ctx.config.snippet_cap) { item.insert_snippet(cap, snippet); } - item.add_to(acc); + item.add_to(acc, ctx.db); } } } diff --git a/crates/ide-completion/src/completions/dot.rs b/crates/ide-completion/src/completions/dot.rs index ba76634016..57a784c45b 100644 --- a/crates/ide-completion/src/completions/dot.rs +++ b/crates/ide-completion/src/completions/dot.rs @@ -23,7 +23,7 @@ pub(crate) fn complete_dot( let mut item = CompletionItem::new(CompletionItemKind::Keyword, ctx.source_range(), "await"); item.detail("expr.await"); - item.add_to(acc); + item.add_to(acc, ctx.db); } if let DotAccessKind::Method { .. } = dot_access.kind { diff --git a/crates/ide-completion/src/completions/env_vars.rs b/crates/ide-completion/src/completions/env_vars.rs index c525e0c807..419b864565 100644 --- a/crates/ide-completion/src/completions/env_vars.rs +++ b/crates/ide-completion/src/completions/env_vars.rs @@ -40,7 +40,7 @@ pub(crate) fn complete_cargo_env_vars( CARGO_DEFINED_VARS.into_iter().for_each(|&(var, detail)| { let mut item = CompletionItem::new(CompletionItemKind::Keyword, range, var); item.detail(detail); - item.add_to(acc); + item.add_to(acc, ctx.db); }); Some(()) diff --git a/crates/ide-completion/src/completions/extern_abi.rs b/crates/ide-completion/src/completions/extern_abi.rs index 4e89ef6960..c717a9cb55 100644 --- a/crates/ide-completion/src/completions/extern_abi.rs +++ b/crates/ide-completion/src/completions/extern_abi.rs @@ -42,7 +42,7 @@ const SUPPORTED_CALLING_CONVENTIONS: &[&str] = &[ pub(crate) fn complete_extern_abi( acc: &mut Completions, - _ctx: &CompletionContext<'_>, + ctx: &CompletionContext<'_>, expanded: &ast::String, ) -> Option<()> { if !expanded.syntax().parent().map_or(false, |it| ast::Abi::can_cast(it.kind())) { @@ -51,7 +51,7 @@ pub(crate) fn complete_extern_abi( let abi_str = expanded; let source_range = abi_str.text_range_between_quotes()?; for &abi in SUPPORTED_CALLING_CONVENTIONS { - CompletionItem::new(CompletionItemKind::Keyword, source_range, abi).add_to(acc); + CompletionItem::new(CompletionItemKind::Keyword, source_range, abi).add_to(acc, ctx.db); } Some(()) } diff --git a/crates/ide-completion/src/completions/flyimport.rs b/crates/ide-completion/src/completions/flyimport.rs index 1edf636aea..39c1b7f7b3 100644 --- a/crates/ide-completion/src/completions/flyimport.rs +++ b/crates/ide-completion/src/completions/flyimport.rs @@ -273,7 +273,7 @@ fn import_on_the_fly( .filter_map(|import| { render_resolution_with_import(RenderContext::new(ctx), path_ctx, import) }) - .map(|builder| builder.build()) + .map(|builder| builder.build(ctx.db)) .for_each(|item| acc.add(item)); Some(()) } @@ -315,7 +315,7 @@ fn import_on_the_fly_pat_( .filter_map(|import| { render_resolution_with_import_pat(RenderContext::new(ctx), pattern_ctx, import) }) - .map(|builder| builder.build()) + .map(|builder| builder.build(ctx.db)) .for_each(|item| acc.add(item)); Some(()) } diff --git a/crates/ide-completion/src/completions/fn_param.rs b/crates/ide-completion/src/completions/fn_param.rs index 734e1bed8d..8b38d4f01f 100644 --- a/crates/ide-completion/src/completions/fn_param.rs +++ b/crates/ide-completion/src/completions/fn_param.rs @@ -40,7 +40,7 @@ pub(crate) fn complete_fn_param( }; // Completion lookup is omitted intentionally here. // See the full discussion: https://github.com/rust-lang/rust-analyzer/issues/12073 - item.add_to(acc) + item.add_to(acc, ctx.db) }; match kind { @@ -50,7 +50,7 @@ pub(crate) fn complete_fn_param( ParamKind::Closure(closure) => { let stmt_list = closure.syntax().ancestors().find_map(ast::StmtList::cast)?; params_from_stmt_list_scope(ctx, stmt_list, |name, ty| { - add_new_item_to_acc(&format!("{name}: {ty}")); + add_new_item_to_acc(&format!("{}: {ty}", name.display(ctx.db))); }); } } @@ -100,7 +100,9 @@ fn fill_fn_params( if let Some(stmt_list) = function.syntax().parent().and_then(ast::StmtList::cast) { params_from_stmt_list_scope(ctx, stmt_list, |name, ty| { - file_params.entry(format!("{name}: {ty}")).or_insert(name.to_string()); + file_params + .entry(format!("{}: {ty}", name.display(ctx.db))) + .or_insert(name.display(ctx.db).to_string()); }); } remove_duplicated(&mut file_params, param_list.params()); diff --git a/crates/ide-completion/src/completions/format_string.rs b/crates/ide-completion/src/completions/format_string.rs index 5c46c5806e..8e904fd605 100644 --- a/crates/ide-completion/src/completions/format_string.rs +++ b/crates/ide-completion/src/completions/format_string.rs @@ -32,7 +32,7 @@ pub(crate) fn format_string( let source_range = TextRange::new(brace_offset, cursor); ctx.locals.iter().for_each(|(name, _)| { CompletionItem::new(CompletionItemKind::Binding, source_range, name.to_smol_str()) - .add_to(acc); + .add_to(acc, ctx.db); }) } diff --git a/crates/ide-completion/src/completions/item_list/trait_impl.rs b/crates/ide-completion/src/completions/item_list/trait_impl.rs index e82908a361..7de1bf2dc1 100644 --- a/crates/ide-completion/src/completions/item_list/trait_impl.rs +++ b/crates/ide-completion/src/completions/item_list/trait_impl.rs @@ -182,7 +182,7 @@ fn add_function_impl( let label = format!( "fn {}({})", - fn_name, + fn_name.display(ctx.db), if func.assoc_fn_params(ctx.db).is_empty() { "" } else { ".." } ); @@ -193,7 +193,7 @@ fn add_function_impl( }; let mut item = CompletionItem::new(completion_kind, replacement_range, label); - item.lookup_by(format!("fn {fn_name}")) + item.lookup_by(format!("fn {}", fn_name.display(ctx.db))) .set_documentation(func.docs(ctx.db)) .set_relevance(CompletionRelevance { is_item_from_trait: true, ..Default::default() }); @@ -216,7 +216,7 @@ fn add_function_impl( item.text_edit(TextEdit::replace(replacement_range, header)); } }; - item.add_to(acc); + item.add_to(acc, ctx.db); } } } @@ -300,7 +300,7 @@ fn add_type_alias_impl( item.text_edit(TextEdit::replace(replacement_range, decl)); } }; - item.add_to(acc); + item.add_to(acc, ctx.db); } } } @@ -340,7 +340,7 @@ fn add_const_impl( ), None => item.text_edit(TextEdit::replace(replacement_range, replacement)), }; - item.add_to(acc); + item.add_to(acc, ctx.db); } } } diff --git a/crates/ide-completion/src/completions/mod_.rs b/crates/ide-completion/src/completions/mod_.rs index 950731eb4c..d3e75c6da4 100644 --- a/crates/ide-completion/src/completions/mod_.rs +++ b/crates/ide-completion/src/completions/mod_.rs @@ -52,7 +52,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_map(|module| Some(module.name(ctx.db)?.display(ctx.db).to_string())) .filter(|module| module != ctx.original_token.text()) .collect::>(); @@ -99,7 +99,7 @@ pub(crate) fn complete_mod( label.push(';'); } let item = CompletionItem::new(SymbolKind::Module, ctx.source_range(), &label); - item.add_to(acc) + item.add_to(acc, ctx.db) }); Some(()) diff --git a/crates/ide-completion/src/completions/postfix.rs b/crates/ide-completion/src/completions/postfix.rs index c55bd9aaae..2ffe123374 100644 --- a/crates/ide-completion/src/completions/postfix.rs +++ b/crates/ide-completion/src/completions/postfix.rs @@ -64,7 +64,7 @@ pub(crate) fn complete_postfix( &format!("drop($0{receiver_text})"), ); item.set_documentation(drop_fn.docs(ctx.db)); - item.add_to(acc); + item.add_to(acc, ctx.db); } } } @@ -78,14 +78,14 @@ pub(crate) fn complete_postfix( "if let Ok {}", &format!("if let Ok($1) = {receiver_text} {{\n $0\n}}"), ) - .add_to(acc); + .add_to(acc, ctx.db); postfix_snippet( "while", "while let Ok {}", &format!("while let Ok($1) = {receiver_text} {{\n $0\n}}"), ) - .add_to(acc); + .add_to(acc, ctx.db); } TryEnum::Option => { postfix_snippet( @@ -93,22 +93,22 @@ pub(crate) fn complete_postfix( "if let Some {}", &format!("if let Some($1) = {receiver_text} {{\n $0\n}}"), ) - .add_to(acc); + .add_to(acc, ctx.db); postfix_snippet( "while", "while let Some {}", &format!("while let Some($1) = {receiver_text} {{\n $0\n}}"), ) - .add_to(acc); + .add_to(acc, ctx.db); } } } else if receiver_ty.is_bool() || receiver_ty.is_unknown() { postfix_snippet("if", "if expr {}", &format!("if {receiver_text} {{\n $0\n}}")) - .add_to(acc); + .add_to(acc, ctx.db); postfix_snippet("while", "while expr {}", &format!("while {receiver_text} {{\n $0\n}}")) - .add_to(acc); - postfix_snippet("not", "!expr", &format!("!{receiver_text}")).add_to(acc); + .add_to(acc, ctx.db); + postfix_snippet("not", "!expr", &format!("!{receiver_text}")).add_to(acc, ctx.db); } else if let Some(trait_) = ctx.famous_defs().core_iter_IntoIterator() { if receiver_ty.impls_trait(ctx.db, trait_, &[]) { postfix_snippet( @@ -116,12 +116,12 @@ pub(crate) fn complete_postfix( "for ele in expr {}", &format!("for ele in {receiver_text} {{\n $0\n}}"), ) - .add_to(acc); + .add_to(acc, ctx.db); } } - postfix_snippet("ref", "&expr", &format!("&{receiver_text}")).add_to(acc); - postfix_snippet("refm", "&mut expr", &format!("&mut {receiver_text}")).add_to(acc); + postfix_snippet("ref", "&expr", &format!("&{receiver_text}")).add_to(acc, ctx.db); + postfix_snippet("refm", "&mut expr", &format!("&mut {receiver_text}")).add_to(acc, ctx.db); let mut unsafe_should_be_wrapped = true; if dot_receiver.syntax().kind() == BLOCK_EXPR { @@ -137,7 +137,7 @@ pub(crate) fn complete_postfix( } else { format!("unsafe {receiver_text}") }; - postfix_snippet("unsafe", "unsafe {}", &unsafe_completion_string).add_to(acc); + postfix_snippet("unsafe", "unsafe {}", &unsafe_completion_string).add_to(acc, ctx.db); // The rest of the postfix completions create an expression that moves an argument, // so it's better to consider references now to avoid breaking the compilation @@ -162,7 +162,7 @@ pub(crate) fn complete_postfix( "match expr {}", &format!("match {receiver_text} {{\n Ok(${{1:_}}) => {{$2}},\n Err(${{3:_}}) => {{$0}},\n}}"), ) - .add_to(acc); + .add_to(acc, ctx.db); } TryEnum::Option => { postfix_snippet( @@ -172,7 +172,7 @@ pub(crate) fn complete_postfix( "match {receiver_text} {{\n Some(${{1:_}}) => {{$2}},\n None => {{$0}},\n}}" ), ) - .add_to(acc); + .add_to(acc, ctx.db); } }, None => { @@ -181,20 +181,23 @@ pub(crate) fn complete_postfix( "match expr {}", &format!("match {receiver_text} {{\n ${{1:_}} => {{$0}},\n}}"), ) - .add_to(acc); + .add_to(acc, ctx.db); } } - postfix_snippet("box", "Box::new(expr)", &format!("Box::new({receiver_text})")).add_to(acc); - postfix_snippet("dbg", "dbg!(expr)", &format!("dbg!({receiver_text})")).add_to(acc); // fixme - postfix_snippet("dbgr", "dbg!(&expr)", &format!("dbg!(&{receiver_text})")).add_to(acc); - postfix_snippet("call", "function(expr)", &format!("${{1}}({receiver_text})")).add_to(acc); + postfix_snippet("box", "Box::new(expr)", &format!("Box::new({receiver_text})")) + .add_to(acc, ctx.db); + postfix_snippet("dbg", "dbg!(expr)", &format!("dbg!({receiver_text})")).add_to(acc, ctx.db); // fixme + postfix_snippet("dbgr", "dbg!(&expr)", &format!("dbg!(&{receiver_text})")).add_to(acc, ctx.db); + postfix_snippet("call", "function(expr)", &format!("${{1}}({receiver_text})")) + .add_to(acc, ctx.db); if let Some(parent) = dot_receiver.syntax().parent().and_then(|p| p.parent()) { if matches!(parent.kind(), STMT_LIST | EXPR_STMT) { - postfix_snippet("let", "let", &format!("let $0 = {receiver_text};")).add_to(acc); + postfix_snippet("let", "let", &format!("let $0 = {receiver_text};")) + .add_to(acc, ctx.db); postfix_snippet("letm", "let mut", &format!("let mut $0 = {receiver_text};")) - .add_to(acc); + .add_to(acc, ctx.db); } } @@ -315,7 +318,7 @@ fn add_custom_postfix_completions( for import in imports.into_iter() { builder.add_import(import); } - builder.add_to(acc); + builder.add_to(acc, ctx.db); }, ); None diff --git a/crates/ide-completion/src/completions/postfix/format_like.rs b/crates/ide-completion/src/completions/postfix/format_like.rs index dfcc78e923..cb242e4aa6 100644 --- a/crates/ide-completion/src/completions/postfix/format_like.rs +++ b/crates/ide-completion/src/completions/postfix/format_like.rs @@ -60,7 +60,7 @@ pub(crate) fn add_format_like_completions( format!(r#"{}({}, {})"#, macro_name, out, exprs.join(", ")) }; - postfix_snippet(label, macro_name, &snippet).add_to(acc); + postfix_snippet(label, macro_name, &snippet).add_to(acc, ctx.db); } } } diff --git a/crates/ide-completion/src/completions/record.rs b/crates/ide-completion/src/completions/record.rs index 0521e735de..945c3945bf 100644 --- a/crates/ide-completion/src/completions/record.rs +++ b/crates/ide-completion/src/completions/record.rs @@ -69,7 +69,7 @@ pub(crate) fn complete_record_expr_fields( let mut item = CompletionItem::new(CompletionItemKind::Snippet, ctx.source_range(), ".."); item.insert_text("."); - item.add_to(acc); + item.add_to(acc, ctx.db); return; } missing_fields @@ -98,7 +98,7 @@ pub(crate) fn add_default_update( postfix_match: Some(CompletionRelevancePostfixMatch::Exact), ..Default::default() }); - item.add_to(acc); + item.add_to(acc, ctx.db); } } diff --git a/crates/ide-completion/src/completions/snippet.rs b/crates/ide-completion/src/completions/snippet.rs index da1f0542d2..e9831a5b2a 100644 --- a/crates/ide-completion/src/completions/snippet.rs +++ b/crates/ide-completion/src/completions/snippet.rs @@ -32,8 +32,8 @@ pub(crate) fn complete_expr_snippet( } if in_block_expr { - snippet(ctx, cap, "pd", "eprintln!(\"$0 = {:?}\", $0);").add_to(acc); - snippet(ctx, cap, "ppd", "eprintln!(\"$0 = {:#?}\", $0);").add_to(acc); + snippet(ctx, cap, "pd", "eprintln!(\"$0 = {:?}\", $0);").add_to(acc, ctx.db); + snippet(ctx, cap, "ppd", "eprintln!(\"$0 = {:#?}\", $0);").add_to(acc, ctx.db); let item = snippet( ctx, cap, @@ -45,7 +45,7 @@ macro_rules! $1 { }; }", ); - item.add_to(acc); + item.add_to(acc, ctx.db); } } @@ -88,7 +88,7 @@ mod tests { }", ); item.lookup_by("tmod"); - item.add_to(acc); + item.add_to(acc, ctx.db); let mut item = snippet( ctx, @@ -101,7 +101,7 @@ fn ${1:feature}() { }", ); item.lookup_by("tfn"); - item.add_to(acc); + item.add_to(acc, ctx.db); let item = snippet( ctx, @@ -114,7 +114,7 @@ macro_rules! $1 { }; }", ); - item.add_to(acc); + item.add_to(acc, ctx.db); } } @@ -146,7 +146,7 @@ fn add_custom_completions( builder.add_import(import); } builder.set_detail(snip.description.clone()); - builder.add_to(acc); + builder.add_to(acc, ctx.db); }, ); None diff --git a/crates/ide-completion/src/completions/use_.rs b/crates/ide-completion/src/completions/use_.rs index 45be4fb205..7a60030e9e 100644 --- a/crates/ide-completion/src/completions/use_.rs +++ b/crates/ide-completion/src/completions/use_.rs @@ -75,7 +75,7 @@ pub(crate) fn complete_use_path( is_name_already_imported, ..Default::default() }); - acc.add(builder.build()); + acc.add(builder.build(ctx.db)); } } } @@ -108,9 +108,9 @@ pub(crate) fn complete_use_path( let item = CompletionItem::new( CompletionItemKind::SymbolKind(SymbolKind::Enum), ctx.source_range(), - format!("{}::", e.name(ctx.db)), + format!("{}::", e.name(ctx.db).display(ctx.db)), ); - acc.add(item.build()); + acc.add(item.build(ctx.db)); } } _ => {} diff --git a/crates/ide-completion/src/context/analysis.rs b/crates/ide-completion/src/context/analysis.rs index 94787abf73..cc5221cfcc 100644 --- a/crates/ide-completion/src/context/analysis.rs +++ b/crates/ide-completion/src/context/analysis.rs @@ -1190,7 +1190,7 @@ fn pattern_context_for( }) }).and_then(|variants| { Some(variants.iter().filter_map(|variant| { - let variant_name = variant.name(sema.db).to_string(); + let variant_name = variant.name(sema.db).display(sema.db).to_string(); let variant_already_present = match_arm_list.arms().any(|arm| { arm.pat().and_then(|pat| { diff --git a/crates/ide-completion/src/item.rs b/crates/ide-completion/src/item.rs index e95cae9d67..e850f7bfdf 100644 --- a/crates/ide-completion/src/item.rs +++ b/crates/ide-completion/src/item.rs @@ -3,7 +3,7 @@ use std::fmt; use hir::{Documentation, Mutability}; -use ide_db::{imports::import_assets::LocatedImport, SnippetCap, SymbolKind}; +use ide_db::{imports::import_assets::LocatedImport, RootDatabase, SnippetCap, SymbolKind}; use itertools::Itertools; use smallvec::SmallVec; use stdx::{impl_from, never}; @@ -76,7 +76,8 @@ pub struct CompletionItem { pub ref_match: Option<(Mutability, TextSize)>, /// The import data to add to completion's edits. - pub import_to_add: SmallVec<[LocatedImport; 1]>, + /// (ImportPath, LastSegment) + pub import_to_add: SmallVec<[(String, String); 1]>, } // We use custom debug for CompletionItem to make snapshot tests more readable. @@ -418,7 +419,7 @@ impl Builder { ) } - pub(crate) fn build(self) -> CompletionItem { + pub(crate) fn build(self, db: &RootDatabase) -> CompletionItem { let _p = profile::span("item::Builder::build"); let mut label = self.label; @@ -433,7 +434,7 @@ impl Builder { if let [import_edit] = &*self.imports_to_add { // snippets can have multiple imports, but normal completions only have up to one if let Some(original_path) = import_edit.original_path.as_ref() { - label = SmolStr::from(format!("{label} (use {original_path})")); + label = SmolStr::from(format!("{label} (use {})", original_path.display(db))); } } else if let Some(trait_name) = self.trait_name { label = SmolStr::from(format!("{label} (as {trait_name})")); @@ -444,6 +445,17 @@ impl Builder { None => TextEdit::replace(self.source_range, insert_text), }; + let import_to_add = self + .imports_to_add + .into_iter() + .filter_map(|import| { + Some(( + import.import_path.display(db).to_string(), + import.import_path.segments().last()?.display(db).to_string(), + )) + }) + .collect(); + CompletionItem { source_range: self.source_range, label, @@ -457,7 +469,7 @@ impl Builder { trigger_call_info: self.trigger_call_info, relevance: self.relevance, ref_match: self.ref_match, - import_to_add: self.imports_to_add, + import_to_add, } } pub(crate) fn lookup_by(&mut self, lookup: impl Into) -> &mut Builder { diff --git a/crates/ide-completion/src/lib.rs b/crates/ide-completion/src/lib.rs index a88798563d..106d4e1e52 100644 --- a/crates/ide-completion/src/lib.rs +++ b/crates/ide-completion/src/lib.rs @@ -243,7 +243,7 @@ pub fn resolve_completion_edits( config.prefer_no_std, ) }) - .find(|mod_path| mod_path.to_string() == full_import_path); + .find(|mod_path| mod_path.display(db).to_string() == full_import_path); if let Some(import_path) = import { insert_use::insert_use(&new_ast, mod_path_to_ast(&import_path), &config.insert_use); } diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs index 9673252ff5..1953eb4795 100644 --- a/crates/ide-completion/src/render.rs +++ b/crates/ide-completion/src/render.rs @@ -126,24 +126,25 @@ pub(crate) fn render_field( field: hir::Field, ty: &hir::Type, ) -> CompletionItem { + let db = ctx.db(); let is_deprecated = ctx.is_deprecated(field); - let name = field.name(ctx.db()); + let name = field.name(db); let (name, escaped_name) = (name.unescaped().to_smol_str(), name.to_smol_str()); let mut item = CompletionItem::new( SymbolKind::Field, ctx.source_range(), - field_with_receiver(receiver.as_ref(), &name), + field_with_receiver(db, receiver.as_ref(), &name), ); item.set_relevance(CompletionRelevance { type_match: compute_type_match(ctx.completion, ty), exact_name_match: compute_exact_name_match(ctx.completion, name.as_str()), ..CompletionRelevance::default() }); - item.detail(ty.display(ctx.db()).to_string()) - .set_documentation(field.docs(ctx.db())) + item.detail(ty.display(db).to_string()) + .set_documentation(field.docs(db)) .set_deprecated(is_deprecated) .lookup_by(name); - item.insert_text(field_with_receiver(receiver.as_ref(), &escaped_name)); + item.insert_text(field_with_receiver(db, receiver.as_ref(), &escaped_name)); if let Some(receiver) = &dot_access.receiver { if let Some(original) = ctx.completion.sema.original_ast_node(receiver.clone()) { if let Some(ref_match) = compute_ref_match(ctx.completion, ty) { @@ -152,11 +153,18 @@ pub(crate) fn render_field( } } item.doc_aliases(ctx.doc_aliases); - item.build() + item.build(db) } -fn field_with_receiver(receiver: Option<&hir::Name>, field_name: &str) -> SmolStr { - receiver.map_or_else(|| field_name.into(), |receiver| format!("{receiver}.{field_name}").into()) +fn field_with_receiver( + db: &RootDatabase, + receiver: Option<&hir::Name>, + field_name: &str, +) -> SmolStr { + receiver.map_or_else( + || field_name.into(), + |receiver| format!("{}.{field_name}", receiver.display(db)).into(), + ) } pub(crate) fn render_tuple_field( @@ -168,10 +176,10 @@ pub(crate) fn render_tuple_field( let mut item = CompletionItem::new( SymbolKind::Field, ctx.source_range(), - field_with_receiver(receiver.as_ref(), &field.to_string()), + field_with_receiver(ctx.db(), receiver.as_ref(), &field.to_string()), ); item.detail(ty.display(ctx.db()).to_string()).lookup_by(field.to_string()); - item.build() + item.build(ctx.db()) } pub(crate) fn render_type_inference( @@ -181,7 +189,7 @@ pub(crate) fn render_type_inference( let mut builder = CompletionItem::new(CompletionItemKind::InferredType, ctx.source_range(), ty_string); builder.set_relevance(CompletionRelevance { is_definite: true, ..Default::default() }); - builder.build() + builder.build(ctx.db) } pub(crate) fn render_path_resolution( @@ -319,7 +327,7 @@ fn render_resolution_path( item.lookup_by(name.clone()) .label(SmolStr::from_iter([&name, "<…>"])) .trigger_call_info() - .insert_snippet(cap, format!("{local_name}<$0>")); + .insert_snippet(cap, format!("{}<$0>", local_name.display(db))); } } } diff --git a/crates/ide-completion/src/render/const_.rs b/crates/ide-completion/src/render/const_.rs index 70b19988ca..3c73983c39 100644 --- a/crates/ide-completion/src/render/const_.rs +++ b/crates/ide-completion/src/render/const_.rs @@ -29,5 +29,5 @@ fn render(ctx: RenderContext<'_>, const_: hir::Const) -> Option } item.insert_text(escaped_name); - Some(item.build()) + Some(item.build(ctx.db())) } diff --git a/crates/ide-completion/src/render/function.rs b/crates/ide-completion/src/render/function.rs index bfcd23280c..8afce8db5e 100644 --- a/crates/ide-completion/src/render/function.rs +++ b/crates/ide-completion/src/render/function.rs @@ -52,8 +52,13 @@ fn render( let (call, escaped_call) = match &func_kind { FuncKind::Method(_, Some(receiver)) => ( - format!("{}.{}", receiver.unescaped(), name.unescaped()).into(), - format!("{receiver}.{name}").into(), + format!( + "{}.{}", + receiver.unescaped().display(ctx.db()), + name.unescaped().display(ctx.db()) + ) + .into(), + format!("{}.{}", receiver.display(ctx.db()), name.display(ctx.db())).into(), ), _ => (name.unescaped().to_smol_str(), name.to_smol_str()), }; diff --git a/crates/ide-completion/src/render/literal.rs b/crates/ide-completion/src/render/literal.rs index ed78fcd8e6..728d236dff 100644 --- a/crates/ide-completion/src/render/literal.rs +++ b/crates/ide-completion/src/render/literal.rs @@ -71,8 +71,10 @@ fn render( } None => (name.clone().into(), name.into(), false), }; - let (qualified_name, escaped_qualified_name) = - (qualified_name.unescaped().to_string(), qualified_name.to_string()); + let (qualified_name, escaped_qualified_name) = ( + qualified_name.unescaped().display(ctx.db()).to_string(), + qualified_name.display(ctx.db()).to_string(), + ); let snippet_cap = ctx.snippet_cap(); let mut rendered = match kind { @@ -98,7 +100,7 @@ fn render( } let label = format_literal_label(&qualified_name, kind, snippet_cap); let lookup = if qualified { - format_literal_lookup(&short_qualified_name.to_string(), kind) + format_literal_lookup(&short_qualified_name.display(ctx.db()).to_string(), kind) } else { format_literal_lookup(&qualified_name, kind) }; diff --git a/crates/ide-completion/src/render/pattern.rs b/crates/ide-completion/src/render/pattern.rs index 9225c91beb..d06abc5e91 100644 --- a/crates/ide-completion/src/render/pattern.rs +++ b/crates/ide-completion/src/render/pattern.rs @@ -57,7 +57,10 @@ pub(crate) fn render_variant_pat( let enum_ty = variant.parent_enum(ctx.db()).ty(ctx.db()); let (name, escaped_name) = match path { - Some(path) => (path.unescaped().to_string().into(), path.to_string().into()), + Some(path) => ( + path.unescaped().display(ctx.db()).to_string().into(), + path.display(ctx.db()).to_string().into(), + ), None => { let name = local_name.unwrap_or_else(|| variant.name(ctx.db())); (name.unescaped().to_smol_str(), name.to_smol_str()) @@ -121,7 +124,7 @@ fn build_completion( Some(snippet_cap) => item.insert_snippet(snippet_cap, pat), None => item.insert_text(pat), }; - item.build() + item.build(ctx.db()) } fn render_pat( @@ -172,7 +175,7 @@ fn render_record_as_pat( format!( "{name} {{ {}{} }}", fields.enumerate().format_with(", ", |(idx, field), f| { - f(&format_args!("{}${}", field.name(db), idx + 1)) + f(&format_args!("{}${}", field.name(db).display(db.upcast()), idx + 1)) }), if fields_omitted { ", .." } else { "" }, name = name diff --git a/crates/ide-completion/src/render/type_alias.rs b/crates/ide-completion/src/render/type_alias.rs index fbe120d2ac..343ba7e28d 100644 --- a/crates/ide-completion/src/render/type_alias.rs +++ b/crates/ide-completion/src/render/type_alias.rs @@ -53,5 +53,5 @@ fn render( } item.insert_text(escaped_name); - Some(item.build()) + Some(item.build(ctx.db())) } diff --git a/crates/ide-completion/src/render/union_literal.rs b/crates/ide-completion/src/render/union_literal.rs index 6e0c53ec94..93e943dbed 100644 --- a/crates/ide-completion/src/render/union_literal.rs +++ b/crates/ide-completion/src/render/union_literal.rs @@ -21,8 +21,10 @@ pub(crate) fn render_union_literal( let name = local_name.unwrap_or_else(|| un.name(ctx.db())); let (qualified_name, escaped_qualified_name) = match path { - Some(p) => (p.unescaped().to_string(), p.to_string()), - None => (name.unescaped().to_string(), name.to_string()), + Some(p) => (p.unescaped().display(ctx.db()).to_string(), p.display(ctx.db()).to_string()), + None => { + (name.unescaped().display(ctx.db()).to_string(), name.display(ctx.db()).to_string()) + } }; let label = format_literal_label(&name.to_smol_str(), StructKind::Record, ctx.snippet_cap()); let lookup = format_literal_lookup(&name.to_smol_str(), StructKind::Record); @@ -51,9 +53,9 @@ pub(crate) fn render_union_literal( format!( "{} {{ {} }}", escaped_qualified_name, - fields - .iter() - .format_with(", ", |field, f| { f(&format_args!("{}: ()", field.name(ctx.db()))) }) + fields.iter().format_with(", ", |field, f| { + f(&format_args!("{}: ()", field.name(ctx.db()).display(ctx.db()))) + }) ) }; @@ -61,7 +63,11 @@ pub(crate) fn render_union_literal( "{} {{ {}{} }}", qualified_name, fields.iter().format_with(", ", |field, f| { - f(&format_args!("{}: {}", field.name(ctx.db()), field.ty(ctx.db()).display(ctx.db()))) + f(&format_args!( + "{}: {}", + field.name(ctx.db()).display(ctx.db()), + field.ty(ctx.db()).display(ctx.db()) + )) }), if fields_omitted { ", .." } else { "" } ); @@ -76,5 +82,5 @@ pub(crate) fn render_union_literal( None => item.insert_text(literal), }; - Some(item.build()) + Some(item.build(ctx.db())) } diff --git a/crates/ide-completion/src/render/variant.rs b/crates/ide-completion/src/render/variant.rs index 55c55725be..a9a01a3a30 100644 --- a/crates/ide-completion/src/render/variant.rs +++ b/crates/ide-completion/src/render/variant.rs @@ -27,14 +27,14 @@ pub(crate) fn render_record_lit( } let completions = fields.iter().enumerate().format_with(", ", |(idx, field), f| { if snippet_cap.is_some() { - f(&format_args!("{}: ${{{}:()}}", field.name(db), idx + 1)) + f(&format_args!("{}: ${{{}:()}}", field.name(db).display(db.upcast()), idx + 1)) } else { - f(&format_args!("{}: ()", field.name(db))) + f(&format_args!("{}: ()", field.name(db).display(db.upcast()))) } }); let types = fields.iter().format_with(", ", |field, f| { - f(&format_args!("{}: {}", field.name(db), field.ty(db).display(db))) + f(&format_args!("{}: {}", field.name(db).display(db.upcast()), field.ty(db).display(db))) }); RenderedLiteral { diff --git a/crates/ide-completion/src/tests.rs b/crates/ide-completion/src/tests.rs index ef4c939fe6..2464e8d5f8 100644 --- a/crates/ide-completion/src/tests.rs +++ b/crates/ide-completion/src/tests.rs @@ -198,11 +198,11 @@ pub(crate) fn check_edit_with_config( &db, &config, position, - completion.import_to_add.iter().filter_map(|import_edit| { - let import_path = &import_edit.import_path; - let import_name = import_path.segments().last()?; - Some((import_path.to_string(), import_name.to_string())) - }), + completion + .import_to_add + .iter() + .cloned() + .filter_map(|(import_path, import_name)| Some((import_path, import_name))), ) .into_iter() .flatten() diff --git a/crates/ide-db/src/imports/import_assets.rs b/crates/ide-db/src/imports/import_assets.rs index b26b0a9087..901d592c69 100644 --- a/crates/ide-db/src/imports/import_assets.rs +++ b/crates/ide-db/src/imports/import_assets.rs @@ -362,12 +362,12 @@ fn import_for_item( let original_item_candidate = item_for_path_search(db, original_item)?; let import_path_candidate = mod_path(original_item_candidate)?; - let import_path_string = import_path_candidate.to_string(); + let import_path_string = import_path_candidate.display(db).to_string(); let expected_import_end = if item_as_assoc(db, original_item).is_some() { unresolved_qualifier.to_string() } else { - format!("{unresolved_qualifier}::{}", item_name(db, original_item)?) + format!("{unresolved_qualifier}::{}", item_name(db, original_item)?.display(db)) }; if !import_path_string.contains(unresolved_first_segment) || !import_path_string.ends_with(&expected_import_end) diff --git a/crates/ide-db/src/rename.rs b/crates/ide-db/src/rename.rs index 9aadf40363..5b2558ea8f 100644 --- a/crates/ide-db/src/rename.rs +++ b/crates/ide-db/src/rename.rs @@ -202,12 +202,13 @@ fn rename_mod( // - Module has submodules defined in separate files let dir_paths = match (is_mod_rs, has_detached_child, module.name(sema.db)) { // Go up one level since the anchor is inside the dir we're trying to rename - (true, _, Some(mod_name)) => { - Some((format!("../{}", mod_name.unescaped()), format!("../{new_name}"))) - } + (true, _, Some(mod_name)) => Some(( + format!("../{}", mod_name.unescaped().display(sema.db)), + format!("../{new_name}"), + )), // The anchor is on the same level as target dir (false, true, Some(mod_name)) => { - Some((mod_name.unescaped().to_string(), new_name.to_owned())) + Some((mod_name.unescaped().display(sema.db).to_string(), new_name.to_owned())) } _ => None, }; diff --git a/crates/ide-db/src/traits.rs b/crates/ide-db/src/traits.rs index 6a7ea7c19f..9abbc34414 100644 --- a/crates/ide-db/src/traits.rs +++ b/crates/ide-db/src/traits.rs @@ -38,15 +38,15 @@ pub fn get_missing_assoc_items( for item in imp.items(sema.db) { match item { hir::AssocItem::Function(it) => { - impl_fns_consts.insert(it.name(sema.db).to_string()); + impl_fns_consts.insert(it.name(sema.db).display(sema.db).to_string()); } hir::AssocItem::Const(it) => { if let Some(name) = it.name(sema.db) { - impl_fns_consts.insert(name.to_string()); + impl_fns_consts.insert(name.display(sema.db).to_string()); } } hir::AssocItem::TypeAlias(it) => { - impl_type.insert(it.name(sema.db).to_string()); + impl_type.insert(it.name(sema.db).display(sema.db).to_string()); } } } @@ -57,12 +57,14 @@ pub fn get_missing_assoc_items( .into_iter() .filter(|i| match i { hir::AssocItem::Function(f) => { - !impl_fns_consts.contains(&f.name(sema.db).to_string()) + !impl_fns_consts.contains(&f.name(sema.db).display(sema.db).to_string()) + } + hir::AssocItem::TypeAlias(t) => { + !impl_type.contains(&t.name(sema.db).display(sema.db).to_string()) } - hir::AssocItem::TypeAlias(t) => !impl_type.contains(&t.name(sema.db).to_string()), hir::AssocItem::Const(c) => c .name(sema.db) - .map(|n| !impl_fns_consts.contains(&n.to_string())) + .map(|n| !impl_fns_consts.contains(&n.display(sema.db).to_string())) .unwrap_or_default(), }) .collect() @@ -137,7 +139,7 @@ mod tests { sema.find_node_at_offset_with_descend(file.syntax(), position.offset).unwrap(); let trait_ = crate::traits::resolve_target_trait(&sema, &impl_block); let actual = match trait_ { - Some(trait_) => trait_.name(&db).to_string(), + Some(trait_) => trait_.name(&db).display(&db).to_string(), None => String::new(), }; expect.assert_eq(&actual); @@ -152,7 +154,7 @@ mod tests { let items = crate::traits::get_missing_assoc_items(&sema, &impl_block); let actual = items .into_iter() - .map(|item| item.name(&db).unwrap().to_string()) + .map(|item| item.name(&db).unwrap().display(&db).to_string()) .collect::>() .join("\n"); expect.assert_eq(&actual); diff --git a/crates/ide-diagnostics/src/handlers/missing_fields.rs b/crates/ide-diagnostics/src/handlers/missing_fields.rs index 17a2b44ccd..60ccc41df0 100644 --- a/crates/ide-diagnostics/src/handlers/missing_fields.rs +++ b/crates/ide-diagnostics/src/handlers/missing_fields.rs @@ -31,7 +31,7 @@ use crate::{fix, Diagnostic, DiagnosticsContext}; pub(crate) fn missing_fields(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Diagnostic { let mut message = String::from("missing structure fields:\n"); for field in &d.missed_fields { - format_to!(message, "- {}\n", field); + format_to!(message, "- {}\n", field.display(ctx.sema.db)); } let ptr = InFile::new( @@ -175,7 +175,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Option ast::Type { let ty_str = match ty.as_adt() { - Some(adt) => adt.name(db).to_string(), + Some(adt) => adt.name(db).display(db.upcast()).to_string(), None => { ty.display_source_code(db, module.into(), false).ok().unwrap_or_else(|| "_".to_string()) } diff --git a/crates/ide-diagnostics/src/handlers/mutability_errors.rs b/crates/ide-diagnostics/src/handlers/mutability_errors.rs index 9d6a862cb1..0af4100180 100644 --- a/crates/ide-diagnostics/src/handlers/mutability_errors.rs +++ b/crates/ide-diagnostics/src/handlers/mutability_errors.rs @@ -30,7 +30,10 @@ pub(crate) fn need_mut(ctx: &DiagnosticsContext<'_>, d: &hir::NeedMut) -> Diagno })(); Diagnostic::new( "need-mut", - format!("cannot mutate immutable variable `{}`", d.local.name(ctx.sema.db)), + format!( + "cannot mutate immutable variable `{}`", + d.local.name(ctx.sema.db).display(ctx.sema.db) + ), ctx.sema.diagnostics_display_range(d.span.clone()).range, ) .with_fixes(fixes) diff --git a/crates/ide-diagnostics/src/handlers/private_assoc_item.rs b/crates/ide-diagnostics/src/handlers/private_assoc_item.rs index 67da5c7f27..4cd85a479a 100644 --- a/crates/ide-diagnostics/src/handlers/private_assoc_item.rs +++ b/crates/ide-diagnostics/src/handlers/private_assoc_item.rs @@ -11,7 +11,11 @@ pub(crate) fn private_assoc_item( d: &hir::PrivateAssocItem, ) -> Diagnostic { // FIXME: add quickfix - let name = d.item.name(ctx.sema.db).map(|name| format!("`{name}` ")).unwrap_or_default(); + let name = d + .item + .name(ctx.sema.db) + .map(|name| format!("`{}` ", name.display(ctx.sema.db))) + .unwrap_or_default(); Diagnostic::new( "private-assoc-item", format!( diff --git a/crates/ide-diagnostics/src/handlers/private_field.rs b/crates/ide-diagnostics/src/handlers/private_field.rs index be83ad6aaa..de7f51f693 100644 --- a/crates/ide-diagnostics/src/handlers/private_field.rs +++ b/crates/ide-diagnostics/src/handlers/private_field.rs @@ -9,8 +9,8 @@ pub(crate) fn private_field(ctx: &DiagnosticsContext<'_>, d: &hir::PrivateField) "private-field", format!( "field `{}` of `{}` is private", - d.field.name(ctx.sema.db), - d.field.parent_def(ctx.sema.db).name(ctx.sema.db) + d.field.name(ctx.sema.db).display(ctx.sema.db), + d.field.parent_def(ctx.sema.db).name(ctx.sema.db).display(ctx.sema.db) ), ctx.sema.diagnostics_display_range(d.expr.clone().map(|it| it.into())).range, ) diff --git a/crates/ide-diagnostics/src/handlers/undeclared_label.rs b/crates/ide-diagnostics/src/handlers/undeclared_label.rs index dbedf1e6c1..768efecb08 100644 --- a/crates/ide-diagnostics/src/handlers/undeclared_label.rs +++ b/crates/ide-diagnostics/src/handlers/undeclared_label.rs @@ -8,7 +8,7 @@ pub(crate) fn undeclared_label( let name = &d.name; Diagnostic::new( "undeclared-label", - format!("use of undeclared label `{name}`"), + format!("use of undeclared label `{}`", name.display(ctx.sema.db)), ctx.sema.diagnostics_display_range(d.node.clone().map(|it| it.into())).range, ) } diff --git a/crates/ide-diagnostics/src/handlers/unreachable_label.rs b/crates/ide-diagnostics/src/handlers/unreachable_label.rs index 5933a9b694..9fedadeae0 100644 --- a/crates/ide-diagnostics/src/handlers/unreachable_label.rs +++ b/crates/ide-diagnostics/src/handlers/unreachable_label.rs @@ -8,7 +8,7 @@ pub(crate) fn unreachable_label( let name = &d.name; Diagnostic::new( "unreachable-label", - format!("use of unreachable label `{name}`"), + format!("use of unreachable label `{}`", name.display(ctx.sema.db)), ctx.sema.diagnostics_display_range(d.node.clone().map(|it| it.into())).range, ) } diff --git a/crates/ide-diagnostics/src/handlers/unresolved_field.rs b/crates/ide-diagnostics/src/handlers/unresolved_field.rs index fe2d03bb10..5e4efa41fd 100644 --- a/crates/ide-diagnostics/src/handlers/unresolved_field.rs +++ b/crates/ide-diagnostics/src/handlers/unresolved_field.rs @@ -26,7 +26,7 @@ pub(crate) fn unresolved_field( "unresolved-field", format!( "no field `{}` on type `{}`{method_suffix}", - d.name, + d.name.display(ctx.sema.db), d.receiver.display(ctx.sema.db) ), ctx.sema.diagnostics_display_range(d.expr.clone().map(|it| it.into())).range, diff --git a/crates/ide-diagnostics/src/handlers/unresolved_macro_call.rs b/crates/ide-diagnostics/src/handlers/unresolved_macro_call.rs index 1a5efff2c0..3943b51ab4 100644 --- a/crates/ide-diagnostics/src/handlers/unresolved_macro_call.rs +++ b/crates/ide-diagnostics/src/handlers/unresolved_macro_call.rs @@ -13,7 +13,7 @@ pub(crate) fn unresolved_macro_call( let bang = if d.is_bang { "!" } else { "" }; Diagnostic::new( "unresolved-macro-call", - format!("unresolved macro `{}{bang}`", d.path), + format!("unresolved macro `{}{bang}`", d.path.display(ctx.sema.db)), display_range, ) .experimental() diff --git a/crates/ide-diagnostics/src/handlers/unresolved_method.rs b/crates/ide-diagnostics/src/handlers/unresolved_method.rs index 8a0b457857..8bbb837e67 100644 --- a/crates/ide-diagnostics/src/handlers/unresolved_method.rs +++ b/crates/ide-diagnostics/src/handlers/unresolved_method.rs @@ -26,7 +26,7 @@ pub(crate) fn unresolved_method( "unresolved-method", format!( "no method `{}` on type `{}`{field_suffix}", - d.name, + d.name.display(ctx.sema.db), d.receiver.display(ctx.sema.db) ), ctx.sema.diagnostics_display_range(d.expr.clone().map(|it| it.into())).range, diff --git a/crates/ide-ssr/src/lib.rs b/crates/ide-ssr/src/lib.rs index f51a9547a5..66832a0bee 100644 --- a/crates/ide-ssr/src/lib.rs +++ b/crates/ide-ssr/src/lib.rs @@ -184,6 +184,7 @@ impl<'db> MatchFinder<'db> { ( file_id, replacing::matches_to_edit( + self.sema.db, &matches, &self.sema.db.file_text(file_id), &self.rules, diff --git a/crates/ide-ssr/src/replacing.rs b/crates/ide-ssr/src/replacing.rs index e27ef6e35e..b4b83f62da 100644 --- a/crates/ide-ssr/src/replacing.rs +++ b/crates/ide-ssr/src/replacing.rs @@ -14,14 +14,16 @@ use crate::{fragments, resolving::ResolvedRule, Match, SsrMatches}; /// template. Placeholders in the template will have been substituted with whatever they matched to /// in the original code. pub(crate) fn matches_to_edit( + db: &dyn hir::db::ExpandDatabase, matches: &SsrMatches, file_src: &str, rules: &[ResolvedRule], ) -> TextEdit { - matches_to_edit_at_offset(matches, file_src, 0.into(), rules) + matches_to_edit_at_offset(db, matches, file_src, 0.into(), rules) } fn matches_to_edit_at_offset( + db: &dyn hir::db::ExpandDatabase, matches: &SsrMatches, file_src: &str, relative_start: TextSize, @@ -31,13 +33,14 @@ fn matches_to_edit_at_offset( for m in &matches.matches { edit_builder.replace( m.range.range.checked_sub(relative_start).unwrap(), - render_replace(m, file_src, rules), + render_replace(db, m, file_src, rules), ); } edit_builder.finish() } struct ReplacementRenderer<'a> { + db: &'a dyn hir::db::ExpandDatabase, match_info: &'a Match, file_src: &'a str, rules: &'a [ResolvedRule], @@ -53,13 +56,19 @@ struct ReplacementRenderer<'a> { placeholder_tokens_requiring_parenthesis: FxHashSet, } -fn render_replace(match_info: &Match, file_src: &str, rules: &[ResolvedRule]) -> String { +fn render_replace( + db: &dyn hir::db::ExpandDatabase, + match_info: &Match, + file_src: &str, + rules: &[ResolvedRule], +) -> String { let rule = &rules[match_info.rule_index]; let template = rule .template .as_ref() .expect("You called MatchFinder::edits after calling MatchFinder::add_search_pattern"); let mut renderer = ReplacementRenderer { + db, match_info, file_src, rules, @@ -96,7 +105,7 @@ impl ReplacementRenderer<'_> { fn render_node(&mut self, node: &SyntaxNode) { if let Some(mod_path) = self.match_info.rendered_template_paths.get(node) { - self.out.push_str(&mod_path.to_string()); + self.out.push_str(&mod_path.display(self.db).to_string()); // Emit everything except for the segment's name-ref, since we already effectively // emitted that as part of `mod_path`. if let Some(path) = ast::Path::cast(node.clone()) { @@ -144,6 +153,7 @@ impl ReplacementRenderer<'_> { ); } let edit = matches_to_edit_at_offset( + self.db, &placeholder_value.inner_matches, self.file_src, range.start(), diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs index 597b28d36d..8112c4f725 100644 --- a/crates/ide/src/doc_links.rs +++ b/crates/ide/src/doc_links.rs @@ -394,7 +394,7 @@ fn rewrite_url_link(db: &RootDatabase, def: Definition, target: &str) -> Option< fn mod_path_of_def(db: &RootDatabase, def: Definition) -> Option { def.canonical_module_path(db).map(|it| { let mut path = String::new(); - it.flat_map(|it| it.name(db)).for_each(|name| format_to!(path, "{}/", name)); + it.flat_map(|it| it.name(db)).for_each(|name| format_to!(path, "{}/", name.display(db))); path }) } @@ -567,9 +567,9 @@ fn filename_and_frag_for_def( let res = match def { Definition::Adt(adt) => match adt { - Adt::Struct(s) => format!("struct.{}.html", s.name(db)), - Adt::Enum(e) => format!("enum.{}.html", e.name(db)), - Adt::Union(u) => format!("union.{}.html", u.name(db)), + Adt::Struct(s) => format!("struct.{}.html", s.name(db).display(db.upcast())), + Adt::Enum(e) => format!("enum.{}.html", e.name(db).display(db.upcast())), + Adt::Union(u) => format!("union.{}.html", u.name(db).display(db.upcast())), }, Definition::Module(m) => match m.name(db) { // `#[doc(keyword = "...")]` is internal used only by rust compiler @@ -577,21 +577,25 @@ fn filename_and_frag_for_def( Some(kw) => { format!("keyword.{}.html", kw.trim_matches('"')) } - None => format!("{name}/index.html"), + None => format!("{}/index.html", name.display(db.upcast())), }, None => String::from("index.html"), }, - Definition::Trait(t) => format!("trait.{}.html", t.name(db)), - Definition::TraitAlias(t) => format!("traitalias.{}.html", t.name(db)), - Definition::TypeAlias(t) => format!("type.{}.html", t.name(db)), - Definition::BuiltinType(t) => format!("primitive.{}.html", t.name()), - Definition::Function(f) => format!("fn.{}.html", f.name(db)), + Definition::Trait(t) => format!("trait.{}.html", t.name(db).display(db.upcast())), + Definition::TraitAlias(t) => format!("traitalias.{}.html", t.name(db).display(db.upcast())), + Definition::TypeAlias(t) => format!("type.{}.html", t.name(db).display(db.upcast())), + Definition::BuiltinType(t) => format!("primitive.{}.html", t.name().display(db.upcast())), + Definition::Function(f) => format!("fn.{}.html", f.name(db).display(db.upcast())), Definition::Variant(ev) => { - format!("enum.{}.html#variant.{}", ev.parent_enum(db).name(db), ev.name(db)) + format!( + "enum.{}.html#variant.{}", + ev.parent_enum(db).name(db).display(db.upcast()), + ev.name(db).display(db.upcast()) + ) } - Definition::Const(c) => format!("const.{}.html", c.name(db)?), - Definition::Static(s) => format!("static.{}.html", s.name(db)), - Definition::Macro(mac) => format!("macro.{}.html", mac.name(db)), + Definition::Const(c) => format!("const.{}.html", c.name(db)?.display(db.upcast())), + Definition::Static(s) => format!("static.{}.html", s.name(db).display(db.upcast())), + Definition::Macro(mac) => format!("macro.{}.html", mac.name(db).display(db.upcast())), Definition::Field(field) => { let def = match field.parent_def(db) { hir::VariantDef::Struct(it) => Definition::Adt(it.into()), @@ -599,7 +603,11 @@ fn filename_and_frag_for_def( hir::VariantDef::Variant(it) => Definition::Variant(it), }; let (_, file, _) = filename_and_frag_for_def(db, def)?; - return Some((def, file, Some(format!("structfield.{}", field.name(db))))); + return Some(( + def, + file, + Some(format!("structfield.{}", field.name(db).display(db.upcast()))), + )); } Definition::SelfType(impl_) => { let adt = impl_.self_ty(db).as_adt()?.into(); @@ -633,12 +641,14 @@ fn get_assoc_item_fragment(db: &dyn HirDatabase, assoc_item: hir::AssocItem) -> // Rustdoc makes this decision based on whether a method 'has defaultness'. // Currently this is only the case for provided trait methods. if is_trait_method && !function.has_body(db) { - format!("tymethod.{}", function.name(db)) + format!("tymethod.{}", function.name(db).display(db.upcast())) } else { - format!("method.{}", function.name(db)) + format!("method.{}", function.name(db).display(db.upcast())) } } - AssocItem::Const(constant) => format!("associatedconstant.{}", constant.name(db)?), - AssocItem::TypeAlias(ty) => format!("associatedtype.{}", ty.name(db)), + AssocItem::Const(constant) => { + format!("associatedconstant.{}", constant.name(db)?.display(db.upcast())) + } + AssocItem::TypeAlias(ty) => format!("associatedtype.{}", ty.name(db).display(db.upcast())), }) } diff --git a/crates/ide/src/expand_macro.rs b/crates/ide/src/expand_macro.rs index 8c03d197e1..d6bbf2bf79 100644 --- a/crates/ide/src/expand_macro.rs +++ b/crates/ide/src/expand_macro.rs @@ -76,7 +76,7 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< if let Some(item) = ast::Item::cast(node.clone()) { if let Some(def) = sema.resolve_attr_macro_call(&item) { break ( - def.name(db).to_string(), + def.name(db).display(db).to_string(), expand_attr_macro_recur(&sema, &item)?, SyntaxKind::MACRO_ITEMS, ); diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index b6279295ce..1a84a963f5 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs @@ -56,7 +56,7 @@ impl HoverAction { mod_path: render::path( db, it.module(db)?, - it.name(db).map(|name| name.to_string()), + it.name(db).map(|name| name.display(db).to_string()), ), nav: it.try_to_nav(db)?, }) diff --git a/crates/ide/src/hover/render.rs b/crates/ide/src/hover/render.rs index fffc837876..d9d4a1a992 100644 --- a/crates/ide/src/hover/render.rs +++ b/crates/ide/src/hover/render.rs @@ -370,7 +370,7 @@ fn definition_owner_name(db: &RootDatabase, def: &Definition) -> Option Definition::Variant(e) => Some(e.parent_enum(db).name(db)), _ => None, } - .map(|name| name.to_string()) + .map(|name| name.display(db).to_string()) } pub(super) fn path(db: &RootDatabase, module: hir::Module, item_name: Option) -> String { @@ -380,7 +380,7 @@ pub(super) fn path(db: &RootDatabase, module: hir::Module, item_name: Option { return famous_defs .and_then(|fd| builtin(fd, it)) - .or_else(|| Some(Markup::fenced_block(&it.name()))) + .or_else(|| Some(Markup::fenced_block(&it.name().display(db)))) } Definition::Local(it) => return local(db, it, config), Definition::SelfType(impl_def) => { impl_def.self_ty(db).as_adt().map(|adt| label_and_docs(db, adt))? } Definition::GenericParam(it) => label_and_docs(db, it), - Definition::Label(it) => return Some(Markup::fenced_block(&it.name(db))), + Definition::Label(it) => return Some(Markup::fenced_block(&it.name(db).display(db))), // FIXME: We should be able to show more info about these Definition::BuiltinAttr(it) => return render_builtin_attr(db, it), Definition::ToolModule(it) => return Some(Markup::fenced_block(&it.name(db))), - Definition::DeriveHelper(it) => (format!("derive_helper {}", it.name(db)), None), + Definition::DeriveHelper(it) => { + (format!("derive_helper {}", it.name(db).display(db)), None) + } }; let docs = docs @@ -717,19 +719,19 @@ fn markup(docs: Option, desc: String, mod_path: Option) -> Optio fn builtin(famous_defs: &FamousDefs<'_, '_>, builtin: hir::BuiltinType) -> Option { // std exposes prim_{} modules with docstrings on the root to document the builtins - let primitive_mod = format!("prim_{}", builtin.name()); + let primitive_mod = format!("prim_{}", builtin.name().display(famous_defs.0.db)); let doc_owner = find_std_module(famous_defs, &primitive_mod)?; let docs = doc_owner.attrs(famous_defs.0.db).docs()?; - markup(Some(docs.into()), builtin.name().to_string(), None) + markup(Some(docs.into()), builtin.name().display(famous_defs.0.db).to_string(), None) } fn find_std_module(famous_defs: &FamousDefs<'_, '_>, name: &str) -> Option { let db = famous_defs.0.db; let std_crate = famous_defs.std()?; let std_root_module = std_crate.root_module(db); - std_root_module - .children(db) - .find(|module| module.name(db).map_or(false, |module| module.to_string() == name)) + std_root_module.children(db).find(|module| { + module.name(db).map_or(false, |module| module.display(db).to_string() == name) + }) } fn local(db: &RootDatabase, it: hir::Local, config: &HoverConfig) -> Option { @@ -748,7 +750,7 @@ fn local(db: &RootDatabase, it: hir::Local, config: &HoverConfig) -> Option format!("{is_mut}self: {ty}"), }; diff --git a/crates/ide/src/inlay_hints/closing_brace.rs b/crates/ide/src/inlay_hints/closing_brace.rs index cd5a815abb..2cefd5acdc 100644 --- a/crates/ide/src/inlay_hints/closing_brace.rs +++ b/crates/ide/src/inlay_hints/closing_brace.rs @@ -35,7 +35,7 @@ pub(super) fn hints( let ty = imp.self_ty(sema.db); let trait_ = imp.trait_(sema.db); let hint_text = match trait_ { - Some(tr) => format!("impl {} for {}", tr.name(sema.db), ty.display_truncated(sema.db, config.max_length)), + Some(tr) => format!("impl {} for {}", tr.name(sema.db).display(sema.db), ty.display_truncated(sema.db, config.max_length)), None => format!("impl {}", ty.display_truncated(sema.db, config.max_length)), }; (hint_text, None) diff --git a/crates/ide/src/moniker.rs b/crates/ide/src/moniker.rs index 7f36e1df54..0d57e63d29 100644 --- a/crates/ide/src/moniker.rs +++ b/crates/ide/src/moniker.rs @@ -1,7 +1,7 @@ //! This module generates [moniker](https://microsoft.github.io/language-server-protocol/specifications/lsif/0.6.0/specification/#exportsImports) //! for LSIF and LSP. -use hir::{AsAssocItem, AssocItemContainer, Crate, Name, Semantics}; +use hir::{AsAssocItem, AssocItemContainer, Crate, Semantics}; use ide_db::{ base_db::{CrateOrigin, FilePosition, LangCrateOrigin}, defs::{Definition, IdentClass}, @@ -27,7 +27,7 @@ pub enum MonikerDescriptorKind { #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct MonikerDescriptor { - pub name: Name, + pub name: String, pub desc: MonikerDescriptorKind, } @@ -41,11 +41,7 @@ impl ToString for MonikerIdentifier { fn to_string(&self) -> String { match self { MonikerIdentifier { description, crate_name } => { - format!( - "{}::{}", - crate_name, - description.iter().map(|x| x.name.to_string()).join("::") - ) + format!("{}::{}", crate_name, description.iter().map(|x| &x.name).join("::")) } } } @@ -136,7 +132,10 @@ pub(crate) fn def_to_moniker( let krate = module.krate(); let mut description = vec![]; description.extend(module.path_to_root(db).into_iter().filter_map(|x| { - Some(MonikerDescriptor { name: x.name(db)?, desc: MonikerDescriptorKind::Namespace }) + Some(MonikerDescriptor { + name: x.name(db)?.display(db).to_string(), + desc: MonikerDescriptorKind::Namespace, + }) })); // Handle associated items within a trait @@ -147,7 +146,7 @@ pub(crate) fn def_to_moniker( // Because different traits can have functions with the same name, // we have to include the trait name as part of the moniker for uniqueness. description.push(MonikerDescriptor { - name: trait_.name(db), + name: trait_.name(db).display(db).to_string(), desc: MonikerDescriptorKind::Type, }); } @@ -156,14 +155,14 @@ pub(crate) fn def_to_moniker( // we add both the struct name and the trait name to the path if let Some(adt) = impl_.self_ty(db).as_adt() { description.push(MonikerDescriptor { - name: adt.name(db), + name: adt.name(db).display(db).to_string(), desc: MonikerDescriptorKind::Type, }); } if let Some(trait_) = impl_.trait_(db) { description.push(MonikerDescriptor { - name: trait_.name(db), + name: trait_.name(db).display(db).to_string(), desc: MonikerDescriptorKind::Type, }); } @@ -173,7 +172,7 @@ pub(crate) fn def_to_moniker( if let Definition::Field(it) = def { description.push(MonikerDescriptor { - name: it.parent_def(db).name(db), + name: it.parent_def(db).name(db).display(db).to_string(), desc: MonikerDescriptorKind::Type, }); } @@ -191,48 +190,63 @@ pub(crate) fn def_to_moniker( return None; } - MonikerDescriptor { name: local.name(db), desc: MonikerDescriptorKind::Parameter } + MonikerDescriptor { + name: local.name(db).display(db).to_string(), + desc: MonikerDescriptorKind::Parameter, + } } - Definition::Macro(m) => { - MonikerDescriptor { name: m.name(db), desc: MonikerDescriptorKind::Macro } - } - Definition::Function(f) => { - MonikerDescriptor { name: f.name(db), desc: MonikerDescriptorKind::Method } - } - Definition::Variant(v) => { - MonikerDescriptor { name: v.name(db), desc: MonikerDescriptorKind::Type } - } - Definition::Const(c) => { - MonikerDescriptor { name: c.name(db)?, desc: MonikerDescriptorKind::Term } - } - Definition::Trait(trait_) => { - MonikerDescriptor { name: trait_.name(db), desc: MonikerDescriptorKind::Type } - } - Definition::TraitAlias(ta) => { - MonikerDescriptor { name: ta.name(db), desc: MonikerDescriptorKind::Type } - } - Definition::TypeAlias(ta) => { - MonikerDescriptor { name: ta.name(db), desc: MonikerDescriptorKind::TypeParameter } - } - Definition::Module(m) => { - MonikerDescriptor { name: m.name(db)?, desc: MonikerDescriptorKind::Namespace } - } - Definition::BuiltinType(b) => { - MonikerDescriptor { name: b.name(), desc: MonikerDescriptorKind::Type } - } - Definition::SelfType(imp) => MonikerDescriptor { - name: imp.self_ty(db).as_adt()?.name(db), + Definition::Macro(m) => MonikerDescriptor { + name: m.name(db).display(db).to_string(), + desc: MonikerDescriptorKind::Macro, + }, + Definition::Function(f) => MonikerDescriptor { + name: f.name(db).display(db).to_string(), + desc: MonikerDescriptorKind::Method, + }, + Definition::Variant(v) => MonikerDescriptor { + name: v.name(db).display(db).to_string(), desc: MonikerDescriptorKind::Type, }, - Definition::Field(it) => { - MonikerDescriptor { name: it.name(db), desc: MonikerDescriptorKind::Term } - } - Definition::Adt(adt) => { - MonikerDescriptor { name: adt.name(db), desc: MonikerDescriptorKind::Type } - } - Definition::Static(s) => { - MonikerDescriptor { name: s.name(db), desc: MonikerDescriptorKind::Meta } - } + Definition::Const(c) => MonikerDescriptor { + name: c.name(db)?.display(db).to_string(), + desc: MonikerDescriptorKind::Term, + }, + Definition::Trait(trait_) => MonikerDescriptor { + name: trait_.name(db).display(db).to_string(), + desc: MonikerDescriptorKind::Type, + }, + Definition::TraitAlias(ta) => MonikerDescriptor { + name: ta.name(db).display(db).to_string(), + desc: MonikerDescriptorKind::Type, + }, + Definition::TypeAlias(ta) => MonikerDescriptor { + name: ta.name(db).display(db).to_string(), + desc: MonikerDescriptorKind::TypeParameter, + }, + Definition::Module(m) => MonikerDescriptor { + name: m.name(db)?.display(db).to_string(), + desc: MonikerDescriptorKind::Namespace, + }, + Definition::BuiltinType(b) => MonikerDescriptor { + name: b.name().display(db).to_string(), + desc: MonikerDescriptorKind::Type, + }, + Definition::SelfType(imp) => MonikerDescriptor { + name: imp.self_ty(db).as_adt()?.name(db).display(db).to_string(), + desc: MonikerDescriptorKind::Type, + }, + Definition::Field(it) => MonikerDescriptor { + name: it.name(db).display(db).to_string(), + desc: MonikerDescriptorKind::Term, + }, + Definition::Adt(adt) => MonikerDescriptor { + name: adt.name(db).display(db).to_string(), + desc: MonikerDescriptorKind::Type, + }, + Definition::Static(s) => MonikerDescriptor { + name: s.name(db).display(db).to_string(), + desc: MonikerDescriptorKind::Meta, + }, }; description.push(name_desc); diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs index 64150cc2f7..78972241bd 100644 --- a/crates/ide/src/runnables.rs +++ b/crates/ide/src/runnables.rs @@ -349,8 +349,13 @@ pub(crate) fn runnable_mod( if !has_test_function_or_multiple_test_submodules(sema, &def) { return None; } - let path = - def.path_to_root(sema.db).into_iter().rev().filter_map(|it| it.name(sema.db)).join("::"); + let path = def + .path_to_root(sema.db) + .into_iter() + .rev() + .filter_map(|it| it.name(sema.db)) + .map(|it| it.display(sema.db).to_string()) + .join("::"); let attrs = def.attrs(sema.db); let cfg = attrs.cfg(); @@ -376,7 +381,7 @@ pub(crate) fn runnable_impl( } else { String::new() }; - let mut test_id = format!("{adt_name}{params}"); + let mut test_id = format!("{}{params}", adt_name.display(sema.db)); test_id.retain(|c| c != ' '); let test_id = TestId::Path(test_id); @@ -391,8 +396,13 @@ fn runnable_mod_outline_definition( if !has_test_function_or_multiple_test_submodules(sema, &def) { return None; } - let path = - def.path_to_root(sema.db).into_iter().rev().filter_map(|it| it.name(sema.db)).join("::"); + let path = def + .path_to_root(sema.db) + .into_iter() + .rev() + .filter_map(|it| it.name(sema.db)) + .map(|it| it.display(sema.db).to_string()) + .join("::"); let attrs = def.attrs(sema.db); let cfg = attrs.cfg(); @@ -430,7 +440,7 @@ fn module_def_doctest(db: &RootDatabase, def: Definition) -> Option { let mut path = String::new(); def.canonical_module_path(db)? .flat_map(|it| it.name(db)) - .for_each(|name| format_to!(path, "{}::", name)); + .for_each(|name| format_to!(path, "{}::", name.display(db))); // This probably belongs to canonical_path? if let Some(assoc_item) = def.as_assoc_item(db) { if let hir::AssocItemContainer::Impl(imp) = assoc_item.container(db) { @@ -438,17 +448,17 @@ fn module_def_doctest(db: &RootDatabase, def: Definition) -> Option { if let Some(adt) = ty.as_adt() { let name = adt.name(db); let mut ty_args = ty.generic_parameters(db).peekable(); - format_to!(path, "{}", name); + format_to!(path, "{}", name.display(db)); if ty_args.peek().is_some() { format_to!(path, "<{}>", ty_args.format_with(",", |ty, cb| cb(&ty))); } - format_to!(path, "::{}", def_name); + format_to!(path, "::{}", def_name.display(db)); path.retain(|c| c != ' '); return Some(path); } } } - format_to!(path, "{}", def_name); + format_to!(path, "{}", def_name.display(db)); Some(path) })(); diff --git a/crates/ide/src/signature_help.rs b/crates/ide/src/signature_help.rs index cdee705cbf..9a0529ec20 100644 --- a/crates/ide/src/signature_help.rs +++ b/crates/ide/src/signature_help.rs @@ -162,7 +162,7 @@ fn signature_help_for_call( match callable.kind() { hir::CallableKind::Function(func) => { res.doc = func.docs(db).map(|it| it.into()); - format_to!(res.signature, "fn {}", func.name(db)); + format_to!(res.signature, "fn {}", func.name(db).display(db)); fn_params = Some(match callable.receiver_param(db) { Some(_self) => func.params_without_self(db), None => func.assoc_fn_params(db), @@ -170,15 +170,15 @@ fn signature_help_for_call( } hir::CallableKind::TupleStruct(strukt) => { res.doc = strukt.docs(db).map(|it| it.into()); - format_to!(res.signature, "struct {}", strukt.name(db)); + format_to!(res.signature, "struct {}", strukt.name(db).display(db)); } hir::CallableKind::TupleEnumVariant(variant) => { res.doc = variant.docs(db).map(|it| it.into()); format_to!( res.signature, "enum {}::{}", - variant.parent_enum(db).name(db), - variant.name(db) + variant.parent_enum(db).name(db).display(db), + variant.name(db).display(db) ); } hir::CallableKind::Closure | hir::CallableKind::FnPtr | hir::CallableKind::Other => (), @@ -248,31 +248,31 @@ fn signature_help_for_generics( match generics_def { hir::GenericDef::Function(it) => { res.doc = it.docs(db).map(|it| it.into()); - format_to!(res.signature, "fn {}", it.name(db)); + format_to!(res.signature, "fn {}", it.name(db).display(db)); } hir::GenericDef::Adt(hir::Adt::Enum(it)) => { res.doc = it.docs(db).map(|it| it.into()); - format_to!(res.signature, "enum {}", it.name(db)); + format_to!(res.signature, "enum {}", it.name(db).display(db)); } hir::GenericDef::Adt(hir::Adt::Struct(it)) => { res.doc = it.docs(db).map(|it| it.into()); - format_to!(res.signature, "struct {}", it.name(db)); + format_to!(res.signature, "struct {}", it.name(db).display(db)); } hir::GenericDef::Adt(hir::Adt::Union(it)) => { res.doc = it.docs(db).map(|it| it.into()); - format_to!(res.signature, "union {}", it.name(db)); + format_to!(res.signature, "union {}", it.name(db).display(db)); } hir::GenericDef::Trait(it) => { res.doc = it.docs(db).map(|it| it.into()); - format_to!(res.signature, "trait {}", it.name(db)); + format_to!(res.signature, "trait {}", it.name(db).display(db)); } hir::GenericDef::TraitAlias(it) => { res.doc = it.docs(db).map(|it| it.into()); - format_to!(res.signature, "trait {}", it.name(db)); + format_to!(res.signature, "trait {}", it.name(db).display(db)); } hir::GenericDef::TypeAlias(it) => { res.doc = it.docs(db).map(|it| it.into()); - format_to!(res.signature, "type {}", it.name(db)); + format_to!(res.signature, "type {}", it.name(db).display(db)); } hir::GenericDef::Variant(it) => { // In paths, generics of an enum can be specified *after* one of its variants. @@ -280,7 +280,7 @@ fn signature_help_for_generics( // We'll use the signature of the enum, but include the docs of the variant. res.doc = it.docs(db).map(|it| it.into()); let enum_ = it.parent_enum(db); - format_to!(res.signature, "enum {}", enum_.name(db)); + format_to!(res.signature, "enum {}", enum_.name(db).display(db)); generics_def = enum_.into(); } // These don't have generic args that can be specified @@ -412,7 +412,12 @@ fn signature_help_for_tuple_struct_pat( let en = variant.parent_enum(db); res.doc = en.docs(db).map(|it| it.into()); - format_to!(res.signature, "enum {}::{} (", en.name(db), variant.name(db)); + format_to!( + res.signature, + "enum {}::{} (", + en.name(db).display(db), + variant.name(db).display(db) + ); variant.fields(db) } else { let adt = match path_res { @@ -424,7 +429,7 @@ fn signature_help_for_tuple_struct_pat( match adt { hir::Adt::Struct(it) => { res.doc = it.docs(db).map(|it| it.into()); - format_to!(res.signature, "struct {} (", it.name(db)); + format_to!(res.signature, "struct {} (", it.name(db).display(db)); it.fields(db) } _ => return None, @@ -486,7 +491,12 @@ fn signature_help_for_record_( let en = variant.parent_enum(db); res.doc = en.docs(db).map(|it| it.into()); - format_to!(res.signature, "enum {}::{} {{ ", en.name(db), variant.name(db)); + format_to!( + res.signature, + "enum {}::{} {{ ", + en.name(db).display(db), + variant.name(db).display(db) + ); } else { let adt = match path_res { PathResolution::SelfType(imp) => imp.self_ty(db).as_adt()?, @@ -498,12 +508,12 @@ fn signature_help_for_record_( hir::Adt::Struct(it) => { fields = it.fields(db); res.doc = it.docs(db).map(|it| it.into()); - format_to!(res.signature, "struct {} {{ ", it.name(db)); + format_to!(res.signature, "struct {} {{ ", it.name(db).display(db)); } hir::Adt::Union(it) => { fields = it.fields(db); res.doc = it.docs(db).map(|it| it.into()); - format_to!(res.signature, "union {} {{ ", it.name(db)); + format_to!(res.signature, "union {} {{ ", it.name(db).display(db)); } _ => return None, } @@ -514,7 +524,7 @@ fn signature_help_for_record_( let mut buf = String::new(); for (field, ty) in fields2 { let name = field.name(db); - format_to!(buf, "{name}: {}", ty.display_truncated(db, Some(20))); + format_to!(buf, "{}: {}", name.display(db), ty.display_truncated(db, Some(20))); res.push_record_field(&buf); buf.clear(); @@ -524,7 +534,7 @@ fn signature_help_for_record_( } for (name, field) in fields { let Some(field) = field else { continue }; - format_to!(buf, "{name}: {}", field.ty(db).display_truncated(db, Some(20))); + format_to!(buf, "{}: {}", name.display(db), field.ty(db).display_truncated(db, Some(20))); res.push_record_field(&buf); buf.clear(); } diff --git a/crates/ide/src/view_item_tree.rs b/crates/ide/src/view_item_tree.rs index 9c1f93356e..e072df430f 100644 --- a/crates/ide/src/view_item_tree.rs +++ b/crates/ide/src/view_item_tree.rs @@ -12,5 +12,5 @@ use ide_db::RootDatabase; // | VS Code | **rust-analyzer: Debug ItemTree** // |=== pub(crate) fn view_item_tree(db: &RootDatabase, file_id: FileId) -> String { - db.file_item_tree(file_id.into()).pretty_print() + db.file_item_tree(file_id.into()).pretty_print(db) } diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs index 673192f571..2c2a9a18d2 100644 --- a/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -221,6 +221,7 @@ impl flags::AnalysisStats { .rev() .filter_map(|it| it.name(db)) .chain(Some(a.name(db))) + .map(|it| it.display(db).to_string()) .join("::"); println!("Data layout for {full_name} failed due {e:?}"); } @@ -248,6 +249,7 @@ impl flags::AnalysisStats { .rev() .filter_map(|it| it.name(db)) .chain(c.name(db)) + .map(|it| it.display(db).to_string()) .join("::"); println!("Const eval for {full_name} failed due {e:?}"); } @@ -274,6 +276,7 @@ impl flags::AnalysisStats { .rev() .filter_map(|it| it.name(db)) .chain(Some(f.name(db))) + .map(|it| it.display(db).to_string()) .join("::"); println!("Mir body for {full_name} failed due {e:?}"); } @@ -332,9 +335,10 @@ impl flags::AnalysisStats { .rev() .filter_map(|it| it.name(db)) .chain(Some(f.name(db))) + .map(|it| it.display(db).to_string()) .join("::"); if let Some(only_name) = self.only.as_deref() { - if name.to_string() != only_name && full_name != only_name { + if name.display(db).to_string() != only_name && full_name != only_name { continue; } } @@ -376,7 +380,7 @@ impl flags::AnalysisStats { end.col, )); } else { - bar.println(format!("{name}: Unknown type",)); + bar.println(format!("{}: Unknown type", name.display(db))); } } true @@ -431,7 +435,7 @@ impl flags::AnalysisStats { } else { bar.println(format!( "{}: Expected {}, got {}", - name, + name.display(db), mismatch.expected.display(db), mismatch.actual.display(db) )); @@ -479,7 +483,7 @@ impl flags::AnalysisStats { end.col, )); } else { - bar.println(format!("{name}: Unknown type",)); + bar.println(format!("{}: Unknown type", name.display(db))); } } true @@ -533,7 +537,7 @@ impl flags::AnalysisStats { } else { bar.println(format!( "{}: Expected {}, got {}", - name, + name.display(db), mismatch.expected.display(db), mismatch.actual.display(db) )); diff --git a/crates/rust-analyzer/src/cli/scip.rs b/crates/rust-analyzer/src/cli/scip.rs index 1c848090b6..61924d5843 100644 --- a/crates/rust-analyzer/src/cli/scip.rs +++ b/crates/rust-analyzer/src/cli/scip.rs @@ -9,7 +9,6 @@ use crate::{ cli::load_cargo::ProcMacroServerChoice, line_index::{LineEndings, LineIndex, PositionEncoding}, }; -use hir::Name; use ide::{ LineCol, MonikerDescriptorKind, StaticIndex, StaticIndexedFile, TextRange, TokenId, TokenStaticData, @@ -209,13 +208,12 @@ fn new_descriptor_str( } } -fn new_descriptor(name: Name, suffix: scip_types::descriptor::Suffix) -> scip_types::Descriptor { - let mut name = name.to_string(); +fn new_descriptor(name: &str, suffix: scip_types::descriptor::Suffix) -> scip_types::Descriptor { if name.contains('\'') { - name = format!("`{name}`"); + new_descriptor_str(&format!("`{name}`"), suffix) + } else { + new_descriptor_str(&name, suffix) } - - new_descriptor_str(name.as_str(), suffix) } /// Loosely based on `def_to_moniker` @@ -235,7 +233,7 @@ fn token_to_symbol(token: &TokenStaticData) -> Option { .iter() .map(|desc| { new_descriptor( - desc.name.clone(), + &desc.name, match desc.desc { MonikerDescriptorKind::Namespace => Namespace, MonikerDescriptorKind::Type => Type, diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 71a57772b1..8a9e947ded 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs @@ -306,12 +306,10 @@ fn completion_item( let imports: Vec<_> = item .import_to_add .into_iter() - .filter_map(|import_edit| { - let import_path = &import_edit.import_path; - let import_name = import_path.segments().last()?; + .filter_map(|(import_path, import_name)| { Some(lsp_ext::CompletionImport { - full_import_path: import_path.to_string(), - imported_name: import_name.to_string(), + full_import_path: import_path, + imported_name: import_name, }) }) .collect();