internal: Replace Display impl for Name

This commit is contained in:
Lukas Wirth 2023-05-24 18:04:29 +02:00
parent 2f840c2236
commit c7ef6c25b7
108 changed files with 1045 additions and 656 deletions

View file

@ -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(|(&param, 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));
}
}

View file

@ -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),
}
}
}

View file

@ -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<ast::Expr>) -> 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 {

View file

@ -33,13 +33,23 @@ pub struct ImportPath {
pub segments: Vec<Name>,
}
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::<Vec<_>>();
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::<String>();

View file

@ -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");

View file

@ -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 {

View file

@ -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<TypeBound>]) {
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 &params.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()),
}
}

View file

@ -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);
}

View file

@ -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);
}
}
}

View file

@ -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);
}

View file

@ -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));

View file

@ -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,

View file

@ -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

View file

@ -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, "<macro>")?;
@ -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<TypeBound>],
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}}")?,
}
}

View file

@ -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<Name> 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,

View file

@ -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 {

View file

@ -365,13 +365,19 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
fn trait_name(&self, trait_id: chalk_ir::TraitId<Interner>) -> 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<Interner>) -> Arc<rust_ir::AdtSizeAlign> {
@ -380,7 +386,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
}
fn assoc_type_name(&self, assoc_ty_id: chalk_ir::AssocTypeId<Interner>) -> 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<Interner>) -> String {
format!("Opaque_{}", opaque_ty_id.0)

View file

@ -79,7 +79,7 @@ fn eval_goal(db: &TestDB, file_id: FileId) -> Result<Const, ConstEvalError> {
.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

View file

@ -243,13 +243,19 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
fn infer_wait(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> {
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)

View file

@ -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,
};

View file

@ -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)
})
});

View file

@ -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("<enum-not-supported>"),
},
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<Bar>` instead of `Foo::<Bar>`.
// 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()))
}
}
}
}

View file

@ -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 {

View file

@ -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)))
}
}

View file

@ -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

View file

@ -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<Arc<MirBody>> {
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);

View file

@ -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);

View file

@ -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()))
}
}
}

View file

@ -88,7 +88,7 @@ pub(crate) fn trait_solve_query(
) -> Option<Solution> {
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(),

View file

@ -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 &params.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()))
}
}

View file

@ -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<AnyDiagnostic>) {
let _p = profile::span("Module::diagnostics").detail(|| {
format!("{:?}", self.name(db).map_or("<unknown>".into(), |name| name.to_string()))
format!(
"{:?}",
self.name(db)
.map_or("<unknown>".into(), |name| name.display(db.upcast()).to_string())
)
});
let def_map = self.id.def_map(db.upcast());
for diag in def_map.diagnostics() {

View file

@ -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))

View file

@ -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() {

View file

@ -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)?;

View file

@ -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})");

View file

@ -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();

View file

@ -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))
}

View file

@ -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;
}

View file

@ -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(

View file

@ -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);

View file

@ -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();

View file

@ -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);
}

View file

@ -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 {

View file

@ -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());
}

View file

@ -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(

View file

@ -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()))
}
_ => (),
}

View file

@ -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(

View file

@ -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)),
}
}

View file

@ -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)

View file

@ -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(),
)
}

View file

@ -234,7 +234,7 @@ fn from_type(expr: &ast::Expr, sema: &Semantics<'_, RootDatabase>) -> Option<Str
fn name_of_type(ty: &hir::Type, db: &RootDatabase) -> Option<String> {
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<String> {
}
fn trait_name(trait_: &hir::Trait, db: &RootDatabase) -> Option<String> {
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;
}

View file

@ -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<Completions> for Vec<CompletionItem> {
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(

View file

@ -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);
}
};

View file

@ -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));
}),
};
}

View file

@ -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),
}

View file

@ -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)
}
}

View file

@ -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);
}
}
}

View file

@ -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 {

View file

@ -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(())

View file

@ -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(())
}

View file

@ -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(())
}

View file

@ -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());

View file

@ -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);
})
}

View file

@ -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);
}
}
}

View file

@ -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::<FxHashSet<_>>();
@ -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(())

View file

@ -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

View file

@ -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);
}
}
}

View file

@ -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);
}
}

View file

@ -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

View file

@ -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));
}
}
_ => {}

View file

@ -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| {

View file

@ -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<SmolStr>) -> &mut Builder {

View file

@ -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);
}

View file

@ -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)));
}
}
}

View file

@ -29,5 +29,5 @@ fn render(ctx: RenderContext<'_>, const_: hir::Const) -> Option<CompletionItem>
}
item.insert_text(escaped_name);
Some(item.build())
Some(item.build(ctx.db()))
}

View file

@ -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()),
};

View file

@ -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)
};

View file

@ -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

View file

@ -53,5 +53,5 @@ fn render(
}
item.insert_text(escaped_name);
Some(item.build())
Some(item.build(ctx.db()))
}

View file

@ -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()))
}

View file

@ -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 {

View file

@ -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()

View file

@ -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)

View file

@ -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,
};

View file

@ -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::<Vec<_>>()
.join("\n");
expect.assert_eq(&actual);

View file

@ -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<Vec<Ass
fn make_ty(ty: &hir::Type, db: &dyn HirDatabase, module: hir::Module) -> 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())
}

View file

@ -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)

View file

@ -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!(

View file

@ -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,
)

View file

@ -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,
)
}

View file

@ -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,
)
}

View file

@ -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,

View file

@ -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()

View file

@ -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,

View file

@ -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,

View file

@ -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<SyntaxToken>,
}
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(),

View file

@ -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<String> {
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())),
})
}

View file

@ -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,
);

View file

@ -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)?,
})

View file

@ -370,7 +370,7 @@ fn definition_owner_name(db: &RootDatabase, def: &Definition) -> Option<String>
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>) -> String {
@ -380,7 +380,7 @@ pub(super) fn path(db: &RootDatabase, module: hir::Module, item_name: Option<Str
.path_to_root(db)
.into_iter()
.rev()
.flat_map(|it| it.name(db).map(|name| name.to_string()));
.flat_map(|it| it.name(db).map(|name| name.display(db).to_string()));
crate_name.into_iter().chain(module_path).chain(item_name).join("::")
}
@ -468,18 +468,20 @@ pub(super) fn definition(
Definition::BuiltinType(it) => {
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<String>, desc: String, mod_path: Option<String>) -> Optio
fn builtin(famous_defs: &FamousDefs<'_, '_>, builtin: hir::BuiltinType) -> Option<Markup> {
// 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<hir::Module> {
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<Markup> {
@ -748,7 +750,7 @@ fn local(db: &RootDatabase, it: hir::Local, config: &HoverConfig) -> Option<Mark
} else {
""
};
format!("{let_kw}{is_mut}{name}: {ty}")
format!("{let_kw}{is_mut}{}: {ty}", name.display(db))
}
None => format!("{is_mut}self: {ty}"),
};

Some files were not shown because too many files have changed in this diff Show more