Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/display.rs')
-rw-r--r--crates/hir-ty/src/display.rs116
1 files changed, 77 insertions, 39 deletions
diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs
index 5a96d396ab..4ef053130a 100644
--- a/crates/hir-ty/src/display.rs
+++ b/crates/hir-ty/src/display.rs
@@ -33,6 +33,7 @@ use rustc_apfloat::{
Float,
};
use smallvec::SmallVec;
+use span::Edition;
use stdx::{never, IsNoneOr};
use triomphe::Arc;
@@ -131,7 +132,11 @@ pub trait HirDisplay {
/// Returns a `Display`able type that is human-readable.
/// Use this for showing types to the user (e.g. diagnostics)
- fn display<'a>(&'a self, db: &'a dyn HirDatabase) -> HirDisplayWrapper<'a, Self>
+ fn display<'a>(
+ &'a self,
+ db: &'a dyn HirDatabase,
+ edition: Edition,
+ ) -> HirDisplayWrapper<'a, Self>
where
Self: Sized,
{
@@ -142,7 +147,7 @@ pub trait HirDisplay {
limited_size: None,
omit_verbose_types: false,
closure_style: ClosureStyle::ImplFn,
- display_target: DisplayTarget::Diagnostics,
+ display_target: DisplayTarget::Diagnostics { edition },
show_container_bounds: false,
}
}
@@ -153,6 +158,7 @@ pub trait HirDisplay {
&'a self,
db: &'a dyn HirDatabase,
max_size: Option<usize>,
+ edition: Edition,
) -> HirDisplayWrapper<'a, Self>
where
Self: Sized,
@@ -164,7 +170,7 @@ pub trait HirDisplay {
limited_size: None,
omit_verbose_types: true,
closure_style: ClosureStyle::ImplFn,
- display_target: DisplayTarget::Diagnostics,
+ display_target: DisplayTarget::Diagnostics { edition },
show_container_bounds: false,
}
}
@@ -175,6 +181,7 @@ pub trait HirDisplay {
&'a self,
db: &'a dyn HirDatabase,
limited_size: Option<usize>,
+ edition: Edition,
) -> HirDisplayWrapper<'a, Self>
where
Self: Sized,
@@ -186,7 +193,7 @@ pub trait HirDisplay {
limited_size,
omit_verbose_types: true,
closure_style: ClosureStyle::ImplFn,
- display_target: DisplayTarget::Diagnostics,
+ display_target: DisplayTarget::Diagnostics { edition },
show_container_bounds: false,
}
}
@@ -242,6 +249,7 @@ pub trait HirDisplay {
&'a self,
db: &'a dyn HirDatabase,
show_container_bounds: bool,
+ edition: Edition,
) -> HirDisplayWrapper<'a, Self>
where
Self: Sized,
@@ -253,13 +261,23 @@ pub trait HirDisplay {
limited_size: None,
omit_verbose_types: false,
closure_style: ClosureStyle::ImplFn,
- display_target: DisplayTarget::Diagnostics,
+ display_target: DisplayTarget::Diagnostics { edition },
show_container_bounds,
}
}
}
impl HirFormatter<'_> {
+ pub fn edition(&self) -> Edition {
+ match self.display_target {
+ DisplayTarget::Diagnostics { edition } => edition,
+ DisplayTarget::SourceCode { module_id, .. } => {
+ self.db.crate_graph()[module_id.krate()].edition
+ }
+ DisplayTarget::Test => Edition::CURRENT,
+ }
+ }
+
pub fn write_joined<T: HirDisplay>(
&mut self,
iter: impl IntoIterator<Item = T>,
@@ -324,7 +342,7 @@ pub enum DisplayTarget {
/// Display types for inlays, doc popups, autocompletion, etc...
/// Showing `{unknown}` or not qualifying paths is fine here.
/// There's no reason for this to fail.
- Diagnostics,
+ Diagnostics { edition: Edition },
/// Display types for inserting them in source files.
/// The generated code should compile, so paths need to be qualified.
SourceCode { module_id: ModuleId, allow_opaque: bool },
@@ -460,7 +478,7 @@ impl HirDisplay for ProjectionTy {
">::{}",
f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id))
.name
- .display(f.db.upcast())
+ .display(f.db.upcast(), f.edition())
)?;
let proj_params_count =
self.substitution.len(Interner) - trait_ref.substitution.len(Interner);
@@ -499,7 +517,7 @@ impl HirDisplay for Const {
let id = from_placeholder_idx(f.db, *idx);
let generics = generics(f.db.upcast(), id.parent);
let param_data = &generics[id.local_id];
- write!(f, "{}", param_data.name().unwrap().display(f.db.upcast()))?;
+ write!(f, "{}", param_data.name().unwrap().display(f.db.upcast(), f.edition()))?;
Ok(())
}
ConstValue::Concrete(c) => match &c.interned {
@@ -633,7 +651,7 @@ fn render_const_scalar(
TyKind::Adt(adt, _) if b.len() == 2 * size_of::<usize>() => match adt.0 {
hir_def::AdtId::StructId(s) => {
let data = f.db.struct_data(s);
- write!(f, "&{}", data.name.display(f.db.upcast()))?;
+ write!(f, "&{}", data.name.display(f.db.upcast(), f.edition()))?;
Ok(())
}
_ => f.write_str("<unsized-enum-or-union>"),
@@ -691,7 +709,7 @@ fn render_const_scalar(
match adt.0 {
hir_def::AdtId::StructId(s) => {
let data = f.db.struct_data(s);
- write!(f, "{}", data.name.display(f.db.upcast()))?;
+ write!(f, "{}", data.name.display(f.db.upcast(), f.edition()))?;
let field_types = f.db.field_types(s.into());
render_variant_after_name(
&data.variant_data,
@@ -705,7 +723,7 @@ fn render_const_scalar(
)
}
hir_def::AdtId::UnionId(u) => {
- write!(f, "{}", f.db.union_data(u).name.display(f.db.upcast()))
+ write!(f, "{}", f.db.union_data(u).name.display(f.db.upcast(), f.edition()))
}
hir_def::AdtId::EnumId(e) => {
let Ok(target_data_layout) = f.db.target_data_layout(trait_env.krate) else {
@@ -717,7 +735,7 @@ fn render_const_scalar(
return f.write_str("<failed-to-detect-variant>");
};
let data = f.db.enum_variant_data(var_id);
- write!(f, "{}", data.name.display(f.db.upcast()))?;
+ write!(f, "{}", data.name.display(f.db.upcast(), f.edition()))?;
let field_types = f.db.field_types(var_id.into());
render_variant_after_name(
&data.variant_data,
@@ -802,11 +820,11 @@ fn render_variant_after_name(
if matches!(data, VariantData::Record(_)) {
write!(f, " {{")?;
if let Some((id, data)) = it.next() {
- write!(f, " {}: ", data.name.display(f.db.upcast()))?;
+ write!(f, " {}: ", data.name.display(f.db.upcast(), f.edition()))?;
render_field(f, id)?;
}
for (id, data) in it {
- write!(f, ", {}: ", data.name.display(f.db.upcast()))?;
+ write!(f, ", {}: ", data.name.display(f.db.upcast(), f.edition()))?;
render_field(f, id)?;
}
write!(f, " }}")?;
@@ -1000,15 +1018,23 @@ impl HirDisplay for Ty {
CallableDefId::FunctionId(ff) => {
write!(f, "fn ")?;
f.start_location_link(def.into());
- write!(f, "{}", db.function_data(ff).name.display(f.db.upcast()))?
+ write!(
+ f,
+ "{}",
+ db.function_data(ff).name.display(f.db.upcast(), f.edition())
+ )?
}
CallableDefId::StructId(s) => {
f.start_location_link(def.into());
- write!(f, "{}", db.struct_data(s).name.display(f.db.upcast()))?
+ write!(f, "{}", db.struct_data(s).name.display(f.db.upcast(), f.edition()))?
}
CallableDefId::EnumVariantId(e) => {
f.start_location_link(def.into());
- write!(f, "{}", db.enum_variant_data(e).name.display(f.db.upcast()))?
+ write!(
+ f,
+ "{}",
+ db.enum_variant_data(e).name.display(f.db.upcast(), f.edition())
+ )?
}
};
f.end_location_link();
@@ -1053,13 +1079,13 @@ impl HirDisplay for Ty {
TyKind::Adt(AdtId(def_id), parameters) => {
f.start_location_link((*def_id).into());
match f.display_target {
- DisplayTarget::Diagnostics | DisplayTarget::Test => {
+ DisplayTarget::Diagnostics { .. } | DisplayTarget::Test => {
let name = match *def_id {
hir_def::AdtId::StructId(it) => db.struct_data(it).name.clone(),
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.display(f.db.upcast()))?;
+ write!(f, "{}", name.display(f.db.upcast(), f.edition()))?;
}
DisplayTarget::SourceCode { module_id, allow_opaque: _ } => {
if let Some(path) = find_path::find_path(
@@ -1075,7 +1101,7 @@ impl HirDisplay for Ty {
prefer_absolute: false,
},
) {
- write!(f, "{}", path.display(f.db.upcast()))?;
+ write!(f, "{}", path.display(f.db.upcast(), f.edition()))?;
} else {
return Err(HirDisplayError::DisplaySourceCodeError(
DisplaySourceCodeError::PathNotFound,
@@ -1101,12 +1127,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.display(f.db.upcast()))?;
+ write!(f, "{}", trait_data.name.display(f.db.upcast(), f.edition()))?;
f.end_location_link();
write!(f, "::")?;
f.start_location_link(type_alias.into());
- write!(f, "{}", type_alias_data.name.display(f.db.upcast()))?;
+ write!(f, "{}", type_alias_data.name.display(f.db.upcast(), f.edition()))?;
f.end_location_link();
// Note that the generic args for the associated type come before those for the
// trait (including the self type).
@@ -1124,7 +1150,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.display(f.db.upcast()))?;
+ write!(f, "{}", type_alias.name.display(f.db.upcast(), f.edition()))?;
f.end_location_link();
}
TyKind::OpaqueType(opaque_ty_id, parameters) => {
@@ -1256,7 +1282,10 @@ impl HirDisplay for Ty {
write!(
f,
"{}",
- p.name.clone().unwrap_or_else(Name::missing).display(f.db.upcast())
+ p.name
+ .clone()
+ .unwrap_or_else(Name::missing)
+ .display(f.db.upcast(), f.edition())
)?
}
TypeParamProvenance::ArgumentImplTrait => {
@@ -1289,7 +1318,7 @@ impl HirDisplay for Ty {
}
},
TypeOrConstParamData::ConstParamData(p) => {
- write!(f, "{}", p.name.display(f.db.upcast()))?;
+ write!(f, "{}", p.name.display(f.db.upcast(), f.edition()))?;
}
}
}
@@ -1632,7 +1661,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.display(f.db.upcast()))?;
+ write!(f, "{}", f.db.trait_data(trait_).name.display(f.db.upcast(), f.edition()))?;
f.end_location_link();
if is_fn_trait {
if let [self_, params @ ..] = trait_ref.substitution.as_slice(Interner) {
@@ -1706,7 +1735,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.display(f.db.upcast()))?;
+ write!(f, "{}", type_alias.name.display(f.db.upcast(), f.edition()))?;
f.end_location_link();
let proj_arg_count = generics(f.db.upcast(), assoc_ty_id.into()).len_self();
@@ -1770,7 +1799,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.display(f.db.upcast()))?;
+ write!(f, "{}", f.db.trait_data(trait_).name.display(f.db.upcast(), f.edition()))?;
f.end_location_link();
let substs = tr.substitution.as_slice(Interner);
hir_fmt_generics(f, &substs[1..], None, substs[0].ty(Interner))
@@ -1796,7 +1825,11 @@ 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.display(f.db.upcast()),)?;
+ write!(
+ f,
+ "{}",
+ f.db.type_alias_data(type_alias).name.display(f.db.upcast(), f.edition()),
+ )?;
f.end_location_link();
write!(f, " = ")?;
ty.hir_fmt(f)?;
@@ -1832,7 +1865,7 @@ 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[id.local_id];
- write!(f, "{}", param_data.name.display(f.db.upcast()))?;
+ write!(f, "{}", param_data.name.display(f.db.upcast(), f.edition()))?;
Ok(())
}
_ if f.display_target.is_source_code() => write!(f, "'_"),
@@ -1913,7 +1946,7 @@ impl HirDisplay for TypeRef {
};
write!(f, "&")?;
if let Some(lifetime) = lifetime {
- write!(f, "{} ", lifetime.name.display(f.db.upcast()))?;
+ write!(f, "{} ", lifetime.name.display(f.db.upcast(), f.edition()))?;
}
write!(f, "{mutability}")?;
inner.hir_fmt(f)?;
@@ -1921,7 +1954,7 @@ impl HirDisplay for TypeRef {
TypeRef::Array(inner, len) => {
write!(f, "[")?;
inner.hir_fmt(f)?;
- write!(f, "; {}]", len.display(f.db.upcast()))?;
+ write!(f, "; {}]", len.display(f.db.upcast(), f.edition()))?;
}
TypeRef::Slice(inner) => {
write!(f, "[")?;
@@ -1942,7 +1975,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.display(f.db.upcast()))?;
+ write!(f, "{}: ", name.display(f.db.upcast(), f.edition()))?;
}
param_type.hir_fmt(f)?;
@@ -2000,12 +2033,15 @@ impl HirDisplay for TypeBound {
}
path.hir_fmt(f)
}
- TypeBound::Lifetime(lifetime) => write!(f, "{}", lifetime.name.display(f.db.upcast())),
+ TypeBound::Lifetime(lifetime) => {
+ write!(f, "{}", lifetime.name.display(f.db.upcast(), f.edition()))
+ }
TypeBound::ForLifetime(lifetimes, path) => {
+ let edition = f.edition();
write!(
f,
"for<{}> ",
- lifetimes.iter().map(|it| it.display(f.db.upcast())).format(", ")
+ lifetimes.iter().map(|it| it.display(f.db.upcast(), edition)).format(", ")
)?;
path.hir_fmt(f)
}
@@ -2071,7 +2107,7 @@ impl HirDisplay for Path {
if !matches!(self.kind(), PathKind::Plain) || seg_idx > 0 {
write!(f, "::")?;
}
- write!(f, "{}", segment.name.display(f.db.upcast()))?;
+ write!(f, "{}", segment.name.display(f.db.upcast(), f.edition()))?;
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?
@@ -2116,7 +2152,7 @@ impl HirDisplay for Path {
} else {
write!(f, ", ")?;
}
- write!(f, "{}", binding.name.display(f.db.upcast()))?;
+ write!(f, "{}", binding.name.display(f.db.upcast(), f.edition()))?;
match &binding.type_ref {
Some(ty) => {
write!(f, " = ")?;
@@ -2150,9 +2186,11 @@ 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.display(f.db.upcast())),
+ hir_def::path::GenericArg::Const(c) => {
+ write!(f, "{}", c.display(f.db.upcast(), f.edition()))
+ }
hir_def::path::GenericArg::Lifetime(lifetime) => {
- write!(f, "{}", lifetime.name.display(f.db.upcast()))
+ write!(f, "{}", lifetime.name.display(f.db.upcast(), f.edition()))
}
}
}