Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/lib.rs')
-rw-r--r--crates/hir/src/lib.rs87
1 files changed, 71 insertions, 16 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 88eb3b127e..ebd84fd2be 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -34,7 +34,10 @@ pub mod term_search;
mod display;
-use std::{mem::discriminant, ops::ControlFlow};
+use std::{
+ mem::discriminant,
+ ops::{ControlFlow, Not},
+};
use arrayvec::ArrayVec;
use base_db::{CrateDisplayName, CrateId, CrateOrigin};
@@ -2303,22 +2306,15 @@ impl Function {
self,
db: &dyn HirDatabase,
span_formatter: impl Fn(FileId, TextRange) -> String,
- ) -> String {
+ ) -> Result<String, ConstEvalError> {
let krate = HasModule::krate(&self.id, db.upcast());
let edition = db.crate_graph()[krate].edition;
- let body = match db.monomorphized_mir_body(
+ let body = db.monomorphized_mir_body(
self.id.into(),
Substitution::empty(Interner),
db.trait_environment(self.id.into()),
- ) {
- Ok(body) => body,
- Err(e) => {
- let mut r = String::new();
- _ = e.pretty_print(&mut r, db, &span_formatter, edition);
- return r;
- }
- };
- let (result, output) = interpret_mir(db, body, false, None);
+ )?;
+ let (result, output) = interpret_mir(db, body, false, None)?;
let mut text = match result {
Ok(_) => "pass".to_owned(),
Err(e) => {
@@ -2337,7 +2333,7 @@ impl Function {
text += "\n--------- stderr ---------\n";
text += &stderr;
}
- text
+ Ok(text)
}
}
@@ -2560,9 +2556,9 @@ impl Const {
/// Evaluate the constant and return the result as a string.
///
/// This function is intended for IDE assistance, different from [`Const::render_eval`].
- pub fn eval(self, db: &dyn HirDatabase, edition: Edition) -> Result<String, ConstEvalError> {
+ pub fn eval(self, db: &dyn HirDatabase) -> Result<String, ConstEvalError> {
let c = db.const_eval(self.id.into(), Substitution::empty(Interner), None)?;
- Ok(format!("{}", c.display(db, edition)))
+ Ok(format!("{}", c.display(db, self.krate(db).edition(db))))
}
/// Evaluate the constant and return the result as a string, with more detailed information.
@@ -2597,7 +2593,7 @@ impl Const {
}
}
}
- if let Ok(s) = mir::render_const_using_debug_impl(db, self.id, &c) {
+ if let Ok(s) = mir::render_const_using_debug_impl(db, self.id.into(), &c) {
Ok(s)
} else {
Ok(format!("{}", c.display(db, edition)))
@@ -2636,6 +2632,53 @@ impl Static {
pub fn ty(self, db: &dyn HirDatabase) -> Type {
Type::from_value_def(db, self.id)
}
+
+ /// Evaluate the static and return the result as a string.
+ ///
+ /// This function is intended for IDE assistance, different from [`Static::render_eval`].
+ pub fn eval(self, db: &dyn HirDatabase) -> Result<String, ConstEvalError> {
+ let c = db.const_eval(self.id.into(), Substitution::empty(Interner), None)?;
+ Ok(format!("{}", c.display(db, self.krate(db).edition(db))))
+ }
+
+ /// Evaluate the static and return the result as a string, with more detailed information.
+ ///
+ /// This function is intended for user-facing display.
+ pub fn render_eval(
+ self,
+ db: &dyn HirDatabase,
+ edition: Edition,
+ ) -> Result<String, ConstEvalError> {
+ let c = db.const_eval(self.id.into(), Substitution::empty(Interner), None)?;
+ let data = &c.data(Interner);
+ if let TyKind::Scalar(s) = data.ty.kind(Interner) {
+ if matches!(s, Scalar::Int(_) | Scalar::Uint(_)) {
+ if let hir_ty::ConstValue::Concrete(c) = &data.value {
+ if let hir_ty::ConstScalar::Bytes(b, _) = &c.interned {
+ let value = u128::from_le_bytes(mir::pad16(b, false));
+ let value_signed =
+ i128::from_le_bytes(mir::pad16(b, matches!(s, Scalar::Int(_))));
+ let mut result = if let Scalar::Int(_) = s {
+ value_signed.to_string()
+ } else {
+ value.to_string()
+ };
+ if value >= 10 {
+ format_to!(result, " ({value:#X})");
+ return Ok(result);
+ } else {
+ return Ok(result);
+ }
+ }
+ }
+ }
+ }
+ if let Ok(s) = mir::render_const_using_debug_impl(db, self.id.into(), &c) {
+ Ok(s)
+ } else {
+ Ok(format!("{}", c.display(db, edition)))
+ }
+ }
}
impl HasVisibility for Static {
@@ -2697,6 +2740,18 @@ impl Trait {
hir_ty::dyn_compatibility::dyn_compatibility(db, self.id)
}
+ pub fn dyn_compatibility_all_violations(
+ &self,
+ db: &dyn HirDatabase,
+ ) -> Option<Vec<DynCompatibilityViolation>> {
+ let mut violations = vec![];
+ hir_ty::dyn_compatibility::dyn_compatibility_with_callback(db, self.id, &mut |violation| {
+ violations.push(violation);
+ ControlFlow::Continue(())
+ });
+ violations.is_empty().not().then_some(violations)
+ }
+
fn all_macro_calls(&self, db: &dyn HirDatabase) -> Box<[(AstId<ast::Item>, MacroCallId)]> {
db.trait_data(self.id)
.macro_calls