Skip to content

Commit 4dc5cf8

Browse files
committed
Add render associated constant in notable trait
Example --- ```rust impl Notable for u32 { type Assoc = &str; type Assoc2 = char; const ID: u32 = 3; } ``` **Before this PR** ```text Implements notable traits: `Notable<Assoc = &str, Assoc2 = char>` ``` **After this PR** ```text Implements notable traits: `Notable<Assoc = &str, Assoc2 = char, ID = 3>` ```
1 parent c9472ba commit 4dc5cf8

File tree

3 files changed

+58
-41
lines changed

3 files changed

+58
-41
lines changed

crates/ide/src/hover.rs

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,17 @@ pub enum HoverDocFormat {
7878
PlainText,
7979
}
8080

81+
enum TyOrConst<'db> {
82+
EvaluatedConst(hir::EvaluatedConst<'db>),
83+
Type(hir::Type<'db>),
84+
}
85+
86+
impl<'db> TyOrConst<'db> {
87+
fn as_type(&self) -> Option<&hir::Type<'db>> {
88+
if let Self::Type(ty) = self { Some(ty) } else { None }
89+
}
90+
}
91+
8192
#[derive(Debug, Clone, Hash, PartialEq, Eq, UpmapFromRaFixture)]
8293
pub enum HoverAction {
8394
Runnable(Runnable),
@@ -514,7 +525,7 @@ pub(crate) fn hover_for_definition(
514525
fn notable_traits<'db>(
515526
db: &'db RootDatabase,
516527
ty: &hir::Type<'db>,
517-
) -> Vec<(hir::Trait, Vec<(Option<hir::Type<'db>>, hir::Name)>)> {
528+
) -> Vec<(hir::Trait, Vec<(Option<TyOrConst<'db>>, hir::Name)>)> {
518529
if ty.is_unknown() {
519530
// The trait solver returns "yes" to the question whether the error type
520531
// impls any trait, and we don't want to show it as having any notable trait.
@@ -531,9 +542,16 @@ fn notable_traits<'db>(
531542
trait_
532543
.items(db)
533544
.into_iter()
534-
.filter_map(hir::AssocItem::as_type_alias)
535-
.map(|alias| {
536-
(ty.normalize_trait_assoc_type(db, &[], alias), alias.name(db))
545+
.filter_map(|item| match item {
546+
hir::AssocItem::Function(_) => None,
547+
hir::AssocItem::Const(it) => Some((
548+
it.eval(db).ok().map(TyOrConst::EvaluatedConst),
549+
it.name(db)?,
550+
)),
551+
hir::AssocItem::TypeAlias(it) => Some((
552+
ty.normalize_trait_assoc_type(db, &[], it).map(TyOrConst::Type),
553+
it.name(db),
554+
)),
537555
})
538556
.collect::<Vec<_>>(),
539557
)
@@ -606,7 +624,7 @@ fn runnable_action(
606624
fn goto_type_action_for_def(
607625
sema: &Semantics<'_, RootDatabase>,
608626
def: Definition,
609-
notable_traits: &[(hir::Trait, Vec<(Option<hir::Type<'_>>, hir::Name)>)],
627+
notable_traits: &[(hir::Trait, Vec<(Option<TyOrConst<'_>>, hir::Name)>)],
610628
subst_types: Option<Vec<(hir::Symbol, hir::Type<'_>)>>,
611629
edition: Edition,
612630
) -> Option<HoverAction> {
@@ -620,9 +638,11 @@ fn goto_type_action_for_def(
620638

621639
for &(trait_, ref assocs) in notable_traits {
622640
push_new_def(trait_.into());
623-
assocs.iter().filter_map(|(ty, _)| ty.as_ref()).for_each(|ty| {
624-
walk_and_push_ty(db, ty, &mut push_new_def);
625-
});
641+
assocs.iter().filter_map(|(ty, _)| ty.as_ref()).filter_map(TyOrConst::as_type).for_each(
642+
|ty| {
643+
walk_and_push_ty(db, ty, &mut push_new_def);
644+
},
645+
);
626646
}
627647

628648
if let Ok(generic_def) = GenericDef::try_from(def) {

crates/ide/src/hover/render.rs

Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use crate::{
2929
HoverAction, HoverConfig, HoverResult, Markup, MemoryLayoutHoverConfig,
3030
MemoryLayoutHoverRenderKind,
3131
doc_links::{remove_links, rewrite_links},
32-
hover::{SubstTyLen, notable_traits, walk_and_push_ty},
32+
hover::{SubstTyLen, TyOrConst, notable_traits, walk_and_push_ty},
3333
interpret::render_const_eval_error,
3434
};
3535

@@ -477,7 +477,7 @@ pub(super) fn definition(
477477
db: &RootDatabase,
478478
def: Definition,
479479
famous_defs: Option<&FamousDefs<'_, '_>>,
480-
notable_traits: &[(Trait, Vec<(Option<Type<'_>>, Name)>)],
480+
notable_traits: &[(Trait, Vec<(Option<TyOrConst<'_>>, Name)>)],
481481
macro_arm: Option<u32>,
482482
render_extras: bool,
483483
subst_types: Option<&Vec<(Symbol, Type<'_>)>>,
@@ -553,20 +553,7 @@ pub(super) fn definition(
553553
Definition::Const(it) => {
554554
let body = it.eval(db);
555555
Some(match body {
556-
Ok(it) => match it.render_debug(db) {
557-
Ok(it) => it,
558-
Err(err) => {
559-
let it = it.render(db, display_target);
560-
if env::var_os("RA_DEV").is_some() {
561-
format!(
562-
"{it}\n{}",
563-
render_const_eval_error(db, err.into(), display_target)
564-
)
565-
} else {
566-
it
567-
}
568-
}
569-
},
556+
Ok(it) => const_value(&it, db, display_target),
570557
Err(err) => {
571558
let source = it.source(db)?;
572559
let mut body = source.value.body()?.syntax().clone();
@@ -585,20 +572,7 @@ pub(super) fn definition(
585572
Definition::Static(it) => {
586573
let body = it.eval(db);
587574
Some(match body {
588-
Ok(it) => match it.render_debug(db) {
589-
Ok(it) => it,
590-
Err(err) => {
591-
let it = it.render(db, display_target);
592-
if env::var_os("RA_DEV").is_some() {
593-
format!(
594-
"{it}\n{}",
595-
render_const_eval_error(db, err.into(), display_target)
596-
)
597-
} else {
598-
it
599-
}
600-
}
601-
},
575+
Ok(it) => const_value(&it, db, display_target),
602576
Err(err) => {
603577
let source = it.source(db)?;
604578
let mut body = source.value.body()?.syntax().clone();
@@ -939,7 +913,7 @@ pub(super) fn literal(
939913

940914
fn render_notable_trait(
941915
db: &RootDatabase,
942-
notable_traits: &[(Trait, Vec<(Option<Type<'_>>, Name)>)],
916+
notable_traits: &[(Trait, Vec<(Option<TyOrConst<'_>>, Name)>)],
943917
edition: Edition,
944918
display_target: DisplayTarget,
945919
) -> Option<String> {
@@ -961,7 +935,10 @@ fn render_notable_trait(
961935
f(&name.display(db, edition))?;
962936
f(&" = ")?;
963937
match ty {
964-
Some(ty) => f(&ty.display(db, display_target)),
938+
Some(TyOrConst::Type(ty)) => f(&ty.display(db, display_target)),
939+
Some(TyOrConst::EvaluatedConst(value)) => {
940+
f(&const_value(value, db, display_target))
941+
}
965942
None => f(&"?"),
966943
}
967944
})
@@ -1105,6 +1082,24 @@ fn closure_ty(
11051082
Some(res)
11061083
}
11071084

1085+
fn const_value(
1086+
evaluated: &hir::EvaluatedConst<'_>,
1087+
db: &RootDatabase,
1088+
display_target: DisplayTarget,
1089+
) -> String {
1090+
match evaluated.render_debug(db) {
1091+
Ok(it) => it,
1092+
Err(err) => {
1093+
let it = evaluated.render(db, display_target);
1094+
if env::var_os("RA_DEV").is_some() {
1095+
format!("{it}\n{}", render_const_eval_error(db, err.into(), display_target))
1096+
} else {
1097+
it
1098+
}
1099+
}
1100+
}
1101+
}
1102+
11081103
fn definition_path(db: &RootDatabase, &def: &Definition, edition: Edition) -> Option<String> {
11091104
if matches!(
11101105
def,

crates/ide/src/hover/tests.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9097,11 +9097,13 @@ fn notable_local() {
90979097
trait Notable {
90989098
type Assoc;
90999099
type Assoc2;
9100+
const ID: u32;
91009101
}
91019102
91029103
impl Notable for u32 {
91039104
type Assoc = &str;
91049105
type Assoc2 = char;
9106+
const ID: u32 = 3;
91059107
}
91069108
fn main(notable$0: u32) {}
91079109
"#,
@@ -9114,7 +9116,7 @@ fn main(notable$0: u32) {}
91149116
91159117
---
91169118
9117-
Implements notable traits: `Notable<Assoc = &str, Assoc2 = char>`
9119+
Implements notable traits: `Notable<Assoc = &str, Assoc2 = char, ID = 3>`
91189120
91199121
---
91209122

0 commit comments

Comments
 (0)