diff --git a/rust/kcl-lib/src/execution/types.rs b/rust/kcl-lib/src/execution/types.rs index 0485e992e..3fbe8cff9 100644 --- a/rust/kcl-lib/src/execution/types.rs +++ b/rust/kcl-lib/src/execution/types.rs @@ -72,6 +72,10 @@ impl RuntimeType { RuntimeType::Primitive(PrimitiveType::Tag) } + pub fn tag_identifier() -> Self { + RuntimeType::Primitive(PrimitiveType::TagId) + } + pub fn bool() -> Self { RuntimeType::Primitive(PrimitiveType::Boolean) } @@ -337,6 +341,8 @@ pub enum PrimitiveType { String, Boolean, Tag, + // Annoyingly some functions only want a TagIdentifier, not any kind of tag. + TagId, Sketch, Solid, Plane, @@ -365,12 +371,14 @@ impl PrimitiveType { PrimitiveType::Axis3d => "3d axes".to_owned(), PrimitiveType::ImportedGeometry => "imported geometries".to_owned(), PrimitiveType::Tag => "tags".to_owned(), + PrimitiveType::TagId => "tag identifiers".to_owned(), } } fn subtype(&self, other: &PrimitiveType) -> bool { match (self, other) { (PrimitiveType::Number(n1), PrimitiveType::Number(n2)) => n1.subtype(n2), + (PrimitiveType::TagId, PrimitiveType::Tag) => true, (t1, t2) => t1 == t2, } } @@ -386,6 +394,7 @@ impl fmt::Display for PrimitiveType { PrimitiveType::String => write!(f, "string"), PrimitiveType::Boolean => write!(f, "bool"), PrimitiveType::Tag => write!(f, "tag"), + PrimitiveType::TagId => write!(f, "tag identifier"), PrimitiveType::Sketch => write!(f, "Sketch"), PrimitiveType::Solid => write!(f, "Solid"), PrimitiveType::Plane => write!(f, "Plane"), @@ -1159,6 +1168,10 @@ impl KclValue { KclValue::ImportedGeometry { .. } => Ok(value.clone()), _ => Err(self.into()), }, + PrimitiveType::TagId => match value { + KclValue::TagIdentifier { .. } => Ok(value.clone()), + _ => Err(self.into()), + }, PrimitiveType::Tag => match value { KclValue::TagDeclarator { .. } | KclValue::TagIdentifier { .. } | KclValue::Uuid { .. } => { Ok(value.clone()) diff --git a/rust/kcl-lib/src/std/args.rs b/rust/kcl-lib/src/std/args.rs index 78ff879a4..69efbec8d 100644 --- a/rust/kcl-lib/src/std/args.rs +++ b/rust/kcl-lib/src/std/args.rs @@ -408,13 +408,10 @@ impl Args { })?; T::from_kcl_val(&arg).ok_or_else(|| { - KclError::Semantic(KclErrorDetails { + KclError::Internal(KclErrorDetails { source_ranges: vec![self.source_range], - message: format!( - "This function expected the input argument to be {}", - ty.human_friendly_type(), - ), - }) + message: "Mismatch between type coercion and value extraction (this isn't your fault).\nTo assist in bug-reporting, expected type: {ty:?}; actual value: {arg:?}".to_owned(), + }) }) } diff --git a/rust/kcl-lib/src/std/edge.rs b/rust/kcl-lib/src/std/edge.rs index 9f8570d8f..c912ed36e 100644 --- a/rust/kcl-lib/src/std/edge.rs +++ b/rust/kcl-lib/src/std/edge.rs @@ -14,7 +14,7 @@ use crate::{ /// Get the opposite edge to the edge given. pub async fn get_opposite_edge(exec_state: &mut ExecState, args: Args) -> Result { - let input_edge = args.get_unlabeled_kw_arg_typed("edge", &RuntimeType::edge(), exec_state)?; + let input_edge = args.get_unlabeled_kw_arg_typed("edge", &RuntimeType::tag_identifier(), exec_state)?; let edge = inner_get_opposite_edge(input_edge, exec_state, args.clone()).await?; Ok(KclValue::Uuid { @@ -98,7 +98,7 @@ async fn inner_get_opposite_edge( /// Get the next adjacent edge to the edge given. pub async fn get_next_adjacent_edge(exec_state: &mut ExecState, args: Args) -> Result { - let input_edge = args.get_unlabeled_kw_arg_typed("edge", &RuntimeType::edge(), exec_state)?; + let input_edge = args.get_unlabeled_kw_arg_typed("edge", &RuntimeType::tag_identifier(), exec_state)?; let edge = inner_get_next_adjacent_edge(input_edge, exec_state, args.clone()).await?; Ok(KclValue::Uuid { @@ -191,7 +191,7 @@ async fn inner_get_next_adjacent_edge( /// Get the previous adjacent edge to the edge given. pub async fn get_previous_adjacent_edge(exec_state: &mut ExecState, args: Args) -> Result { - let input_edge = args.get_unlabeled_kw_arg_typed("edge", &RuntimeType::edge(), exec_state)?; + let input_edge = args.get_unlabeled_kw_arg_typed("edge", &RuntimeType::tag_identifier(), exec_state)?; let edge = inner_get_previous_adjacent_edge(input_edge, exec_state, args.clone()).await?; Ok(KclValue::Uuid { diff --git a/rust/kcl-lib/tests/panic_repro_cube/execution_error.snap b/rust/kcl-lib/tests/panic_repro_cube/execution_error.snap index cf01cc22f..c4a277cfb 100644 --- a/rust/kcl-lib/tests/panic_repro_cube/execution_error.snap +++ b/rust/kcl-lib/tests/panic_repro_cube/execution_error.snap @@ -4,11 +4,12 @@ description: Error from executing panic_repro_cube.kcl --- KCL Semantic error - × semantic: This function expected the input argument to be Edge - ╭─[43:5] + × semantic: This function expected the input argument to be tag identifier + │ but it's actually of type Unique ID (uuid) + ╭─[43:25] 42 │ // these double wrapped functions are the point of this test 43 │ getNextAdjacentEdge(getNextAdjacentEdge(seg01)), - · ───────────────────────┬─────────────────────── - · ╰── tests/panic_repro_cube/input.kcl + · ─────────────┬──────────── + · ╰── tests/panic_repro_cube/input.kcl 44 │ getNextAdjacentEdge(getNextAdjacentEdge(seg02)) ╰────