From 5b83c9899c1fb7f8e045a1a70295fd39fa78bde9 Mon Sep 17 00:00:00 2001 From: Austin Seipp Date: Wed, 3 Sep 2025 13:49:20 -0500 Subject: [PATCH] cli, lib: convert revset expressions to use Arc over Rc We want these to be `Send` and `Sync` so we can send them between threads in our multi-threaded backend. This requires a bunch of subsequent (but obvious) changes throughout cli and the tests. Co-authored-by: Benjamin Brittain Signed-off-by: Austin Seipp Signed-off-by: Austin Seipp --- cli/examples/custom-commit-templater/main.rs | 6 +- cli/src/cli_util.rs | 20 +- cli/src/commands/bench/revset.rs | 4 +- cli/src/commit_templater.rs | 7 +- cli/src/movement_util.rs | 8 +- cli/src/revset_util.rs | 13 +- lib/src/absorb.rs | 4 +- lib/src/annotate.rs | 6 +- lib/src/bisect.rs | 6 +- lib/src/id_prefix.rs | 9 +- lib/src/revset.rs | 443 +++++++++---------- lib/tests/test_annotate.rs | 4 +- lib/tests/test_bisect.rs | 4 +- lib/tests/test_revset_optimized.rs | 8 +- 14 files changed, 270 insertions(+), 272 deletions(-) diff --git a/cli/examples/custom-commit-templater/main.rs b/cli/examples/custom-commit-templater/main.rs index 883f0cba6..a37ee3f24 100644 --- a/cli/examples/custom-commit-templater/main.rs +++ b/cli/examples/custom-commit-templater/main.rs @@ -13,7 +13,7 @@ // limitations under the License. use std::any::Any; -use std::rc::Rc; +use std::sync::Arc; use jj_cli::cli_util::CliRunner; use jj_cli::commit_templater::CommitTemplateBuildFnTable; @@ -187,10 +187,10 @@ fn even_digits( _diagnostics: &mut RevsetDiagnostics, function: &FunctionCallNode, _context: &LoweringContext, -) -> Result, RevsetParseError> { +) -> Result, RevsetParseError> { function.expect_no_arguments()?; Ok(RevsetExpression::filter(RevsetFilterPredicate::Extension( - Rc::new(EvenDigitsFilter), + Arc::new(EvenDigitsFilter), ))) } diff --git a/cli/src/cli_util.rs b/cli/src/cli_util.rs index c1b2d0a34..a5c9a7538 100644 --- a/cli/src/cli_util.rs +++ b/cli/src/cli_util.rs @@ -782,8 +782,8 @@ pub struct WorkspaceCommandEnvironment { template_aliases_map: TemplateAliasesMap, path_converter: RepoPathUiConverter, workspace_name: WorkspaceNameBuf, - immutable_heads_expression: Rc, - short_prefixes_expression: Option>, + immutable_heads_expression: Arc, + short_prefixes_expression: Option>, conflict_marker_style: ConflictMarkerStyle, } @@ -854,14 +854,14 @@ impl WorkspaceCommandEnvironment { } /// User-configured expression defining the immutable set. - pub fn immutable_expression(&self) -> Rc { + pub fn immutable_expression(&self) -> Arc { // Negated ancestors expression `~::( | root())` is slightly // easier to optimize than negated union `~(:: | root())`. self.immutable_heads_expression.ancestors() } /// User-configured expression defining the heads of the immutable set. - pub fn immutable_heads_expression(&self) -> &Rc { + pub fn immutable_heads_expression(&self) -> &Arc { &self.immutable_heads_expression } @@ -873,7 +873,7 @@ impl WorkspaceCommandEnvironment { fn load_immutable_heads_expression( &self, ui: &Ui, - ) -> Result, CommandError> { + ) -> Result, CommandError> { let mut diagnostics = RevsetDiagnostics::new(); let expression = revset_util::parse_immutable_heads_expression( &mut diagnostics, @@ -887,7 +887,7 @@ impl WorkspaceCommandEnvironment { fn load_short_prefixes_expression( &self, ui: &Ui, - ) -> Result>, CommandError> { + ) -> Result>, CommandError> { let revset_string = self .settings .get_string("revsets.short-prefixes") @@ -1641,7 +1641,7 @@ to the current parents may contain changes from multiple commits. pub fn attach_revset_evaluator( &self, - expression: Rc, + expression: Arc, ) -> RevsetExpressionEvaluator<'_> { RevsetExpressionEvaluator::new( self.repo().as_ref(), @@ -2168,7 +2168,7 @@ See https://jj-vcs.github.io/jj/latest/working-copy/#stale-working-copy \ let added_conflicts_expr = old_heads.range(&new_heads).intersection(&conflicts); let get_commits = - |expr: Rc| -> Result, CommandError> { + |expr: Arc| -> Result, CommandError> { let commits = expr .evaluate(new_repo)? .iter() @@ -3113,8 +3113,8 @@ pub fn compute_commit_location( /// parents of the given commits. fn ensure_no_commit_loop( repo: &ReadonlyRepo, - children_expression: &Rc, - parents_expression: &Rc, + children_expression: &Arc, + parents_expression: &Arc, commit_type: &str, ) -> Result<(), CommandError> { if let Some(commit_id) = children_expression diff --git a/cli/src/commands/bench/revset.rs b/cli/src/commands/bench/revset.rs index b544e8abc..f03170ef1 100644 --- a/cli/src/commands/bench/revset.rs +++ b/cli/src/commands/bench/revset.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::rc::Rc; +use std::sync::Arc; use std::time::Instant; use criterion::BatchSize; @@ -85,7 +85,7 @@ fn bench_revset( .clone(); // Time both evaluation and iteration. let routine = |workspace_command: &WorkspaceCommandHelper, - expression: Rc| { + expression: Arc| { // Evaluate the expression without parsing/evaluating short-prefixes. let repo = workspace_command.repo().as_ref(); let symbol_resolver = diff --git a/cli/src/commit_templater.rs b/cli/src/commit_templater.rs index 78395ff01..3c960fecd 100644 --- a/cli/src/commit_templater.rs +++ b/cli/src/commit_templater.rs @@ -22,6 +22,7 @@ use std::fmt; use std::fmt::Display; use std::io; use std::rc::Rc; +use std::sync::Arc; use bstr::BString; use futures::StreamExt as _; @@ -130,7 +131,7 @@ pub struct CommitTemplateLanguage<'repo> { // WorkspaceName are contained in RevsetParseContext for example. revset_parse_context: RevsetParseContext<'repo>, id_prefix_context: &'repo IdPrefixContext, - immutable_expression: Rc, + immutable_expression: Arc, conflict_marker_style: ConflictMarkerStyle, build_fn_table: CommitTemplateBuildFnTable<'repo>, keyword_cache: CommitKeywordCache<'repo>, @@ -147,7 +148,7 @@ impl<'repo> CommitTemplateLanguage<'repo> { workspace_name: &WorkspaceName, revset_parse_context: RevsetParseContext<'repo>, id_prefix_context: &'repo IdPrefixContext, - immutable_expression: Rc, + immutable_expression: Arc, conflict_marker_style: ConflictMarkerStyle, extensions: &[impl AsRef], ) -> Self { @@ -2688,7 +2689,7 @@ mod tests { id_prefix_context: IdPrefixContext, revset_aliases_map: RevsetAliasesMap, template_aliases_map: TemplateAliasesMap, - immutable_expression: Rc, + immutable_expression: Arc, extra_functions: HashMap<&'static str, BuildFunctionFn>, } diff --git a/cli/src/movement_util.rs b/cli/src/movement_util.rs index 02276062c..a56937fd5 100644 --- a/cli/src/movement_util.rs +++ b/cli/src/movement_util.rs @@ -13,7 +13,7 @@ // limitations under the License. use std::io::Write as _; -use std::rc::Rc; +use std::sync::Arc; use itertools::Itertools as _; use jj_lib::backend::CommitId; @@ -118,10 +118,10 @@ impl Direction { fn build_target_revset( &self, - working_revset: &Rc, - start_revset: &Rc, + working_revset: &Arc, + start_revset: &Arc, args: &MovementArgsInternal, - ) -> Result, CommandError> { + ) -> Result, CommandError> { let nth = match (self, args.should_edit) { (Self::Next, true) => start_revset.descendants_at(args.offset), (Self::Next, false) => start_revset diff --git a/cli/src/revset_util.rs b/cli/src/revset_util.rs index 6dcd84807..a891a3c52 100644 --- a/cli/src/revset_util.rs +++ b/cli/src/revset_util.rs @@ -15,7 +15,6 @@ //! Utility for parsing and evaluating user-provided revset expressions. use std::io; -use std::rc::Rc; use std::sync::Arc; use itertools::Itertools as _; @@ -66,7 +65,7 @@ pub struct RevsetExpressionEvaluator<'repo> { repo: &'repo dyn Repo, extensions: Arc, id_prefix_context: &'repo IdPrefixContext, - expression: Rc, + expression: Arc, } impl<'repo> RevsetExpressionEvaluator<'repo> { @@ -74,7 +73,7 @@ impl<'repo> RevsetExpressionEvaluator<'repo> { repo: &'repo dyn Repo, extensions: Arc, id_prefix_context: &'repo IdPrefixContext, - expression: Rc, + expression: Arc, ) -> Self { Self { repo, @@ -85,17 +84,17 @@ impl<'repo> RevsetExpressionEvaluator<'repo> { } /// Returns the underlying expression. - pub fn expression(&self) -> &Rc { + pub fn expression(&self) -> &Arc { &self.expression } /// Intersects the underlying expression with the `other` expression. - pub fn intersect_with(&mut self, other: &Rc) { + pub fn intersect_with(&mut self, other: &Arc) { self.expression = self.expression.intersection(other); } /// Resolves user symbols in the expression, returns new expression. - pub fn resolve(&self) -> Result, RevsetResolutionError> { + pub fn resolve(&self) -> Result, RevsetResolutionError> { let symbol_resolver = default_symbol_resolver( self.repo, self.extensions.symbol_resolvers(), @@ -218,7 +217,7 @@ pub fn default_symbol_resolver<'a>( pub fn parse_immutable_heads_expression( diagnostics: &mut RevsetDiagnostics, context: &RevsetParseContext, -) -> Result, RevsetParseError> { +) -> Result, RevsetParseError> { let (_, _, immutable_heads_str) = context .aliases_map .get_function(USER_IMMUTABLE_HEADS, 0) diff --git a/lib/src/absorb.rs b/lib/src/absorb.rs index 458cdc8e1..8d2b21e5a 100644 --- a/lib/src/absorb.rs +++ b/lib/src/absorb.rs @@ -18,7 +18,7 @@ use std::cmp; use std::collections::HashMap; use std::ops::Range; -use std::rc::Rc; +use std::sync::Arc; use bstr::BString; use futures::StreamExt as _; @@ -92,7 +92,7 @@ pub struct SelectedTrees { pub async fn split_hunks_to_trees( repo: &dyn Repo, source: &AbsorbSource, - destinations: &Rc, + destinations: &Arc, matcher: &dyn Matcher, ) -> Result { let mut selected_trees = SelectedTrees::default(); diff --git a/lib/src/annotate.rs b/lib/src/annotate.rs index 3d22fbdfb..c33376394 100644 --- a/lib/src/annotate.rs +++ b/lib/src/annotate.rs @@ -22,7 +22,7 @@ use std::collections::HashMap; use std::collections::hash_map; use std::iter; use std::ops::Range; -use std::rc::Rc; +use std::sync::Arc; use bstr::BStr; use bstr::BString; @@ -212,7 +212,7 @@ impl FileAnnotator { pub fn compute( &mut self, repo: &dyn Repo, - domain: &Rc, + domain: &Arc, ) -> Result<(), RevsetEvaluationError> { process_commits(repo, &mut self.state, domain, &self.file_path) } @@ -292,7 +292,7 @@ pub struct LineOrigin { fn process_commits( repo: &dyn Repo, state: &mut AnnotationState, - domain: &Rc, + domain: &Arc, file_name: &RepoPath, ) -> Result<(), RevsetEvaluationError> { let predicate = RevsetFilterPredicate::File(FilesetExpression::file_path(file_name.to_owned())); diff --git a/lib/src/bisect.rs b/lib/src/bisect.rs index 35350e7e9..3eac3ffe4 100644 --- a/lib/src/bisect.rs +++ b/lib/src/bisect.rs @@ -15,7 +15,7 @@ //! Bisect a range of commits. use std::collections::HashSet; -use std::rc::Rc; +use std::sync::Arc; use itertools::Itertools as _; use thiserror::Error; @@ -51,7 +51,7 @@ pub enum Evaluation { /// Performs bisection to find the first bad commit in a range. pub struct Bisector<'repo> { repo: &'repo dyn Repo, - input_range: Rc, + input_range: Arc, good_commits: HashSet, bad_commits: HashSet, skipped_commits: HashSet, @@ -82,7 +82,7 @@ impl<'repo> Bisector<'repo> { /// Parents of the range's roots are assumed to be good. pub fn new( repo: &'repo dyn Repo, - input_range: Rc, + input_range: Arc, ) -> Result { let bad_commits = input_range.heads().evaluate(repo)?.iter().try_collect()?; Ok(Self { diff --git a/lib/src/id_prefix.rs b/lib/src/id_prefix.rs index e30a82c8f..f0f99732e 100644 --- a/lib/src/id_prefix.rs +++ b/lib/src/id_prefix.rs @@ -16,11 +16,10 @@ use std::iter; use std::marker::PhantomData; -use std::rc::Rc; use std::sync::Arc; use itertools::Itertools as _; -use once_cell::unsync::OnceCell; +use once_cell::sync::OnceCell; use thiserror::Error; use crate::backend::ChangeId; @@ -47,7 +46,7 @@ pub enum IdPrefixIndexLoadError { } struct DisambiguationData { - expression: Rc, + expression: Arc, indexes: OnceCell, } @@ -61,7 +60,7 @@ impl DisambiguationData { fn indexes( &self, repo: &dyn Repo, - extensions: &[impl AsRef], + extensions: &[Box], ) -> Result<&Indexes, IdPrefixIndexLoadError> { self.indexes.get_or_try_init(|| { let symbol_resolver = SymbolResolver::new(repo, extensions); @@ -124,7 +123,7 @@ impl IdPrefixContext { } } - pub fn disambiguate_within(mut self, expression: Rc) -> Self { + pub fn disambiguate_within(mut self, expression: Arc) -> Self { self.disambiguation = Some(DisambiguationData { expression, indexes: OnceCell::new(), diff --git a/lib/src/revset.rs b/lib/src/revset.rs index 06a192689..1b40241c1 100644 --- a/lib/src/revset.rs +++ b/lib/src/revset.rs @@ -21,7 +21,6 @@ use std::convert::Infallible; use std::fmt; use std::ops::ControlFlow; use std::ops::Range; -use std::rc::Rc; use std::sync::Arc; use std::sync::LazyLock; @@ -162,7 +161,7 @@ pub enum RevsetCommitRef { } /// A custom revset filter expression, defined by an extension. -pub trait RevsetFilterExtension: std::fmt::Debug + Any { +pub trait RevsetFilterExtension: std::fmt::Debug + Any + Send + Sync { fn as_any(&self) -> &dyn Any; /// Returns true iff this filter matches the specified commit. @@ -201,7 +200,7 @@ pub enum RevsetFilterPredicate { /// Commits that are cryptographically signed. Signed, /// Custom predicates provided by extensions - Extension(Rc), + Extension(Arc), } mod private { @@ -253,217 +252,217 @@ pub enum RevsetExpression { Commits(Vec), CommitRef(St::CommitRef), Ancestors { - heads: Rc, + heads: Arc, generation: Range, parents_range: Range, }, Descendants { - roots: Rc, + roots: Arc, generation: Range, }, // Commits that are ancestors of "heads" but not ancestors of "roots" Range { - roots: Rc, - heads: Rc, + roots: Arc, + heads: Arc, generation: Range, // Parents range is only used for traversing heads, not roots parents_range: Range, }, // Commits that are descendants of "roots" and ancestors of "heads" DagRange { - roots: Rc, - heads: Rc, + roots: Arc, + heads: Arc, // TODO: maybe add generation_from_roots/heads? }, // Commits reachable from "sources" within "domain" Reachable { - sources: Rc, - domain: Rc, + sources: Arc, + domain: Arc, }, - Heads(Rc), + Heads(Arc), /// Heads of the set of commits which are ancestors of `heads` but are not /// ancestors of `roots`, and which also are contained in `filter`. HeadsRange { - roots: Rc, - heads: Rc, + roots: Arc, + heads: Arc, parents_range: Range, - filter: Rc, + filter: Arc, }, - Roots(Rc), - ForkPoint(Rc), - Bisect(Rc), + Roots(Arc), + ForkPoint(Arc), + Bisect(Arc), Latest { - candidates: Rc, + candidates: Arc, count: usize, }, Filter(RevsetFilterPredicate), /// Marker for subtree that should be intersected as filter. - AsFilter(Rc), + AsFilter(Arc), /// Resolves symbols and visibility at the specified operation. AtOperation { operation: St::Operation, - candidates: Rc, + candidates: Arc, }, /// Makes `All` include the commits and their ancestors in addition to the /// visible heads. WithinReference { - candidates: Rc, + candidates: Arc, /// Commits explicitly referenced within the scope. commits: Vec, }, /// Resolves visibility within the specified repo state. WithinVisibility { - candidates: Rc, + candidates: Arc, /// Copy of `repo.view().heads()` at the operation. visible_heads: Vec, }, - Coalesce(Rc, Rc), - Present(Rc), - NotIn(Rc), - Union(Rc, Rc), - Intersection(Rc, Rc), - Difference(Rc, Rc), + Coalesce(Arc, Arc), + Present(Arc), + NotIn(Arc), + Union(Arc, Arc), + Intersection(Arc, Arc), + Difference(Arc, Arc), } // Leaf expression that never contains unresolved commit refs, which can be // either user or resolved expression impl RevsetExpression { - pub fn none() -> Rc { - Rc::new(Self::None) + pub fn none() -> Arc { + Arc::new(Self::None) } /// Ancestors of visible heads and all referenced commits within the current /// expression scope, which may include hidden commits. - pub fn all() -> Rc { - Rc::new(Self::All) + pub fn all() -> Arc { + Arc::new(Self::All) } - pub fn visible_heads() -> Rc { - Rc::new(Self::VisibleHeads) + pub fn visible_heads() -> Arc { + Arc::new(Self::VisibleHeads) } - fn visible_heads_or_referenced() -> Rc { - Rc::new(Self::VisibleHeadsOrReferenced) + fn visible_heads_or_referenced() -> Arc { + Arc::new(Self::VisibleHeadsOrReferenced) } - pub fn root() -> Rc { - Rc::new(Self::Root) + pub fn root() -> Arc { + Arc::new(Self::Root) } - pub fn commit(commit_id: CommitId) -> Rc { + pub fn commit(commit_id: CommitId) -> Arc { Self::commits(vec![commit_id]) } - pub fn commits(commit_ids: Vec) -> Rc { - Rc::new(Self::Commits(commit_ids)) + pub fn commits(commit_ids: Vec) -> Arc { + Arc::new(Self::Commits(commit_ids)) } - pub fn filter(predicate: RevsetFilterPredicate) -> Rc { - Rc::new(Self::Filter(predicate)) + pub fn filter(predicate: RevsetFilterPredicate) -> Arc { + Arc::new(Self::Filter(predicate)) } /// Find any empty commits. - pub fn is_empty() -> Rc { + pub fn is_empty() -> Arc { Self::filter(RevsetFilterPredicate::File(FilesetExpression::all())).negated() } } // Leaf expression that represents unresolved commit refs impl> RevsetExpression { - pub fn working_copy(name: WorkspaceNameBuf) -> Rc { - Rc::new(Self::CommitRef(RevsetCommitRef::WorkingCopy(name))) + pub fn working_copy(name: WorkspaceNameBuf) -> Arc { + Arc::new(Self::CommitRef(RevsetCommitRef::WorkingCopy(name))) } - pub fn working_copies() -> Rc { - Rc::new(Self::CommitRef(RevsetCommitRef::WorkingCopies)) + pub fn working_copies() -> Arc { + Arc::new(Self::CommitRef(RevsetCommitRef::WorkingCopies)) } - pub fn symbol(value: String) -> Rc { - Rc::new(Self::CommitRef(RevsetCommitRef::Symbol(value))) + pub fn symbol(value: String) -> Arc { + Arc::new(Self::CommitRef(RevsetCommitRef::Symbol(value))) } - pub fn remote_symbol(value: RemoteRefSymbolBuf) -> Rc { + pub fn remote_symbol(value: RemoteRefSymbolBuf) -> Arc { let commit_ref = RevsetCommitRef::RemoteSymbol(value); - Rc::new(Self::CommitRef(commit_ref)) + Arc::new(Self::CommitRef(commit_ref)) } - pub fn change_id_prefix(prefix: HexPrefix) -> Rc { + pub fn change_id_prefix(prefix: HexPrefix) -> Arc { let commit_ref = RevsetCommitRef::ChangeId(prefix); - Rc::new(Self::CommitRef(commit_ref)) + Arc::new(Self::CommitRef(commit_ref)) } - pub fn commit_id_prefix(prefix: HexPrefix) -> Rc { + pub fn commit_id_prefix(prefix: HexPrefix) -> Arc { let commit_ref = RevsetCommitRef::CommitId(prefix); - Rc::new(Self::CommitRef(commit_ref)) + Arc::new(Self::CommitRef(commit_ref)) } - pub fn bookmarks(pattern: StringPattern) -> Rc { - Rc::new(Self::CommitRef(RevsetCommitRef::Bookmarks(pattern))) + pub fn bookmarks(pattern: StringPattern) -> Arc { + Arc::new(Self::CommitRef(RevsetCommitRef::Bookmarks(pattern))) } pub fn remote_bookmarks( bookmark_pattern: StringPattern, remote_pattern: StringPattern, remote_ref_state: Option, - ) -> Rc { - Rc::new(Self::CommitRef(RevsetCommitRef::RemoteBookmarks { + ) -> Arc { + Arc::new(Self::CommitRef(RevsetCommitRef::RemoteBookmarks { bookmark_pattern, remote_pattern, remote_ref_state, })) } - pub fn tags(pattern: StringPattern) -> Rc { - Rc::new(Self::CommitRef(RevsetCommitRef::Tags(pattern))) + pub fn tags(pattern: StringPattern) -> Arc { + Arc::new(Self::CommitRef(RevsetCommitRef::Tags(pattern))) } - pub fn git_refs() -> Rc { - Rc::new(Self::CommitRef(RevsetCommitRef::GitRefs)) + pub fn git_refs() -> Arc { + Arc::new(Self::CommitRef(RevsetCommitRef::GitRefs)) } - pub fn git_head() -> Rc { - Rc::new(Self::CommitRef(RevsetCommitRef::GitHead)) + pub fn git_head() -> Arc { + Arc::new(Self::CommitRef(RevsetCommitRef::GitHead)) } } // Compound expression impl RevsetExpression { - pub fn latest(self: &Rc, count: usize) -> Rc { - Rc::new(Self::Latest { + pub fn latest(self: &Arc, count: usize) -> Arc { + Arc::new(Self::Latest { candidates: self.clone(), count, }) } /// Commits in `self` that don't have descendants in `self`. - pub fn heads(self: &Rc) -> Rc { - Rc::new(Self::Heads(self.clone())) + pub fn heads(self: &Arc) -> Arc { + Arc::new(Self::Heads(self.clone())) } /// Commits in `self` that don't have ancestors in `self`. - pub fn roots(self: &Rc) -> Rc { - Rc::new(Self::Roots(self.clone())) + pub fn roots(self: &Arc) -> Arc { + Arc::new(Self::Roots(self.clone())) } /// Parents of `self`. - pub fn parents(self: &Rc) -> Rc { + pub fn parents(self: &Arc) -> Arc { self.ancestors_at(1) } /// Ancestors of `self`, including `self`. - pub fn ancestors(self: &Rc) -> Rc { + pub fn ancestors(self: &Arc) -> Arc { self.ancestors_range(GENERATION_RANGE_FULL) } /// Ancestors of `self` at an offset of `generation` behind `self`. /// The `generation` offset is zero-based starting from `self`. - pub fn ancestors_at(self: &Rc, generation: u64) -> Rc { + pub fn ancestors_at(self: &Arc, generation: u64) -> Arc { self.ancestors_range(generation..generation.saturating_add(1)) } /// Ancestors of `self` in the given range. - pub fn ancestors_range(self: &Rc, generation_range: Range) -> Rc { - Rc::new(Self::Ancestors { + pub fn ancestors_range(self: &Arc, generation_range: Range) -> Arc { + Arc::new(Self::Ancestors { heads: self.clone(), generation: generation_range, parents_range: PARENTS_RANGE_FULL, @@ -471,19 +470,19 @@ impl RevsetExpression { } /// First-parent ancestors of `self`, including `self`. - pub fn first_ancestors(self: &Rc) -> Rc { + pub fn first_ancestors(self: &Arc) -> Arc { self.first_ancestors_range(GENERATION_RANGE_FULL) } /// First-parent ancestors of `self` at an offset of `generation` behind /// `self`. The `generation` offset is zero-based starting from `self`. - pub fn first_ancestors_at(self: &Rc, generation: u64) -> Rc { + pub fn first_ancestors_at(self: &Arc, generation: u64) -> Arc { self.first_ancestors_range(generation..generation.saturating_add(1)) } /// First-parent ancestors of `self` in the given range. - pub fn first_ancestors_range(self: &Rc, generation_range: Range) -> Rc { - Rc::new(Self::Ancestors { + pub fn first_ancestors_range(self: &Arc, generation_range: Range) -> Arc { + Arc::new(Self::Ancestors { heads: self.clone(), generation: generation_range, parents_range: 0..1, @@ -491,48 +490,48 @@ impl RevsetExpression { } /// Children of `self`. - pub fn children(self: &Rc) -> Rc { + pub fn children(self: &Arc) -> Arc { self.descendants_at(1) } /// Descendants of `self`, including `self`. - pub fn descendants(self: &Rc) -> Rc { + pub fn descendants(self: &Arc) -> Arc { self.descendants_range(GENERATION_RANGE_FULL) } /// Descendants of `self` at an offset of `generation` ahead of `self`. /// The `generation` offset is zero-based starting from `self`. - pub fn descendants_at(self: &Rc, generation: u64) -> Rc { + pub fn descendants_at(self: &Arc, generation: u64) -> Arc { self.descendants_range(generation..generation.saturating_add(1)) } /// Descendants of `self` in the given range. - pub fn descendants_range(self: &Rc, generation_range: Range) -> Rc { - Rc::new(Self::Descendants { + pub fn descendants_range(self: &Arc, generation_range: Range) -> Arc { + Arc::new(Self::Descendants { roots: self.clone(), generation: generation_range, }) } /// Fork point (best common ancestors) of `self`. - pub fn fork_point(self: &Rc) -> Rc { - Rc::new(Self::ForkPoint(self.clone())) + pub fn fork_point(self: &Arc) -> Arc { + Arc::new(Self::ForkPoint(self.clone())) } /// Commits with ~half of the descendants in `self`. - pub fn bisect(self: &Rc) -> Rc { - Rc::new(Self::Bisect(self.clone())) + pub fn bisect(self: &Arc) -> Arc { + Arc::new(Self::Bisect(self.clone())) } /// Filter all commits by `predicate` in `self`. - pub fn filtered(self: &Rc, predicate: RevsetFilterPredicate) -> Rc { + pub fn filtered(self: &Arc, predicate: RevsetFilterPredicate) -> Arc { self.intersection(&Self::filter(predicate)) } /// Commits that are descendants of `self` and ancestors of `heads`, both /// inclusive. - pub fn dag_range_to(self: &Rc, heads: &Rc) -> Rc { - Rc::new(Self::DagRange { + pub fn dag_range_to(self: &Arc, heads: &Arc) -> Arc { + Arc::new(Self::DagRange { roots: self.clone(), heads: heads.clone(), }) @@ -540,22 +539,22 @@ impl RevsetExpression { /// Connects any ancestors and descendants in the set by adding the commits /// between them. - pub fn connected(self: &Rc) -> Rc { + pub fn connected(self: &Arc) -> Arc { self.dag_range_to(self) } /// All commits within `domain` reachable from this set of commits, by /// traversing either parent or child edges. - pub fn reachable(self: &Rc, domain: &Rc) -> Rc { - Rc::new(Self::Reachable { + pub fn reachable(self: &Arc, domain: &Arc) -> Arc { + Arc::new(Self::Reachable { sources: self.clone(), domain: domain.clone(), }) } /// Commits reachable from `heads` but not from `self`. - pub fn range(self: &Rc, heads: &Rc) -> Rc { - Rc::new(Self::Range { + pub fn range(self: &Arc, heads: &Arc) -> Arc { + Arc::new(Self::Range { roots: self.clone(), heads: heads.clone(), generation: GENERATION_RANGE_FULL, @@ -564,43 +563,43 @@ impl RevsetExpression { } /// Suppresses name resolution error within `self`. - pub fn present(self: &Rc) -> Rc { - Rc::new(Self::Present(self.clone())) + pub fn present(self: &Arc) -> Arc { + Arc::new(Self::Present(self.clone())) } /// Commits that are not in `self`, i.e. the complement of `self`. - pub fn negated(self: &Rc) -> Rc { - Rc::new(Self::NotIn(self.clone())) + pub fn negated(self: &Arc) -> Arc { + Arc::new(Self::NotIn(self.clone())) } /// Commits that are in `self` or in `other` (or both). - pub fn union(self: &Rc, other: &Rc) -> Rc { - Rc::new(Self::Union(self.clone(), other.clone())) + pub fn union(self: &Arc, other: &Arc) -> Arc { + Arc::new(Self::Union(self.clone(), other.clone())) } /// Commits that are in any of the `expressions`. - pub fn union_all(expressions: &[Rc]) -> Rc { + pub fn union_all(expressions: &[Arc]) -> Arc { to_binary_expression(expressions, &Self::none, &Self::union) } /// Commits that are in `self` and in `other`. - pub fn intersection(self: &Rc, other: &Rc) -> Rc { - Rc::new(Self::Intersection(self.clone(), other.clone())) + pub fn intersection(self: &Arc, other: &Arc) -> Arc { + Arc::new(Self::Intersection(self.clone(), other.clone())) } /// Commits that are in `self` but not in `other`. - pub fn minus(self: &Rc, other: &Rc) -> Rc { - Rc::new(Self::Difference(self.clone(), other.clone())) + pub fn minus(self: &Arc, other: &Arc) -> Arc { + Arc::new(Self::Difference(self.clone(), other.clone())) } /// Commits that are in the first expression in `expressions` that is not /// `none()`. - pub fn coalesce(expressions: &[Rc]) -> Rc { + pub fn coalesce(expressions: &[Arc]) -> Arc { to_binary_expression(expressions, &Self::none, &Self::coalesce2) } - fn coalesce2(self: &Rc, other: &Rc) -> Rc { - Rc::new(Self::Coalesce(self.clone(), other.clone())) + fn coalesce2(self: &Arc, other: &Arc) -> Arc { + Arc::new(Self::Coalesce(self.clone(), other.clone())) } } @@ -621,7 +620,7 @@ impl UserRevsetExpression { &self, repo: &dyn Repo, symbol_resolver: &SymbolResolver, - ) -> Result, RevsetResolutionError> { + ) -> Result, RevsetResolutionError> { resolve_symbols(repo, self, symbol_resolver) } } @@ -629,7 +628,7 @@ impl UserRevsetExpression { impl ResolvedRevsetExpression { /// Optimizes and evaluates this expression. pub fn evaluate<'index>( - self: Rc, + self: Arc, repo: &'index dyn Repo, ) -> Result, RevsetEvaluationError> { let expr = optimize(self).to_backend_expression(repo); @@ -641,7 +640,7 @@ impl ResolvedRevsetExpression { /// Use this function if `self` is already optimized, or to debug /// optimization pass. pub fn evaluate_unoptimized<'index>( - self: &Rc, + self: &Arc, repo: &'index dyn Repo, ) -> Result, RevsetEvaluationError> { // Since referenced commits change the evaluation result, they must be @@ -738,7 +737,7 @@ pub type RevsetFunction = fn( &mut RevsetDiagnostics, &FunctionCallNode, &LoweringContext, -) -> Result, RevsetParseError>; +) -> Result, RevsetParseError>; static BUILTIN_FUNCTION_MAP: LazyLock> = LazyLock::new(|| { // Not using maplit::hashmap!{} or custom declarative macro here because @@ -1065,7 +1064,7 @@ static BUILTIN_FUNCTION_MAP: LazyLock> = LazyLock: Ok(node.span.as_str().to_owned()) })?; let candidates = lower_expression(diagnostics, cand_arg, context)?; - Ok(Rc::new(RevsetExpression::AtOperation { + Ok(Arc::new(RevsetExpression::AtOperation { operation, candidates, })) @@ -1139,7 +1138,7 @@ fn parse_remote_bookmarks_arguments( diagnostics: &mut RevsetDiagnostics, function: &FunctionCallNode, remote_ref_state: Option, -) -> Result, RevsetParseError> { +) -> Result, RevsetParseError> { let ([], [bookmark_opt_arg, remote_opt_arg]) = function.expect_named_arguments(&["", "remote"])?; let bookmark_pattern = if let Some(bookmark_arg) = bookmark_opt_arg { @@ -1164,7 +1163,7 @@ fn lower_function_call( diagnostics: &mut RevsetDiagnostics, function: &FunctionCallNode, context: &LoweringContext, -) -> Result, RevsetParseError> { +) -> Result, RevsetParseError> { let function_map = &context.extensions.function_map; if let Some(func) = function_map.get(function.name) { func(diagnostics, function, context) @@ -1185,7 +1184,7 @@ pub fn lower_expression( diagnostics: &mut RevsetDiagnostics, node: &ExpressionNode, context: &LoweringContext, -) -> Result, RevsetParseError> { +) -> Result, RevsetParseError> { revset_parser::catch_aliases(diagnostics, node, |diagnostics, node| match &node.kind { ExpressionKind::Identifier(name) => Ok(RevsetExpression::symbol((*name).to_owned())), ExpressionKind::String(name) => Ok(RevsetExpression::symbol(name.to_owned())), @@ -1259,7 +1258,7 @@ pub fn parse( diagnostics: &mut RevsetDiagnostics, revset_str: &str, context: &RevsetParseContext, -) -> Result, RevsetParseError> { +) -> Result, RevsetParseError> { let node = parse_program(revset_str)?; let node = dsl_util::expand_aliases_with_locals(node, context.aliases_map, &context.local_variables)?; @@ -1271,7 +1270,7 @@ pub fn parse_with_modifier( diagnostics: &mut RevsetDiagnostics, revset_str: &str, context: &RevsetParseContext, -) -> Result<(Rc, Option), RevsetParseError> { +) -> Result<(Arc, Option), RevsetParseError> { let node = parse_program(revset_str)?; let node = dsl_util::expand_aliases_with_locals(node, context.aliases_map, &context.local_variables)?; @@ -1326,16 +1325,16 @@ fn to_binary_expression( } /// `Some` for rewritten expression, or `None` to reuse the original expression. -type TransformedExpression = Option>>; +type TransformedExpression = Option>>; /// `Break` to not transform subtree recursively. `Continue(Some(rewritten))` /// isn't allowed because it could be a source of infinite substitution bugs. type PreTransformedExpression = ControlFlow, ()>; /// Walks `expression` tree and applies `pre`/`post` transformation recursively. fn transform_expression( - expression: &Rc>, - mut pre: impl FnMut(&Rc>) -> PreTransformedExpression, - mut post: impl FnMut(&Rc>) -> TransformedExpression, + expression: &Arc>, + mut pre: impl FnMut(&Arc>) -> PreTransformedExpression, + mut post: impl FnMut(&Arc>) -> TransformedExpression, ) -> TransformedExpression { let Ok(transformed) = try_transform_expression::(expression, |x| Ok(pre(x)), |x| Ok(post(x))); @@ -1344,8 +1343,8 @@ fn transform_expression( /// Walks `expression` tree and applies `post` recursively from leaf nodes. fn transform_expression_bottom_up( - expression: &Rc>, - post: impl FnMut(&Rc>) -> TransformedExpression, + expression: &Arc>, + post: impl FnMut(&Arc>) -> TransformedExpression, ) -> TransformedExpression { transform_expression(expression, |_| ControlFlow::Continue(()), post) } @@ -1363,14 +1362,14 @@ fn transform_expression_bottom_up( /// `std::iter::successors()` could be used if the transformation needs to be /// applied repeatedly until converged. fn try_transform_expression( - expression: &Rc>, - mut pre: impl FnMut(&Rc>) -> Result, E>, - mut post: impl FnMut(&Rc>) -> Result, E>, + expression: &Arc>, + mut pre: impl FnMut(&Arc>) -> Result, E>, + mut post: impl FnMut(&Arc>) -> Result, E>, ) -> Result, E> { fn transform_child_rec( - expression: &Rc>, - pre: &mut impl FnMut(&Rc>) -> Result, E>, - post: &mut impl FnMut(&Rc>) -> Result, E>, + expression: &Arc>, + pre: &mut impl FnMut(&Arc>) -> Result, E>, + post: &mut impl FnMut(&Arc>) -> Result, E>, ) -> Result, E> { Ok(match expression.as_ref() { RevsetExpression::None => None, @@ -1514,15 +1513,15 @@ fn try_transform_expression( ) } } - .map(Rc::new)) + .map(Arc::new)) } #[expect(clippy::type_complexity)] fn transform_rec_pair( - (expression1, expression2): (&Rc>, &Rc>), - pre: &mut impl FnMut(&Rc>) -> Result, E>, - post: &mut impl FnMut(&Rc>) -> Result, E>, - ) -> Result>, Rc>)>, E> { + (expression1, expression2): (&Arc>, &Arc>), + pre: &mut impl FnMut(&Arc>) -> Result, E>, + post: &mut impl FnMut(&Arc>) -> Result, E>, + ) -> Result>, Arc>)>, E> { match ( transform_rec(expression1, pre, post)?, transform_rec(expression2, pre, post)?, @@ -1537,9 +1536,9 @@ fn try_transform_expression( } fn transform_rec( - expression: &Rc>, - pre: &mut impl FnMut(&Rc>) -> Result, E>, - post: &mut impl FnMut(&Rc>) -> Result, E>, + expression: &Arc>, + pre: &mut impl FnMut(&Arc>) -> Result, E>, + post: &mut impl FnMut(&Arc>) -> Result, E>, ) -> Result, E> { if let ControlFlow::Break(transformed) = pre(expression)? { return Ok(transformed); @@ -1567,7 +1566,7 @@ trait ExpressionStateFolder { fn fold_expression( &mut self, expression: &RevsetExpression, - ) -> Result>, Self::Error> { + ) -> Result>, Self::Error> { fold_child_expression_state(self, expression) } @@ -1575,27 +1574,27 @@ trait ExpressionStateFolder { fn fold_commit_ref( &mut self, commit_ref: &InSt::CommitRef, - ) -> Result>, Self::Error>; + ) -> Result>, Self::Error>; /// Transforms `at_operation(operation, candidates)` expression. fn fold_at_operation( &mut self, operation: &InSt::Operation, candidates: &RevsetExpression, - ) -> Result>, Self::Error>; + ) -> Result>, Self::Error>; } /// Transforms inner items of the `expression` by using the `folder`. fn fold_child_expression_state( folder: &mut F, expression: &RevsetExpression, -) -> Result>, F::Error> +) -> Result>, F::Error> where InSt: ExpressionState, OutSt: ExpressionState, F: ExpressionStateFolder + ?Sized, { - let expression: Rc<_> = match expression { + let expression: Arc<_> = match expression { RevsetExpression::None => RevsetExpression::None.into(), RevsetExpression::All => RevsetExpression::All.into(), RevsetExpression::VisibleHeads => RevsetExpression::VisibleHeads.into(), @@ -1761,7 +1760,7 @@ where /// /// User symbols and `at_operation()` scopes should have been resolved. fn resolve_referenced_commits( - expression: &Rc>, + expression: &Arc>, ) -> TransformedExpression { // Trust precomputed value if any if matches!( @@ -1797,7 +1796,7 @@ fn resolve_referenced_commits( inner_commits.extend_from_slice(commits); } ControlFlow::Break(transformed.map(|candidates| { - Rc::new(RevsetExpression::WithinVisibility { + Arc::new(RevsetExpression::WithinVisibility { candidates, visible_heads: visible_heads.clone(), }) @@ -1820,7 +1819,7 @@ fn resolve_referenced_commits( // Omit empty node to keep test/debug output concise return transformed; } - Some(Rc::new(RevsetExpression::WithinReference { + Some(Arc::new(RevsetExpression::WithinReference { candidates: transformed.unwrap_or_else(|| expression.clone()), commits: outer_commits, })) @@ -1829,11 +1828,11 @@ fn resolve_referenced_commits( /// Flatten all intersections to be left-recursive. For instance, transforms /// `(a & b) & (c & d)` into `((a & b) & c) & d`. fn flatten_intersections( - expression: &Rc>, + expression: &Arc>, ) -> TransformedExpression { fn flatten( - expression1: &Rc>, - expression2: &Rc>, + expression1: &Arc>, + expression2: &Arc>, ) -> TransformedExpression { let recurse = |a, b| flatten(a, b).unwrap_or_else(|| a.intersection(b)); @@ -1858,15 +1857,15 @@ fn flatten_intersections( /// provided key. If `base` is an intersection, it must be left-recursive, and /// it must already be in sorted order. fn sort_intersection_by_key( - base: &Rc>, - expression: &Rc>, + base: &Arc>, + expression: &Arc>, mut get_key: impl FnMut(&RevsetExpression) -> T, ) -> TransformedExpression { // We only want to compute the key for `expression` once instead of computing it // on every iteration. fn sort_intersection_helper( - base: &Rc>, - expression: &Rc>, + base: &Arc>, + expression: &Arc>, expression_key: T, mut get_key: impl FnMut(&RevsetExpression) -> T, ) -> TransformedExpression { @@ -1891,7 +1890,7 @@ fn sort_intersection_by_key( /// ancestors can be converted to ranges. All other negations are moved to the /// right, since these negations can usually be evaluated better as differences. fn sort_negations_and_ancestors( - expression: &Rc>, + expression: &Arc>, ) -> TransformedExpression { #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] enum AncestorsOrder { @@ -1935,11 +1934,11 @@ fn sort_negations_and_ancestors( /// c. Wraps union of filter and set (e.g. `author(_) | heads()`), to /// ensure inner filter wouldn't need to evaluate all the input sets. fn internalize_filter( - expression: &Rc>, + expression: &Arc>, ) -> TransformedExpression { fn get_filter( - expression: &Rc>, - ) -> Option<&Rc>> { + expression: &Arc>, + ) -> Option<&Arc>> { match expression.as_ref() { RevsetExpression::Filter(_) => Some(expression), RevsetExpression::AsFilter(candidates) => Some(candidates), @@ -1948,9 +1947,9 @@ fn internalize_filter( } fn mark_filter( - expression: Rc>, - ) -> Rc> { - Rc::new(RevsetExpression::AsFilter(expression)) + expression: Arc>, + ) -> Arc> { + Arc::new(RevsetExpression::AsFilter(expression)) } transform_expression_bottom_up(expression, |expression| match expression.as_ref() { @@ -1998,7 +1997,7 @@ fn internalize_filter( /// Since this function rewrites `x & none()` to `none()`, user symbols should /// have been resolved. Otherwise, an invalid symbol could be optimized out. fn fold_redundant_expression( - expression: &Rc>, + expression: &Arc>, ) -> TransformedExpression { transform_expression_bottom_up(expression, |expression| match expression.as_ref() { RevsetExpression::Commits(commits) if commits.is_empty() => Some(RevsetExpression::none()), @@ -2035,7 +2034,7 @@ fn fold_redundant_expression( /// `ancestors(heads, 2..3)`, which is equivalent to `heads--`. fn ancestors_to_heads( expression: &RevsetExpression, -) -> Result>, ()> { +) -> Result>, ()> { match ancestors_to_heads_and_parents_range(expression) { Ok((heads, PARENTS_RANGE_FULL)) => Ok(heads), _ => Err(()), @@ -2044,7 +2043,7 @@ fn ancestors_to_heads( fn ancestors_to_heads_and_parents_range( expression: &RevsetExpression, -) -> Result<(Rc>, Range), ()> { +) -> Result<(Arc>, Range), ()> { match expression { RevsetExpression::Ancestors { heads, @@ -2059,7 +2058,7 @@ fn ancestors_to_heads_and_parents_range( }, parents_range, } => Ok(( - Rc::new(RevsetExpression::Ancestors { + Arc::new(RevsetExpression::Ancestors { heads: heads.clone(), generation: (*start)..start.saturating_add(1), parents_range: parents_range.clone(), @@ -2075,11 +2074,11 @@ fn ancestors_to_heads_and_parents_range( /// expressions, since this can result in less efficient evaluation, such as for /// `~::x & ~y`, which should be `x.. ~ y` instead of `~(::x | y)`. fn fold_ancestors_union( - expression: &Rc>, + expression: &Arc>, ) -> TransformedExpression { fn union_ancestors( - expression1: &Rc>, - expression2: &Rc>, + expression1: &Arc>, + expression2: &Arc>, ) -> TransformedExpression { let heads1 = ancestors_to_heads(expression1).ok()?; let heads2 = ancestors_to_heads(expression2).ok()?; @@ -2111,17 +2110,17 @@ fn fold_ancestors_union( /// Ancestors and negated ancestors should have already been moved to the left /// in intersections, and negated ancestors should have been combined already. fn fold_heads_range( - expression: &Rc>, + expression: &Arc>, ) -> TransformedExpression { // Represents `roots..heads & filter` struct FilteredRange { - roots: Rc>, - heads_and_parents_range: Option<(Rc>, Range)>, - filter: Rc>, + roots: Arc>, + heads_and_parents_range: Option<(Arc>, Range)>, + filter: Arc>, } impl FilteredRange { - fn new(roots: Rc>) -> Self { + fn new(roots: Arc>) -> Self { // roots.. & all() Self { roots, @@ -2130,7 +2129,7 @@ fn fold_heads_range( } } - fn add(mut self, expression: &Rc>) -> Self { + fn add(mut self, expression: &Arc>) -> Self { if self.heads_and_parents_range.is_none() { // x.. & ::y -> x..y if let Ok(heads_and_parents_range) = @@ -2143,7 +2142,7 @@ fn fold_heads_range( self.add_filter(expression) } - fn add_filter(mut self, expression: &Rc>) -> Self { + fn add_filter(mut self, expression: &Arc>) -> Self { self.filter = if let RevsetExpression::All = self.filter.as_ref() { // x..y & all() & f -> x..y & f expression.clone() @@ -2155,7 +2154,7 @@ fn fold_heads_range( } fn to_filtered_range( - expression: &Rc>, + expression: &Arc>, ) -> Option> { // If the first expression is `ancestors(x)`, then we already know the range // must be `none()..x`, since any roots would've been moved to the left by an @@ -2193,8 +2192,8 @@ fn fold_heads_range( } fn to_heads_range( - candidates: &Rc>, - ) -> Option>> { + candidates: &Arc>, + ) -> Option>> { to_filtered_range(candidates).map(|filtered_range| { let (heads, parents_range) = filtered_range.heads_and_parents_range.unwrap_or_else(|| { @@ -2231,8 +2230,8 @@ fn fold_heads_range( } fn to_difference_range( - expression: &Rc>, - complement: &Rc>, + expression: &Arc>, + complement: &Arc>, ) -> TransformedExpression { let RevsetExpression::Ancestors { heads, @@ -2245,7 +2244,7 @@ fn to_difference_range( let roots = ancestors_to_heads(complement).ok()?; // ::heads & ~(::roots) -> roots..heads // ::heads & ~(::roots-) -> ::heads & ~ancestors(roots, 1..) -> roots-..heads - Some(Rc::new(RevsetExpression::Range { + Some(Arc::new(RevsetExpression::Range { roots, heads: heads.clone(), generation: generation.clone(), @@ -2256,12 +2255,12 @@ fn to_difference_range( /// Transforms negative intersection to difference. Redundant intersections like /// `all() & e` should have been removed. fn fold_difference( - expression: &Rc>, + expression: &Arc>, ) -> TransformedExpression { fn to_difference( - expression: &Rc>, - complement: &Rc>, - ) -> Rc> { + expression: &Arc>, + complement: &Arc>, + ) -> Arc> { to_difference_range(expression, complement).unwrap_or_else(|| expression.minus(complement)) } @@ -2288,7 +2287,7 @@ fn fold_difference( /// Since this rule inserts redundant `visible_heads()`, negative intersections /// should have been transformed. fn fold_not_in_ancestors( - expression: &Rc>, + expression: &Arc>, ) -> TransformedExpression { transform_expression_bottom_up(expression, |expression| match expression.as_ref() { RevsetExpression::NotIn(complement) @@ -2310,7 +2309,7 @@ fn fold_not_in_ancestors( /// For example, `all() ~ e` will become `all() & ~e`, which can be simplified /// further by `fold_redundant_expression()`. fn unfold_difference( - expression: &Rc>, + expression: &Arc>, ) -> TransformedExpression { transform_expression_bottom_up(expression, |expression| match expression.as_ref() { // roots..heads -> ::heads & ~(::roots) @@ -2320,7 +2319,7 @@ fn unfold_difference( parents_range, generation, } => { - let heads_ancestors = Rc::new(RevsetExpression::Ancestors { + let heads_ancestors = Arc::new(RevsetExpression::Ancestors { heads: heads.clone(), generation: generation.clone(), parents_range: parents_range.clone(), @@ -2337,7 +2336,7 @@ fn unfold_difference( /// Transforms nested `ancestors()`/`parents()`/`descendants()`/`children()` /// like `h---`/`r+++`. fn fold_generation( - expression: &Rc>, + expression: &Arc>, ) -> TransformedExpression { fn add_generation(generation1: &Range, generation2: &Range) -> Range { // For any (g1, g2) in (generation1, generation2), g1 + g2. @@ -2364,7 +2363,7 @@ fn fold_generation( heads, generation: generation2, parents_range: parents2, - } if parents2 == parents1 => Some(Rc::new(RevsetExpression::Ancestors { + } if parents2 == parents1 => Some(Arc::new(RevsetExpression::Ancestors { heads: heads.clone(), generation: add_generation(generation1, generation2), parents_range: parents1.clone(), @@ -2383,7 +2382,7 @@ fn fold_generation( RevsetExpression::Descendants { roots, generation: generation2, - } => Some(Rc::new(RevsetExpression::Descendants { + } => Some(Arc::new(RevsetExpression::Descendants { roots: roots.clone(), generation: add_generation(generation1, generation2), })), @@ -2398,8 +2397,8 @@ fn fold_generation( /// Rewrites the given `expression` tree to reduce evaluation cost. Returns new /// tree. pub fn optimize( - expression: Rc>, -) -> Rc> { + expression: Arc>, +) -> Arc> { // Since fold_redundant_expression() can remove hidden commits that look // redundant, referenced commits should be collected earlier. let expression = resolve_referenced_commits(&expression).unwrap_or(expression); @@ -2846,7 +2845,7 @@ impl ExpressionStateFolder fn fold_expression( &mut self, expression: &UserRevsetExpression, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { match expression { // 'present(x)' opens new symbol resolution scope to map error to 'none()' RevsetExpression::Present(candidates) => { @@ -2871,7 +2870,7 @@ impl ExpressionStateFolder fn fold_commit_ref( &mut self, commit_ref: &RevsetCommitRef, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { let commit_ids = resolve_commit_ref(self.repo(), commit_ref, self.symbol_resolver)?; Ok(RevsetExpression::commits(commit_ids)) } @@ -2880,13 +2879,13 @@ impl ExpressionStateFolder &mut self, operation: &String, candidates: &UserRevsetExpression, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { let repo = reload_repo_at_operation(self.repo(), operation)?; self.repo_stack.push(repo); let candidates = self.fold_expression(candidates)?; let visible_heads = self.repo().view().heads().iter().cloned().collect(); self.repo_stack.pop(); - Ok(Rc::new(RevsetExpression::WithinVisibility { + Ok(Arc::new(RevsetExpression::WithinVisibility { candidates, visible_heads, })) @@ -2897,7 +2896,7 @@ fn resolve_symbols( repo: &dyn Repo, expression: &UserRevsetExpression, symbol_resolver: &SymbolResolver, -) -> Result, RevsetResolutionError> { +) -> Result, RevsetResolutionError> { let mut resolver = ExpressionSymbolResolver::new(repo, symbol_resolver); resolver.fold_expression(expression) } @@ -3263,7 +3262,7 @@ impl RevsetExtensions { } } - pub fn symbol_resolvers(&self) -> &[impl AsRef + use<>] { + pub fn symbol_resolvers(&self) -> &[Box] { &self.symbol_resolvers } @@ -3378,21 +3377,21 @@ mod tests { use super::*; - fn parse(revset_str: &str) -> Result, RevsetParseError> { + fn parse(revset_str: &str) -> Result, RevsetParseError> { parse_with_aliases(revset_str, [] as [(&str, &str); 0]) } fn parse_with_workspace( revset_str: &str, workspace_name: &WorkspaceName, - ) -> Result, RevsetParseError> { + ) -> Result, RevsetParseError> { parse_with_aliases_and_workspace(revset_str, [] as [(&str, &str); 0], workspace_name) } fn parse_with_aliases( revset_str: &str, aliases: impl IntoIterator, impl Into)>, - ) -> Result, RevsetParseError> { + ) -> Result, RevsetParseError> { let mut aliases_map = RevsetAliasesMap::new(); for (decl, defn) in aliases { aliases_map.insert(decl, defn).unwrap(); @@ -3412,7 +3411,7 @@ mod tests { revset_str: &str, aliases: impl IntoIterator, impl Into)>, workspace_name: &WorkspaceName, - ) -> Result, RevsetParseError> { + ) -> Result, RevsetParseError> { // Set up pseudo context to resolve `workspace_name@` and `file(path)` let path_converter = RepoPathUiConverter::Fs { cwd: PathBuf::from("/"), @@ -3439,14 +3438,14 @@ mod tests { fn parse_with_modifier( revset_str: &str, - ) -> Result<(Rc, Option), RevsetParseError> { + ) -> Result<(Arc, Option), RevsetParseError> { parse_with_aliases_and_modifier(revset_str, [] as [(&str, &str); 0]) } fn parse_with_aliases_and_modifier( revset_str: &str, aliases: impl IntoIterator, impl Into)>, - ) -> Result<(Rc, Option), RevsetParseError> { + ) -> Result<(Arc, Option), RevsetParseError> { let mut aliases_map = RevsetAliasesMap::new(); for (decl, defn) in aliases { aliases_map.insert(decl, defn).unwrap(); @@ -4230,11 +4229,11 @@ mod tests { let settings = insta_settings(); let _guard = settings.bind_to_scope(); - let visibility1 = Rc::new(ResolvedRevsetExpression::WithinVisibility { + let visibility1 = Arc::new(ResolvedRevsetExpression::WithinVisibility { candidates: RevsetExpression::commit(CommitId::from_hex("100001")), visible_heads: vec![CommitId::from_hex("100000")], }); - let visibility2 = Rc::new(ResolvedRevsetExpression::WithinVisibility { + let visibility2 = Arc::new(ResolvedRevsetExpression::WithinVisibility { candidates: RevsetExpression::filter(RevsetFilterPredicate::HasConflict), visible_heads: vec![CommitId::from_hex("200000")], }); @@ -4360,7 +4359,7 @@ mod tests { // Referenced commits should be propagated from the innermost scope. insta::assert_debug_snapshot!( - resolve_referenced_commits(&Rc::new(ResolvedRevsetExpression::WithinVisibility { + resolve_referenced_commits(&Arc::new(ResolvedRevsetExpression::WithinVisibility { candidates: visibility1.clone(), visible_heads: vec![CommitId::from_hex("400000")], })), @r#" @@ -4402,7 +4401,7 @@ mod tests { "#); // Resolved expression should be reused. - let resolved = Rc::new(ResolvedRevsetExpression::WithinReference { + let resolved = Arc::new(ResolvedRevsetExpression::WithinReference { // No referenced commits within the scope to test whether the // precomputed value is reused. candidates: RevsetExpression::none(), @@ -4430,7 +4429,7 @@ mod tests { ) "#); insta::assert_debug_snapshot!( - resolve_referenced_commits(&Rc::new(ResolvedRevsetExpression::WithinVisibility { + resolve_referenced_commits(&Arc::new(ResolvedRevsetExpression::WithinVisibility { candidates: resolved.clone(), visible_heads: vec![CommitId::from_hex("400000")], })), @r#" @@ -4548,7 +4547,7 @@ mod tests { } "#); insta::assert_debug_snapshot!( - optimize(Rc::new(RevsetExpression::WithinReference { + optimize(Arc::new(RevsetExpression::WithinReference { candidates: parse("bookmarks() & all()").unwrap(), commits: vec![CommitId::from_hex("012345")], })), @r#" @@ -4560,7 +4559,7 @@ mod tests { } "#); insta::assert_debug_snapshot!( - optimize(Rc::new(RevsetExpression::WithinVisibility { + optimize(Arc::new(RevsetExpression::WithinVisibility { candidates: parse("bookmarks() & all()").unwrap(), visible_heads: vec![CommitId::from_hex("012345")], })), @r#" @@ -4607,7 +4606,7 @@ mod tests { fn test_optimize_unchanged_subtree() { fn unwrap_union( expression: &UserRevsetExpression, - ) -> (&Rc, &Rc) { + ) -> (&Arc, &Arc) { match expression { RevsetExpression::Union(left, right) => (left, right), _ => panic!("unexpected expression: {expression:?}"), @@ -4617,15 +4616,15 @@ mod tests { // transform_expression_bottom_up() should not recreate tree unnecessarily. let parsed = parse("foo-").unwrap(); let optimized = optimize(parsed.clone()); - assert!(Rc::ptr_eq(&parsed, &optimized)); + assert!(Arc::ptr_eq(&parsed, &optimized)); let parsed = parse("bookmarks() | tags()").unwrap(); let optimized = optimize(parsed.clone()); - assert!(Rc::ptr_eq(&parsed, &optimized)); + assert!(Arc::ptr_eq(&parsed, &optimized)); let parsed = parse("bookmarks() & tags()").unwrap(); let optimized = optimize(parsed.clone()); - assert!(Rc::ptr_eq(&parsed, &optimized)); + assert!(Arc::ptr_eq(&parsed, &optimized)); // Only left subtree should be rewritten. let parsed = parse("(bookmarks() & all()) | tags()").unwrap(); @@ -4634,7 +4633,7 @@ mod tests { unwrap_union(&optimized).0.as_ref(), RevsetExpression::CommitRef(RevsetCommitRef::Bookmarks(_)) ); - assert!(Rc::ptr_eq( + assert!(Arc::ptr_eq( unwrap_union(&parsed).1, unwrap_union(&optimized).1 )); @@ -4642,7 +4641,7 @@ mod tests { // Only right subtree should be rewritten. let parsed = parse("bookmarks() | (all() & tags())").unwrap(); let optimized = optimize(parsed.clone()); - assert!(Rc::ptr_eq( + assert!(Arc::ptr_eq( unwrap_union(&parsed).0, unwrap_union(&optimized).0 )); diff --git a/lib/tests/test_annotate.rs b/lib/tests/test_annotate.rs index 8f846c6af..dd1217cfb 100644 --- a/lib/tests/test_annotate.rs +++ b/lib/tests/test_annotate.rs @@ -13,7 +13,7 @@ // limitations under the License. use std::fmt::Write as _; -use std::rc::Rc; +use std::sync::Arc; use itertools::Itertools as _; use jj_lib::annotate::FileAnnotation; @@ -67,7 +67,7 @@ fn annotate(repo: &dyn Repo, commit: &Commit, file_path: &RepoPath) -> String { fn annotate_within( repo: &dyn Repo, commit: &Commit, - domain: &Rc, + domain: &Arc, file_path: &RepoPath, ) -> String { let mut annotator = FileAnnotator::from_commit(commit, file_path).unwrap(); diff --git a/lib/tests/test_bisect.rs b/lib/tests/test_bisect.rs index 0cef33084..b6033882b 100644 --- a/lib/tests/test_bisect.rs +++ b/lib/tests/test_bisect.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::rc::Rc; +use std::sync::Arc; use assert_matches::assert_matches; use jj_lib::backend::CommitId; @@ -28,7 +28,7 @@ use testutils::write_random_commit_with_parents; fn test_bisection<'a>( repo: &dyn Repo, - input_range: &Rc, + input_range: &Arc, results: impl IntoIterator, ) -> BisectionResult { let mut bisector = Bisector::new(repo, input_range.clone()).unwrap(); diff --git a/lib/tests/test_revset_optimized.rs b/lib/tests/test_revset_optimized.rs index 6baf632fa..b8b761cd7 100644 --- a/lib/tests/test_revset_optimized.rs +++ b/lib/tests/test_revset_optimized.rs @@ -19,7 +19,7 @@ //! The default is `256`, which might be too small to catch edge-case bugs. //! -use std::rc::Rc; +use std::sync::Arc; use itertools::Itertools as _; use jj_lib::backend::CommitId; @@ -74,7 +74,7 @@ fn rebase_descendants(repo: &mut MutableRepo) -> Vec { fn arb_expression( known_commits: Vec, visible_heads: Vec>, -) -> impl Strategy> { +) -> impl Strategy> { // https://proptest-rs.github.io/proptest/proptest/tutorial/recursive.html let max_commits = known_commits.len(); let leaf_expr = prop_oneof![ @@ -132,7 +132,7 @@ fn arb_expression( expr.clone(), proptest::sample::select(visible_heads.clone()) ) - .prop_map(|(candidates, visible_heads)| Rc::new( + .prop_map(|(candidates, visible_heads)| Arc::new( RevsetExpression::WithinVisibility { candidates, visible_heads @@ -152,7 +152,7 @@ fn arb_expression( fn verify_optimized( repo: &dyn Repo, - expression: &Rc, + expression: &Arc, ) -> Result<(), TestCaseError> { let optimized_revset = expression.clone().evaluate(repo).unwrap(); let unoptimized_revset = expression.clone().evaluate_unoptimized(repo).unwrap();