Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/mir/eval/shim.rs')
| -rw-r--r-- | crates/hir-ty/src/mir/eval/shim.rs | 49 |
1 files changed, 29 insertions, 20 deletions
diff --git a/crates/hir-ty/src/mir/eval/shim.rs b/crates/hir-ty/src/mir/eval/shim.rs index 4b1adecf8c..c61afd62c4 100644 --- a/crates/hir-ty/src/mir/eval/shim.rs +++ b/crates/hir-ty/src/mir/eval/shim.rs @@ -3,7 +3,7 @@ //! use std::cmp::{self, Ordering}; -use hir_def::{CrateRootModuleId, resolver::HasResolver, signatures::FunctionSignature}; +use hir_def::signatures::FunctionSignature; use hir_expand::name::Name; use intern::{Symbol, sym}; use rustc_type_ir::inherent::{AdtDef, IntoKind, SliceLike, Ty as _}; @@ -14,8 +14,8 @@ use crate::{ drop::{DropGlue, has_drop_glue}, mir::eval::{ Address, AdtId, Arc, Evaluator, FunctionId, GenericArgs, HasModule, HirDisplay, - InternedClosure, Interval, IntervalAndTy, IntervalOrOwned, ItemContainerId, LangItem, - Layout, Locals, Lookup, MirEvalError, MirSpan, Mutability, Result, Ty, TyKind, pad16, + InternedClosure, Interval, IntervalAndTy, IntervalOrOwned, ItemContainerId, Layout, Locals, + Lookup, MirEvalError, MirSpan, Mutability, Result, Ty, TyKind, pad16, }, next_solver::Region, }; @@ -38,6 +38,13 @@ macro_rules! not_supported { }; } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum EvalLangItem { + BeginPanic, + SliceLen, + DropInPlace, +} + impl<'db> Evaluator<'db> { pub(super) fn detect_and_exec_special_function( &mut self, @@ -105,7 +112,7 @@ impl<'db> Evaluator<'db> { return Ok(true); } if let ItemContainerId::TraitId(t) = def.lookup(self.db).container - && self.db.lang_attr(t.into()) == Some(LangItem::Clone) + && Some(t) == self.lang_items().Clone { let [self_ty] = generic_args.as_slice() else { not_supported!("wrong generic arg count for clone"); @@ -131,12 +138,8 @@ impl<'db> Evaluator<'db> { def: FunctionId, ) -> Result<'db, Option<FunctionId>> { // `PanicFmt` is redirected to `ConstPanicFmt` - if let Some(LangItem::PanicFmt) = self.db.lang_attr(def.into()) { - let resolver = CrateRootModuleId::from(self.crate_id).resolver(self.db); - - let Some(const_panic_fmt) = - LangItem::ConstPanicFmt.resolve_function(self.db, resolver.krate()) - else { + if Some(def) == self.lang_items().PanicFmt { + let Some(const_panic_fmt) = self.lang_items().ConstPanicFmt else { not_supported!("const_panic_fmt lang item not found or not a function"); }; return Ok(Some(const_panic_fmt)); @@ -286,19 +289,26 @@ impl<'db> Evaluator<'db> { Ok(()) } - fn detect_lang_function(&self, def: FunctionId) -> Option<LangItem> { - use LangItem::*; + fn detect_lang_function(&self, def: FunctionId) -> Option<EvalLangItem> { + use EvalLangItem::*; + let lang_items = self.lang_items(); let attrs = self.db.attrs(def.into()); if attrs.by_key(sym::rustc_const_panic_str).exists() { // `#[rustc_const_panic_str]` is treated like `lang = "begin_panic"` by rustc CTFE. - return Some(LangItem::BeginPanic); + return Some(BeginPanic); } - let candidate = attrs.lang_item()?; // We want to execute these functions with special logic // `PanicFmt` is not detected here as it's redirected later. - if [BeginPanic, SliceLen, DropInPlace].contains(&candidate) { + if let Some((_, candidate)) = [ + (lang_items.BeginPanic, BeginPanic), + (lang_items.SliceLen, SliceLen), + (lang_items.DropInPlace, DropInPlace), + ] + .iter() + .find(|&(candidate, _)| candidate == Some(def)) + { return Some(candidate); } @@ -307,13 +317,13 @@ impl<'db> Evaluator<'db> { fn exec_lang_item( &mut self, - it: LangItem, + it: EvalLangItem, generic_args: GenericArgs<'db>, args: &[IntervalAndTy<'db>], locals: &Locals<'db>, span: MirSpan, ) -> Result<'db, Vec<u8>> { - use LangItem::*; + use EvalLangItem::*; let mut args = args.iter(); match it { BeginPanic => { @@ -374,7 +384,6 @@ impl<'db> Evaluator<'db> { )?; Ok(vec![]) } - it => not_supported!("Executing lang item {it:?}"), } } @@ -1219,7 +1228,7 @@ impl<'db> Evaluator<'db> { let addr = tuple.interval.addr.offset(offset); args.push(IntervalAndTy::new(addr, field, self, locals)?); } - if let Some(target) = LangItem::FnOnce.resolve_trait(self.db, self.crate_id) + if let Some(target) = self.lang_items().FnOnce && let Some(def) = target .trait_items(self.db) .method_by_name(&Name::new_symbol_root(sym::call_once)) @@ -1329,7 +1338,7 @@ impl<'db> Evaluator<'db> { { result = (l as i8).cmp(&(r as i8)); } - if let Some(e) = LangItem::Ordering.resolve_enum(self.db, self.crate_id) { + if let Some(e) = self.lang_items().Ordering { let ty = self.db.ty(e.into()).skip_binder(); let r = self.compute_discriminant(ty, &[result as i8 as u8])?; destination.write_from_bytes(self, &r.to_le_bytes()[0..destination.size])?; |