Skip to content

Commit c2bc293

Browse files
committed
Use Any for plan downcasting
Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
1 parent bd412f3 commit c2bc293

10 files changed

Lines changed: 20 additions & 45 deletions

File tree

vortex-layout/src/plan/display.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ impl PlanTreeExtractor for PlanExpressionExtractor {
120120
_context: &PlanTreeContext,
121121
formatter: &mut fmt::Formatter<'_>,
122122
) -> fmt::Result {
123-
let Some(expression_plan) = plan.as_any().downcast_ref::<ExpressionPlan>() else {
123+
let Some(expression_plan) = plan.downcast_ref::<ExpressionPlan>() else {
124124
return Ok(());
125125
};
126126
write!(formatter, " expr={}", expression_plan.expression())

vortex-layout/src/plan/mod.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,7 @@ pub type PlanRef = Arc<dyn Plan>;
4444
/// Layout plans expose their optimizer-facing children in a stable logical order. Optional child
4545
/// slots count toward [`child_count`](Self::child_count) and are returned as `None` by
4646
/// [`child`](Self::child) when absent. Accessing a child may initialize and cache its plan.
47-
pub trait Plan: 'static + Send + Sync {
48-
/// Returns this plan as [`Any`] for plan-specific optimization rules.
49-
fn as_any(&self) -> &dyn Any;
50-
47+
pub trait Plan: Any + Send + Sync {
5148
/// Returns the display name of this plan kind.
5249
///
5350
/// Plans should override this when the fully qualified Rust type name is not appropriate.
@@ -109,6 +106,16 @@ pub fn new_plan(layout: &LayoutRef) -> VortexResult<PlanRef> {
109106
}
110107

111108
impl dyn Plan + '_ {
109+
/// Returns whether this plan has concrete type `T`.
110+
pub fn is<T: Plan>(&self) -> bool {
111+
(self as &dyn Any).is::<T>()
112+
}
113+
114+
/// Downcasts this plan to concrete type `T`.
115+
pub fn downcast_ref<T: Plan>(&self) -> Option<&T> {
116+
(self as &dyn Any).downcast_ref::<T>()
117+
}
118+
112119
/// Displays this plan and its descendants with the default plan extractors.
113120
pub fn display_tree(&self) -> PlanTreeDisplay<'_> {
114121
PlanTreeDisplay::default_display(self)

vortex-layout/src/plan/plans/chunked.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,6 @@ impl ChunkedPlan {
4646
}
4747

4848
impl Plan for ChunkedPlan {
49-
fn as_any(&self) -> &dyn std::any::Any {
50-
self
51-
}
52-
5349
fn name(&self) -> &'static str {
5450
"ChunkedPlan"
5551
}

vortex-layout/src/plan/plans/dict.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,6 @@ impl DictPlan {
5353
}
5454

5555
impl Plan for DictPlan {
56-
fn as_any(&self) -> &dyn std::any::Any {
57-
self
58-
}
59-
6056
fn name(&self) -> &'static str {
6157
"DictPlan"
6258
}

vortex-layout/src/plan/plans/expression.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// SPDX-License-Identifier: Apache-2.0
22
// SPDX-FileCopyrightText: Copyright the Vortex contributors
33

4-
use std::any::Any;
54
use std::borrow::Cow;
65
use std::sync::Arc;
76

@@ -46,10 +45,6 @@ impl ExpressionPlan {
4645
}
4746

4847
impl Plan for ExpressionPlan {
49-
fn as_any(&self) -> &dyn Any {
50-
self
51-
}
52-
5348
fn name(&self) -> &'static str {
5449
"ExpressionPlan"
5550
}
@@ -60,7 +55,7 @@ impl Plan for ExpressionPlan {
6055
if is_root(&expression) {
6156
return Ok(child);
6257
}
63-
if let Some(inner) = child.as_any().downcast_ref::<Self>() {
58+
if let Some(inner) = child.downcast_ref::<Self>() {
6459
let expression = replace(expression, &root(), inner.expression.clone());
6560
return Ok(Arc::new(Self::try_new(
6661
expression,

vortex-layout/src/plan/plans/flat.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@ impl FlatPlan {
2323
}
2424

2525
impl Plan for FlatPlan {
26-
fn as_any(&self) -> &dyn std::any::Any {
27-
self
28-
}
29-
3026
fn name(&self) -> &'static str {
3127
"FlatPlan"
3228
}

vortex-layout/src/plan/plans/list.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,6 @@ impl ListPlan {
7070
}
7171

7272
impl Plan for ListPlan {
73-
fn as_any(&self) -> &dyn std::any::Any {
74-
self
75-
}
76-
7773
fn name(&self) -> &'static str {
7874
"ListPlan"
7975
}

vortex-layout/src/plan/plans/row_idx.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// SPDX-License-Identifier: Apache-2.0
22
// SPDX-FileCopyrightText: Copyright the Vortex contributors
33

4-
use std::any::Any;
54
use std::borrow::Cow;
65
use std::sync::Arc;
76

@@ -26,10 +25,6 @@ impl RowIdxPlan {
2625
}
2726

2827
impl Plan for RowIdxPlan {
29-
fn as_any(&self) -> &dyn Any {
30-
self
31-
}
32-
3328
fn name(&self) -> &'static str {
3429
"RowIdxPlan"
3530
}

vortex-layout/src/plan/plans/struct_.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,6 @@ impl StructPlan {
5555
}
5656

5757
impl Plan for StructPlan {
58-
fn as_any(&self) -> &dyn std::any::Any {
59-
self
60-
}
61-
6258
fn name(&self) -> &'static str {
6359
"StructPlan"
6460
}

vortex-layout/src/plan/tests.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ fn unsupported_layout_has_no_plan() -> VortexResult<()> {
6969
fn flat_plan_has_no_children() -> VortexResult<()> {
7070
let plan = make_plan(flat(3, primitive(PType::I32, Nullability::NonNullable), 0))?;
7171

72-
assert!(plan.as_any().is::<FlatPlan>());
72+
assert!(plan.is::<FlatPlan>());
7373
assert_eq!(plan.child_count(), 0);
7474
assert!(plan.child(0).is_err());
7575
Ok(())
@@ -86,7 +86,7 @@ fn chunked_plan_exposes_chunks() -> VortexResult<()> {
8686
.into_layout();
8787
let plan = make_plan(layout)?;
8888

89-
assert!(plan.as_any().is::<ChunkedPlan>());
89+
assert!(plan.is::<ChunkedPlan>());
9090
assert_eq!(plan.child_count(), 2);
9191
assert_eq!(
9292
plan.child(0)?
@@ -120,7 +120,7 @@ fn chunked_plan_defers_unrequested_chunks_through_optimization() -> VortexResult
120120
let first = plan
121121
.child(0)?
122122
.ok_or_else(|| vortex_err!("missing first chunk"))?;
123-
assert!(first.as_any().is::<FlatPlan>());
123+
assert!(first.is::<FlatPlan>());
124124
let cached = plan
125125
.child(0)?
126126
.ok_or_else(|| vortex_err!("missing cached first chunk"))?;
@@ -149,7 +149,7 @@ fn dict_plan_orders_codes_before_values() -> VortexResult<()> {
149149
.into_layout();
150150
let plan = make_plan(layout)?;
151151

152-
assert!(plan.as_any().is::<DictPlan>());
152+
assert!(plan.is::<DictPlan>());
153153
assert_eq!(plan.child_count(), 2);
154154
assert_eq!(
155155
plan.child(0)?
@@ -179,7 +179,7 @@ fn list_plan_has_stable_optional_validity_slot() -> VortexResult<()> {
179179
.into_layout();
180180
let plan = make_plan(non_nullable)?;
181181

182-
assert!(plan.as_any().is::<ListPlan>());
182+
assert!(plan.is::<ListPlan>());
183183
assert_eq!(plan.child_count(), 3);
184184
assert_eq!(
185185
plan.child(0)?
@@ -228,7 +228,7 @@ fn struct_plan_orders_fields_before_optional_validity() -> VortexResult<()> {
228228
.into_layout();
229229
let plan = make_plan(non_nullable)?;
230230

231-
assert!(plan.as_any().is::<StructPlan>());
231+
assert!(plan.is::<StructPlan>());
232232
assert_eq!(plan.child_count(), 3);
233233
assert_eq!(
234234
plan.child(0)?
@@ -282,7 +282,6 @@ fn struct_plan_defers_unrequested_fields_through_optimization() -> VortexResult<
282282
assert!(
283283
plan.child(0)?
284284
.ok_or_else(|| vortex_err!("missing field a"))?
285-
.as_any()
286285
.is::<FlatPlan>()
287286
);
288287
let error = plan
@@ -445,12 +444,11 @@ fn row_idx_plan_preserves_row_index_expressions() -> VortexResult<()> {
445444
let plan = RowIdxPlan::new_ref(10, make_plan(layout)?);
446445
let plan = ExpressionPlan::try_new(row_idx(), plan)?.optimize()?;
447446
let expression = plan
448-
.as_any()
449447
.downcast_ref::<ExpressionPlan>()
450448
.ok_or_else(|| vortex_err!("optimized plan is not an expression plan"))?;
451449

452450
assert_eq!(expression.expression(), &row_idx());
453-
assert!(expression.child_plan().as_any().is::<RowIdxPlan>());
451+
assert!(expression.child_plan().is::<RowIdxPlan>());
454452
assert_eq!(expression.row_count(), 3);
455453
Ok(())
456454
}

0 commit comments

Comments
 (0)