Skip to content

Commit 3fc043c

Browse files
committed
internal: Remove unnecessary Arc allocations in macro_expand
1 parent 426d284 commit 3fc043c

File tree

6 files changed

+40
-19
lines changed

6 files changed

+40
-19
lines changed

crates/hir-expand/src/db.rs

+33-15
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,13 @@ fn parse_macro_expansion(
390390
let expand_to = loc.expand_to();
391391
let mbe::ValueResult { value: tt, err } = macro_expand(db, macro_file.macro_call_id, loc);
392392

393-
let (parse, rev_token_map) = token_tree_to_syntax_node(&tt, expand_to);
393+
let (parse, rev_token_map) = token_tree_to_syntax_node(
394+
match &tt {
395+
CowArc::Arc(it) => it,
396+
CowArc::Owned(it) => it,
397+
},
398+
expand_to,
399+
);
394400

395401
ExpandResult { value: (parse, Arc::new(rev_token_map)), err }
396402
}
@@ -669,15 +675,20 @@ fn macro_expander(db: &dyn ExpandDatabase, id: MacroDefId) -> TokenExpander {
669675
}
670676
}
671677

678+
enum CowArc<T> {
679+
Arc(Arc<T>),
680+
Owned(T),
681+
}
682+
672683
fn macro_expand(
673684
db: &dyn ExpandDatabase,
674685
macro_call_id: MacroCallId,
675686
loc: MacroCallLoc,
676-
) -> ExpandResult<Arc<tt::Subtree>> {
687+
) -> ExpandResult<CowArc<tt::Subtree>> {
677688
let _p = profile::span("macro_expand");
678689

679690
let ExpandResult { value: tt, mut err } = match loc.def.kind {
680-
MacroDefKind::ProcMacro(..) => return db.expand_proc_macro(macro_call_id),
691+
MacroDefKind::ProcMacro(..) => return db.expand_proc_macro(macro_call_id).map(CowArc::Arc),
681692
MacroDefKind::BuiltInDerive(expander, ..) => {
682693
let (root, map) = parse_with_map(db, loc.kind.file_id());
683694
let root = root.syntax_node();
@@ -692,7 +703,7 @@ fn macro_expand(
692703
let ValueResult { value, err } = db.macro_arg(macro_call_id);
693704
let Some((macro_arg, undo_info)) = value else {
694705
return ExpandResult {
695-
value: Arc::new(tt::Subtree {
706+
value: CowArc::Owned(tt::Subtree {
696707
delimiter: tt::Delimiter::invisible_spanned(loc.call_site),
697708
token_trees: Vec::new(),
698709
}),
@@ -718,7 +729,7 @@ fn macro_expand(
718729
// As such we just return the input subtree here.
719730
MacroDefKind::BuiltInEager(..) if loc.eager.is_none() => {
720731
return ExpandResult {
721-
value: macro_arg.clone(),
732+
value: CowArc::Arc(macro_arg.clone()),
722733
err: err.map(|err| {
723734
let mut buf = String::new();
724735
for err in &**err {
@@ -752,12 +763,17 @@ fn macro_expand(
752763
// Skip checking token tree limit for include! macro call
753764
if !loc.def.is_include() {
754765
// Set a hard limit for the expanded tt
755-
if let Err(value) = check_tt_count(&tt, loc.call_site) {
756-
return value;
766+
if let Err(value) = check_tt_count(&tt) {
767+
return value.map(|()| {
768+
CowArc::Owned(tt::Subtree {
769+
delimiter: tt::Delimiter::invisible_spanned(loc.call_site),
770+
token_trees: vec![],
771+
})
772+
});
757773
}
758774
}
759775

760-
ExpandResult { value: Arc::new(tt), err }
776+
ExpandResult { value: CowArc::Owned(tt), err }
761777
}
762778

763779
fn expand_proc_macro(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult<Arc<tt::Subtree>> {
@@ -796,8 +812,13 @@ fn expand_proc_macro(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult<A
796812
);
797813

798814
// Set a hard limit for the expanded tt
799-
if let Err(value) = check_tt_count(&tt, loc.call_site) {
800-
return value;
815+
if let Err(value) = check_tt_count(&tt) {
816+
return value.map(|()| {
817+
Arc::new(tt::Subtree {
818+
delimiter: tt::Delimiter::invisible_spanned(loc.call_site),
819+
token_trees: vec![],
820+
})
821+
});
801822
}
802823

803824
fixup::reverse_fixups(&mut tt, &undo_info);
@@ -819,14 +840,11 @@ fn token_tree_to_syntax_node(
819840
mbe::token_tree_to_syntax_node(tt, entry_point)
820841
}
821842

822-
fn check_tt_count(tt: &tt::Subtree, call_site: Span) -> Result<(), ExpandResult<Arc<tt::Subtree>>> {
843+
fn check_tt_count(tt: &tt::Subtree) -> Result<(), ExpandResult<()>> {
823844
let count = tt.count();
824845
if TOKEN_LIMIT.check(count).is_err() {
825846
Err(ExpandResult {
826-
value: Arc::new(tt::Subtree {
827-
delimiter: tt::Delimiter::invisible_spanned(call_site),
828-
token_trees: vec![],
829-
}),
847+
value: (),
830848
err: Some(ExpandError::other(format!(
831849
"macro invocation exceeds token limit: produced {} tokens, limit is {}",
832850
count,

editors/code/src/config.ts

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import * as vscode from "vscode";
55
import type { Env } from "./client";
66
import { log } from "./util";
77
import { expectNotUndefined, unwrapUndefinable } from "./undefinable";
8+
import type { JsonProject } from "./rust_project";
89

910
export type RunnableEnvCfgItem = {
1011
mask?: string;

editors/code/src/ctx.ts

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { execRevealDependency } from "./commands";
2323
import { PersistentState } from "./persistent_state";
2424
import { bootstrap } from "./bootstrap";
2525
import type { RustAnalyzerExtensionApi } from "./main";
26+
import type { JsonProject } from "./rust_project";
2627

2728
// We only support local folders, not eg. Live Share (`vlsl:` scheme), so don't activate if
2829
// only those are in use. We use "Empty" to represent these scenarios

editors/code/src/main.ts

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { type CommandFactory, Ctx, fetchWorkspace } from "./ctx";
66
import * as diagnostics from "./diagnostics";
77
import { activateTaskProvider } from "./tasks";
88
import { setContextValue } from "./util";
9+
import type { JsonProject } from "./rust_project";
910

1011
const RUST_PROJECT_CONTEXT_NAME = "inRustProject";
1112

editors/code/src/rust_project.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
interface JsonProject {
1+
export interface JsonProject {
22
/// Path to the directory with *source code* of
33
/// sysroot crates.
44
///
@@ -21,7 +21,7 @@ interface JsonProject {
2121
crates: Crate[];
2222
}
2323

24-
interface Crate {
24+
export interface Crate {
2525
/// Optional crate name used for display purposes,
2626
/// without affecting semantics. See the `deps`
2727
/// key for semantically-significant crate names.
@@ -82,7 +82,7 @@ interface Crate {
8282
proc_macro_dylib_path?: string;
8383
}
8484

85-
interface Dep {
85+
export interface Dep {
8686
/// Index of a crate in the `crates` array.
8787
crate: number;
8888
/// Name as should appear in the (implicit)

editors/code/tsconfig.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"extends": "@tsconfig/strictest/tsconfig.json",
33
"compilerOptions": {
44
"esModuleInterop": false,
5-
"module": "CommonJS",
5+
"module": "Node16",
66
"moduleResolution": "Node16",
77
"target": "ES2021",
88
"outDir": "out",

0 commit comments

Comments
 (0)