chiark / gitweb /
Introduce and use PieceTraitDowncastFailed error
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 30 Apr 2022 17:47:21 +0000 (18:47 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 30 Apr 2022 17:56:58 +0000 (18:56 +0100)
We want this to be cheap to make - not InternalError which contains a
stack trace - so that we can use downcast_piece in contexts where it's
not an error.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/fastsplit.rs
src/gamestate.rs

index e5f1569d5de2cda80e7e4ed9887bbf34e29d827c..b8930072ca2b47029ee446bb42923bec1d7742d5 100644 (file)
@@ -224,11 +224,11 @@ impl IFastSplits {
 
 #[ext(pub)]
 impl<'r> &'r dyn PieceTrait {
-  #[throws(IE)]
+  #[throws(PieceTraitDowncastFailed<'r>)]
   fn downcast_piece_fastsplit<P: PieceTrait>(self) -> &'r P {
     self.downcast_piece::<Piece>()?
-      .ipc.as_ref().ok_or_else(|| internal_logic_error(
-        format!("downcast_piece_fastsplit not fastsplit {:?}", self)))?
+      .ipc.as_ref().ok_or_else(
+        || PieceTraitDowncastFailed { p: self, why: "unresolved fastsplit"})?
       .p.direct_trait_access() // we're just digging down, this is fine
       .downcast_piece::<P>()?
   }
index 57af8d30676dcbd251798dbb2b53c5a7dc155468..512db5ffcf148b4a32a70b4f5776af1e6ac64a75 100644 (file)
@@ -421,15 +421,32 @@ impl Timestamp {
   }
 }
 
+#[derive(Error, Debug)]
+#[error("{self:?}")]
+pub struct PieceTraitDowncastFailed<'p> {
+  pub p: &'p dyn PieceTrait,
+  pub why: &'static str,
+}
+
 #[ext(pub)]
 impl<'r> &'r dyn PieceTrait {
-  #[throws(IE)]
+  #[throws(PieceTraitDowncastFailed<'r>)]
   fn downcast_piece<P: PieceTrait>(self) -> &'r P {
-    self.downcast_ref::<P>().ok_or_else(|| internal_logic_error(format!(
-      "downcaste_piece failure! got: {:?}", &self)))?
+    self.downcast_ref::<P>().ok_or_else(
+      || PieceTraitDowncastFailed { p: self, why: "piece" })?
   }
 }
 
+impl<'p> From<PieceTraitDowncastFailed<'p>> for InternalError {
+  fn from(e: PieceTraitDowncastFailed<'p>) -> InternalError {
+    internal_logic_error(format!(
+      "downcaste_piece failure {}! got: {:?}", &e.why, &e.p))
+  }
+}
+impl<'p> From<PieceTraitDowncastFailed<'p>> for ApiPieceOpError {
+  fn from(e: PieceTraitDowncastFailed<'p>) -> ApiPieceOpError { e.into() }
+}
+
 // ---------- positions and ClampTable ----------
 
 #[derive(Error,Debug,Copy,Clone)]