diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs index 3123ddb985b..6dde4773602 100644 --- a/crates/hir-ty/src/display.rs +++ b/crates/hir-ty/src/display.rs @@ -5,7 +5,7 @@ use std::fmt::{self, Debug}; use base_db::CrateId; -use chalk_ir::BoundVar; +use chalk_ir::{BoundVar, TyKind}; use hir_def::{ adt::VariantData, body, @@ -36,7 +36,7 @@ AdtId, AliasEq, AliasTy, Binders, CallableDefId, CallableSig, Const, ConstScalar, ConstValue, DomainGoal, GenericArg, ImplTraitId, Interner, Lifetime, LifetimeData, LifetimeOutlives, MemoryMap, Mutability, OpaqueTy, ProjectionTy, ProjectionTyExt, QuantifiedWhereClause, Scalar, - Substitution, TraitRef, TraitRefExt, Ty, TyExt, TyKind, WhereClause, + Substitution, TraitRef, TraitRefExt, Ty, TyExt, WhereClause, }; pub trait HirWrite: fmt::Write { @@ -383,6 +383,28 @@ fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> { } } +pub struct HexifiedConst(pub Const); + +impl HirDisplay for HexifiedConst { + fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> { + let data = &self.0.data(Interner); + if let TyKind::Scalar(s) = data.ty.kind(Interner) { + if matches!(s, Scalar::Int(_) | Scalar::Uint(_)) { + if let ConstValue::Concrete(c) = &data.value { + if let ConstScalar::Bytes(b, m) = &c.interned { + let value = u128::from_le_bytes(pad16(b, false)); + if value >= 10 { + render_const_scalar(f, &b, m, &data.ty)?; + return write!(f, " ({:#X})", value); + } + } + } + } + } + self.0.hir_fmt(f) + } +} + fn render_const_scalar( f: &mut HirFormatter<'_>, b: &[u8], diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 20009698f91..df6484db536 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -60,6 +60,7 @@ all_super_traits, autoderef, consteval::{try_const_usize, unknown_const_as_generic, ConstEvalError, ConstExt}, diagnostics::BodyValidationDiagnostic, + display::HexifiedConst, layout::layout_of_ty, method_resolution::{self, TyFingerprint}, mir::interpret_mir, @@ -1883,8 +1884,18 @@ pub fn ty(self, db: &dyn HirDatabase) -> Type { Type::new_with_resolver_inner(db, &resolver, ty) } - pub fn eval(self, db: &dyn HirDatabase) -> Result { - db.const_eval(self.id) + pub fn render_eval(self, db: &dyn HirDatabase) -> Result { + let c = db.const_eval(self.id)?; + let r = format!("{}", HexifiedConst(c).display(db)); + // We want to see things like `` and `` as they are probably bug in our + // implementation, but there is no need to show things like `` or `` to + // the user. + if r.contains("not-supported>") { + return Err(ConstEvalError::MirEvalError(MirEvalError::NotSupported( + "rendering complex constants".to_string(), + ))); + } + return Ok(r); } } diff --git a/crates/ide/src/hover/render.rs b/crates/ide/src/hover/render.rs index c64b60d2936..6a29ddf59e1 100644 --- a/crates/ide/src/hover/render.rs +++ b/crates/ide/src/hover/render.rs @@ -432,9 +432,9 @@ pub(super) fn definition( } }), Definition::Const(it) => label_value_and_docs(db, it, |it| { - let body = it.eval(db); + let body = it.render_eval(db); match body { - Ok(x) => Some(format!("{}", x.display(db))), + Ok(x) => Some(x), Err(_) => { let source = it.source(db)?; let mut body = source.value.body()?.syntax().clone(); diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs index 2e67056b913..57bf0f9ad5f 100644 --- a/crates/ide/src/hover/tests.rs +++ b/crates/ide/src/hover/tests.rs @@ -531,7 +531,7 @@ fn hover_const_static() { ``` ```rust - const foo: u32 = 123 + const foo: u32 = 123 (0x7B) ``` "#]], ); @@ -3770,7 +3770,6 @@ fn main() { This is a doc "#]], ); - // FIXME: show hex for >10 check( r#" /// This is a doc @@ -3784,7 +3783,7 @@ fn main() { ``` ```rust - const FOO: usize = 12 + const FOO: usize = 12 (0xC) ``` --- @@ -3828,7 +3827,7 @@ fn main() { ``` ```rust - const FOO: i32 = -1 + const FOO: i32 = -1 (0xFFFFFFFF) ``` --- @@ -3915,7 +3914,7 @@ fn main() { ``` ```rust - const FOO: u8 = 97 + const FOO: u8 = 97 (0x61) ``` --- @@ -3937,7 +3936,7 @@ fn main() { ``` ```rust - const FOO: u8 = 97 + const FOO: u8 = 97 (0x61) ``` --- @@ -3989,6 +3988,28 @@ fn main() { This is a doc "#]], ); + // Don't show `` in const hover + check( + r#" +/// This is a doc +const FOO$0: &i32 = &2; +"#, + expect![[r#" + *FOO* + + ```rust + test + ``` + + ```rust + const FOO: &i32 = &2 + ``` + + --- + + This is a doc + "#]], + ); //show f64 typecasted from float check( r#"