mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-27 12:29:21 +00:00
Replace Display by a pretty printing trait for Ty
This allows removing the names from Adt and FnDef (and more later), as a first step towards aligning more with chalk's Ty :)
This commit is contained in:
parent
eb4d6cf25f
commit
c5ee60e05b
7 changed files with 136 additions and 60 deletions
|
@ -56,7 +56,7 @@ pub use self::{
|
||||||
ids::{HirFileId, MacroCallId, MacroCallLoc, HirInterner},
|
ids::{HirFileId, MacroCallId, MacroCallLoc, HirInterner},
|
||||||
macros::{MacroDef, MacroInput, MacroExpansion},
|
macros::{MacroDef, MacroInput, MacroExpansion},
|
||||||
nameres::{ItemMap, PerNs, Namespace},
|
nameres::{ItemMap, PerNs, Namespace},
|
||||||
ty::{Ty, Substs},
|
ty::{Ty, Substs, display::HirDisplay},
|
||||||
impl_block::{ImplBlock, ImplItem},
|
impl_block::{ImplBlock, ImplItem},
|
||||||
docs::{Docs, Documentation},
|
docs::{Docs, Documentation},
|
||||||
adt::AdtDef,
|
adt::AdtDef,
|
||||||
|
|
|
@ -9,16 +9,16 @@ pub(crate) mod method_resolution;
|
||||||
mod op;
|
mod op;
|
||||||
mod lower;
|
mod lower;
|
||||||
mod infer;
|
mod infer;
|
||||||
|
pub(crate) mod display;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::{fmt, mem};
|
use std::{fmt, mem};
|
||||||
|
|
||||||
use join_to_string::join;
|
use crate::{Name, AdtDef, type_ref::Mutability, db::HirDatabase};
|
||||||
|
|
||||||
use crate::{Name, AdtDef, type_ref::Mutability};
|
|
||||||
|
|
||||||
pub(crate) use lower::{TypableDef, CallableDef, type_for_def, type_for_field};
|
pub(crate) use lower::{TypableDef, CallableDef, type_for_def, type_for_field};
|
||||||
pub(crate) use infer::{infer, InferenceResult, InferTy};
|
pub(crate) use infer::{infer, InferenceResult, InferTy};
|
||||||
|
use display::{HirDisplay, HirFormatter};
|
||||||
|
|
||||||
/// A type. This is based on the `TyKind` enum in rustc (librustc/ty/sty.rs).
|
/// A type. This is based on the `TyKind` enum in rustc (librustc/ty/sty.rs).
|
||||||
///
|
///
|
||||||
|
@ -42,8 +42,6 @@ pub enum Ty {
|
||||||
Adt {
|
Adt {
|
||||||
/// The definition of the struct/enum.
|
/// The definition of the struct/enum.
|
||||||
def_id: AdtDef,
|
def_id: AdtDef,
|
||||||
/// The name, for displaying.
|
|
||||||
name: Name,
|
|
||||||
/// Substitutions for the generic parameters of the type.
|
/// Substitutions for the generic parameters of the type.
|
||||||
substs: Substs,
|
substs: Substs,
|
||||||
},
|
},
|
||||||
|
@ -79,8 +77,6 @@ pub enum Ty {
|
||||||
FnDef {
|
FnDef {
|
||||||
/// The definition of the function / constructor.
|
/// The definition of the function / constructor.
|
||||||
def: CallableDef,
|
def: CallableDef,
|
||||||
/// For display
|
|
||||||
name: Name,
|
|
||||||
/// Parameters and return type
|
/// Parameters and return type
|
||||||
sig: Arc<FnSig>,
|
sig: Arc<FnSig>,
|
||||||
/// Substitutions for the generic parameters of the type
|
/// Substitutions for the generic parameters of the type
|
||||||
|
@ -265,8 +261,8 @@ impl Ty {
|
||||||
/// `Option<u32>` afterwards.)
|
/// `Option<u32>` afterwards.)
|
||||||
pub fn apply_substs(self, substs: Substs) -> Ty {
|
pub fn apply_substs(self, substs: Substs) -> Ty {
|
||||||
match self {
|
match self {
|
||||||
Ty::Adt { def_id, name, .. } => Ty::Adt { def_id, name, substs },
|
Ty::Adt { def_id, .. } => Ty::Adt { def_id, substs },
|
||||||
Ty::FnDef { def, name, sig, .. } => Ty::FnDef { def, name, sig, substs },
|
Ty::FnDef { def, sig, .. } => Ty::FnDef { def, sig, substs },
|
||||||
_ => self,
|
_ => self,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -297,50 +293,80 @@ impl Ty {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Ty {
|
impl HirDisplay for &Ty {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
|
||||||
|
HirDisplay::hir_fmt(*self, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HirDisplay for Ty {
|
||||||
|
fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Ty::Bool => write!(f, "bool"),
|
Ty::Bool => write!(f, "bool")?,
|
||||||
Ty::Char => write!(f, "char"),
|
Ty::Char => write!(f, "char")?,
|
||||||
Ty::Int(t) => write!(f, "{}", t.ty_to_string()),
|
Ty::Int(t) => write!(f, "{}", t.ty_to_string())?,
|
||||||
Ty::Float(t) => write!(f, "{}", t.ty_to_string()),
|
Ty::Float(t) => write!(f, "{}", t.ty_to_string())?,
|
||||||
Ty::Str => write!(f, "str"),
|
Ty::Str => write!(f, "str")?,
|
||||||
Ty::Slice(t) | Ty::Array(t) => write!(f, "[{}]", t),
|
Ty::Slice(t) | Ty::Array(t) => {
|
||||||
Ty::RawPtr(t, m) => write!(f, "*{}{}", m.as_keyword_for_ptr(), t),
|
write!(f, "[{}]", t.display(f.db))?;
|
||||||
Ty::Ref(t, m) => write!(f, "&{}{}", m.as_keyword_for_ref(), t),
|
}
|
||||||
Ty::Never => write!(f, "!"),
|
Ty::RawPtr(t, m) => {
|
||||||
|
write!(f, "*{}{}", m.as_keyword_for_ptr(), t.display(f.db))?;
|
||||||
|
}
|
||||||
|
Ty::Ref(t, m) => {
|
||||||
|
write!(f, "&{}{}", m.as_keyword_for_ref(), t.display(f.db))?;
|
||||||
|
}
|
||||||
|
Ty::Never => write!(f, "!")?,
|
||||||
Ty::Tuple(ts) => {
|
Ty::Tuple(ts) => {
|
||||||
if ts.len() == 1 {
|
if ts.len() == 1 {
|
||||||
write!(f, "({},)", ts[0])
|
write!(f, "({},)", ts[0].display(f.db))?;
|
||||||
} else {
|
} else {
|
||||||
join(ts.iter()).surround_with("(", ")").separator(", ").to_fmt(f)
|
write!(f, "(")?;
|
||||||
|
f.write_joined(&**ts, ", ")?;
|
||||||
|
write!(f, ")")?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ty::FnPtr(sig) => {
|
Ty::FnPtr(sig) => {
|
||||||
join(sig.input.iter()).surround_with("fn(", ")").separator(", ").to_fmt(f)?;
|
write!(f, "fn(")?;
|
||||||
write!(f, " -> {}", sig.output)
|
f.write_joined(&sig.input, ", ")?;
|
||||||
|
write!(f, ") -> {}", sig.output.display(f.db))?;
|
||||||
}
|
}
|
||||||
Ty::FnDef { def, name, substs, sig, .. } => {
|
Ty::FnDef { def, substs, sig, .. } => {
|
||||||
|
let name = match def {
|
||||||
|
CallableDef::Function(ff) => ff.name(f.db),
|
||||||
|
CallableDef::Struct(s) => s.name(f.db).unwrap_or_else(Name::missing),
|
||||||
|
CallableDef::EnumVariant(e) => e.name(f.db).unwrap_or_else(Name::missing),
|
||||||
|
};
|
||||||
match def {
|
match def {
|
||||||
CallableDef::Function(_) => write!(f, "fn {}", name)?,
|
CallableDef::Function(_) => write!(f, "fn {}", name)?,
|
||||||
CallableDef::Struct(_) | CallableDef::EnumVariant(_) => write!(f, "{}", name)?,
|
CallableDef::Struct(_) | CallableDef::EnumVariant(_) => write!(f, "{}", name)?,
|
||||||
}
|
}
|
||||||
if substs.0.len() > 0 {
|
if substs.0.len() > 0 {
|
||||||
join(substs.0.iter()).surround_with("<", ">").separator(", ").to_fmt(f)?;
|
write!(f, "<")?;
|
||||||
|
f.write_joined(&*substs.0, ", ")?;
|
||||||
|
write!(f, ">")?;
|
||||||
}
|
}
|
||||||
join(sig.input.iter()).surround_with("(", ")").separator(", ").to_fmt(f)?;
|
write!(f, "(")?;
|
||||||
write!(f, " -> {}", sig.output)
|
f.write_joined(&sig.input, ", ")?;
|
||||||
|
write!(f, ") -> {}", sig.output.display(f.db))?;
|
||||||
}
|
}
|
||||||
Ty::Adt { name, substs, .. } => {
|
Ty::Adt { def_id, substs, .. } => {
|
||||||
|
let name = match def_id {
|
||||||
|
AdtDef::Struct(s) => s.name(f.db),
|
||||||
|
AdtDef::Enum(e) => e.name(f.db),
|
||||||
|
}
|
||||||
|
.unwrap_or_else(Name::missing);
|
||||||
write!(f, "{}", name)?;
|
write!(f, "{}", name)?;
|
||||||
if substs.0.len() > 0 {
|
if substs.0.len() > 0 {
|
||||||
join(substs.0.iter()).surround_with("<", ">").separator(", ").to_fmt(f)?;
|
write!(f, "<")?;
|
||||||
|
f.write_joined(&*substs.0, ", ")?;
|
||||||
|
write!(f, ">")?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ty::Param { name, .. } => write!(f, "{}", name)?,
|
||||||
|
Ty::Unknown => write!(f, "{{unknown}}")?,
|
||||||
|
Ty::Infer(..) => write!(f, "_")?,
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Ty::Param { name, .. } => write!(f, "{}", name),
|
|
||||||
Ty::Unknown => write!(f, "{{unknown}}"),
|
|
||||||
Ty::Infer(..) => write!(f, "_"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
56
crates/ra_hir/src/ty/display.rs
Normal file
56
crates/ra_hir/src/ty/display.rs
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
use crate::db::HirDatabase;
|
||||||
|
|
||||||
|
pub struct HirFormatter<'a, 'b, DB> {
|
||||||
|
pub db: &'a DB,
|
||||||
|
fmt: &'a mut fmt::Formatter<'b>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait HirDisplay {
|
||||||
|
fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result;
|
||||||
|
fn display<'a, DB>(&'a self, db: &'a DB) -> HirDisplayWrapper<'a, DB, Self>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
HirDisplayWrapper(db, self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'b, DB> HirFormatter<'a, 'b, DB>
|
||||||
|
where
|
||||||
|
DB: HirDatabase,
|
||||||
|
{
|
||||||
|
pub fn write_joined<T: HirDisplay>(
|
||||||
|
&mut self,
|
||||||
|
iter: impl IntoIterator<Item = T>,
|
||||||
|
sep: &str,
|
||||||
|
) -> fmt::Result {
|
||||||
|
let mut first = true;
|
||||||
|
for e in iter {
|
||||||
|
if !first {
|
||||||
|
write!(self, "{}", sep)?;
|
||||||
|
}
|
||||||
|
first = false;
|
||||||
|
e.hir_fmt(self)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This allows using the `write!` macro directly with a `HirFormatter`.
|
||||||
|
pub fn write_fmt(&mut self, args: fmt::Arguments) -> fmt::Result {
|
||||||
|
fmt::write(self.fmt, args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct HirDisplayWrapper<'a, DB, T>(&'a DB, &'a T);
|
||||||
|
|
||||||
|
impl<'a, DB, T> fmt::Display for HirDisplayWrapper<'a, DB, T>
|
||||||
|
where
|
||||||
|
DB: HirDatabase,
|
||||||
|
T: HirDisplay,
|
||||||
|
{
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
self.1.hir_fmt(&mut HirFormatter { db: self.0, fmt: f })
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,7 +9,7 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Function, Struct, StructField, Enum, EnumVariant, Path, Name,
|
Function, Struct, StructField, Enum, EnumVariant, Path,
|
||||||
ModuleDef, TypeAlias,
|
ModuleDef, TypeAlias,
|
||||||
Const, Static,
|
Const, Static,
|
||||||
HirDatabase,
|
HirDatabase,
|
||||||
|
@ -232,13 +232,12 @@ fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty {
|
||||||
let signature = def.signature(db);
|
let signature = def.signature(db);
|
||||||
let resolver = def.resolver(db);
|
let resolver = def.resolver(db);
|
||||||
let generics = def.generic_params(db);
|
let generics = def.generic_params(db);
|
||||||
let name = def.name(db);
|
|
||||||
let input =
|
let input =
|
||||||
signature.params().iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>();
|
signature.params().iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::<Vec<_>>();
|
||||||
let output = Ty::from_hir(db, &resolver, signature.ret_type());
|
let output = Ty::from_hir(db, &resolver, signature.ret_type());
|
||||||
let sig = Arc::new(FnSig { input, output });
|
let sig = Arc::new(FnSig { input, output });
|
||||||
let substs = make_substs(&generics);
|
let substs = make_substs(&generics);
|
||||||
Ty::FnDef { def: def.into(), sig, name, substs }
|
Ty::FnDef { def: def.into(), sig, substs }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Build the declared type of a const.
|
/// Build the declared type of a const.
|
||||||
|
@ -266,7 +265,6 @@ fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty {
|
||||||
};
|
};
|
||||||
let resolver = def.resolver(db);
|
let resolver = def.resolver(db);
|
||||||
let generics = def.generic_params(db);
|
let generics = def.generic_params(db);
|
||||||
let name = def.name(db).unwrap_or_else(Name::missing);
|
|
||||||
let input = fields
|
let input = fields
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref))
|
.map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref))
|
||||||
|
@ -274,7 +272,7 @@ fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty {
|
||||||
let output = type_for_struct(db, def);
|
let output = type_for_struct(db, def);
|
||||||
let sig = Arc::new(FnSig { input, output });
|
let sig = Arc::new(FnSig { input, output });
|
||||||
let substs = make_substs(&generics);
|
let substs = make_substs(&generics);
|
||||||
Ty::FnDef { def: def.into(), sig, name, substs }
|
Ty::FnDef { def: def.into(), sig, substs }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Build the type of a tuple enum variant constructor.
|
/// Build the type of a tuple enum variant constructor.
|
||||||
|
@ -286,7 +284,6 @@ fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) ->
|
||||||
};
|
};
|
||||||
let resolver = def.parent_enum(db).resolver(db);
|
let resolver = def.parent_enum(db).resolver(db);
|
||||||
let generics = def.parent_enum(db).generic_params(db);
|
let generics = def.parent_enum(db).generic_params(db);
|
||||||
let name = def.name(db).unwrap_or_else(Name::missing);
|
|
||||||
let input = fields
|
let input = fields
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref))
|
.map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref))
|
||||||
|
@ -294,7 +291,7 @@ fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) ->
|
||||||
let substs = make_substs(&generics);
|
let substs = make_substs(&generics);
|
||||||
let output = type_for_enum(db, def.parent_enum(db)).subst(&substs);
|
let output = type_for_enum(db, def.parent_enum(db)).subst(&substs);
|
||||||
let sig = Arc::new(FnSig { input, output });
|
let sig = Arc::new(FnSig { input, output });
|
||||||
Ty::FnDef { def: def.into(), sig, name, substs }
|
Ty::FnDef { def: def.into(), sig, substs }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_substs(generics: &GenericParams) -> Substs {
|
fn make_substs(generics: &GenericParams) -> Substs {
|
||||||
|
@ -310,20 +307,12 @@ fn make_substs(generics: &GenericParams) -> Substs {
|
||||||
|
|
||||||
fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty {
|
fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty {
|
||||||
let generics = s.generic_params(db);
|
let generics = s.generic_params(db);
|
||||||
Ty::Adt {
|
Ty::Adt { def_id: s.into(), substs: make_substs(&generics) }
|
||||||
def_id: s.into(),
|
|
||||||
name: s.name(db).unwrap_or_else(Name::missing),
|
|
||||||
substs: make_substs(&generics),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty {
|
fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty {
|
||||||
let generics = s.generic_params(db);
|
let generics = s.generic_params(db);
|
||||||
Ty::Adt {
|
Ty::Adt { def_id: s.into(), substs: make_substs(&generics) }
|
||||||
def_id: s.into(),
|
|
||||||
name: s.name(db).unwrap_or_else(Name::missing),
|
|
||||||
substs: make_substs(&generics),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty {
|
fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty {
|
||||||
|
|
|
@ -10,6 +10,7 @@ use test_utils::covers;
|
||||||
use crate::{
|
use crate::{
|
||||||
source_binder,
|
source_binder,
|
||||||
mock::MockDatabase,
|
mock::MockDatabase,
|
||||||
|
ty::display::HirDisplay,
|
||||||
};
|
};
|
||||||
|
|
||||||
// These tests compare the inference results for all expressions in a file
|
// These tests compare the inference results for all expressions in a file
|
||||||
|
@ -2142,7 +2143,7 @@ fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String {
|
||||||
let node = algo::find_node_at_offset::<ast::Expr>(syntax.syntax(), pos.offset).unwrap();
|
let node = algo::find_node_at_offset::<ast::Expr>(syntax.syntax(), pos.offset).unwrap();
|
||||||
let expr = body_source_map.node_expr(node).unwrap();
|
let expr = body_source_map.node_expr(node).unwrap();
|
||||||
let ty = &inference_result[expr];
|
let ty = &inference_result[expr];
|
||||||
ty.to_string()
|
ty.display(db).to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn infer(content: &str) -> String {
|
fn infer(content: &str) -> String {
|
||||||
|
@ -2178,7 +2179,7 @@ fn infer(content: &str) -> String {
|
||||||
"{} '{}': {}\n",
|
"{} '{}': {}\n",
|
||||||
syntax_ptr.range(),
|
syntax_ptr.range(),
|
||||||
ellipsize(node.text().to_string().replace("\n", " "), 15),
|
ellipsize(node.text().to_string().replace("\n", " "), 15),
|
||||||
ty
|
ty.display(&db)
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! This modules takes care of rendering various defenitions as completion items.
|
//! This modules takes care of rendering various defenitions as completion items.
|
||||||
use join_to_string::join;
|
use join_to_string::join;
|
||||||
use test_utils::tested_by;
|
use test_utils::tested_by;
|
||||||
use hir::{Docs, PerNs, Resolution};
|
use hir::{Docs, PerNs, Resolution, HirDisplay};
|
||||||
use ra_syntax::ast::NameOwner;
|
use ra_syntax::ast::NameOwner;
|
||||||
|
|
||||||
use crate::completion::{
|
use crate::completion::{
|
||||||
|
@ -22,7 +22,7 @@ impl Completions {
|
||||||
field.name(ctx.db).to_string(),
|
field.name(ctx.db).to_string(),
|
||||||
)
|
)
|
||||||
.kind(CompletionItemKind::Field)
|
.kind(CompletionItemKind::Field)
|
||||||
.detail(field.ty(ctx.db).subst(substs).to_string())
|
.detail(field.ty(ctx.db).subst(substs).display(ctx.db).to_string())
|
||||||
.set_documentation(field.docs(ctx.db))
|
.set_documentation(field.docs(ctx.db))
|
||||||
.add_to(self);
|
.add_to(self);
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ impl Completions {
|
||||||
pub(crate) fn add_pos_field(&mut self, ctx: &CompletionContext, field: usize, ty: &hir::Ty) {
|
pub(crate) fn add_pos_field(&mut self, ctx: &CompletionContext, field: usize, ty: &hir::Ty) {
|
||||||
CompletionItem::new(CompletionKind::Reference, ctx.source_range(), field.to_string())
|
CompletionItem::new(CompletionKind::Reference, ctx.source_range(), field.to_string())
|
||||||
.kind(CompletionItemKind::Field)
|
.kind(CompletionItemKind::Field)
|
||||||
.detail(ty.to_string())
|
.detail(ty.display(ctx.db).to_string())
|
||||||
.add_to(self);
|
.add_to(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,7 +154,10 @@ impl Completions {
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
let detail_types = variant.fields(ctx.db).into_iter().map(|field| field.ty(ctx.db));
|
let detail_types = variant.fields(ctx.db).into_iter().map(|field| field.ty(ctx.db));
|
||||||
let detail = join(detail_types).separator(", ").surround_with("(", ")").to_string();
|
let detail = join(detail_types.map(|t| t.display(ctx.db).to_string()))
|
||||||
|
.separator(", ")
|
||||||
|
.surround_with("(", ")")
|
||||||
|
.to_string();
|
||||||
|
|
||||||
CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.to_string())
|
CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.to_string())
|
||||||
.kind(CompletionItemKind::EnumVariant)
|
.kind(CompletionItemKind::EnumVariant)
|
||||||
|
|
|
@ -3,6 +3,7 @@ use ra_syntax::{
|
||||||
AstNode, SyntaxNode, TreeArc, ast::{self, NameOwner, VisibilityOwner, TypeAscriptionOwner},
|
AstNode, SyntaxNode, TreeArc, ast::{self, NameOwner, VisibilityOwner, TypeAscriptionOwner},
|
||||||
algo::{find_covering_node, find_node_at_offset, find_leaf_at_offset, visit::{visitor, Visitor}},
|
algo::{find_covering_node, find_node_at_offset, find_leaf_at_offset, visit::{visitor, Visitor}},
|
||||||
};
|
};
|
||||||
|
use hir::HirDisplay;
|
||||||
|
|
||||||
use crate::{db::RootDatabase, RangeInfo, FilePosition, FileRange, NavigationTarget};
|
use crate::{db::RootDatabase, RangeInfo, FilePosition, FileRange, NavigationTarget};
|
||||||
|
|
||||||
|
@ -134,9 +135,9 @@ pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Option<String> {
|
||||||
let infer = function.infer(db);
|
let infer = function.infer(db);
|
||||||
let source_map = function.body_source_map(db);
|
let source_map = function.body_source_map(db);
|
||||||
if let Some(expr) = ast::Expr::cast(node).and_then(|e| source_map.node_expr(e)) {
|
if let Some(expr) = ast::Expr::cast(node).and_then(|e| source_map.node_expr(e)) {
|
||||||
Some(infer[expr].to_string())
|
Some(infer[expr].display(db).to_string())
|
||||||
} else if let Some(pat) = ast::Pat::cast(node).and_then(|p| source_map.node_pat(p)) {
|
} else if let Some(pat) = ast::Pat::cast(node).and_then(|p| source_map.node_pat(p)) {
|
||||||
Some(infer[pat].to_string())
|
Some(infer[pat].display(db).to_string())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue