Unnamed repository; edit this file 'description' to name the repository.
Remove more `Arc`s
25 files changed, 344 insertions, 290 deletions
diff --git a/crates/hir-def/src/nameres/attr_resolution.rs b/crates/hir-def/src/nameres/attr_resolution.rs index 062b55fcef..5aabd7dbc6 100644 --- a/crates/hir-def/src/nameres/attr_resolution.rs +++ b/crates/hir-def/src/nameres/attr_resolution.rs @@ -9,7 +9,6 @@ use hir_expand::{ }; use span::SyntaxContext; use syntax::ast; -use triomphe::Arc; use crate::{ AstIdWithPath, MacroId, ModuleId, UnresolvedMacro, @@ -126,7 +125,7 @@ pub(super) fn attr_macro_as_call_id( krate, MacroCallKind::Attr { ast_id: item_attr.ast_id, - attr_args: arg.map(Arc::new), + attr_args: arg.map(Box::new), censored_attr_ids, }, macro_attr.ctxt, diff --git a/crates/hir-def/src/nameres/tests/incremental.rs b/crates/hir-def/src/nameres/tests/incremental.rs index 60ec3035fa..08f672aa0c 100644 --- a/crates/hir-def/src/nameres/tests/incremental.rs +++ b/crates/hir-def/src/nameres/tests/incremental.rs @@ -227,7 +227,7 @@ pub struct S {} "ast_id_map", "parse", "real_span_map", - "decl_macro_expander_shim", + "DeclarativeMacroExpander::expander_", "file_item_tree_query", "ast_id_map", "parse", @@ -240,7 +240,7 @@ pub struct S {} "file_item_tree_query", "ast_id_map", "parse_macro_expansion", - "macro_arg_shim", + "macro_arg", ] "#]], expect![[r#" @@ -249,7 +249,7 @@ pub struct S {} "ast_id_map", "file_item_tree_query", "real_span_map", - "macro_arg_shim", + "macro_arg", "parse_macro_expansion", "ast_id_map", "file_item_tree_query", @@ -303,8 +303,8 @@ fn f() { foo } "file_item_tree_query", "ast_id_map", "parse_macro_expansion", - "expand_proc_macro_shim", - "macro_arg_shim", + "expand_proc_macro", + "macro_arg", "proc_macro_span_shim", ] "#]], @@ -314,8 +314,8 @@ fn f() { foo } "ast_id_map", "file_item_tree_query", "real_span_map", - "macro_arg_shim", - "expand_proc_macro_shim", + "macro_arg", + "expand_proc_macro", "parse_macro_expansion", "ast_id_map", "file_item_tree_query", @@ -415,7 +415,7 @@ pub struct S {} "ast_id_map", "parse", "real_span_map", - "decl_macro_expander_shim", + "DeclarativeMacroExpander::expander_", "file_item_tree_query", "ast_id_map", "parse", @@ -428,19 +428,19 @@ pub struct S {} "file_item_tree_query", "ast_id_map", "parse_macro_expansion", - "macro_arg_shim", - "decl_macro_expander_shim", + "macro_arg", + "DeclarativeMacroExpander::expander_", "macro_def_shim", "file_item_tree_query", "ast_id_map", "parse_macro_expansion", - "macro_arg_shim", + "macro_arg", "macro_def_shim", "file_item_tree_query", "ast_id_map", "parse_macro_expansion", - "expand_proc_macro_shim", - "macro_arg_shim", + "expand_proc_macro", + "macro_arg", "proc_macro_span_shim", ] "#]], @@ -450,10 +450,10 @@ pub struct S {} "ast_id_map", "file_item_tree_query", "real_span_map", - "macro_arg_shim", - "decl_macro_expander_shim", - "macro_arg_shim", - "macro_arg_shim", + "macro_arg", + "DeclarativeMacroExpander::expander_", + "macro_arg", + "macro_arg", ] "#]], ); @@ -526,7 +526,7 @@ m!(Z); "ast_id_map", "parse", "real_span_map", - "decl_macro_expander_shim", + "DeclarativeMacroExpander::expander_", "file_item_tree_query", "ast_id_map", "parse", @@ -539,15 +539,15 @@ m!(Z); "file_item_tree_query", "ast_id_map", "parse_macro_expansion", - "macro_arg_shim", + "macro_arg", "file_item_tree_query", "ast_id_map", "parse_macro_expansion", - "macro_arg_shim", + "macro_arg", "file_item_tree_query", "ast_id_map", "parse_macro_expansion", - "macro_arg_shim", + "macro_arg", ] "#]], ); @@ -575,9 +575,9 @@ m!(Z); "ast_id_map", "file_item_tree_query", "real_span_map", - "macro_arg_shim", - "macro_arg_shim", - "macro_arg_shim", + "macro_arg", + "macro_arg", + "macro_arg", ] "#]], ); diff --git a/crates/hir-expand/src/db.rs b/crates/hir-expand/src/db.rs index 57c78748f8..4b26c1f0e5 100644 --- a/crates/hir-expand/src/db.rs +++ b/crates/hir-expand/src/db.rs @@ -3,6 +3,7 @@ use base_db::{Crate, SourceDatabase}; use mbe::MatchedArmIndex; use span::{AstIdMap, Edition, Span, SyntaxContext}; +use std::borrow::Cow; use syntax::{AstNode, Parse, SyntaxError, SyntaxNode, SyntaxToken, T, ast}; use syntax_bridge::{DocCommentDesugarMode, syntax_node_to_token_tree}; use triomphe::Arc; @@ -21,7 +22,7 @@ use crate::{ tt, }; /// This is just to ensure the types of smart_macro_arg and macro_arg are the same -type MacroArgResult = (Arc<tt::TopSubtree>, SyntaxFixupUndoInfo, Span); +type MacroArgResult = (tt::TopSubtree, SyntaxFixupUndoInfo, Span); /// Total limit on the number of tokens produced by any macro invocation. /// /// If an invocation produces more tokens than this limit, it will not be stored in the database and @@ -30,10 +31,10 @@ type MacroArgResult = (Arc<tt::TopSubtree>, SyntaxFixupUndoInfo, Span); /// Actual max for `analysis-stats .` at some point: 30672. const TOKEN_LIMIT: usize = 2_097_152; -#[derive(Debug, Clone, Eq, PartialEq)] -pub enum TokenExpander { +#[derive(Debug, Clone, Copy, Eq, PartialEq)] +pub enum TokenExpander<'db> { /// Old-style `macro_rules` or the new macros 2.0 - DeclarativeMacro(Arc<DeclarativeMacroExpander>), + DeclarativeMacro(&'db DeclarativeMacroExpander), /// Stuff like `line!` and `file!`. BuiltIn(BuiltinFnLikeExpander), /// Built-in eagerly expanded fn-like macros (`include!`, `concat!`, etc.) @@ -99,34 +100,37 @@ pub trait ExpandDatabase: SourceDatabase { /// subtree. #[deprecated = "calling this is incorrect, call `macro_arg_considering_derives` instead"] #[salsa::invoke(macro_arg)] - fn macro_arg(&self, id: MacroCallId) -> MacroArgResult; + #[salsa::transparent] + fn macro_arg(&self, id: MacroCallId) -> &MacroArgResult; #[salsa::transparent] - fn macro_arg_considering_derives( - &self, + fn macro_arg_considering_derives<'db>( + &'db self, id: MacroCallId, kind: &MacroCallKind, - ) -> MacroArgResult; + ) -> &'db MacroArgResult; /// Fetches the expander for this macro. #[salsa::transparent] #[salsa::invoke(TokenExpander::macro_expander)] - fn macro_expander(&self, id: MacroDefId) -> TokenExpander; + fn macro_expander(&self, id: MacroDefId) -> TokenExpander<'_>; /// Fetches (and compiles) the expander of this decl macro. #[salsa::invoke(DeclarativeMacroExpander::expander)] + #[salsa::transparent] fn decl_macro_expander( &self, def_crate: Crate, id: AstId<ast::Macro>, - ) -> Arc<DeclarativeMacroExpander>; + ) -> &DeclarativeMacroExpander; /// Special case of the previous query for procedural macros. We can't LRU /// proc macros, since they are not deterministic in general, and /// non-determinism breaks salsa in a very, very, very bad way. /// @edwin0cheng heroically debugged this once! See #4315 for details #[salsa::invoke(expand_proc_macro)] - fn expand_proc_macro(&self, call: MacroCallId) -> ExpandResult<Arc<tt::TopSubtree>>; + #[salsa::transparent] + fn expand_proc_macro(&self, call: MacroCallId) -> &ExpandResult<tt::TopSubtree>; /// Retrieves the span to be used for a proc-macro expansions spans. /// This is a firewall query as it requires parsing the file, which we don't want proc-macros to /// directly depend on as that would cause to frequent invalidations, mainly because of the @@ -135,12 +139,12 @@ pub trait ExpandDatabase: SourceDatabase { #[salsa::invoke_interned(proc_macro_span)] fn proc_macro_span(&self, fun: AstId<ast::Fn>) -> Span; - /// Firewall query that returns the errors from the `parse_macro_expansion` query. #[salsa::invoke(parse_macro_expansion_error)] + #[salsa::transparent] fn parse_macro_expansion_error( &self, macro_call: MacroCallId, - ) -> Option<Arc<ExpandResult<Arc<[SyntaxError]>>>>; + ) -> Option<ExpandResult<Arc<[SyntaxError]>>>; #[salsa::transparent] fn syntax_context(&self, file: HirFileId, edition: Edition) -> SyntaxContext; @@ -179,7 +183,7 @@ pub fn expand_speculative( token_to_map: SyntaxToken, ) -> Option<(SyntaxNode, Vec<(SyntaxToken, u8)>)> { let loc = db.lookup_intern_macro_call(actual_macro_call); - let (_, _, span) = db.macro_arg_considering_derives(actual_macro_call, &loc.kind); + let (_, _, span) = *db.macro_arg_considering_derives(actual_macro_call, &loc.kind); let span_map = RealSpanMap::absolute(span.anchor.file_id); let span_map = SpanMap::RealSpanMap(&span_map); @@ -369,14 +373,7 @@ fn parse_macro_expansion( let expand_to = loc.expand_to(); let mbe::ValueResult { value: (tt, matched_arm), err } = macro_expand(db, macro_file, loc); - let (parse, mut rev_token_map) = token_tree_to_syntax_node( - db, - match &tt { - CowArc::Arc(it) => it, - CowArc::Owned(it) => it, - }, - expand_to, - ); + let (parse, mut rev_token_map) = token_tree_to_syntax_node(db, &tt, expand_to); rev_token_map.matched_arm = matched_arm; ExpandResult { value: (parse, rev_token_map), err } @@ -385,10 +382,10 @@ fn parse_macro_expansion( fn parse_macro_expansion_error( db: &dyn ExpandDatabase, macro_call_id: MacroCallId, -) -> Option<Arc<ExpandResult<Arc<[SyntaxError]>>>> { +) -> Option<ExpandResult<Arc<[SyntaxError]>>> { let e: ExpandResult<Arc<[SyntaxError]>> = db.parse_macro_expansion(macro_call_id).as_ref().map(|it| Arc::from(it.0.errors())); - if e.value.is_empty() && e.err.is_none() { None } else { Some(Arc::new(e)) } + if e.value.is_empty() && e.err.is_none() { None } else { Some(e) } } pub(crate) fn parse_with_map( @@ -411,11 +408,11 @@ pub(crate) fn parse_with_map( /// /// This is not connected to the database so it does not cached the result. However, the inner [macro_arg] query is #[allow(deprecated)] // we are macro_arg_considering_derives -fn macro_arg_considering_derives( - db: &dyn ExpandDatabase, +fn macro_arg_considering_derives<'db>( + db: &'db dyn ExpandDatabase, id: MacroCallId, kind: &MacroCallKind, -) -> MacroArgResult { +) -> &'db MacroArgResult { match kind { // Get the macro arg for the derive macro MacroCallKind::Derive { derive_macro_id, .. } => db.macro_arg(*derive_macro_id), @@ -424,6 +421,7 @@ fn macro_arg_considering_derives( } } +#[salsa_macros::tracked(returns(ref))] fn macro_arg(db: &dyn ExpandDatabase, id: MacroCallId) -> MacroArgResult { let loc = db.lookup_intern_macro_call(id); @@ -449,10 +447,10 @@ fn macro_arg(db: &dyn ExpandDatabase, id: MacroCallId) -> MacroArgResult { let dummy_tt = |kind| { ( - Arc::new(tt::TopSubtree::from_token_trees( + tt::TopSubtree::from_token_trees( tt::Delimiter { open: span, close: span, kind }, tt::TokenTreesView::empty(), - )), + ), SyntaxFixupUndoInfo::default(), span, ) @@ -501,7 +499,7 @@ fn macro_arg(db: &dyn ExpandDatabase, id: MacroCallId) -> MacroArgResult { // proc macros expect their inputs without parentheses, MBEs expect it with them included tt.set_top_subtree_delimiter_kind(tt::DelimiterKind::Invisible); } - return (Arc::new(tt), SyntaxFixupUndoInfo::NONE, span); + return (tt, SyntaxFixupUndoInfo::NONE, span); } // MacroCallKind::Derive should not be here. As we are getting the argument for the derive macro MacroCallKind::Derive { .. } => { @@ -536,11 +534,11 @@ fn macro_arg(db: &dyn ExpandDatabase, id: MacroCallId) -> MacroArgResult { tt.set_top_subtree_delimiter_kind(tt::DelimiterKind::Invisible); } - (Arc::new(tt), undo_info, span) + (tt, undo_info, span) } -impl TokenExpander { - fn macro_expander(db: &dyn ExpandDatabase, id: MacroDefId) -> TokenExpander { +impl<'db> TokenExpander<'db> { + fn macro_expander(db: &'db dyn ExpandDatabase, id: MacroDefId) -> TokenExpander<'db> { match id.kind { MacroDefKind::Declarative(ast_id, _) => { TokenExpander::DeclarativeMacro(db.decl_macro_expander(id.krate, ast_id)) @@ -554,27 +552,26 @@ impl TokenExpander { } } -enum CowArc<T> { - Arc(Arc<T>), - Owned(T), -} - fn macro_expand( db: &dyn ExpandDatabase, macro_call_id: MacroCallId, loc: MacroCallLoc, -) -> ExpandResult<(CowArc<tt::TopSubtree>, MatchedArmIndex)> { +) -> ExpandResult<(Cow<'_, tt::TopSubtree>, MatchedArmIndex)> { let _p = tracing::info_span!("macro_expand").entered(); let (ExpandResult { value: (tt, matched_arm), err }, span) = match loc.def.kind { MacroDefKind::ProcMacro(..) => { - return db.expand_proc_macro(macro_call_id).map(CowArc::Arc).zip_val(None); + return db + .expand_proc_macro(macro_call_id) + .as_ref() + .map(|it| (Cow::Borrowed(it), None)); } _ => { let (macro_arg, undo_info, span) = db.macro_arg_considering_derives(macro_call_id, &loc.kind); + let span = *span; - let arg = &*macro_arg; + let arg = macro_arg; let res = match loc.def.kind { MacroDefKind::Declarative(id, _) => db .decl_macro_expander(loc.def.krate, id) @@ -594,7 +591,7 @@ fn macro_expand( // As such we just return the input subtree here. let eager = match &loc.kind { MacroCallKind::FnLike { eager: None, .. } => { - return ExpandResult::ok(CowArc::Arc(macro_arg.clone())).zip_val(None); + return ExpandResult::ok(Cow::Borrowed(macro_arg)).zip_val(None); } MacroCallKind::FnLike { eager: Some(eager), .. } => Some(&**eager), _ => None, @@ -610,7 +607,7 @@ fn macro_expand( } MacroDefKind::BuiltInAttr(_, it) => { let mut res = it.expand(db, macro_call_id, arg, span); - fixup::reverse_fixups(&mut res.value, &undo_info); + fixup::reverse_fixups(&mut res.value, undo_info); res.zip_val(None) } MacroDefKind::ProcMacro(_, _, _) => unreachable!(), @@ -624,12 +621,12 @@ fn macro_expand( // Set a hard limit for the expanded tt if let Err(value) = check_tt_count(&tt) { return value - .map(|()| CowArc::Owned(tt::TopSubtree::empty(tt::DelimSpan::from_single(span)))) + .map(|()| Cow::Owned(tt::TopSubtree::empty(tt::DelimSpan::from_single(span)))) .zip_val(matched_arm); } } - ExpandResult { value: (CowArc::Owned(tt), matched_arm), err } + ExpandResult { value: (Cow::Owned(tt), matched_arm), err } } fn proc_macro_span(db: &dyn ExpandDatabase, ast: AstId<ast::Fn>) -> Span { @@ -643,10 +640,8 @@ fn proc_macro_span(db: &dyn ExpandDatabase, ast: AstId<ast::Fn>) -> Span { span_map.span_for_range(range) } -fn expand_proc_macro( - db: &dyn ExpandDatabase, - id: MacroCallId, -) -> ExpandResult<Arc<tt::TopSubtree>> { +#[salsa_macros::tracked(returns(ref))] +fn expand_proc_macro(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult<tt::TopSubtree> { let loc = db.lookup_intern_macro_call(id); let (macro_arg, undo_info, span) = db.macro_arg_considering_derives(id, &loc.kind); @@ -666,7 +661,7 @@ fn expand_proc_macro( db, loc.def.krate, loc.krate, - ¯o_arg, + macro_arg, attr_arg, span_with_def_site_ctxt(db, span, id.into(), loc.def.edition), span_with_call_site_ctxt(db, span, id.into(), loc.def.edition), @@ -676,12 +671,12 @@ fn expand_proc_macro( // Set a hard limit for the expanded tt if let Err(value) = check_tt_count(&tt) { - return value.map(|()| Arc::new(tt::TopSubtree::empty(tt::DelimSpan::from_single(span)))); + return value.map(|()| tt::TopSubtree::empty(tt::DelimSpan::from_single(*span))); } - fixup::reverse_fixups(&mut tt, &undo_info); + fixup::reverse_fixups(&mut tt, undo_info); - ExpandResult { value: Arc::new(tt), err } + ExpandResult { value: tt, err } } pub(crate) fn token_tree_to_syntax_node( diff --git a/crates/hir-expand/src/declarative.rs b/crates/hir-expand/src/declarative.rs index aa745a2ccd..ead10a51a8 100644 --- a/crates/hir-expand/src/declarative.rs +++ b/crates/hir-expand/src/declarative.rs @@ -10,7 +10,6 @@ use syntax::{ ast::{self, HasAttrs}, }; use syntax_bridge::DocCommentDesugarMode; -use triomphe::Arc; use crate::{ AstId, ExpandError, ExpandErrorKind, ExpandResult, HirFileId, Lookup, MacroCallId, @@ -78,12 +77,16 @@ impl DeclarativeMacroExpander { .map_err(Into::into), } } +} +#[salsa::tracked] +impl DeclarativeMacroExpander { + #[salsa::tracked(returns(ref))] pub(crate) fn expander( db: &dyn ExpandDatabase, def_crate: Crate, id: AstId<ast::Macro>, - ) -> Arc<DeclarativeMacroExpander> { + ) -> DeclarativeMacroExpander { let (root, map) = crate::db::parse_with_map(db, id.file_id); let root = root.syntax_node(); @@ -177,6 +180,6 @@ impl DeclarativeMacroExpander { HirFileId::MacroFile(macro_file) => macro_file.lookup(db).ctxt, HirFileId::FileId(file) => SyntaxContext::root(file.edition(db)), }); - Arc::new(DeclarativeMacroExpander { mac, transparency, edition }) + DeclarativeMacroExpander { mac, transparency, edition } } } diff --git a/crates/hir-expand/src/eager.rs b/crates/hir-expand/src/eager.rs index 6e95ff01c3..dddef17ce7 100644 --- a/crates/hir-expand/src/eager.rs +++ b/crates/hir-expand/src/eager.rs @@ -22,7 +22,6 @@ use base_db::Crate; use span::SyntaxContext; use syntax::{AstPtr, Parse, SyntaxElement, SyntaxNode, TextSize, WalkEvent, ted}; use syntax_bridge::DocCommentDesugarMode; -use triomphe::Arc; use crate::{ AstId, EagerCallInfo, ExpandError, ExpandResult, ExpandTo, ExpansionSpanMap, InFile, @@ -92,7 +91,7 @@ pub fn expand_eager_macro_input( let mut subtree = syntax_bridge::syntax_node_to_token_tree( &expanded_eager_input, arg_map, - span, + *span, DocCommentDesugarMode::Mbe, ); @@ -104,11 +103,11 @@ pub fn expand_eager_macro_input( kind: MacroCallKind::FnLike { ast_id, expand_to, - eager: Some(Arc::new(EagerCallInfo { - arg: Arc::new(subtree), + eager: Some(Box::new(EagerCallInfo { + arg: subtree, arg_id, error: err.clone(), - span, + span: *span, })), }, ctxt: call_site, diff --git a/crates/hir-expand/src/fixup.rs b/crates/hir-expand/src/fixup.rs index b51ec39ce7..939104b709 100644 --- a/crates/hir-expand/src/fixup.rs +++ b/crates/hir-expand/src/fixup.rs @@ -14,7 +14,7 @@ use syntax::{ match_ast, }; use syntax_bridge::DocCommentDesugarMode; -use triomphe::Arc; +use thin_vec::ThinVec; use tt::{Spacing, TransformTtAction, transform_tt}; use crate::{ @@ -35,8 +35,7 @@ pub(crate) struct SyntaxFixups { /// This is the information needed to reverse the fixups. #[derive(Clone, Debug, Default, PartialEq, Eq)] pub struct SyntaxFixupUndoInfo { - // FIXME: ThinArc<[Subtree]> - original: Option<Arc<Box<[TopSubtree]>>>, + original: Option<ThinVec<TopSubtree>>, } impl SyntaxFixupUndoInfo { @@ -59,7 +58,7 @@ pub(crate) fn fixup_syntax( let mut append = FxHashMap::<SyntaxElement, _>::default(); let mut remove = FxHashSet::<SyntaxElement>::default(); let mut preorder = node.preorder(); - let mut original = Vec::new(); + let mut original = ThinVec::new(); let dummy_range = FIXUP_DUMMY_RANGE; let fake_span = |range| { let span = span_map.span_for_range(range); @@ -317,13 +316,12 @@ pub(crate) fn fixup_syntax( } } } + original.shrink_to_fit(); let needs_fixups = !append.is_empty() || !original.is_empty(); SyntaxFixups { append, remove, - undo_info: SyntaxFixupUndoInfo { - original: needs_fixups.then(|| Arc::new(original.into_boxed_slice())), - }, + undo_info: SyntaxFixupUndoInfo { original: needs_fixups.then_some(original) }, } } @@ -340,7 +338,7 @@ fn has_error_to_handle(node: &SyntaxNode) -> bool { } pub(crate) fn reverse_fixups(tt: &mut TopSubtree, undo_info: &SyntaxFixupUndoInfo) { - let Some(undo_info) = undo_info.original.as_deref() else { return }; + let Some(undo_info) = &undo_info.original else { return }; let undo_info = &**undo_info; let top_subtree = tt.top_subtree(); let open_span = top_subtree.delimiter.open; diff --git a/crates/hir-expand/src/lib.rs b/crates/hir-expand/src/lib.rs index fc2a07435b..403e544bf8 100644 --- a/crates/hir-expand/src/lib.rs +++ b/crates/hir-expand/src/lib.rs @@ -279,7 +279,7 @@ impl MacroDefKind { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct EagerCallInfo { /// The expanded argument of the eager macro. - arg: Arc<tt::TopSubtree>, + arg: tt::TopSubtree, /// Call id of the eager macro's input file (this is the macro file for its fully expanded input). arg_id: MacroCallId, error: Option<ExpandError>, @@ -296,7 +296,7 @@ pub enum MacroCallKind { /// for the eager input macro file. // FIXME: This is being interned, subtrees can vary quickly differing just slightly causing // leakage problems here - eager: Option<Arc<EagerCallInfo>>, + eager: Option<Box<EagerCallInfo>>, }, Derive { ast_id: AstId<ast::Adt>, @@ -311,7 +311,7 @@ pub enum MacroCallKind { Attr { ast_id: AstId<ast::Item>, // FIXME: This shouldn't be here, we can derive this from `invoc_attr_index`. - attr_args: Option<Arc<tt::TopSubtree>>, + attr_args: Option<Box<tt::TopSubtree>>, /// This contains the list of all *active* attributes (derives and attr macros) preceding this /// attribute, including this attribute. You can retrieve the [`AttrId`] of the current attribute /// by calling [`invoc_attr()`] on this. diff --git a/crates/hir-ty/src/consteval.rs b/crates/hir-ty/src/consteval.rs index 80e7e05d76..87633ad4aa 100644 --- a/crates/hir-ty/src/consteval.rs +++ b/crates/hir-ty/src/consteval.rs @@ -16,7 +16,6 @@ use rustc_abi::Size; use rustc_apfloat::Float; use rustc_type_ir::inherent::IntoKind; use stdx::never; -use triomphe::Arc; use crate::{ LifetimeElisionKind, ParamEnvAndCrate, TyLoweringContext, @@ -300,7 +299,7 @@ pub(crate) fn eval_to_const<'db>(expr: ExprId, ctx: &mut InferenceContext<'_, 'd if let Some(body_owner) = ctx.owner.as_def_with_body() && let Ok(mir_body) = lower_body_to_mir(ctx.db, body_owner, Body::of(ctx.db, body_owner), &infer, expr) - && let Ok((Ok(result), _)) = interpret_mir(ctx.db, Arc::new(mir_body), true, None) + && let Ok((Ok(result), _)) = interpret_mir(ctx.db, &mir_body, true, None) { return Const::new_from_allocation( ctx.interner(), diff --git a/crates/hir-ty/src/db.rs b/crates/hir-ty/src/db.rs index 2e130c1028..5dba53a761 100644 --- a/crates/hir-ty/src/db.rs +++ b/crates/hir-ty/src/db.rs @@ -37,33 +37,44 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug { // FXME: Collapse `mir_body_for_closure` into `mir_body` // and `monomorphized_mir_body_for_closure` into `monomorphized_mir_body` - #[salsa::invoke(crate::mir::mir_body_query)] - #[salsa::cycle(cycle_result = crate::mir::mir_body_cycle_result)] - fn mir_body(&self, def: DefWithBodyId) -> Result<Arc<MirBody>, MirLowerError>; + #[salsa::transparent] + fn mir_body(&self, def: DefWithBodyId) -> Result<&MirBody, MirLowerError> { + crate::mir::mir_body_query(self, def).as_ref().map_err(|err| err.clone()) + } - #[salsa::invoke(crate::mir::mir_body_for_closure_query)] - fn mir_body_for_closure(&self, def: InternedClosureId) -> Result<Arc<MirBody>, MirLowerError>; + #[salsa::transparent] + fn mir_body_for_closure(&self, def: InternedClosureId) -> Result<&MirBody, MirLowerError> { + crate::mir::mir_body_for_closure_query(self, def).as_ref().map_err(|err| err.clone()) + } - #[salsa::invoke(crate::mir::monomorphized_mir_body_query)] - #[salsa::cycle(cycle_result = crate::mir::monomorphized_mir_body_cycle_result)] + #[salsa::transparent] fn monomorphized_mir_body( &self, def: DefWithBodyId, subst: StoredGenericArgs, env: StoredParamEnvAndCrate, - ) -> Result<Arc<MirBody>, MirLowerError>; + ) -> Result<&MirBody, MirLowerError> { + crate::mir::monomorphized_mir_body_query(self, def, subst, env) + .as_ref() + .map_err(|err| err.clone()) + } - #[salsa::invoke(crate::mir::monomorphized_mir_body_for_closure_query)] + #[salsa::transparent] fn monomorphized_mir_body_for_closure( &self, def: InternedClosureId, subst: StoredGenericArgs, env: StoredParamEnvAndCrate, - ) -> Result<Arc<MirBody>, MirLowerError>; + ) -> Result<&MirBody, MirLowerError> { + crate::mir::monomorphized_mir_body_for_closure_query(self, def, subst, env) + .as_ref() + .map_err(|err| err.clone()) + } - #[salsa::invoke(crate::mir::borrowck_query)] - #[salsa::lru(2024)] - fn borrowck(&self, def: DefWithBodyId) -> Result<Arc<[BorrowckResult]>, MirLowerError>; + #[salsa::transparent] + fn borrowck(&self, def: DefWithBodyId) -> Result<&[BorrowckResult], MirLowerError> { + crate::mir::borrowck_query(self, def).as_ref().map(|it| &**it).map_err(|err| err.clone()) + } #[salsa::invoke(crate::consteval::const_eval)] #[salsa::transparent] @@ -110,8 +121,10 @@ pub trait HirDatabase: DefDatabase + std::fmt::Debug { env: StoredParamEnvAndCrate, ) -> Result<Arc<Layout>, LayoutError>; - #[salsa::invoke(crate::layout::target_data_layout_query)] - fn target_data_layout(&self, krate: Crate) -> Result<Arc<TargetDataLayout>, TargetLoadError>; + #[salsa::transparent] + fn target_data_layout(&self, krate: Crate) -> Result<&TargetDataLayout, TargetLoadError> { + crate::layout::target_data_layout_query(self, krate).as_ref().map_err(|err| err.clone()) + } #[salsa::invoke(crate::dyn_compatibility::dyn_compatibility_of_trait_query)] fn dyn_compatibility_of_trait(&self, trait_: TraitId) -> Option<DynCompatibilityViolation>; diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs index 2df190bb7a..c300388c5e 100644 --- a/crates/hir-ty/src/display.rs +++ b/crates/hir-ty/src/display.rs @@ -974,7 +974,7 @@ fn render_const_scalar_inner<'db>( return f.write_str("<target-layout-not-available>"); }; let Some((var_id, var_layout)) = - detect_variant_from_bytes(&layout, f.db, &target_data_layout, b, e) + detect_variant_from_bytes(&layout, f.db, target_data_layout, b, e) else { return f.write_str("<failed-to-detect-variant>"); }; diff --git a/crates/hir-ty/src/layout.rs b/crates/hir-ty/src/layout.rs index d2759ddeeb..da0be818f6 100644 --- a/crates/hir-ty/src/layout.rs +++ b/crates/hir-ty/src/layout.rs @@ -167,7 +167,7 @@ pub fn layout_of_ty_query( let Ok(target) = db.target_data_layout(krate) else { return Err(LayoutError::TargetLayoutNotAvailable); }; - let dl = &*target; + let dl = target; let cx = LayoutCx::new(dl); let infer_ctxt = interner.infer_ctxt().build(TypingMode::PostAnalysis); let cause = ObligationCause::dummy(); @@ -187,7 +187,7 @@ pub fn layout_of_ty_query( repr.packed(), &args, trait_env.as_ref(), - &target, + target, ); } } diff --git a/crates/hir-ty/src/layout/adt.rs b/crates/hir-ty/src/layout/adt.rs index 6090ddfd45..e77fb139be 100644 --- a/crates/hir-ty/src/layout/adt.rs +++ b/crates/hir-ty/src/layout/adt.rs @@ -29,7 +29,7 @@ pub fn layout_of_adt_query( let Ok(target) = db.target_data_layout(krate) else { return Err(LayoutError::TargetLayoutNotAvailable); }; - let dl = &*target; + let dl = target; let cx = LayoutCx::new(dl); let handle_variant = |def: VariantId, var: &VariantFields| { var.fields() diff --git a/crates/hir-ty/src/layout/target.rs b/crates/hir-ty/src/layout/target.rs index 1752b56b0f..26fa73e76b 100644 --- a/crates/hir-ty/src/layout/target.rs +++ b/crates/hir-ty/src/layout/target.rs @@ -3,17 +3,17 @@ use base_db::{Crate, target::TargetLoadError}; use hir_def::layout::TargetDataLayout; use rustc_abi::{AddressSpace, AlignFromBytesError, TargetDataLayoutError}; -use triomphe::Arc; use crate::db::HirDatabase; +#[salsa_macros::tracked(returns(ref))] pub fn target_data_layout_query( db: &dyn HirDatabase, krate: Crate, -) -> Result<Arc<TargetDataLayout>, TargetLoadError> { +) -> Result<TargetDataLayout, TargetLoadError> { match &krate.workspace_data(db).target { Ok(target) => match TargetDataLayout::parse_from_llvm_datalayout_string(&target.data_layout, AddressSpace::ZERO) { - Ok(it) => Ok(Arc::new(it)), + Ok(it) => Ok(it), Err(e) => { Err(match e { TargetDataLayoutError::InvalidAddressSpace { addr_space, cause, err } => { diff --git a/crates/hir-ty/src/mir.rs b/crates/hir-ty/src/mir.rs index a8e06f3a2b..67cc67fd39 100644 --- a/crates/hir-ty/src/mir.rs +++ b/crates/hir-ty/src/mir.rs @@ -47,9 +47,6 @@ pub use monomorphization::{ monomorphized_mir_body_for_closure_query, monomorphized_mir_body_query, }; -pub(crate) use lower::mir_body_cycle_result; -pub(crate) use monomorphization::monomorphized_mir_body_cycle_result; - use super::consteval::try_const_usize; pub type BasicBlockId = Idx<BasicBlock>; diff --git a/crates/hir-ty/src/mir/borrowck.rs b/crates/hir-ty/src/mir/borrowck.rs index 17715d3fcd..dcd06ae25f 100644 --- a/crates/hir-ty/src/mir/borrowck.rs +++ b/crates/hir-ty/src/mir/borrowck.rs @@ -5,11 +5,11 @@ use std::iter; +use either::Either; use hir_def::{DefWithBodyId, ExpressionStoreOwnerId, HasModule}; use la_arena::ArenaMap; use rustc_hash::FxHashMap; use stdx::never; -use triomphe::Arc; use crate::{ closure_analysis::ProjectionKind as HirProjectionKind, @@ -57,68 +57,86 @@ pub struct BorrowRegion { #[derive(Debug, Clone, PartialEq, Eq)] pub struct BorrowckResult { - pub mir_body: Arc<MirBody>, + owner: Either<DefWithBodyId, InternedClosureId>, pub mutability_of_locals: ArenaMap<LocalId, MutabilityReason>, pub moved_out_of_ref: Vec<MovedOutOfRef>, pub partially_moved: Vec<PartiallyMoved>, pub borrow_regions: Vec<BorrowRegion>, } -fn all_mir_bodies( - db: &dyn HirDatabase, +impl BorrowckResult { + pub fn mir_body<'db>(&self, db: &'db dyn HirDatabase) -> &'db MirBody { + match self.owner { + Either::Left(it) => db.mir_body(it).unwrap(), + Either::Right(it) => db.mir_body_for_closure(it).unwrap(), + } + } +} + +fn all_mir_bodies<'db>( + db: &'db dyn HirDatabase, def: DefWithBodyId, - mut cb: impl FnMut(Arc<MirBody>) -> BorrowckResult, - mut merge_from_closures: impl FnMut(&mut BorrowckResult, &BorrowckResult), -) -> Result<Arc<[BorrowckResult]>, MirLowerError> { - fn for_closure( - db: &dyn HirDatabase, + mut cb: impl FnMut(&'db MirBody, Either<DefWithBodyId, InternedClosureId>) -> BorrowckResult, + mut merge_from_closures: impl FnMut( + (&mut BorrowckResult, &'db MirBody), + (&BorrowckResult, &'db MirBody), + ), +) -> Result<Box<[BorrowckResult]>, MirLowerError> { + fn for_closure<'db>( + db: &'db dyn HirDatabase, c: InternedClosureId, - results: &mut Vec<BorrowckResult>, - cb: &mut impl FnMut(Arc<MirBody>) -> BorrowckResult, - merge_from_closures: &mut impl FnMut(&mut BorrowckResult, &BorrowckResult), + results: &mut Vec<(BorrowckResult, &'db MirBody)>, + cb: &mut impl FnMut(&'db MirBody, Either<DefWithBodyId, InternedClosureId>) -> BorrowckResult, + merge_from_closures: &mut impl FnMut( + (&mut BorrowckResult, &'db MirBody), + (&BorrowckResult, &'db MirBody), + ), ) -> Result<(), MirLowerError> { match db.mir_body_for_closure(c) { Ok(body) => { let parent_index = results.len(); - results.push(cb(body.clone())); + results.push((cb(body, Either::Right(c)), body)); body.closures .iter() .try_for_each(|&it| for_closure(db, it, results, cb, merge_from_closures))?; merge(results, merge_from_closures, parent_index); Ok(()) } - Err(e) => Err(e), + Err(e) => Err(e.clone()), } } - fn merge( - results: &mut [BorrowckResult], - merge: &mut impl FnMut(&mut BorrowckResult, &BorrowckResult), + fn merge<'db>( + results: &mut [(BorrowckResult, &'db MirBody)], + merge: &mut impl FnMut((&mut BorrowckResult, &'db MirBody), (&BorrowckResult, &'db MirBody)), parent_index: usize, ) { let (parent_and_before, children) = results.split_at_mut(parent_index + 1); - let parent = &mut parent_and_before[parent_and_before.len() - 1]; - children.iter().for_each(|child| merge(parent, child)); + let (parent, parent_mir_body) = &mut parent_and_before[parent_and_before.len() - 1]; + children.iter().for_each(|(child, child_mir_body)| { + merge((parent, parent_mir_body), (child, child_mir_body)) + }); } let mut results = Vec::new(); match db.mir_body(def) { Ok(body) => { - results.push(cb(body.clone())); + results.push((cb(body, Either::Left(def)), body)); body.closures.iter().try_for_each(|&it| { for_closure(db, it, &mut results, &mut cb, &mut merge_from_closures) })?; merge(&mut results, &mut merge_from_closures, 0); - Ok(results.into()) + Ok(results.into_iter().map(|(it, _)| it).collect()) } - Err(e) => Err(e), + Err(e) => Err(e.clone()), } } +#[salsa_macros::tracked(returns(ref), lru = 2024)] pub fn borrowck_query( db: &dyn HirDatabase, def: DefWithBodyId, -) -> Result<Arc<[BorrowckResult]>, MirLowerError> { +) -> Result<Box<[BorrowckResult]>, MirLowerError> { let _p = tracing::info_span!("borrowck_query").entered(); let module = def.module(db); let interner = DbInterner::new_with(db, module.krate(db)); @@ -128,20 +146,20 @@ pub fn borrowck_query( let res = all_mir_bodies( db, def, - |body| { + |body, owner| { // FIXME(next-solver): Opaques. let infcx = interner.infer_ctxt().build(typing_mode); BorrowckResult { - mutability_of_locals: mutability_of_locals(&infcx, env, &body), - moved_out_of_ref: moved_out_of_ref(&infcx, env, &body), - partially_moved: partially_moved(&infcx, env, &body), - borrow_regions: borrow_regions(db, &body), - mir_body: body, + owner, + mutability_of_locals: mutability_of_locals(&infcx, env, body), + moved_out_of_ref: moved_out_of_ref(&infcx, env, body), + partially_moved: partially_moved(&infcx, env, body), + borrow_regions: borrow_regions(db, body), } }, - |parent, child| { - for (upvar, child_locals) in &child.mir_body.upvar_locals { - let Some(&parent_local) = parent.mir_body.binding_locals.get(*upvar) else { + |(parent, parent_mir_body), (child, child_mir_body)| { + for (upvar, child_locals) in &child_mir_body.upvar_locals { + let Some(&parent_local) = parent_mir_body.binding_locals.get(*upvar) else { continue; }; for (child_local, capture_place) in child_locals { diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs index 87d64e567e..104b90eaf5 100644 --- a/crates/hir-ty/src/mir/eval.rs +++ b/crates/hir-ty/src/mir/eval.rs @@ -156,26 +156,26 @@ impl TlsData { } } -struct StackFrame { - locals: Locals, +struct StackFrame<'a> { + locals: Locals<'a>, destination: Option<BasicBlockId>, prev_stack_ptr: usize, span: (MirSpan, DefWithBodyId), } #[derive(Clone)] -enum MirOrDynIndex { - Mir(Arc<MirBody>), +enum MirOrDynIndex<'a> { + Mir(&'a MirBody), Dyn(usize), } -pub struct Evaluator<'db> { +pub struct Evaluator<'a, 'db> { db: &'db dyn HirDatabase, param_env: ParamEnvAndCrate<'db>, - target_data_layout: Arc<TargetDataLayout>, + target_data_layout: &'db TargetDataLayout, stack: Vec<u8>, heap: Vec<u8>, - code_stack: Vec<StackFrame>, + code_stack: Vec<StackFrame<'a>>, /// Stores the global location of the statics. We const evaluate every static first time we need it /// and see it's missing, then we add it to this to reuse. static_locations: FxHashMap<StaticId, Address>, @@ -190,11 +190,11 @@ pub struct Evaluator<'db> { layout_cache: RefCell<FxHashMap<Ty<'db>, Arc<Layout>>>, projected_ty_cache: RefCell<FxHashMap<(Ty<'db>, PlaceElem), Ty<'db>>>, not_special_fn_cache: RefCell<FxHashSet<FunctionId>>, - mir_or_dyn_index_cache: RefCell<FxHashMap<(FunctionId, GenericArgs<'db>), MirOrDynIndex>>, + mir_or_dyn_index_cache: RefCell<FxHashMap<(FunctionId, GenericArgs<'db>), MirOrDynIndex<'a>>>, /// Constantly dropping and creating `Locals` is very costly. We store /// old locals that we normally want to drop here, to reuse their allocations /// later. - unused_locals_store: RefCell<FxHashMap<DefWithBodyId, Vec<Locals>>>, + unused_locals_store: RefCell<FxHashMap<DefWithBodyId, Vec<Locals<'a>>>>, cached_ptr_size: usize, cached_fn_trait_func: Option<FunctionId>, cached_fn_mut_trait_func: Option<FunctionId>, @@ -237,17 +237,21 @@ impl Interval { Self { addr, size } } - fn get<'a, 'db>(&self, memory: &'a Evaluator<'db>) -> Result<'db, &'a [u8]> { + fn get<'b, 'a, 'db: 'a>(&self, memory: &'b Evaluator<'a, 'db>) -> Result<'db, &'b [u8]> { memory.read_memory(self.addr, self.size) } - fn write_from_bytes<'db>(&self, memory: &mut Evaluator<'db>, bytes: &[u8]) -> Result<'db, ()> { + fn write_from_bytes<'a, 'db: 'a>( + &self, + memory: &mut Evaluator<'a, 'db>, + bytes: &[u8], + ) -> Result<'db, ()> { memory.write_memory(self.addr, bytes) } - fn write_from_interval<'db>( + fn write_from_interval<'a, 'db: 'a>( &self, - memory: &mut Evaluator<'db>, + memory: &mut Evaluator<'a, 'db>, interval: Interval, ) -> Result<'db, ()> { memory.copy_from_interval(self.addr, interval) @@ -259,16 +263,22 @@ impl Interval { } impl<'db> IntervalAndTy<'db> { - fn get<'a>(&self, memory: &'a Evaluator<'db>) -> Result<'db, &'a [u8]> { + fn get<'b, 'a>(&self, memory: &'b Evaluator<'a, 'db>) -> Result<'db, &'b [u8]> + where + 'db: 'a, + { memory.read_memory(self.interval.addr, self.interval.size) } - fn new( + fn new<'a>( addr: Address, ty: Ty<'db>, - evaluator: &Evaluator<'db>, - locals: &Locals, - ) -> Result<'db, IntervalAndTy<'db>> { + evaluator: &Evaluator<'a, 'db>, + locals: &Locals<'a>, + ) -> Result<'db, IntervalAndTy<'db>> + where + 'db: 'a, + { let size = evaluator.size_of_sized(ty, locals, "type of interval")?; Ok(IntervalAndTy { interval: Interval { addr, size }, ty }) } @@ -286,7 +296,7 @@ impl From<Interval> for IntervalOrOwned { } impl IntervalOrOwned { - fn get<'a, 'db>(&'a self, memory: &'a Evaluator<'db>) -> Result<'db, &'a [u8]> { + fn get<'b, 'a, 'db: 'a>(&'b self, memory: &'b Evaluator<'a, 'db>) -> Result<'db, &'b [u8]> { Ok(match self { IntervalOrOwned::Owned(o) => o, IntervalOrOwned::Borrowed(b) => b.get(memory)?, @@ -576,9 +586,9 @@ impl DropFlags { } #[derive(Debug)] -struct Locals { +struct Locals<'a> { ptr: ArenaMap<LocalId, Interval>, - body: Arc<MirBody>, + body: &'a MirBody, drop_flags: DropFlags, } @@ -596,9 +606,9 @@ impl MirOutput { } } -pub fn interpret_mir<'db>( +pub fn interpret_mir<'a, 'db: 'a>( db: &'db dyn HirDatabase, - body: Arc<MirBody>, + body: &MirBody, // FIXME: This is workaround. Ideally, const generics should have a separate body (issue #7434), but now // they share their body with their parent, so in MIR lowering we have locals of the parent body, which // might have placeholders. With this argument, we (wrongly) assume that every placeholder type has @@ -613,7 +623,7 @@ pub fn interpret_mir<'db>( if evaluator.ptr_size() != size_of::<usize>() { not_supported!("targets with different pointer size from host"); } - let interval = evaluator.interpret_mir(body.clone(), None.into_iter())?; + let interval = evaluator.interpret_mir(body, None.into_iter())?; let bytes = interval.get(&evaluator)?; let mut memory_map = evaluator.create_memory_map( bytes, @@ -638,13 +648,13 @@ const EXECUTION_LIMIT: usize = 100_000; #[cfg(not(test))] const EXECUTION_LIMIT: usize = 10_000_000; -impl<'db> Evaluator<'db> { +impl<'a, 'db: 'a> Evaluator<'a, 'db> { pub fn new( db: &'db dyn HirDatabase, owner: DefWithBodyId, assert_placeholder_ty_is_unused: bool, trait_env: Option<ParamEnvAndCrate<'db>>, - ) -> Result<'db, Evaluator<'db>> { + ) -> Result<'db, Evaluator<'a, 'db>> { let module = owner.module(db); let crate_id = module.krate(db); let target_data_layout = match db.target_data_layout(crate_id) { @@ -705,11 +715,11 @@ impl<'db> Evaluator<'db> { self.infcx.interner.lang_items() } - fn place_addr(&self, p: &Place, locals: &Locals) -> Result<'db, Address> { + fn place_addr(&self, p: &Place, locals: &Locals<'a>) -> Result<'db, Address> { Ok(self.place_addr_and_ty_and_metadata(p, locals)?.0) } - fn place_interval(&self, p: &Place, locals: &Locals) -> Result<'db, Interval> { + fn place_interval(&self, p: &Place, locals: &Locals<'a>) -> Result<'db, Interval> { let place_addr_and_ty = self.place_addr_and_ty_and_metadata(p, locals)?; Ok(Interval { addr: place_addr_and_ty.0, @@ -736,10 +746,10 @@ impl<'db> Evaluator<'db> { r } - fn place_addr_and_ty_and_metadata<'a>( - &'a self, + fn place_addr_and_ty_and_metadata<'b>( + &'b self, p: &Place, - locals: &'a Locals, + locals: &'b Locals<'a>, ) -> Result<'db, (Address, Ty<'db>, Option<IntervalOrOwned>)> { let mut addr = locals.ptr[p.local].addr; let mut ty: Ty<'db> = locals.body.locals[p.local].ty.as_ref(); @@ -873,11 +883,11 @@ impl<'db> Evaluator<'db> { self.layout(Ty::new_adt(self.interner(), adt, subst)) } - fn place_ty<'a>(&'a self, p: &Place, locals: &'a Locals) -> Result<'db, Ty<'db>> { + fn place_ty<'b>(&'b self, p: &Place, locals: &'b Locals<'a>) -> Result<'db, Ty<'db>> { Ok(self.place_addr_and_ty_and_metadata(p, locals)?.1) } - fn operand_ty(&self, o: &Operand, locals: &Locals) -> Result<'db, Ty<'db>> { + fn operand_ty(&self, o: &Operand, locals: &Locals<'a>) -> Result<'db, Ty<'db>> { Ok(match &o.kind { OperandKind::Copy(p) | OperandKind::Move(p) => self.place_ty(p, locals)?, OperandKind::Constant { konst: _, ty } => ty.as_ref(), @@ -898,7 +908,7 @@ impl<'db> Evaluator<'db> { fn operand_ty_and_eval( &mut self, o: &Operand, - locals: &mut Locals, + locals: &mut Locals<'a>, ) -> Result<'db, IntervalAndTy<'db>> { Ok(IntervalAndTy { interval: self.eval_operand(o, locals)?, @@ -908,7 +918,7 @@ impl<'db> Evaluator<'db> { fn interpret_mir( &mut self, - body: Arc<MirBody>, + body: &'a MirBody, args: impl Iterator<Item = IntervalOrOwned>, ) -> Result<'db, Interval> { if let Some(it) = self.stack_depth_limit.checked_sub(1) { @@ -917,8 +927,8 @@ impl<'db> Evaluator<'db> { return Err(MirEvalError::StackOverflow); } let mut current_block_idx = body.start_block; - let (mut locals, prev_stack_ptr) = self.create_locals_for_body(&body, None)?; - self.fill_locals_for_body(&body, &mut locals, args)?; + let (mut locals, prev_stack_ptr) = self.create_locals_for_body(body, None)?; + self.fill_locals_for_body(body, &mut locals, args)?; let prev_code_stack = mem::take(&mut self.code_stack); let span = (MirSpan::Unknown, body.owner); self.code_stack.push(StackFrame { locals, destination: None, prev_stack_ptr, span }); @@ -1073,7 +1083,7 @@ impl<'db> Evaluator<'db> { fn fill_locals_for_body( &mut self, body: &MirBody, - locals: &mut Locals, + locals: &mut Locals<'a>, args: impl Iterator<Item = IntervalOrOwned>, ) -> Result<'db, ()> { let mut remain_args = body.param_locals.len(); @@ -1096,19 +1106,15 @@ impl<'db> Evaluator<'db> { fn create_locals_for_body( &mut self, - body: &Arc<MirBody>, + body: &'a MirBody, destination: Option<Interval>, - ) -> Result<'db, (Locals, usize)> { + ) -> Result<'db, (Locals<'a>, usize)> { let mut locals = match self.unused_locals_store.borrow_mut().entry(body.owner).or_default().pop() { - None => Locals { - ptr: ArenaMap::new(), - body: body.clone(), - drop_flags: DropFlags::default(), - }, + None => Locals { ptr: ArenaMap::new(), body, drop_flags: DropFlags::default() }, Some(mut l) => { l.drop_flags.clear(); - l.body = body.clone(); + l.body = body; l } }; @@ -1145,7 +1151,7 @@ impl<'db> Evaluator<'db> { Ok((locals, prev_stack_pointer)) } - fn eval_rvalue(&mut self, r: &Rvalue, locals: &mut Locals) -> Result<'db, IntervalOrOwned> { + fn eval_rvalue(&mut self, r: &Rvalue, locals: &mut Locals<'a>) -> Result<'db, IntervalOrOwned> { use IntervalOrOwned::*; Ok(match r { Rvalue::Use(it) => Borrowed(self.eval_operand(it, locals)?), @@ -1662,7 +1668,7 @@ impl<'db> Evaluator<'db> { Ok(r) } Variants::Multiple { tag, tag_encoding, variants, .. } => { - let size = tag.size(&*self.target_data_layout).bytes_usize(); + let size = tag.size(self.target_data_layout).bytes_usize(); let offset = layout.fields.offset(0).bytes_usize(); // The only field on enum variants is the tag field let is_signed = tag.is_signed(); match tag_encoding { @@ -1804,7 +1810,7 @@ impl<'db> Evaluator<'db> { &mut self, it: VariantId, subst: GenericArgs<'db>, - locals: &Locals, + locals: &Locals<'a>, ) -> Result<'db, (usize, Arc<Layout>, Option<(usize, usize, i128)>)> { let adt = it.adt_id(self.db); if let DefWithBodyId::VariantId(f) = locals.body.owner @@ -1851,7 +1857,7 @@ impl<'db> Evaluator<'db> { if have_tag { Some(( layout.fields.offset(0).bytes_usize(), - tag.size(&*self.target_data_layout).bytes_usize(), + tag.size(self.target_data_layout).bytes_usize(), discriminant, )) } else { @@ -1898,7 +1904,7 @@ impl<'db> Evaluator<'db> { Ok(result) } - fn eval_operand(&mut self, it: &Operand, locals: &mut Locals) -> Result<'db, Interval> { + fn eval_operand(&mut self, it: &Operand, locals: &mut Locals<'a>) -> Result<'db, Interval> { Ok(match &it.kind { OperandKind::Copy(p) | OperandKind::Move(p) => { locals.drop_flags.remove_place(p, &locals.body.projection_store); @@ -2051,7 +2057,7 @@ impl<'db> Evaluator<'db> { #[allow(clippy::double_parens)] fn allocate_const_in_heap( &mut self, - locals: &Locals, + locals: &Locals<'a>, konst: Const<'db>, ) -> Result<'db, Interval> { match konst.kind() { @@ -2089,7 +2095,7 @@ impl<'db> Evaluator<'db> { fn allocate_allocation_in_heap( &mut self, - locals: &Locals, + locals: &Locals<'a>, allocation: Allocation<'db>, ) -> Result<'db, Interval> { let AllocationData { ty, memory: ref v, ref memory_map } = *allocation; @@ -2128,7 +2134,7 @@ impl<'db> Evaluator<'db> { Ok(Interval::new(addr, size)) } - fn eval_place(&mut self, p: &Place, locals: &Locals) -> Result<'db, Interval> { + fn eval_place(&mut self, p: &Place, locals: &Locals<'a>) -> Result<'db, Interval> { let addr = self.place_addr(p, locals)?; Ok(Interval::new( addr, @@ -2228,7 +2234,11 @@ impl<'db> Evaluator<'db> { Ok(()) } - fn size_align_of(&self, ty: Ty<'db>, locals: &Locals) -> Result<'db, Option<(usize, usize)>> { + fn size_align_of( + &self, + ty: Ty<'db>, + locals: &Locals<'a>, + ) -> Result<'db, Option<(usize, usize)>> { if let Some(layout) = self.layout_cache.borrow().get(&ty) { return Ok(layout .is_sized() @@ -2257,7 +2267,7 @@ impl<'db> Evaluator<'db> { fn size_of_sized( &self, ty: Ty<'db>, - locals: &Locals, + locals: &Locals<'a>, what: &'static str, ) -> Result<'db, usize> { match self.size_align_of(ty, locals)? { @@ -2271,7 +2281,7 @@ impl<'db> Evaluator<'db> { fn size_align_of_sized( &self, ty: Ty<'db>, - locals: &Locals, + locals: &Locals<'a>, what: &'static str, ) -> Result<'db, (usize, usize)> { match self.size_align_of(ty, locals)? { @@ -2312,13 +2322,13 @@ impl<'db> Evaluator<'db> { &self, bytes: &[u8], ty: Ty<'db>, - locals: &Locals, + locals: &Locals<'a>, ) -> Result<'db, ComplexMemoryMap<'db>> { - fn rec<'db>( - this: &Evaluator<'db>, + fn rec<'a, 'db: 'a>( + this: &Evaluator<'a, 'db>, bytes: &[u8], ty: Ty<'db>, - locals: &Locals, + locals: &Locals<'a>, mm: &mut ComplexMemoryMap<'db>, stack_depth_limit: usize, ) -> Result<'db, ()> { @@ -2436,7 +2446,7 @@ impl<'db> Evaluator<'db> { if let Some((v, l)) = detect_variant_from_bytes( &layout, this.db, - &this.target_data_layout, + this.target_data_layout, bytes, e, ) { @@ -2487,7 +2497,7 @@ impl<'db> Evaluator<'db> { ty_of_bytes: impl Fn(&[u8]) -> Result<'db, Ty<'db>> + Copy, addr: Address, ty: Ty<'db>, - locals: &Locals, + locals: &Locals<'a>, ) -> Result<'db, ()> { // FIXME: support indirect references let layout = self.layout(ty)?; @@ -2546,7 +2556,7 @@ impl<'db> Evaluator<'db> { if let Some((ev, layout)) = detect_variant_from_bytes( &layout, self.db, - &self.target_data_layout, + self.target_data_layout, self.read_memory(addr, layout.size.bytes_usize())?, e, ) { @@ -2619,10 +2629,10 @@ impl<'db> Evaluator<'db> { bytes: Interval, destination: Interval, args: &[IntervalAndTy<'db>], - locals: &Locals, + locals: &Locals<'a>, target_bb: Option<BasicBlockId>, span: MirSpan, - ) -> Result<'db, Option<StackFrame>> { + ) -> Result<'db, Option<StackFrame<'a>>> { let id = from_bytes!(usize, bytes.get(self)?); let next_ty = self.vtable_map.ty(id)?; use rustc_type_ir::TyKind; @@ -2650,9 +2660,9 @@ impl<'db> Evaluator<'db> { generic_args: GenericArgs<'db>, destination: Interval, args: &[IntervalAndTy<'db>], - locals: &Locals, + locals: &Locals<'a>, span: MirSpan, - ) -> Result<'db, Option<StackFrame>> { + ) -> Result<'db, Option<StackFrame<'a>>> { let mir_body = self .db .monomorphized_mir_body_for_closure( @@ -2688,10 +2698,10 @@ impl<'db> Evaluator<'db> { generic_args: GenericArgs<'db>, destination: Interval, args: &[IntervalAndTy<'db>], - locals: &Locals, + locals: &Locals<'a>, target_bb: Option<BasicBlockId>, span: MirSpan, - ) -> Result<'db, Option<StackFrame>> { + ) -> Result<'db, Option<StackFrame<'a>>> { match def { CallableDefId::FunctionId(def) => { if self.detect_fn_trait(def).is_some() { @@ -2746,9 +2756,9 @@ impl<'db> Evaluator<'db> { &self, def: FunctionId, generic_args: GenericArgs<'db>, - locals: &Locals, + locals: &Locals<'a>, span: MirSpan, - ) -> Result<'db, MirOrDynIndex> { + ) -> Result<'db, MirOrDynIndex<'a>> { let pair = (def, generic_args); if let Some(r) = self.mir_or_dyn_index_cache.borrow().get(&pair) { return Ok(r.clone()); @@ -2788,11 +2798,11 @@ impl<'db> Evaluator<'db> { mut def: FunctionId, args: &[IntervalAndTy<'db>], generic_args: GenericArgs<'db>, - locals: &Locals, + locals: &Locals<'a>, destination: Interval, target_bb: Option<BasicBlockId>, span: MirSpan, - ) -> Result<'db, Option<StackFrame>> { + ) -> Result<'db, Option<StackFrame<'a>>> { if self.detect_and_exec_special_function( def, args, @@ -2854,18 +2864,18 @@ impl<'db> Evaluator<'db> { fn exec_looked_up_function( &mut self, - mir_body: Arc<MirBody>, - locals: &Locals, + mir_body: &'a MirBody, + locals: &Locals<'a>, def: FunctionId, arg_bytes: impl Iterator<Item = IntervalOrOwned>, span: MirSpan, destination: Interval, target_bb: Option<BasicBlockId>, - ) -> Result<'db, Option<StackFrame>> { + ) -> Result<'db, Option<StackFrame<'a>>> { Ok(if let Some(target_bb) = target_bb { let (mut locals, prev_stack_ptr) = - self.create_locals_for_body(&mir_body, Some(destination))?; - self.fill_locals_for_body(&mir_body, &mut locals, arg_bytes.into_iter())?; + self.create_locals_for_body(mir_body, Some(destination))?; + self.fill_locals_for_body(mir_body, &mut locals, arg_bytes.into_iter())?; let span = (span, locals.body.owner); Some(StackFrame { locals, destination: Some(target_bb), prev_stack_ptr, span }) } else { @@ -2885,11 +2895,11 @@ impl<'db> Evaluator<'db> { def: FunctionId, args: &[IntervalAndTy<'db>], generic_args: GenericArgs<'db>, - locals: &Locals, + locals: &Locals<'a>, destination: Interval, target_bb: Option<BasicBlockId>, span: MirSpan, - ) -> Result<'db, Option<StackFrame>> { + ) -> Result<'db, Option<StackFrame<'a>>> { let func = args .first() .ok_or_else(|| MirEvalError::InternalError("fn trait with no arg".into()))?; @@ -2954,7 +2964,7 @@ impl<'db> Evaluator<'db> { } } - fn eval_static(&mut self, st: StaticId, locals: &Locals) -> Result<'db, Address> { + fn eval_static(&mut self, st: StaticId, locals: &Locals<'a>) -> Result<'db, Address> { if let Some(o) = self.static_locations.get(&st) { return Ok(*o); }; @@ -3001,7 +3011,12 @@ impl<'db> Evaluator<'db> { } } - fn drop_place(&mut self, place: &Place, locals: &mut Locals, span: MirSpan) -> Result<'db, ()> { + fn drop_place( + &mut self, + place: &Place, + locals: &mut Locals<'a>, + span: MirSpan, + ) -> Result<'db, ()> { let (addr, ty, metadata) = self.place_addr_and_ty_and_metadata(place, locals)?; if !locals.drop_flags.remove_place(place, &locals.body.projection_store) { return Ok(()); @@ -3016,7 +3031,7 @@ impl<'db> Evaluator<'db> { fn run_drop_glue_deep( &mut self, ty: Ty<'db>, - locals: &Locals, + locals: &Locals<'a>, addr: Address, _metadata: &[u8], span: MirSpan, diff --git a/crates/hir-ty/src/mir/eval/shim.rs b/crates/hir-ty/src/mir/eval/shim.rs index 4154760f6e..a0978bd6e8 100644 --- a/crates/hir-ty/src/mir/eval/shim.rs +++ b/crates/hir-ty/src/mir/eval/shim.rs @@ -29,13 +29,13 @@ enum EvalLangItem { DropInPlace, } -impl<'db> Evaluator<'db> { +impl<'a, 'db: 'a> Evaluator<'a, 'db> { pub(super) fn detect_and_exec_special_function( &mut self, def: FunctionId, args: &[IntervalAndTy<'db>], generic_args: GenericArgs<'db>, - locals: &Locals, + locals: &Locals<'a>, destination: Interval, span: MirSpan, ) -> Result<'db, bool> { @@ -132,7 +132,7 @@ impl<'db> Evaluator<'db> { def: FunctionId, args: &[IntervalAndTy<'db>], self_ty: Ty<'db>, - locals: &Locals, + locals: &Locals<'a>, destination: Interval, span: MirSpan, ) -> Result<'db, ()> { @@ -190,7 +190,7 @@ impl<'db> Evaluator<'db> { layout: Arc<Layout>, addr: Address, def: FunctionId, - locals: &Locals, + locals: &Locals<'a>, destination: Interval, span: MirSpan, ) -> Result<'db, ()> { @@ -296,7 +296,7 @@ impl<'db> Evaluator<'db> { it: EvalLangItem, generic_args: GenericArgs<'db>, args: &[IntervalAndTy<'db>], - locals: &Locals, + locals: &Locals<'a>, span: MirSpan, ) -> Result<'db, Vec<u8>> { use EvalLangItem::*; @@ -368,7 +368,7 @@ impl<'db> Evaluator<'db> { id: i64, args: &[IntervalAndTy<'db>], destination: Interval, - _locals: &Locals, + _locals: &Locals<'a>, _span: MirSpan, ) -> Result<'db, ()> { match id { @@ -399,7 +399,7 @@ impl<'db> Evaluator<'db> { args: &[IntervalAndTy<'db>], _generic_args: GenericArgs<'db>, destination: Interval, - locals: &Locals, + locals: &Locals<'a>, span: MirSpan, ) -> Result<'db, ()> { match as_str { @@ -563,7 +563,7 @@ impl<'db> Evaluator<'db> { args: &[IntervalAndTy<'db>], generic_args: GenericArgs<'db>, destination: Interval, - locals: &Locals, + locals: &Locals<'a>, span: MirSpan, needs_override: bool, ) -> Result<'db, bool> { @@ -1345,7 +1345,7 @@ impl<'db> Evaluator<'db> { &mut self, ty: Ty<'db>, metadata: Interval, - locals: &Locals, + locals: &Locals<'a>, ) -> Result<'db, (usize, usize)> { Ok(match ty.kind() { TyKind::Str => (from_bytes!(usize, metadata.get(self)?), 1), @@ -1404,7 +1404,7 @@ impl<'db> Evaluator<'db> { args: &[IntervalAndTy<'db>], generic_args: GenericArgs<'db>, destination: Interval, - locals: &Locals, + locals: &Locals<'a>, _span: MirSpan, ) -> Result<'db, ()> { // We are a single threaded runtime with no UB checking and no optimization, so diff --git a/crates/hir-ty/src/mir/eval/shim/simd.rs b/crates/hir-ty/src/mir/eval/shim/simd.rs index 6e20562b4e..2458597ff4 100644 --- a/crates/hir-ty/src/mir/eval/shim/simd.rs +++ b/crates/hir-ty/src/mir/eval/shim/simd.rs @@ -6,7 +6,7 @@ use crate::consteval::try_const_usize; use super::*; -impl<'db> Evaluator<'db> { +impl<'a, 'db: 'a> Evaluator<'a, 'db> { fn detect_simd_ty(&self, ty: Ty<'db>) -> Result<'db, (usize, Ty<'db>)> { match ty.kind() { TyKind::Adt(adt_def, subst) => { @@ -53,7 +53,7 @@ impl<'db> Evaluator<'db> { args: &[IntervalAndTy<'db>], _generic_args: GenericArgs<'db>, destination: Interval, - _locals: &Locals, + _locals: &Locals<'a>, _span: MirSpan, ) -> Result<'db, ()> { match name { diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs index 9c9cf0ac0b..b2a7eaa674 100644 --- a/crates/hir-ty/src/mir/lower.rs +++ b/crates/hir-ty/src/mir/lower.rs @@ -25,7 +25,6 @@ use rustc_hash::FxHashMap; use rustc_type_ir::inherent::{Const as _, GenericArgs as _, IntoKind, Ty as _}; use span::{Edition, FileId}; use syntax::TextRange; -use triomphe::Arc; use crate::{ Adjust, Adjustment, AutoBorrow, CallableDefId, ParamEnvAndCrate, @@ -2137,10 +2136,11 @@ fn cast_kind<'db>( }) } +#[salsa_macros::tracked(returns(ref), cycle_result = mir_body_for_closure_cycle_result)] pub fn mir_body_for_closure_query<'db>( db: &'db dyn HirDatabase, closure: InternedClosureId, -) -> Result<'db, Arc<MirBody>> { +) -> Result<'db, MirBody> { let InternedClosure { owner, expr, .. } = closure.loc(db); let body_owner = owner.as_def_with_body().expect("MIR lowering should only happen for body-owned closures"); @@ -2293,13 +2293,11 @@ pub fn mir_body_for_closure_query<'db>( return Err(MirLowerError::UnresolvedUpvar(err)); } ctx.result.shrink_to_fit(); - Ok(Arc::new(ctx.result)) + Ok(ctx.result) } -pub fn mir_body_query<'db>( - db: &'db dyn HirDatabase, - def: DefWithBodyId, -) -> Result<'db, Arc<MirBody>> { +#[salsa_macros::tracked(returns(ref), cycle_result = mir_body_cycle_result)] +pub fn mir_body_query<'db>(db: &'db dyn HirDatabase, def: DefWithBodyId) -> Result<'db, MirBody> { let krate = def.krate(db); let edition = krate.data(db).edition; let detail = match def { @@ -2328,14 +2326,22 @@ pub fn mir_body_query<'db>( let infer = InferenceResult::of(db, def); let mut result = lower_body_to_mir(db, def, body, infer, body.root_expr())?; result.shrink_to_fit(); - Ok(Arc::new(result)) + Ok(result) } -pub(crate) fn mir_body_cycle_result<'db>( +fn mir_body_cycle_result<'db>( _db: &'db dyn HirDatabase, _: salsa::Id, _def: DefWithBodyId, -) -> Result<'db, Arc<MirBody>> { +) -> Result<'db, MirBody> { + Err(MirLowerError::Loop) +} + +fn mir_body_for_closure_cycle_result<'db>( + _db: &'db dyn HirDatabase, + _: salsa::Id, + _def: InternedClosureId, +) -> Result<'db, MirBody> { Err(MirLowerError::Loop) } diff --git a/crates/hir-ty/src/mir/monomorphization.rs b/crates/hir-ty/src/mir/monomorphization.rs index dfce8ca2a5..b3529437c0 100644 --- a/crates/hir-ty/src/mir/monomorphization.rs +++ b/crates/hir-ty/src/mir/monomorphization.rs @@ -12,7 +12,6 @@ use rustc_type_ir::inherent::IntoKind; use rustc_type_ir::{ FallibleTypeFolder, TypeFlags, TypeFoldable, TypeSuperFoldable, TypeVisitableExt, }; -use triomphe::Arc; use crate::{ ParamEnvAndCrate, @@ -240,38 +239,50 @@ impl<'db> Filler<'db> { } } +#[salsa_macros::tracked(returns(ref), cycle_result = monomorphized_mir_body_cycle_result)] pub fn monomorphized_mir_body_query( db: &dyn HirDatabase, owner: DefWithBodyId, subst: StoredGenericArgs, trait_env: StoredParamEnvAndCrate, -) -> Result<Arc<MirBody>, MirLowerError> { +) -> Result<MirBody, MirLowerError> { let mut filler = Filler::new(db, trait_env.as_ref(), subst.as_ref()); let body = db.mir_body(owner)?; let mut body = (*body).clone(); filler.fill_body(&mut body)?; - Ok(Arc::new(body)) + Ok(body) } -pub(crate) fn monomorphized_mir_body_cycle_result( +fn monomorphized_mir_body_cycle_result( _db: &dyn HirDatabase, _: salsa::Id, _: DefWithBodyId, _: StoredGenericArgs, _: StoredParamEnvAndCrate, -) -> Result<Arc<MirBody>, MirLowerError> { +) -> Result<MirBody, MirLowerError> { Err(MirLowerError::Loop) } +#[salsa_macros::tracked(returns(ref), cycle_result = monomorphized_mir_body_for_closure_cycle_result)] pub fn monomorphized_mir_body_for_closure_query( db: &dyn HirDatabase, closure: InternedClosureId, subst: StoredGenericArgs, trait_env: StoredParamEnvAndCrate, -) -> Result<Arc<MirBody>, MirLowerError> { +) -> Result<MirBody, MirLowerError> { let mut filler = Filler::new(db, trait_env.as_ref(), subst.as_ref()); let body = db.mir_body_for_closure(closure)?; let mut body = (*body).clone(); filler.fill_body(&mut body)?; - Ok(Arc::new(body)) + Ok(body) +} + +fn monomorphized_mir_body_for_closure_cycle_result( + _db: &dyn HirDatabase, + _: salsa::Id, + _: InternedClosureId, + _: StoredGenericArgs, + _: StoredParamEnvAndCrate, +) -> Result<MirBody, MirLowerError> { + Err(MirLowerError::Loop) } diff --git a/crates/hir-ty/src/mir/pretty.rs b/crates/hir-ty/src/mir/pretty.rs index de5ee223a1..c224f2054f 100644 --- a/crates/hir-ty/src/mir/pretty.rs +++ b/crates/hir-ty/src/mir/pretty.rs @@ -160,7 +160,7 @@ impl<'a, 'db> MirPrettyCtx<'a, 'db> { let result = mem::take(&mut self.result); let indent = mem::take(&mut self.indent); let mut ctx = MirPrettyCtx { - body: &body, + body, local_to_binding: body.local_to_binding_map(), result, indent, diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 6f5508691e..b74f594ebe 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -1120,7 +1120,7 @@ fn macro_call_diagnostics<'db>( let Some(e) = db.parse_macro_expansion_error(macro_call_id) else { return; }; - let ValueResult { value: parse_errors, err } = &*e; + let ValueResult { value: parse_errors, err } = e; if let Some(err) = err { let loc = db.lookup_intern_macro_call(macro_call_id); let file_id = loc.kind.file_id(); @@ -1436,7 +1436,7 @@ impl Field { Type::new(db, var_id, ty) } - pub fn layout(&self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> { + pub fn layout<'db>(&self, db: &'db dyn HirDatabase) -> Result<Layout<'db>, LayoutError> { db.layout_of_ty( self.ty(db).ty.store(), param_env_from_has_crate( @@ -1696,7 +1696,7 @@ impl Enum { self.variants(db).iter().any(|v| !matches!(v.kind(db), StructKind::Unit)) } - pub fn layout(self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> { + pub fn layout<'db>(self, db: &'db dyn HirDatabase) -> Result<Layout<'db>, LayoutError> { Adt::from(self).layout(db) } @@ -1783,7 +1783,7 @@ impl EnumVariant { db.const_eval_discriminant(self.into()) } - pub fn layout(&self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> { + pub fn layout<'db>(&self, db: &'db dyn HirDatabase) -> Result<Layout<'db>, LayoutError> { let parent_enum = self.parent_enum(db); let parent_layout = parent_enum.layout(db)?; Ok(match &parent_layout.0.variants { @@ -1866,7 +1866,7 @@ impl Adt { has_non_default_type_params(db, self.into()) } - pub fn layout(self, db: &dyn HirDatabase) -> Result<Layout, LayoutError> { + pub fn layout<'db>(self, db: &'db dyn HirDatabase) -> Result<Layout<'db>, LayoutError> { let interner = DbInterner::new_no_crate(db); let adt_id = AdtId::from(self); let args = GenericArgs::for_item_with_defaults(interner, adt_id.into(), |_, id, _| { @@ -2211,7 +2211,7 @@ impl DefWithBody { if let Ok(borrowck_results) = db.borrowck(id) { for borrowck_result in borrowck_results.iter() { - let mir_body = &borrowck_result.mir_body; + let mir_body = borrowck_result.mir_body(db); for moof in &borrowck_result.moved_out_of_ref { let span: InFile<SyntaxNodePtr> = match moof.span { mir::MirSpan::ExprId(e) => match source_map.expr_syntax(e) { @@ -6530,7 +6530,7 @@ impl<'db> Type<'db> { .collect() } - pub fn layout(&self, db: &'db dyn HirDatabase) -> Result<Layout, LayoutError> { + pub fn layout(&self, db: &'db dyn HirDatabase) -> Result<Layout<'db>, LayoutError> { db.layout_of_ty(self.ty.store(), self.env.store()) .map(|layout| Layout(layout, db.target_data_layout(self.env.krate).unwrap())) } @@ -6702,9 +6702,9 @@ impl<'db> Callable<'db> { } #[derive(Clone, Debug, Eq, PartialEq)] -pub struct Layout(Arc<TyLayout>, Arc<TargetDataLayout>); +pub struct Layout<'db>(Arc<TyLayout>, &'db TargetDataLayout); -impl Layout { +impl<'db> Layout<'db> { pub fn size(&self) -> u64 { self.0.size.bytes() } @@ -6714,7 +6714,7 @@ impl Layout { } pub fn niches(&self) -> Option<u128> { - Some(self.0.largest_niche?.available(&*self.1)) + Some(self.0.largest_niche?.available(self.1)) } pub fn field_offset(&self, field: Field) -> Option<u64> { @@ -6803,7 +6803,7 @@ impl Layout { let tag_size = if let layout::Variants::Multiple { tag, tag_encoding, .. } = &self.0.variants { match tag_encoding { - TagEncoding::Direct => tag.size(&*self.1).bytes_usize(), + TagEncoding::Direct => tag.size(self.1).bytes_usize(), TagEncoding::Niche { .. } => 0, } } else { diff --git a/crates/hir/src/term_search/tactics.rs b/crates/hir/src/term_search/tactics.rs index b11f7a1723..99ad1e0739 100644 --- a/crates/hir/src/term_search/tactics.rs +++ b/crates/hir/src/term_search/tactics.rs @@ -56,11 +56,12 @@ pub(super) fn trivial<'a, 'lt, 'db, DB: HirDatabase>( let borrowck = db.borrowck(it.parent.as_def_with_body()?).ok()?; let invalid = borrowck.iter().any(|b| { + let mir_body = b.mir_body(ctx.sema.db); b.partially_moved.iter().any(|moved| { - Some(&moved.local) == b.mir_body.binding_locals.get(it.binding_id) + Some(&moved.local) == mir_body.binding_locals.get(it.binding_id) }) || b.borrow_regions.iter().any(|region| { // Shared borrows are fine - Some(®ion.local) == b.mir_body.binding_locals.get(it.binding_id) + Some(®ion.local) == mir_body.binding_locals.get(it.binding_id) && region.kind != BorrowKind::Shared }) }); diff --git a/crates/ide/src/hover/render.rs b/crates/ide/src/hover/render.rs index 4f60321e32..e08bbc5c21 100644 --- a/crates/ide/src/hover/render.rs +++ b/crates/ide/src/hover/render.rs @@ -1136,12 +1136,12 @@ fn markup( } } -fn render_memory_layout( +fn render_memory_layout<'db>( config: Option<MemoryLayoutHoverConfig>, - layout: impl FnOnce() -> Result<Layout, LayoutError>, - offset: impl FnOnce(&Layout) -> Option<u64>, - padding: impl FnOnce(&Layout) -> Option<(&str, u64)>, - tag: impl FnOnce(&Layout) -> Option<usize>, + layout: impl FnOnce() -> Result<Layout<'db>, LayoutError>, + offset: impl FnOnce(&Layout<'db>) -> Option<u64>, + padding: impl for<'a> FnOnce(&'a Layout<'db>) -> Option<(&'a str, u64)>, + tag: impl FnOnce(&Layout<'db>) -> Option<usize>, ) -> Option<String> { let config = config?; let layout = layout().ok()?; diff --git a/crates/ide/src/view_memory_layout.rs b/crates/ide/src/view_memory_layout.rs index 47ca616f31..1b9df9722b 100644 --- a/crates/ide/src/view_memory_layout.rs +++ b/crates/ide/src/view_memory_layout.rs @@ -108,7 +108,7 @@ pub(crate) fn view_memory_layout( nodes: &mut Vec<MemoryLayoutNode>, db: &RootDatabase, ty: &Type<'_>, - layout: &Layout, + layout: &Layout<'_>, parent_idx: usize, display_target: DisplayTarget, ) { |