From 868964a912ccdcddae7f230f8dec831c69d4f258 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Tue, 25 Jun 2024 15:50:06 +0000 Subject: [PATCH] types: add type bound to occurscheck error variant I originally wanted to do this but couldn't because we weren't capping the depth of error bound prints. Now we are. --- src/node/construct.rs | 6 +++--- src/types/mod.rs | 12 ++++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/node/construct.rs b/src/node/construct.rs index adec3407..c6eb9ed5 100644 --- a/src/node/construct.rs +++ b/src/node/construct.rs @@ -300,7 +300,7 @@ mod tests { assert!(matches!( node.finalize_types_non_program(), - Err(crate::Error::Type(types::Error::OccursCheck)), + Err(crate::Error::Type(types::Error::OccursCheck { .. })), )); } @@ -320,7 +320,7 @@ mod tests { assert!(matches!( comp2.finalize_types_non_program(), - Err(crate::Error::Type(types::Error::OccursCheck)), + Err(crate::Error::Type(types::Error::OccursCheck { .. })), )); } @@ -347,7 +347,7 @@ mod tests { assert!(matches!( comp8.finalize_types_non_program(), - Err(crate::Error::Type(types::Error::OccursCheck)), + Err(crate::Error::Type(types::Error::OccursCheck { .. })), )); } diff --git a/src/types/mod.rs b/src/types/mod.rs index a82317d9..fdad4a9b 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -103,7 +103,7 @@ pub enum Error { hint: &'static str, }, /// A type is recursive (i.e., occurs within itself), violating the "occurs check" - OccursCheck, + OccursCheck { infinite_bound: Arc }, } impl fmt::Display for Error { @@ -131,7 +131,9 @@ impl fmt::Display for Error { type1, type2, hint, ) } - Error::OccursCheck => f.write_str("detected infinitely-sized type"), + Error::OccursCheck { infinite_bound } => { + write!(f, "infinitely-sized type {}", infinite_bound,) + } } } } @@ -471,13 +473,15 @@ impl Type { // First, do occurs-check to ensure that we have no infinitely sized types. let mut occurs_check = HashSet::new(); - for data in bound.verbose_pre_order_iter::(None) { + for data in Arc::clone(&bound).verbose_pre_order_iter::(None) { if data.is_complete { occurs_check.remove(&(data.node.as_ref() as *const _)); } else if data.n_children_yielded == 0 && !occurs_check.insert(data.node.as_ref() as *const _) { - return Err(Error::OccursCheck); + return Err(Error::OccursCheck { + infinite_bound: bound, + }); } }