Repository: cedar-policy/cedar
Pull request #1428 (2025-01-16 20:05:41)

new method on core Expr
## Description of changes

We have `into_expr_kind()` and `into_data()`, but no way for other Core consumers to consume the `Expr` and get back both the kind and the data.

## Issue #, if available

## Checklist for requesting a review

The change in this PR is (choose one, and delete the other options):

- [x] A change "invisible" to users (e.g., documentation, changes to "internal" crates like `cedar-policy-core`, `cedar-validator`, etc.)

I confirm that this PR (choose one, and delete the other options):

- [x] Does not update the CHANGELOG because my change does not significantly impact released code.

I confirm that [`cedar-spec`](https://github.com/cedar-policy/cedar-spec) (choose one, and delete the other options):

- [x] Does not require updates because my change does not impact the Cedar formal model or DRT infrastructure.

I confirm that [`docs.cedarpolicy.com`](https://docs.cedarpolicy.com/) (choose one, and delete the other options):

- [x] Does not require updates because my change does not impact the Cedar language specification.



Patch:
diff --git a/cedar-policy-cli/src/lib.rs b/cedar-policy-cli/src/lib.rs
index 43970dd1..59dd8448 100644
--- a/cedar-policy-cli/src/lib.rs
+++ b/cedar-policy-cli/src/lib.rs
@@ -741,7 +741,7 @@ pub struct EvaluateArgs {
     pub expression: String,
 }
 
-#[derive(Eq, PartialEq, Debug)]
+#[derive(Eq, PartialEq, Debug, Copy, Clone)]
 pub enum CedarExitCode {
     // The command completed successfully with a result other than a
     // authorization deny or validation failure.
@@ -1421,9 +1421,9 @@ fn rename_from_id_annotation(ps: &PolicySet) -> Result<PolicySet> {
 }
 
 // Read from a file (when `filename` is a `Some`) or stdin (when `filename` is `None`) to a `String`
-fn read_from_file_or_stdin(filename: Option<impl AsRef<Path>>, context: &str) -> Result<String> {
+fn read_from_file_or_stdin(filename: Option<&impl AsRef<Path>>, context: &str) -> Result<String> {
     let mut src_str = String::new();
-    match filename.as_ref() {
+    match filename {
         Some(path) => {
             src_str = std::fs::read_to_string(path)
                 .into_diagnostic()
@@ -1442,7 +1442,7 @@ fn read_from_file_or_stdin(filename: Option<impl AsRef<Path>>, context: &str) ->
 
 // Convenient wrapper around `read_from_file_or_stdin` to just read from a file
 fn read_from_file(filename: impl AsRef<Path>, context: &str) -> Result<String> {
-    read_from_file_or_stdin(Some(filename), context)
+    read_from_file_or_stdin(Some(&filename), context)
 }
 
 /// Read a policy set, in Cedar syntax, from the file given in `filename`,
@@ -1451,7 +1451,7 @@ fn read_cedar_policy_set(
     filename: Option<impl AsRef<Path> + std::marker::Copy>,
 ) -> Result<PolicySet> {
     let context = "policy set";
-    let ps_str = read_from_file_or_stdin(filename, context)?;
+    let ps_str = read_from_file_or_stdin(filename.as_ref(), context)?;
     let ps = PolicySet::from_str(&ps_str)
         .map_err(|err| {
             let name = filename.map_or_else(
@@ -1470,7 +1470,7 @@ fn read_json_policy_set(
     filename: Option<impl AsRef<Path> + std::marker::Copy>,
 ) -> Result<PolicySet> {
     let context = "JSON policy";
-    let json_source = read_from_file_or_stdin(filename, context)?;
+    let json_source = read_from_file_or_stdin(filename.as_ref(), context)?;
     let json = serde_json::from_str::<serde_json::Value>(&json_source).into_diagnostic()?;
     let policy_type = get_json_policy_type(&json)?;
 
diff --git a/cedar-policy-core/src/ast/entity.rs b/cedar-policy-core/src/ast/entity.rs
index f5fde915..b8a93b01 100644
--- a/cedar-policy-core/src/ast/entity.rs
+++ b/cedar-policy-core/src/ast/entity.rs
@@ -521,10 +521,10 @@ impl Entity {
     pub fn set_attr(
         &mut self,
         attr: SmolStr,
-        val: RestrictedExpr,
+        val: BorrowedRestrictedExpr<'_>,
         extensions: &Extensions<'_>,
     ) -> Result<(), EvaluationError> {
-        let val = RestrictedEvaluator::new(extensions).partial_interpret(val.as_borrowed())?;
+        let val = RestrictedEvaluator::new(extensions).partial_interpret(val)?;
         self.attrs.insert(attr, val.into());
         Ok(())
     }
@@ -535,10 +535,10 @@ impl Entity {
     pub fn set_tag(
         &mut self,
         tag: SmolStr,
-        val: RestrictedExpr,
+        val: BorrowedRestrictedExpr<'_>,
         extensions: &Extensions<'_>,
     ) -> Result<(), EvaluationError> {
-        let val = RestrictedEvaluator::new(extensions).partial_interpret(val.as_borrowed())?;
+        let val = RestrictedEvaluator::new(extensions).partial_interpret(val)?;
         self.tags.insert(tag, val.into());
         Ok(())
     }
diff --git a/cedar-policy-core/src/ast/expr.rs b/cedar-policy-core/src/ast/expr.rs
index bd746c5f..a5e04077 100644
--- a/cedar-policy-core/src/ast/expr.rs
+++ b/cedar-policy-core/src/ast/expr.rs
@@ -222,6 +222,12 @@ impl<T> Expr<T> {
         self.data
     }
 
+    /// Consume the `Expr`, returning the `ExprKind`, `source_loc`, and stored
+    /// data.
+    pub fn into_parts(self) -> (ExprKind<T>, Option<Loc>, T) {
+        (self.expr_kind, self.source_loc, self.data)
+    }
+
     /// Access the `Loc` stored on the `Expr`.
     pub fn source_loc(&self) -> Option<&Loc> {
         self.source_loc.as_ref()
@@ -1455,10 +1461,9 @@ impl<T: Default + Clone> expr_builder::ExprBuilder for ExprBuilder<T> {
 }
 
 impl<T> ExprBuilder<T> {
-    /// Internally used by the following methods to construct an `Expr`
-    /// containing the `data` and `source_loc` in this `ExprBuilder` with some
-    /// inner `ExprKind`.
-    fn with_expr_kind(self, expr_kind: ExprKind<T>) -> Expr<T> {
+    /// Construct an `Expr` containing the `data` and `source_loc` in this
+    /// `ExprBuilder` and the given `ExprKind`.
+    pub fn with_expr_kind(self, expr_kind: ExprKind<T>) -> Expr<T> {
         Expr::new(expr_kind, self.source_loc, self.data)
     }
 
diff --git a/cedar-policy-core/src/ast/policy.rs b/cedar-policy-core/src/ast/policy.rs
index a0f4f2c1..b27dac9e 100644
--- a/cedar-policy-core/src/ast/policy.rs
+++ b/cedar-policy-core/src/ast/policy.rs
@@ -736,7 +736,7 @@ mod hashing_tests {
 
     use super::*;
 
-    fn compute_hash(ir: LiteralPolicy) -> u64 {
+    fn compute_hash(ir: &LiteralPolicy) -> u64 {
         let mut s = DefaultHasher::new();
         ir.hash(&mut s);
         s.finish()
@@ -757,7 +757,7 @@ mod hashing_tests {
         let a = build_template_linked_policy();
         let b = build_template_linked_policy();
         assert_eq!(a, b);
-        assert_eq!(compute_hash(a), compute_hash(b));
+        assert_eq!(compute_hash(&a), compute_hash(&b));
     }
 }
 // by default, Coverlay does not track coverage for lines after a line
diff --git a/cedar-policy-core/src/est.rs b/cedar-policy-core/src/est.rs
index caf11bb3..3d8f1e2f 100644
--- a/cedar-policy-core/src/est.rs
+++ b/cedar-policy-core/src/est.rs
@@ -4594,7 +4594,7 @@ mod issue_891 {
     use cool_asserts::assert_matches;
     use serde_json::json;
 
-    fn est_json_with_body(body: serde_json::Value) -> serde_json::Value {
+    fn est_json_with_body(body: &serde_json::Value) -> serde_json::Value {
         json!(
             {
                 "effect": "permit",
@@ -4613,12 +4613,12 @@ mod issue_891 {
 
     #[test]
     fn invalid_extension_func() {
-        let src = est_json_with_body(json!( { "ow4": [ { "Var": "principal" } ] }));
+        let src = est_json_with_body(&json!( { "ow4": [ { "Var": "principal" } ] }));
         assert_matches!(serde_json::from_value::<est::Policy>(src), Err(e) => {
             assert!(e.to_string().starts_with("unknown variant `ow4`, expected one of `Value`, `Var`, "), "e was: {e}");
         });
 
-        let src = est_json_with_body(json!(
+        let src = est_json_with_body(&json!(
             {
                 "==": {
                     "left": {"Var": "principal"},
@@ -4635,7 +4635,7 @@ mod issue_891 {
             assert!(e.to_string().starts_with("unknown variant `ownerOrEqual`, expected one of `Value`, `Var`, "), "e was: {e}");
         });
 
-        let src = est_json_with_body(json!(
+        let src = est_json_with_body(&json!(
             {
                 "==": {
                     "left": {"Var": "principal"},
diff --git a/cedar-policy-core/src/evaluator.rs b/cedar-policy-core/src/evaluator.rs
index eb73c656..f38cde46 100644
--- a/cedar-policy-core/src/evaluator.rs
+++ b/cedar-policy-core/src/evaluator.rs
@@ -465,7 +465,7 @@ impl<'e> Evaluator<'e> {
                                 ))
                             }
                             _ => {
-                                let expected_types = valid_comparison_op_types(&self.extensions);
+                                let expected_types = valid_comparison_op_types(self.extensions);
                                 Err(EvaluationError::type_error_with_advice(
                                     expected_types.clone(),
                                     &arg1,
@@ -1185,12 +1185,16 @@ pub(crate) mod test {
 
         let mut entity_with_attrs = Entity::with_uid(EntityUID::with_eid("entity_with_attrs"));
         entity_with_attrs
-            .set_attr("spoon".into(), RestrictedExpr::val(787), Extensions::none())
+            .set_attr(
+                "spoon".into(),
+                RestrictedExpr::val(787).as_borrowed(),
+                Extensions::none(),
+            )
             .unwrap();
         entity_with_attrs
             .set_attr(
                 "fork".into(),
-                RestrictedExpr::val("spoon"),
+                RestrictedExpr::val("spoon").as_borrowed(),
                 Extensions::none(),
             )
             .unwrap();
@@ -1201,7 +1205,8 @@ pub(crate) mod test {
                     RestrictedExpr::val("fun"),
                     RestrictedExpr::val("good"),
                     RestrictedExpr::val("useful"),
-                ]),
+                ])
+                .as_borrowed(),
                 Extensions::none(),
             )
             .unwrap();
@@ -1213,7 +1218,8 @@ pub(crate) mod test {
                     ("town".into(), RestrictedExpr::val("barmstadt")),
                     ("country".into(), RestrictedExpr::val("amazonia")),
                 ])
-                .unwrap(),
+                .unwrap()
+                .as_borrowed(),
                 Extensions::none(),
             )
             .unwrap();
@@ -1222,7 +1228,7 @@ pub(crate) mod test {
         entity_with_tags
             .set_tag(
                 "spoon".into(),
-                RestrictedExpr::val(-121),
+                RestrictedExpr::val(-121).as_borrowed(),
                 Extensions::none(),
             )
             .unwrap();
@@ -1232,7 +1238,7 @@ pub(crate) mod test {
         entity_with_tags_and_attrs
             .set_tag(
                 "spoon".into(),
-                RestrictedExpr::val(-121),
+                RestrictedExpr::val(-121).as_borrowed(),
                 Extensions::none(),
             )
             .unwrap();
@@ -4906,9 +4912,9 @@ pub(crate) mod test {
     }
 
     #[track_caller] // report the caller's location as the location of the panic, not the location in this function
-    fn assert_restricted_expression_error(e: Expr) {
+    fn assert_restricted_expression_error(e: &Expr) {
         assert_matches!(
-            BorrowedRestrictedExpr::new(&e),
+            BorrowedRestrictedExpr::new(e),
             Err(RestrictedExpressionError::InvalidRestrictedExpression { .. })
         );
     }
@@ -4937,19 +4943,23 @@ pub(crate) mod test {
             ),
             Ok(Value::from(EntityUID::with_eid("alice")).into())
         );
-        assert_restricted_expression_error(Expr::var(Var::Principal));
-        assert_restricted_expression_error(Expr::var(Var::Action));
-        assert_restricted_expression_error(Expr::var(Var::Resource));
-        assert_restricted_expression_error(Expr::var(Var::Context));
-        assert_restricted_expression_error(Expr::ite(Expr::val(true), Expr::val(7), Expr::val(12)));
-        assert_restricted_expression_error(Expr::and(Expr::val("bogus"), Expr::val(true)));
-        assert_restricted_expression_error(Expr::or(Expr::val("bogus"), Expr::val(true)));
-        assert_restricted_expression_error(Expr::not(Expr::val(true)));
-        assert_restricted_expression_error(Expr::is_in(
+        assert_restricted_expression_error(&Expr::var(Var::Principal));
+        assert_restricted_expression_error(&Expr::var(Var::Action));
+        assert_restricted_expression_error(&Expr::var(Var::Resource));
+        assert_restricted_expression_error(&Expr::var(Var::Context));
+        assert_restricted_expression_error(&Expr::ite(
+            Expr::val(true),
+            Expr::val(7),
+            Expr::val(12),
+        ));
+        assert_restricted_expression_error(&Expr::and(Expr::val("bogus"), Expr::val(true)));
+        assert_restricted_expression_error(&Expr::or(Expr::val("bogus"), Expr::val(true)));
+        assert_restricted_expression_error(&Expr::not(Expr::val(true)));
+        assert_restricted_expression_error(&Expr::is_in(
             Expr::val(EntityUID::with_eid("alice")),
             Expr::val(EntityUID::with_eid("some_group")),
         ));
-        assert_restricted_expression_error(Expr::is_eq(
+        assert_restricted_expression_error(&Expr::is_eq(
             Expr::val(EntityUID::with_eid("alice")),
             Expr::val(EntityUID::with_eid("some_group")),
         ));
@@ -4967,15 +4977,15 @@ pub(crate) mod test {
                 ..
             }))
         );
-        assert_restricted_expression_error(Expr::get_attr(
+        assert_restricted_expression_error(&Expr::get_attr(
             Expr::val(EntityUID::with_eid("alice")),
             "pancakes".into(),
         ));
-        assert_restricted_expression_error(Expr::has_attr(
+        assert_restricted_expression_error(&Expr::has_attr(
             Expr::val(EntityUID::with_eid("alice")),
             "pancakes".into(),
         ));
-        assert_restricted_expression_error(Expr::like(
+        assert_restricted_expression_error(&Expr::like(
             Expr::val("abcdefg12"),
             Pattern::from(vec![
                 PatternElem::Char('a'),
@@ -5012,16 +5022,16 @@ pub(crate) mod test {
         );
 
         // complex expressions -- for instance, violation not at top level
-        assert_restricted_expression_error(Expr::set([
+        assert_restricted_expression_error(&Expr::set([
             Expr::val("hi"),
             Expr::and(Expr::val("bogus"), Expr::val(false)),
         ]));
-        assert_restricted_expression_error(Expr::call_extension_fn(
+        assert_restricted_expression_error(&Expr::call_extension_fn(
             "ip".parse().expect("should be a valid Name"),
             vec![Expr::var(Var::Principal)],
         ));
 
-        assert_restricted_expression_error(Expr::is_entity_type(
+        assert_restricted_expression_error(&Expr::is_entity_type(
             Expr::val(EntityUID::with_eid("alice")),
             "User".parse().unwrap(),
         ));
@@ -5068,7 +5078,7 @@ pub(crate) mod test {
         }
     }
 
-    fn partial_context_test(context_expr: Expr, e: Expr) -> Either<Value, Expr> {
+    fn partial_context_test(context_expr: Expr, e: &Expr) -> Either<Value, Expr> {
         let euid: EntityUID = r#"Test::"test""#.parse().unwrap();
         let rexpr = RestrictedExpr::new(context_expr)
             .expect("Context Expression was not a restricted expression");
@@ -5084,7 +5094,7 @@ pub(crate) mod test {
         .unwrap();
         let es = Entities::new();
         let eval = Evaluator::new(q, &es, Extensions::none());
-        eval.partial_eval_expr(&e).unwrap()
+        eval.partial_eval_expr(e).unwrap()
     }
 
     #[test]
@@ -5103,7 +5113,7 @@ pub(crate) mod test {
             Expr::val(2),
         );
 
-        let r = partial_context_test(c_expr, expr);
+        let r = partial_context_test(c_expr, &expr);
 
         assert_eq!(r, Either::Right(expected));
     }
@@ -5122,7 +5132,7 @@ pub(crate) mod test {
             Expr::get_attr(Expr::var(Var::Context), "cell".into()),
             Expr::val(2),
         );
-        let r = partial_context_test(c_expr.clone(), expr);
+        let r = partial_context_test(c_expr.clone(), &expr);
         let expected = Expr::binary_app(
             BinaryOp::Eq,
             Expr::unknown(Unknown::new_untyped("cell")),
@@ -5136,7 +5146,7 @@ pub(crate) mod test {
             Expr::get_attr(Expr::var(Var::Context), "loc".into()),
             Expr::val(2),
         );
-        let r = partial_context_test(c_expr, expr);
+        let r = partial_context_test(c_expr, &expr);
         assert_eq!(r, Either::Left(false.into()));
     }
 
@@ -5158,7 +5168,7 @@ pub(crate) mod test {
             ),
             Expr::val(2),
         );
-        let r = partial_context_test(c_expr, expr);
+        let r = partial_context_test(c_expr, &expr);
         let expected = Expr::binary_app(
             BinaryOp::Eq,
             Expr::unknown(Unknown::new_untyped("row")),
@@ -5188,7 +5198,7 @@ pub(crate) mod test {
             ),
             Expr::val(2),
         );
-        let r = partial_context_test(c_expr.clone(), expr);
+        let r = partial_context_test(c_expr.clone(), &expr);
         let expected = Expr::binary_app(
             BinaryOp::Eq,
             Expr::unknown(Unknown::new_untyped("row")),
@@ -5204,7 +5214,7 @@ pub(crate) mod test {
             ),
             Expr::val(2),
         );
-        let r = partial_context_test(c_expr, expr);
+        let r = partial_context_test(c_expr, &expr);
         let expected = Expr::binary_app(
             BinaryOp::Eq,
             Expr::unknown(Unknown::new_untyped("col")),
diff --git a/cedar-policy-validator/src/cedar_schema/to_json_schema.rs b/cedar-policy-validator/src/cedar_schema/to_json_schema.rs
index 882c6603..ac40274f 100644
--- a/cedar-policy-validator/src/cedar_schema/to_json_schema.rs
+++ b/cedar-policy-validator/src/cedar_schema/to_json_schema.rs
@@ -700,7 +700,7 @@ mod preserves_source_locations {
             };
         }
         "#,
-            &Extensions::all_available(),
+            Extensions::all_available(),
         )
         .unwrap();
         let ns = schema
@@ -784,7 +784,7 @@ mod preserves_source_locations {
             };
         }
         "#,
-            &Extensions::all_available(),
+            Extensions::all_available(),
         )
         .unwrap();
         let ns = schema
diff --git a/cedar-policy-validator/src/json_schema.rs b/cedar-policy-validator/src/json_schema.rs
index 8f2e69bf..25b7f536 100644
--- a/cedar-policy-validator/src/json_schema.rs
+++ b/cedar-policy-validator/src/json_schema.rs
@@ -120,9 +120,9 @@ where
             .map(|(key, value)| {
                 let key = if key.is_empty() {
                     if !value.annotations.is_empty() {
-                        Err(serde::de::Error::custom(format!(
-                            "annotations are not allowed on the empty namespace"
-                        )))?
+                        Err(serde::de::Error::custom(
+                            "annotations are not allowed on the empty namespace".to_string(),
+                        ))?
                     }
                     None
                 } else {
@@ -1294,7 +1294,13 @@ impl<'de, N: Deserialize<'de> + From<RawName>> Visitor<'de> for TypeVisitor<N> {
             }
         }
 
-        Self::build_schema_type::<M>(type_name, element, attributes, additional_attributes, name)
+        Self::build_schema_type::<M>(
+            type_name.as_ref(),
+            element,
+            attributes,
+            additional_attributes,
+            name,
+        )
     }
 }
 
@@ -1304,7 +1310,7 @@ impl<'de, N: Deserialize<'de> + From<RawName>> TypeVisitor<N> {
     /// which is not used for a particular type to be `Some` when building that
     /// type.
     fn build_schema_type<M>(
-        type_name: Option<SmolStr>,
+        type_name: Option<&SmolStr>,
         element: Option<Type<N>>,
         attributes: Option<AttributesTypeMap>,
         additional_attributes: Option<bool>,
@@ -1327,7 +1333,7 @@ impl<'de, N: Deserialize<'de> + From<RawName>> TypeVisitor<N> {
         .map(|(field, _)| field)
         .collect::<HashSet<_>>();
 
-        match type_name.as_ref() {
+        match type_name {
             Some(s) => {
                 // We've concluded that type exists
                 remaining_fields.remove(&TypeField);
@@ -2917,16 +2923,16 @@ mod test_json_roundtrip {
     use super::*;
 
     #[track_caller] // report the caller's location as the location of the panic, not the location in this function
-    fn roundtrip(schema: Fragment<RawName>) {
+    fn roundtrip(schema: &Fragment<RawName>) {
         let json = serde_json::to_value(schema.clone()).unwrap();
         let new_schema: Fragment<RawName> = serde_json::from_value(json).unwrap();
-        assert_eq!(schema, new_schema);
+        assert_eq!(schema, &new_schema);
     }
 
     #[test]
     fn empty_namespace() {
         let fragment = Fragment(BTreeMap::from([(None, NamespaceDefinition::new([], []))]));
-        roundtrip(fragment);
+        roundtrip(&fragment);
     }
 
     #[test]
@@ -2935,7 +2941,7 @@ mod test_json_roundtrip {
             Some("a".parse().unwrap()),
             NamespaceDefinition::new([], []),
         )]));
-        roundtrip(fragment);
+        roundtrip(&fragment);
     }
 
     #[test]
@@ -2981,7 +2987,7 @@ mod test_json_roundtrip {
                 )],
             ),
         )]));
-        roundtrip(fragment);
+        roundtrip(&fragment);
     }
 
     #[test]
@@ -3036,7 +3042,7 @@ mod test_json_roundtrip {
                 ),
             ),
         ]));
-        roundtrip(fragment);
+        roundtrip(&fragment);
     }
 }
 
@@ -3600,6 +3606,7 @@ mod ord {
 
     /// Tests that `Type<RawName>` and `Type<InternalName>` are `Ord`
     #[test]
+    #[allow(clippy::collection_is_never_read)]
     fn type_ord() {
         let mut set: BTreeSet<Type<RawName>> = BTreeSet::default();
         set.insert(Type::Type {
diff --git a/cedar-policy-validator/src/rbac.rs b/cedar-policy-validator/src/rbac.rs
index 611289d3..6e1be4ad 100644
--- a/cedar-policy-validator/src/rbac.rs
+++ b/cedar-policy-validator/src/rbac.rs
@@ -1130,7 +1130,7 @@ mod test {
     fn assert_validate_policy_fails(
         validator: &Validator,
         policy: &Template,
-        expected: Vec<ValidationError>,
+        expected: &[ValidationError],
     ) {
         assert_eq!(
             validator
@@ -1278,7 +1278,7 @@ mod test {
         assert_validate_policy_fails(
             &validator,
             &policy,
-            vec![ValidationError::invalid_action_application(
+            &[ValidationError::invalid_action_application(
                 Some(Loc::new(0..43, Arc::from(src))),
                 PolicyID::from_string("policy0"),
                 false,
@@ -1293,7 +1293,7 @@ mod test {
         assert_validate_policy_fails(
             &validator,
             &policy,
-            vec![
+            &[
                 ValidationError::unrecognized_entity_type(
                     Some(Loc::new(27..30, Arc::from(src))),
                     PolicyID::from_string("policy0"),
@@ -1322,7 +1322,7 @@ mod test {
         assert_validate_policy_fails(
             &validator,
             &policy,
-            vec![ValidationError::invalid_action_application(
+            &[ValidationError::invalid_action_application(
                 Some(Loc::new(0..57, Arc::from(src))),
                 PolicyID::from_string("policy0"),
                 false,
@@ -1362,7 +1362,7 @@ mod test {
         assert_validate_policy_fails(
             &validator,
             &policy,
-            vec![ValidationError::invalid_action_application(
+            &[ValidationError::invalid_action_application(
                 Some(Loc::new(0..43, Arc::from(src))),
                 PolicyID::from_string("policy0"),
                 false,
@@ -1377,7 +1377,7 @@ mod test {
         assert_validate_policy_fails(
             &validator,
             &policy,
-            vec![ValidationError::invalid_action_application(
+            &[ValidationError::invalid_action_application(
                 Some(Loc::new(0..57, Arc::from(src))),
                 PolicyID::from_string("policy0"),
                 false,
@@ -1392,7 +1392,7 @@ mod test {
         assert_validate_policy_fails(
             &validator,
             &policy,
-            vec![
+            &[
                 ValidationError::unrecognized_entity_type(
                     Some(Loc::new(45..48, Arc::from(src))),
                     PolicyID::from_string("policy0"),
diff --git a/cedar-policy-validator/src/schema.rs b/cedar-policy-validator/src/schema.rs
index c5505836..407d0705 100644
--- a/cedar-policy-validator/src/schema.rs
+++ b/cedar-policy-validator/src/schema.rs
@@ -1511,7 +1511,7 @@ pub(crate) mod test {
         }
 
         #[track_caller]
-        pub fn assert_invalid_json_schema(json: serde_json::Value) {
+        pub fn assert_invalid_json_schema(json: &serde_json::Value) {
             match ValidatorSchema::from_json_value(json.clone(), Extensions::all_available()) {
                 Ok(_) => panic!("{json} should be an invalid schema"),
                 Err(SchemaError::JsonDeserialization(_)) => {}
@@ -4278,7 +4278,7 @@ mod test_rfc70 {
                 "actions": {}
             }
         });
-        assert_invalid_json_schema(src_json);
+        assert_invalid_json_schema(&src_json);
         let src_json = json!({
             "": {
                 "commonTypes": {
diff --git a/cedar-policy-validator/src/typecheck.rs b/cedar-policy-validator/src/typecheck.rs
index d1d82b64..eb7fe059 100644
--- a/cedar-policy-validator/src/typecheck.rs
+++ b/cedar-policy-validator/src/typecheck.rs
@@ -193,13 +193,12 @@ impl<'a> Typechecker<'a> {
         // for the corresponding action.
         self.unlinked_envs
             .iter()
-            .map(|unlinked_e| {
+            .flat_map(|unlinked_e| {
                 self.link_request_env(unlinked_e, t).map(|linked_e| {
                     let check = typecheck_fn(&linked_e, t.id(), &cond);
                     (linked_e, check)
                 })
             })
-            .flatten()
             .collect()
     }
 
@@ -2220,10 +2219,10 @@ impl<'a> SingleEnvTypechecker<'a> {
     // based on the precise EUIDs when they're not actions, so we only look at
     // entity types. The type will be `False` is none of the entities on the rhs
     // have a type which may be an ancestor of the rhs entity type.
-    fn type_of_non_action_in_entities<'b, 'c>(
+    fn type_of_non_action_in_entities<'b>(
         &self,
         lhs: &EntityUID,
-        rhs: &'c [EntityUID],
+        rhs: &[EntityUID],
         in_expr: &Expr,
         lhs_expr: Expr<Option<Type>>,
         rhs_expr: Expr<Option<Type>>,
@@ -2249,7 +2248,7 @@ impl<'a> SingleEnvTypechecker<'a> {
 
     /// Check if the entity is in the list of descendants. Return the singleton
     /// type false if it is not, and boolean otherwise.
-    fn entity_in_descendants<'b, 'c, K: 'c>(
+    fn entity_in_descendants<'b, 'c, K>(
         lhs_entity: &K,
         rhs_descendants: impl IntoIterator<Item = &'c K>,
         in_expr: &Expr,
@@ -2257,7 +2256,7 @@ impl<'a> SingleEnvTypechecker<'a> {
         rhs_expr: Expr<Option<Type>>,
     ) -> TypecheckAnswer<'b>
     where
-        K: PartialEq + 'a,
+        K: PartialEq + 'c,
     {
         let is_var_in_descendants = rhs_descendants.into_iter().any(|e| e == lhs_entity);
         TypecheckAnswer::success(
diff --git a/cedar-policy-validator/src/types.rs b/cedar-policy-validator/src/types.rs
index bbd2711d..60fc3a06 100644
--- a/cedar-policy-validator/src/types.rs
+++ b/cedar-policy-validator/src/types.rs
@@ -387,7 +387,7 @@ impl Type {
                 entity_lub.lub_elements.iter().any(|entity| {
                     schema
                         .get_entity_type(entity)
-                        .map_or(false, |entity_type| entity_type.attr(attr).is_some())
+                        .is_some_and(|entity_type| entity_type.attr(attr).is_some())
                 })
             }
             // UBs of ActionEntities are AnyEntity. So if we have an ActionEntity here its attrs are known.
@@ -2870,7 +2870,7 @@ mod test {
     }
 
     #[track_caller] // report the caller's location as the location of the panic, not the location in this function
-    fn assert_type_display_roundtrip(ty: Type) {
+    fn assert_type_display_roundtrip(ty: &Type) {
         // test that a common type declaration using this type roundtrips properly
         let type_str = format!("type T = {ty}; entity E {{ foo: T }};");
         println!("{type_str}");
@@ -2883,24 +2883,24 @@ mod test {
                 .attr("foo")
                 .unwrap()
                 .attr_type,
-            &ty,
+            ty,
         );
     }
 
     #[test]
     fn type_display_roundtrip() {
-        assert_type_display_roundtrip(Type::primitive_boolean());
-        assert_type_display_roundtrip(Type::primitive_long());
-        assert_type_display_roundtrip(Type::primitive_string());
-        assert_type_display_roundtrip(Type::set(Type::primitive_boolean()));
-        assert_type_display_roundtrip(Type::set(Type::primitive_string()));
-        assert_type_display_roundtrip(Type::set(Type::primitive_long()));
-        assert_type_display_roundtrip(Type::closed_record_with_attributes(None));
-        assert_type_display_roundtrip(Type::closed_record_with_attributes([(
+        assert_type_display_roundtrip(&Type::primitive_boolean());
+        assert_type_display_roundtrip(&Type::primitive_long());
+        assert_type_display_roundtrip(&Type::primitive_string());
+        assert_type_display_roundtrip(&Type::set(Type::primitive_boolean()));
+        assert_type_display_roundtrip(&Type::set(Type::primitive_string()));
+        assert_type_display_roundtrip(&Type::set(Type::primitive_long()));
+        assert_type_display_roundtrip(&Type::closed_record_with_attributes(None));
+        assert_type_display_roundtrip(&Type::closed_record_with_attributes([(
             "a".into(),
             AttributeType::required_attribute(Type::primitive_boolean()),
         )]));
-        assert_type_display_roundtrip(Type::closed_record_with_attributes([
+        assert_type_display_roundtrip(&Type::closed_record_with_attributes([
             (
                 "a".into(),
                 AttributeType::required_attribute(Type::primitive_boolean()),
@@ -2913,7 +2913,7 @@ mod test {
     }
 
     #[track_caller] // report the caller's location as the location of the panic, not the location in this function
-    fn assert_displays_as(ty: Type, repr: &str) {
+    fn assert_displays_as(ty: &Type, repr: &str) {
         assert_eq!(
             ty.to_string(),
             repr,
@@ -2929,24 +2929,27 @@ mod test {
         // checks that they are defined already, so we'd need to provide a
         // complete schema. TODO: the final stage of schema parsing already does
         // this. Can we remove duplicated checks from Cedar schema parsing?
-        assert_displays_as(Type::named_entity_reference_from_str("Foo"), "Foo");
+        assert_displays_as(&Type::named_entity_reference_from_str("Foo"), "Foo");
         assert_displays_as(
-            Type::named_entity_reference_from_str("Foo::Bar"),
+            &Type::named_entity_reference_from_str("Foo::Bar"),
             "Foo::Bar",
         );
         assert_displays_as(
-            Type::named_entity_reference_from_str("Foo::Bar::Baz"),
+            &Type::named_entity_reference_from_str("Foo::Bar::Baz"),
             "Foo::Bar::Baz",
         );
 
         // These type aren't representable in a schema.
-        assert_displays_as(Type::Never, "__cedar::internal::Never");
-        assert_displays_as(Type::True, "__cedar::internal::True");
-        assert_displays_as(Type::False, "__cedar::internal::False");
-        assert_displays_as(Type::any_set(), "Set<__cedar::internal::Any>");
-        assert_displays_as(Type::any_entity_reference(), "__cedar::internal::AnyEntity");
+        assert_displays_as(&Type::Never, "__cedar::internal::Never");
+        assert_displays_as(&Type::True, "__cedar::internal::True");
+        assert_displays_as(&Type::False, "__cedar::internal::False");
+        assert_displays_as(&Type::any_set(), "Set<__cedar::internal::Any>");
         assert_displays_as(
-            Type::least_upper_bound(
+            &Type::any_entity_reference(),
+            "__cedar::internal::AnyEntity",
+        );
+        assert_displays_as(
+            &Type::least_upper_bound(
                 &ValidatorSchema::empty(),
                 &Type::named_entity_reference_from_str("Foo"),
                 &Type::named_entity_reference_from_str("Bar"),
@@ -2961,6 +2964,6 @@ mod test {
     #[cfg(feature = "ipaddr")]
     fn test_extension_type_display() {
         let ipaddr = Name::parse_unqualified_name("ipaddr").expect("should be a valid identifier");
-        assert_type_display_roundtrip(Type::extension(ipaddr));
+        assert_type_display_roundtrip(&Type::extension(ipaddr));
     }
 }
diff --git a/cedar-policy/src/api.rs b/cedar-policy/src/api.rs
index 69df9eed..7118ff5e 100644
--- a/cedar-policy/src/api.rs
+++ b/cedar-policy/src/api.rs
@@ -1535,7 +1535,7 @@ impl SchemaFragment {
     pub fn action_annotations(
         &self,
         namespace: Option<EntityNamespace>,
-        id: EntityId,
+        id: &EntityId,
     ) -> Option<impl Iterator<Item = (&str, &str)>> {
         let ns_def = self.lossless.0.get(&namespace.map(|n| n.0))?;
         ns_def
@@ -1554,7 +1554,7 @@ impl SchemaFragment {
     pub fn action_annotation(
         &self,
         namespace: Option<EntityNamespace>,
-        id: EntityId,
+        id: &EntityId,
         annotation_key: impl AsRef<str>,
     ) -> Option<&str> {
         let ns_def = self.lossless.0.get(&namespace.map(|n| n.0))?;
diff --git a/cedar-policy/src/api/err.rs b/cedar-policy/src/api/err.rs
index c02893e0..b619680b 100644
--- a/cedar-policy/src/api/err.rs
+++ b/cedar-policy/src/api/err.rs
@@ -198,7 +198,9 @@ pub mod to_cedar_syntax_errors {
     impl NameCollisionsError {
         /// Get the names that had collisions
         pub fn names(&self) -> impl Iterator<Item = &str> {
-            self.names_as_strings.iter().map(|s| s.as_str())
+            self.names_as_strings
+                .iter()
+                .map(std::string::String::as_str)
         }
     }
 }


Test patch:
diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml
index 45b66ff0..a5ca5f0c 100644
--- a/.github/workflows/build_and_test.yml
+++ b/.github/workflows/build_and_test.yml
@@ -20,6 +20,7 @@ jobs:
       - uses: actions/checkout@v4
       - run: sudo apt-get install protobuf-compiler
       - run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }}
+      - run: cargo install cargo-audit --locked
       - run: ./panic_safety.sh
       - run: cargo doc --all-features --no-deps
 
diff --git a/cedar-policy-validator/src/cedar_schema/test.rs b/cedar-policy-validator/src/cedar_schema/test.rs
index 1813d125..6607248b 100644
--- a/cedar-policy-validator/src/cedar_schema/test.rs
+++ b/cedar-policy-validator/src/cedar_schema/test.rs
@@ -563,7 +563,7 @@ namespace Baz {action "Foo" appliesTo {
                         type_name: "UserGroup".parse().unwrap(),
                     }, loc: None};
                 let attribute = attributes.get(group).expect("No attribute `{group}`");
-                assert_has_type(attribute, expected);
+                assert_has_type(attribute, &expected);
             });
         }
         let issue = github
@@ -578,14 +578,14 @@ namespace Baz {action "Foo" appliesTo {
             let attribute = attributes.get("repo").expect("No `repo`");
             assert_has_type(
                 attribute,
-                json_schema::Type::Type { ty: json_schema::TypeVariant::EntityOrCommon {
+                &json_schema::Type::Type { ty: json_schema::TypeVariant::EntityOrCommon {
                     type_name: "Repository".parse().unwrap(),
                 }, loc: None },
             );
             let attribute = attributes.get("reporter").expect("No `repo`");
             assert_has_type(
                 attribute,
-                json_schema::Type::Type { ty: json_schema::TypeVariant::EntityOrCommon {
+                &json_schema::Type::Type { ty: json_schema::TypeVariant::EntityOrCommon {
                     type_name: "User".parse().unwrap(),
                 }, loc: None },
             );
@@ -605,7 +605,7 @@ namespace Baz {action "Foo" appliesTo {
                     type_name: "UserGroup".parse().unwrap(),
                 }, loc: None };
                 let attribute = attributes.get(group).expect("No attribute `{group}`");
-                assert_has_type(attribute, expected);
+                assert_has_type(attribute, &expected);
             });
         }
     }
@@ -613,10 +613,10 @@ namespace Baz {action "Foo" appliesTo {
     #[track_caller]
     fn assert_has_type<N: std::fmt::Debug + PartialEq>(
         e: &json_schema::TypeOfAttribute<N>,
-        expected: json_schema::Type<N>,
+        expected: &json_schema::Type<N>,
     ) {
         assert!(e.required);
-        assert_eq!(&e.ty, &expected);
+        assert_eq!(&e.ty, expected);
     }
 
     #[track_caller]
@@ -666,13 +666,13 @@ namespace Baz {action "Foo" appliesTo {
         }), loc: Some(_) }) => {
             assert_has_type(
                 attributes.get("personalGroup").unwrap(),
-                json_schema::Type::Type { ty: json_schema::TypeVariant::EntityOrCommon {
+                &json_schema::Type::Type { ty: json_schema::TypeVariant::EntityOrCommon {
                     type_name: "Group".parse().unwrap(),
                 }, loc: None }, // we do expect a `loc`, but `assert_has_type()` will ignore the mismatch in presence of `loc`. We have separate tests for the correctness of `loc`s coming from the Cedar schema syntax in a test module called `preserves_source_locations`.
             );
             assert_has_type(
                 attributes.get("blocked").unwrap(),
-                json_schema::Type::Type { ty: json_schema::TypeVariant::Set {
+                &json_schema::Type::Type { ty: json_schema::TypeVariant::Set {
                     element: Box::new(json_schema::Type::Type { ty: json_schema::TypeVariant::EntityOrCommon {
                         type_name: "User".parse().unwrap(),
                     }, loc: None }), // we do expect a `loc`, but `assert_has_type()` will ignore the mismatch in presence of `loc`. We have separate tests for the correctness of `loc`s coming from the Cedar schema syntax in a test module called `preserves_source_locations`.
@@ -693,7 +693,7 @@ namespace Baz {action "Foo" appliesTo {
         }), loc: Some(_) }) => {
             assert_has_type(
                 attributes.get("owner").unwrap(),
-                json_schema::Type::Type { ty: json_schema::TypeVariant::EntityOrCommon {
+                &json_schema::Type::Type { ty: json_schema::TypeVariant::EntityOrCommon {
                     type_name: "User".parse().unwrap(),
                 }, loc: None },
             );
@@ -709,37 +709,37 @@ namespace Baz {action "Foo" appliesTo {
         }), loc: Some(_) }) => {
             assert_has_type(
                 attributes.get("owner").unwrap(),
-                json_schema::Type::Type { ty: json_schema::TypeVariant::EntityOrCommon {
+                &json_schema::Type::Type { ty: json_schema::TypeVariant::EntityOrCommon {
                     type_name: "User".parse().unwrap(),
                 }, loc: None },
             );
             assert_has_type(
                 attributes.get("isPrivate").unwrap(),
-                json_schema::Type::Type { ty: json_schema::TypeVariant::EntityOrCommon {
+                &json_schema::Type::Type { ty: json_schema::TypeVariant::EntityOrCommon {
                     type_name: "Bool".parse().unwrap(),
                 }, loc: None },
             );
             assert_has_type(
                 attributes.get("publicAccess").unwrap(),
-                json_schema::Type::Type { ty: json_schema::TypeVariant::EntityOrCommon {
+                &json_schema::Type::Type { ty: json_schema::TypeVariant::EntityOrCommon {
                     type_name: "String".parse().unwrap(),
                 }, loc: None },
             );
             assert_has_type(
                 attributes.get("viewACL").unwrap(),
-                json_schema::Type::Type { ty: json_schema::TypeVariant::EntityOrCommon {
+                &json_schema::Type::Type { ty: json_schema::TypeVariant::EntityOrCommon {
                     type_name: "DocumentShare".parse().unwrap(),
                 }, loc: None },
             );
             assert_has_type(
                 attributes.get("modifyACL").unwrap(),
-                json_schema::Type::Type { ty: json_schema::TypeVariant::EntityOrCommon {
+                &json_schema::Type::Type { ty: json_schema::TypeVariant::EntityOrCommon {
                     type_name: "DocumentShare".parse().unwrap(),
                 }, loc: None },
             );
             assert_has_type(
                 attributes.get("manageACL").unwrap(),
-                json_schema::Type::Type { ty: json_schema::TypeVariant::EntityOrCommon {
+                &json_schema::Type::Type { ty: json_schema::TypeVariant::EntityOrCommon {
                     type_name: "DocumentShare".parse().unwrap(),
                 }, loc: None },
             );
@@ -1970,13 +1970,13 @@ mod translator_tests {
     }
 
     #[track_caller]
-    fn test_translation(src: &str, json_value: serde_json::Value) {
+    fn test_translation(src: &str, json_value: &serde_json::Value) {
         let (schema, _) = cedar_schema_to_json_schema(
             parse_schema(src).expect("should parse Cedar schema"),
             Extensions::none(),
         )
         .expect("should translate to JSON schema");
-        assert_eq!(serde_json::to_value(schema).unwrap(), json_value);
+        assert_eq!(&serde_json::to_value(schema).unwrap(), json_value);
     }
 
     #[test]
@@ -1984,7 +1984,7 @@ mod translator_tests {
         for id in SPECIAL_IDS {
             test_translation(
                 &format!("@{id} entity User {{}};"),
-                serde_json::json!({
+                &serde_json::json!({
                     "": {
                         "entityTypes": {
                             "User": {
@@ -2012,7 +2012,7 @@ mod translator_tests {
               entity E;
             }
             "#,
-            serde_json::json!({
+            &serde_json::json!({
                 "N": {
                     "entityTypes": {
                         "E": {}
@@ -2035,7 +2035,7 @@ mod translator_tests {
             @comment("B->A")
             type B = A;
             "#,
-            serde_json::json!({
+            &serde_json::json!({
                 "": {
                     "entityTypes": {},
                     "actions": {},
@@ -2073,7 +2073,7 @@ mod translator_tests {
             @ae("🌎")
             entity Earth;
             "#,
-            serde_json::json!({
+            &serde_json::json!({
                 "": {
                     "entityTypes": {
                         "Earth": {
@@ -2107,7 +2107,7 @@ mod translator_tests {
             @ae("🍎🍏")
             entity Apple1, Apple2;
             "#,
-            serde_json::json!({
+            &serde_json::json!({
                 "": {
                     "entityTypes": {
                         "Apple1": {
@@ -2143,7 +2143,7 @@ mod translator_tests {
                 resource: Earth,
             };
             "#,
-            serde_json::json!({
+            &serde_json::json!({
                 "": {
                     "entityTypes": {},
                     "actions": {
@@ -2202,7 +2202,7 @@ mod translator_tests {
                 }
             };
             "#,
-            serde_json::json!({
+            &serde_json::json!({
                 "": {
                     "entityTypes": {},
                     "actions": {},
diff --git a/cedar-policy-validator/src/schema/test_579.rs b/cedar-policy-validator/src/schema/test_579.rs
index 23c22a3d..fb65023e 100644
--- a/cedar-policy-validator/src/schema/test_579.rs
+++ b/cedar-policy-validator/src/schema/test_579.rs
@@ -101,10 +101,10 @@ fn assert_parse_error_cedar(s: &str, e: &ExpectedErrorMessage<'_>) {
 }
 
 #[track_caller]
-fn assert_parse_error_json(v: serde_json::Value, e: &ExpectedErrorMessage<'_>) {
-    println!("{}", serde_json::to_string_pretty(&v).unwrap());
+fn assert_parse_error_json(v: &serde_json::Value, e: &ExpectedErrorMessage<'_>) {
+    println!("{}", serde_json::to_string_pretty(v).unwrap());
     assert_matches!(ValidatorSchema::from_json_value(v.clone(), Extensions::all_available()), Err(err) => {
-        expect_err(&v, &miette::Report::new(err), e);
+        expect_err(v, &miette::Report::new(err), e);
     });
 }
 
@@ -1153,7 +1153,7 @@ fn A1c() {
             .exactly_one_underline("MyType")
             .build();
     assert_parse_error_cedar(&c_cedar(A1_cedar()), &expected_cedar);
-    assert_parse_error_json(A1X1_json(c_json()), &expected_json);
+    assert_parse_error_json(&A1X1_json(c_json()), &expected_json);
 }
 #[test]
 fn A2a1() {
@@ -1176,7 +1176,7 @@ fn A2b1() {
         .exactly_one_underline("NS1::MyType")
         .build();
     assert_parse_error_cedar(&b1_cedar(A2_cedar()), &expected_cedar);
-    assert_parse_error_json(A2X1_json(b1_json()), &expected_json);
+    assert_parse_error_json(&A2X1_json(b1_json()), &expected_json);
 }
 #[test]
 fn A2b2() {
@@ -1189,7 +1189,7 @@ fn A2b2() {
         .exactly_one_underline("NS1::MyType")
         .build();
     assert_parse_error_cedar(&b2_cedar(A2_cedar()), &expected_cedar);
-    assert_parse_error_json(A2X2_json(b2_json()), &expected_json);
+    assert_parse_error_json(&A2X2_json(b2_json()), &expected_json);
 }
 #[test]
 fn A2c() {
@@ -1202,7 +1202,7 @@ fn A2c() {
         .exactly_one_underline("NS1::MyType")
         .build();
     assert_parse_error_cedar(&c_cedar(A2_cedar()), &expected_cedar);
-    assert_parse_error_json(A2X1_json(c_json()), &expected_json);
+    assert_parse_error_json(&A2X1_json(c_json()), &expected_json);
 }
 #[test]
 fn A3a1() {
@@ -1215,7 +1215,7 @@ fn A3a1() {
         .exactly_one_underline("NS2::MyType")
         .build();
     assert_parse_error_cedar(&a1_cedar(A3_cedar()), &expected_cedar);
-    assert_parse_error_json(A3X1_json(a1_json()), &expected_json);
+    assert_parse_error_json(&A3X1_json(a1_json()), &expected_json);
 }
 #[test]
 fn A3a2() {
@@ -1228,7 +1228,7 @@ fn A3a2() {
         .exactly_one_underline("NS2::MyType")
         .build();
     assert_parse_error_cedar(&a2_cedar(A3_cedar()), &expected_cedar);
-    assert_parse_error_json(A3X2_json(a2_json()), &expected_json);
+    assert_parse_error_json(&A3X2_json(a2_json()), &expected_json);
 }
 #[test]
 fn A3b1() {
@@ -1241,7 +1241,7 @@ fn A3b1() {
         .exactly_one_underline("NS2::MyType")
         .build();
     assert_parse_error_cedar(&b1_cedar(A3_cedar()), &expected_cedar);
-    assert_parse_error_json(A3X1_json(b1_json()), &expected_json);
+    assert_parse_error_json(&A3X1_json(b1_json()), &expected_json);
 }
 #[test]
 fn A3b2() {
@@ -1254,7 +1254,7 @@ fn A3b2() {
         .exactly_one_underline("NS2::MyType")
         .build();
     assert_parse_error_cedar(&b2_cedar(A3_cedar()), &expected_cedar);
-    assert_parse_error_json(A3X2_json(b2_json()), &expected_json);
+    assert_parse_error_json(&A3X2_json(b2_json()), &expected_json);
 }
 #[test]
 fn A3c() {
@@ -1267,7 +1267,7 @@ fn A3c() {
         .exactly_one_underline("NS2::MyType")
         .build();
     assert_parse_error_cedar(&c_cedar(A3_cedar()), &expected_cedar);
-    assert_parse_error_json(A3X1_json(c_json()), &expected_json);
+    assert_parse_error_json(&A3X1_json(c_json()), &expected_json);
 }
 #[test]
 fn A3d1() {
@@ -1312,7 +1312,7 @@ fn B1c() {
             .exactly_one_underline("MyType")
             .build();
     assert_parse_error_cedar(&c_cedar(B1_cedar()), &expected_cedar);
-    assert_parse_error_json(B1X1_json(c_json()), &expected_json);
+    assert_parse_error_json(&B1X1_json(c_json()), &expected_json);
 }
 #[test]
 fn B2a1() {
@@ -1335,7 +1335,7 @@ fn B2b1() {
         .exactly_one_underline("NS1::MyType")
         .build();
     assert_parse_error_cedar(&b1_cedar(B2_cedar()), &expected_cedar);
-    assert_parse_error_json(B2X1_json(b1_json()), &expected_json);
+    assert_parse_error_json(&B2X1_json(b1_json()), &expected_json);
 }
 #[test]
 fn B2b2() {
@@ -1348,7 +1348,7 @@ fn B2b2() {
         .exactly_one_underline("NS1::MyType")
         .build();
     assert_parse_error_cedar(&b2_cedar(B2_cedar()), &expected_cedar);
-    assert_parse_error_json(B2X2_json(b2_json()), &expected_json);
+    assert_parse_error_json(&B2X2_json(b2_json()), &expected_json);
 }
 #[test]
 fn B2c() {
@@ -1361,7 +1361,7 @@ fn B2c() {
         .exactly_one_underline("NS1::MyType")
         .build();
     assert_parse_error_cedar(&c_cedar(B2_cedar()), &expected_cedar);
-    assert_parse_error_json(B2X1_json(c_json()), &expected_json);
+    assert_parse_error_json(&B2X1_json(c_json()), &expected_json);
 }
 #[test]
 fn B3a1() {
@@ -1374,7 +1374,7 @@ fn B3a1() {
         .exactly_one_underline("NS2::MyType")
         .build();
     assert_parse_error_cedar(&a1_cedar(B3_cedar()), &expected_cedar);
-    assert_parse_error_json(B3X1_json(a1_json()), &expected_json);
+    assert_parse_error_json(&B3X1_json(a1_json()), &expected_json);
 }
 #[test]
 fn B3a2() {
@@ -1387,7 +1387,7 @@ fn B3a2() {
         .exactly_one_underline("NS2::MyType")
         .build();
     assert_parse_error_cedar(&a2_cedar(B3_cedar()), &expected_cedar);
-    assert_parse_error_json(B3X2_json(a2_json()), &expected_json);
+    assert_parse_error_json(&B3X2_json(a2_json()), &expected_json);
 }
 #[test]
 fn B3b1() {
@@ -1400,7 +1400,7 @@ fn B3b1() {
         .exactly_one_underline("NS2::MyType")
         .build();
     assert_parse_error_cedar(&b1_cedar(B3_cedar()), &expected_cedar);
-    assert_parse_error_json(B3X1_json(b1_json()), &expected_json);
+    assert_parse_error_json(&B3X1_json(b1_json()), &expected_json);
 }
 #[test]
 fn B3b2() {
@@ -1413,7 +1413,7 @@ fn B3b2() {
         .exactly_one_underline("NS2::MyType")
         .build();
     assert_parse_error_cedar(&b2_cedar(B3_cedar()), &expected_cedar);
-    assert_parse_error_json(B3X2_json(b2_json()), &expected_json);
+    assert_parse_error_json(&B3X2_json(b2_json()), &expected_json);
 }
 #[test]
 fn B3c() {
@@ -1426,7 +1426,7 @@ fn B3c() {
         .exactly_one_underline("NS2::MyType")
         .build();
     assert_parse_error_cedar(&c_cedar(B3_cedar()), &expected_cedar);
-    assert_parse_error_json(B3X1_json(c_json()), &expected_json);
+    assert_parse_error_json(&B3X1_json(c_json()), &expected_json);
 }
 #[test]
 fn B3d1() {
@@ -1471,7 +1471,7 @@ fn C1c() {
             .exactly_one_underline("MyType")
             .build();
     assert_parse_error_cedar(&c_cedar(C1_cedar()), &expected_cedar);
-    assert_parse_error_json(C1X1_json(c_json()), &expected_json);
+    assert_parse_error_json(&C1X1_json(c_json()), &expected_json);
 }
 #[test]
 fn C2a1() {
@@ -1494,7 +1494,7 @@ fn C2b1() {
         .exactly_one_underline("NS1::MyType")
         .build();
     assert_parse_error_cedar(&b1_cedar(C2_cedar()), &expected_cedar);
-    assert_parse_error_json(C2X1_json(b1_json()), &expected_json);
+    assert_parse_error_json(&C2X1_json(b1_json()), &expected_json);
 }
 #[test]
 fn C2b2() {
@@ -1507,7 +1507,7 @@ fn C2b2() {
         .exactly_one_underline("NS1::MyType")
         .build();
     assert_parse_error_cedar(&b2_cedar(C2_cedar()), &expected_cedar);
-    assert_parse_error_json(C2X2_json(b2_json()), &expected_json);
+    assert_parse_error_json(&C2X2_json(b2_json()), &expected_json);
 }
 #[test]
 fn C2c() {
@@ -1520,7 +1520,7 @@ fn C2c() {
         .exactly_one_underline("NS1::MyType")
         .build();
     assert_parse_error_cedar(&c_cedar(C2_cedar()), &expected_cedar);
-    assert_parse_error_json(C2X1_json(c_json()), &expected_json);
+    assert_parse_error_json(&C2X1_json(c_json()), &expected_json);
 }
 #[test]
 fn C3a1() {
@@ -1533,7 +1533,7 @@ fn C3a1() {
         .exactly_one_underline("NS2::MyType")
         .build();
     assert_parse_error_cedar(&a1_cedar(C3_cedar()), &expected_cedar);
-    assert_parse_error_json(C3X1_json(a1_json()), &expected_json);
+    assert_parse_error_json(&C3X1_json(a1_json()), &expected_json);
 }
 #[test]
 fn C3a2() {
@@ -1546,7 +1546,7 @@ fn C3a2() {
         .exactly_one_underline("NS2::MyType")
         .build();
     assert_parse_error_cedar(&a2_cedar(C3_cedar()), &expected_cedar);
-    assert_parse_error_json(C3X2_json(a2_json()), &expected_json);
+    assert_parse_error_json(&C3X2_json(a2_json()), &expected_json);
 }
 #[test]
 fn C3b1() {
@@ -1559,7 +1559,7 @@ fn C3b1() {
         .exactly_one_underline("NS2::MyType")
         .build();
     assert_parse_error_cedar(&b1_cedar(C3_cedar()), &expected_cedar);
-    assert_parse_error_json(C3X1_json(b1_json()), &expected_json);
+    assert_parse_error_json(&C3X1_json(b1_json()), &expected_json);
 }
 #[test]
 fn C3b2() {
@@ -1572,7 +1572,7 @@ fn C3b2() {
         .exactly_one_underline("NS2::MyType")
         .build();
     assert_parse_error_cedar(&b2_cedar(C3_cedar()), &expected_cedar);
-    assert_parse_error_json(C3X2_json(b2_json()), &expected_json);
+    assert_parse_error_json(&C3X2_json(b2_json()), &expected_json);
 }
 #[test]
 fn C3c() {
@@ -1585,7 +1585,7 @@ fn C3c() {
         .exactly_one_underline("NS2::MyType")
         .build();
     assert_parse_error_cedar(&c_cedar(C3_cedar()), &expected_cedar);
-    assert_parse_error_json(C3X1_json(c_json()), &expected_json);
+    assert_parse_error_json(&C3X1_json(c_json()), &expected_json);
 }
 #[test]
 fn C3d1() {
@@ -1614,7 +1614,7 @@ fn D1a2() {
             .exactly_one_underline("MyType")
             .build();
     assert_parse_error_cedar(&a2_cedar(D1_cedar()), &expected);
-    assert_parse_error_json(D1_json(a2_json()), &expected);
+    assert_parse_error_json(&D1_json(a2_json()), &expected);
 }
 #[test]
 fn D1b1() {
@@ -1633,7 +1633,7 @@ fn D1b2() {
             .exactly_one_underline("MyType")
             .build();
     assert_parse_error_cedar(&b2_cedar(D1_cedar()), &expected);
-    assert_parse_error_json(D1_json(b2_json()), &expected);
+    assert_parse_error_json(&D1_json(b2_json()), &expected);
 }
 #[test]
 fn D1c() {
@@ -1643,7 +1643,7 @@ fn D1c() {
             .exactly_one_underline("MyType")
             .build();
     assert_parse_error_cedar(&c_cedar(D1_cedar()), &expected);
-    assert_parse_error_json(D1_json(c_json()), &expected);
+    assert_parse_error_json(&D1_json(c_json()), &expected);
 }
 #[test]
 fn D2a1() {
@@ -1661,7 +1661,7 @@ fn D2a2() {
         .exactly_one_underline("NS1::MyType")
         .build();
     assert_parse_error_cedar(&a2_cedar(D2_cedar()), &expected);
-    assert_parse_error_json(D2_json(a2_json()), &expected);
+    assert_parse_error_json(&D2_json(a2_json()), &expected);
 }
 #[test]
 fn D2b1() {
@@ -1670,7 +1670,7 @@ fn D2b1() {
         .exactly_one_underline("NS1::MyType")
         .build();
     assert_parse_error_cedar(&b1_cedar(D2_cedar()), &expected);
-    assert_parse_error_json(D2_json(b1_json()), &expected);
+    assert_parse_error_json(&D2_json(b1_json()), &expected);
 }
 #[test]
 fn D2b2() {
@@ -1679,7 +1679,7 @@ fn D2b2() {
         .exactly_one_underline("NS1::MyType")
         .build();
     assert_parse_error_cedar(&b2_cedar(D2_cedar()), &expected);
-    assert_parse_error_json(D2_json(b2_json()), &expected);
+    assert_parse_error_json(&D2_json(b2_json()), &expected);
 }
 #[test]
 fn D2c() {
@@ -1688,7 +1688,7 @@ fn D2c() {
         .exactly_one_underline("NS1::MyType")
         .build();
     assert_parse_error_cedar(&c_cedar(D2_cedar()), &expected);
-    assert_parse_error_json(D2_json(c_json()), &expected);
+    assert_parse_error_json(&D2_json(c_json()), &expected);
 }
 #[test]
 fn D3a1() {
@@ -1697,7 +1697,7 @@ fn D3a1() {
         .exactly_one_underline("NS2::MyType")
         .build();
     assert_parse_error_cedar(&a1_cedar(D3_cedar()), &expected);
-    assert_parse_error_json(D3_json(a1_json()), &expected);
+    assert_parse_error_json(&D3_json(a1_json()), &expected);
 }
 #[test]
 fn D3a2() {
@@ -1706,7 +1706,7 @@ fn D3a2() {
         .exactly_one_underline("NS2::MyType")
         .build();
     assert_parse_error_cedar(&a2_cedar(D3_cedar()), &expected);
-    assert_parse_error_json(D3_json(a2_json()), &expected);
+    assert_parse_error_json(&D3_json(a2_json()), &expected);
 }
 #[test]
 fn D3b1() {
@@ -1715,7 +1715,7 @@ fn D3b1() {
         .exactly_one_underline("NS2::MyType")
         .build();
     assert_parse_error_cedar(&b1_cedar(D3_cedar()), &expected);
-    assert_parse_error_json(D3_json(b1_json()), &expected);
+    assert_parse_error_json(&D3_json(b1_json()), &expected);
 }
 #[test]
 fn D3b2() {
@@ -1724,7 +1724,7 @@ fn D3b2() {
         .exactly_one_underline("NS2::MyType")
         .build();
     assert_parse_error_cedar(&b2_cedar(D3_cedar()), &expected);
-    assert_parse_error_json(D3_json(b2_json()), &expected);
+    assert_parse_error_json(&D3_json(b2_json()), &expected);
 }
 #[test]
 fn D3c() {
@@ -1733,7 +1733,7 @@ fn D3c() {
         .exactly_one_underline("NS2::MyType")
         .build();
     assert_parse_error_cedar(&c_cedar(D3_cedar()), &expected);
-    assert_parse_error_json(D3_json(c_json()), &expected);
+    assert_parse_error_json(&D3_json(c_json()), &expected);
 }
 #[test]
 fn D3d1() {
@@ -1751,7 +1751,7 @@ fn D3d2() {
         .exactly_one_underline("NS2::MyType")
         .build();
     assert_parse_error_cedar(&d2_cedar(D3_cedar()), &expected);
-    assert_parse_error_json(D3_json(d2_json()), &expected);
+    assert_parse_error_json(&D3_json(d2_json()), &expected);
 }
 #[test]
 fn E1a1() {
@@ -1770,7 +1770,7 @@ fn E1a2() {
             .exactly_one_underline("MyType")
             .build();
     assert_parse_error_cedar(&a2_cedar(E1_cedar()), &expected);
-    assert_parse_error_json(E1_json(a2_json()), &expected);
+    assert_parse_error_json(&E1_json(a2_json()), &expected);
 }
 #[test]
 fn E1b1() {
@@ -1789,7 +1789,7 @@ fn E1b2() {
             .exactly_one_underline("MyType")
             .build();
     assert_parse_error_cedar(&b2_cedar(E1_cedar()), &expected);
-    assert_parse_error_json(E1_json(b2_json()), &expected);
+    assert_parse_error_json(&E1_json(b2_json()), &expected);
 }
 #[test]
 fn E1c() {
@@ -1799,7 +1799,7 @@ fn E1c() {
             .exactly_one_underline("MyType")
             .build();
     assert_parse_error_cedar(&c_cedar(E1_cedar()), &expected);
-    assert_parse_error_json(E1_json(c_json()), &expected);
+    assert_parse_error_json(&E1_json(c_json()), &expected);
 }
 #[test]
 fn E2a1() {
@@ -1817,7 +1817,7 @@ fn E2a2() {
         .exactly_one_underline("NS1::MyType")
         .build();
     assert_parse_error_cedar(&a2_cedar(E2_cedar()), &expected);
-    assert_parse_error_json(E2_json(a2_json()), &expected);
+    assert_parse_error_json(&E2_json(a2_json()), &expected);
 }
 #[test]
 fn E2b1() {
@@ -1826,7 +1826,7 @@ fn E2b1() {
         .exactly_one_underline("NS1::MyType")
         .build();
     assert_parse_error_cedar(&b1_cedar(E2_cedar()), &expected);
-    assert_parse_error_json(E2_json(b1_json()), &expected);
+    assert_parse_error_json(&E2_json(b1_json()), &expected);
 }
 #[test]
 fn E2b2() {
@@ -1835,7 +1835,7 @@ fn E2b2() {
         .exactly_one_underline("NS1::MyType")
         .build();
     assert_parse_error_cedar(&b2_cedar(E2_cedar()), &expected);
-    assert_parse_error_json(E2_json(b2_json()), &expected);
+    assert_parse_error_json(&E2_json(b2_json()), &expected);
 }
 #[test]
 fn E2c() {
@@ -1844,7 +1844,7 @@ fn E2c() {
         .exactly_one_underline("NS1::MyType")
         .build();
     assert_parse_error_cedar(&c_cedar(E2_cedar()), &expected);
-    assert_parse_error_json(E2_json(c_json()), &expected);
+    assert_parse_error_json(&E2_json(c_json()), &expected);
 }
 #[test]
 fn E3a1() {
@@ -1853,7 +1853,7 @@ fn E3a1() {
         .exactly_one_underline("NS2::MyType")
         .build();
     assert_parse_error_cedar(&a1_cedar(E3_cedar()), &expected);
-    assert_parse_error_json(E3_json(a1_json()), &expected);
+    assert_parse_error_json(&E3_json(a1_json()), &expected);
 }
 #[test]
 fn E3a2() {
@@ -1862,7 +1862,7 @@ fn E3a2() {
         .exactly_one_underline("NS2::MyType")
         .build();
     assert_parse_error_cedar(&a2_cedar(E3_cedar()), &expected);
-    assert_parse_error_json(E3_json(a2_json()), &expected);
+    assert_parse_error_json(&E3_json(a2_json()), &expected);
 }
 #[test]
 fn E3b1() {
@@ -1871,7 +1871,7 @@ fn E3b1() {
         .exactly_one_underline("NS2::MyType")
         .build();
     assert_parse_error_cedar(&b1_cedar(E3_cedar()), &expected);
-    assert_parse_error_json(E3_json(b1_json()), &expected);
+    assert_parse_error_json(&E3_json(b1_json()), &expected);
 }
 #[test]
 fn E3b2() {
@@ -1880,7 +1880,7 @@ fn E3b2() {
         .exactly_one_underline("NS2::MyType")
         .build();
     assert_parse_error_cedar(&b2_cedar(E3_cedar()), &expected);
-    assert_parse_error_json(E3_json(b2_json()), &expected);
+    assert_parse_error_json(&E3_json(b2_json()), &expected);
 }
 #[test]
 fn E3c() {
@@ -1889,7 +1889,7 @@ fn E3c() {
         .exactly_one_underline("NS2::MyType")
         .build();
     assert_parse_error_cedar(&c_cedar(E3_cedar()), &expected);
-    assert_parse_error_json(E3_json(c_json()), &expected);
+    assert_parse_error_json(&E3_json(c_json()), &expected);
 }
 #[test]
 fn E3d1() {
@@ -1907,7 +1907,7 @@ fn E3d2() {
         .exactly_one_underline("NS2::MyType")
         .build();
     assert_parse_error_cedar(&d2_cedar(E3_cedar()), &expected);
-    assert_parse_error_json(E3_json(d2_json()), &expected);
+    assert_parse_error_json(&E3_json(d2_json()), &expected);
 }
 #[test]
 fn F1a() {
@@ -1925,7 +1925,7 @@ fn F1c() {
         .help("any actions appearing as parents need to be declared as actions")
         .build();
     assert_parse_error_cedar(F1c_cedar(), &expected);
-    assert_parse_error_json(F1c_json(), &expected);
+    assert_parse_error_json(&F1c_json(), &expected);
 }
 #[test]
 fn F2a() {
@@ -1939,7 +1939,7 @@ fn F2b() {
             .help("any actions appearing as parents need to be declared as actions")
             .build();
     assert_parse_error_cedar(F2b_cedar(), &expected);
-    assert_parse_error_json(F2b_json(), &expected);
+    assert_parse_error_json(&F2b_json(), &expected);
 }
 #[test]
 fn F2c() {
@@ -1948,7 +1948,7 @@ fn F2c() {
             .help("any actions appearing as parents need to be declared as actions")
             .build();
     assert_parse_error_cedar(F2c_cedar(), &expected);
-    assert_parse_error_json(F2c_json(), &expected);
+    assert_parse_error_json(&F2c_json(), &expected);
 }
 #[test]
 fn F3a() {
@@ -1957,7 +1957,7 @@ fn F3a() {
             .help("any actions appearing as parents need to be declared as actions")
             .build();
     assert_parse_error_cedar(F3a_cedar(), &expected);
-    assert_parse_error_json(F3a_json(), &expected);
+    assert_parse_error_json(&F3a_json(), &expected);
 }
 #[test]
 fn F3b() {
@@ -1966,7 +1966,7 @@ fn F3b() {
             .help("any actions appearing as parents need to be declared as actions")
             .build();
     assert_parse_error_cedar(F3b_cedar(), &expected);
-    assert_parse_error_json(F3b_json(), &expected);
+    assert_parse_error_json(&F3b_json(), &expected);
 }
 #[test]
 fn F3c() {
@@ -1975,7 +1975,7 @@ fn F3c() {
             .help("any actions appearing as parents need to be declared as actions")
             .build();
     assert_parse_error_cedar(F3c_cedar(), &expected);
-    assert_parse_error_json(F3c_json(), &expected);
+    assert_parse_error_json(&F3c_json(), &expected);
 }
 #[test]
 fn F3d() {
diff --git a/cedar-policy-validator/src/typecheck/test/expr.rs b/cedar-policy-validator/src/typecheck/test/expr.rs
index 1f165ca9..4ae01e0c 100644
--- a/cedar-policy-validator/src/typecheck/test/expr.rs
+++ b/cedar-policy-validator/src/typecheck/test/expr.rs
@@ -47,19 +47,22 @@ use super::test_utils::{
 
 #[test]
 fn primitives_typecheck() {
-    assert_typechecks_empty_schema(Expr::val(true), Type::singleton_boolean(true));
-    assert_typechecks_empty_schema(Expr::val(1), Type::primitive_long());
-    assert_typechecks_empty_schema(Expr::val("foo"), Type::primitive_string());
+    assert_typechecks_empty_schema(&Expr::val(true), &Type::singleton_boolean(true));
+    assert_typechecks_empty_schema(&Expr::val(1), &Type::primitive_long());
+    assert_typechecks_empty_schema(&Expr::val("foo"), &Type::primitive_string());
 }
 
 #[test]
 fn slot_typechecks() {
     assert_typechecks_empty_schema(
-        Expr::slot(SlotId::principal()),
-        Type::any_entity_reference(),
+        &Expr::slot(SlotId::principal()),
+        &Type::any_entity_reference(),
     );
 
-    assert_typechecks_empty_schema(Expr::slot(SlotId::resource()), Type::any_entity_reference());
+    assert_typechecks_empty_schema(
+        &Expr::slot(SlotId::resource()),
+        &Type::any_entity_reference(),
+    );
 }
 
 #[test]
@@ -74,22 +77,22 @@ fn slot_in_typechecks() {
     let schema = json_schema::NamespaceDefinition::new([("typename".parse().unwrap(), etype)], []);
     assert_typechecks_for_mode(
         schema.clone(),
-        Expr::binary_app(
+        &Expr::binary_app(
             BinaryOp::In,
             Expr::val(EntityUID::with_eid_and_type("typename", "id").expect("Bad EUID")),
             Expr::slot(SlotId::principal()),
         ),
-        Type::primitive_boolean(),
+        &Type::primitive_boolean(),
         ValidationMode::Permissive,
     );
     assert_typechecks_for_mode(
         schema,
-        Expr::binary_app(
+        &Expr::binary_app(
             BinaryOp::In,
             Expr::val(EntityUID::with_eid_and_type("typename", "id").expect("Bad EUID")),
             Expr::slot(SlotId::resource()),
         ),
-        Type::primitive_boolean(),
+        &Type::primitive_boolean(),
         ValidationMode::Permissive,
     );
 }
@@ -110,22 +113,22 @@ fn slot_equals_typechecks() {
     let schema = json_schema::NamespaceDefinition::new([("typename".parse().unwrap(), etype)], []);
     assert_typechecks_for_mode(
         schema.clone(),
-        Expr::binary_app(
+        &Expr::binary_app(
             BinaryOp::Eq,
             Expr::val(EntityUID::with_eid_and_type("typename", "edi").expect("EUID Failed")),
             Expr::slot(SlotId::principal()),
         ),
-        Type::primitive_boolean(),
+        &Type::primitive_boolean(),
         ValidationMode::Permissive,
     );
     assert_typechecks_for_mode(
         schema,
-        Expr::binary_app(
+        &Expr::binary_app(
             BinaryOp::Eq,
             Expr::val(EntityUID::with_eid_and_type("typename", "edi").expect("EUID Failed")),
             Expr::slot(SlotId::resource()),
         ),
-        Type::primitive_boolean(),
+        &Type::primitive_boolean(),
         ValidationMode::Permissive,
     );
 }
@@ -133,27 +136,27 @@ fn slot_equals_typechecks() {
 #[test]
 fn slot_has_typechecks() {
     assert_typechecks_empty_schema(
-        Expr::has_attr(Expr::slot(SlotId::principal()), "test".into()),
-        Type::primitive_boolean(),
+        &Expr::has_attr(Expr::slot(SlotId::principal()), "test".into()),
+        &Type::primitive_boolean(),
     );
     assert_typechecks_empty_schema(
-        Expr::has_attr(Expr::slot(SlotId::resource()), "test".into()),
-        Type::primitive_boolean(),
+        &Expr::has_attr(Expr::slot(SlotId::resource()), "test".into()),
+        &Type::primitive_boolean(),
     );
 }
 
 #[test]
 fn set_typechecks() {
     assert_typechecks_empty_schema(
-        Expr::set([Expr::val(true)]),
-        Type::set(Type::singleton_boolean(true)),
+        &Expr::set([Expr::val(true)]),
+        &Type::set(Type::singleton_boolean(true)),
     );
 }
 
 #[test]
 fn heterogeneous_set() {
     let src = "[true, 1]";
-    let errors = assert_typecheck_fails_empty_schema_without_type(src.parse().unwrap());
+    let errors = assert_typecheck_fails_empty_schema_without_type(&src.parse().unwrap());
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
@@ -170,16 +173,16 @@ fn heterogeneous_set() {
 #[test]
 fn record_typechecks() {
     assert_typechecks_empty_schema(
-        Expr::record([("foo".into(), Expr::val(1))]).unwrap(),
-        Type::closed_record_with_required_attributes([("foo".into(), Type::primitive_long())]),
+        &Expr::record([("foo".into(), Expr::val(1))]).unwrap(),
+        &Type::closed_record_with_required_attributes([("foo".into(), Type::primitive_long())]),
     )
 }
 
 #[test]
 fn and_typechecks() {
     assert_typechecks_empty_schema(
-        Expr::and(Expr::val(true), Expr::val(false)),
-        Type::singleton_boolean(false),
+        &Expr::and(Expr::val(true), Expr::val(false)),
+        &Type::singleton_boolean(false),
     );
 }
 
@@ -187,7 +190,7 @@ fn and_typechecks() {
 fn and_typecheck_fails() {
     let src = "1 && true";
     let errors =
-        assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_boolean());
+        assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_boolean());
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
@@ -202,7 +205,7 @@ fn and_typecheck_fails() {
 
     let src = "(1 > 0) && 2";
     let errors =
-        assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_boolean());
+        assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_boolean());
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
@@ -217,7 +220,7 @@ fn and_typecheck_fails() {
 
     let src = "(1 > false) && true";
     let errors =
-        assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_boolean());
+        assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_boolean());
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
@@ -232,7 +235,7 @@ fn and_typecheck_fails() {
 
     let src = "true && (1 > false)";
     let errors =
-        assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_boolean());
+        assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_boolean());
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
@@ -249,24 +252,24 @@ fn and_typecheck_fails() {
 #[test]
 fn or_left_true_is_true() {
     assert_typechecks_empty_schema(
-        Expr::or(Expr::val(true), Expr::val(false)),
-        Type::singleton_boolean(true),
+        &Expr::or(Expr::val(true), Expr::val(false)),
+        &Type::singleton_boolean(true),
     );
 }
 
 #[test]
 fn or_left_false_is_right() {
     assert_typechecks_empty_schema(
-        Expr::or(Expr::val(false), Expr::greater(Expr::val(1), Expr::val(0))),
-        Type::primitive_boolean(),
+        &Expr::or(Expr::val(false), Expr::greater(Expr::val(1), Expr::val(0))),
+        &Type::primitive_boolean(),
     );
 }
 
 #[test]
 fn or_left_true_ignores_right() {
     assert_typechecks_empty_schema(
-        Expr::or(Expr::val(true), Expr::not(Expr::val(1))),
-        Type::singleton_boolean(true),
+        &Expr::or(Expr::val(true), Expr::not(Expr::val(1))),
+        &Type::singleton_boolean(true),
     );
 }
 
@@ -274,7 +277,7 @@ fn or_left_true_ignores_right() {
 fn or_right_true_fails_left() {
     let src = "1 || true";
     let errors =
-        assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_boolean());
+        assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_boolean());
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
@@ -291,35 +294,35 @@ fn or_right_true_fails_left() {
 #[test]
 fn or_right_true_is_true() {
     assert_typechecks_empty_schema(
-        Expr::or(Expr::greater(Expr::val(1), Expr::val(0)), Expr::val(true)),
-        Type::singleton_boolean(true),
+        &Expr::or(Expr::greater(Expr::val(1), Expr::val(0)), Expr::val(true)),
+        &Type::singleton_boolean(true),
     );
 }
 
 #[test]
 fn or_right_false_is_left() {
     assert_typechecks_empty_schema(
-        Expr::or(Expr::greater(Expr::val(1), Expr::val(0)), Expr::val(false)),
-        Type::primitive_boolean(),
+        &Expr::or(Expr::greater(Expr::val(1), Expr::val(0)), Expr::val(false)),
+        &Type::primitive_boolean(),
     );
 }
 
 #[test]
 fn or_boolean() {
     assert_typechecks_empty_schema(
-        Expr::or(
+        &Expr::or(
             Expr::greater(Expr::val(1), Expr::val(0)),
             Expr::greater(Expr::val(1), Expr::val(0)),
         ),
-        Type::primitive_boolean(),
+        &Type::primitive_boolean(),
     );
 }
 
 #[test]
 fn or_false() {
     assert_typechecks_empty_schema(
-        Expr::or(Expr::val(false), Expr::val(false)),
-        Type::singleton_boolean(false),
+        &Expr::or(Expr::val(false), Expr::val(false)),
+        &Type::singleton_boolean(false),
     );
 }
 
@@ -327,7 +330,7 @@ fn or_false() {
 fn or_typecheck_fails() {
     let src = "1 || true";
     let errors =
-        assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_boolean());
+        assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_boolean());
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
@@ -342,7 +345,7 @@ fn or_typecheck_fails() {
 
     let src = "(2 > 0) || 1";
     let errors =
-        assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_boolean());
+        assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_boolean());
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
@@ -357,7 +360,7 @@ fn or_typecheck_fails() {
 
     let src = "(1 > true) || false";
     let errors =
-        assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_boolean());
+        assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_boolean());
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
@@ -372,7 +375,7 @@ fn or_typecheck_fails() {
 
     let src = "(1 > false) || true";
     let errors =
-        assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::singleton_boolean(true));
+        assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::singleton_boolean(true));
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
@@ -387,7 +390,7 @@ fn or_typecheck_fails() {
 
     let src = "false || (1 > true)";
     let errors =
-        assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_boolean());
+        assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_boolean());
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
@@ -404,8 +407,8 @@ fn or_typecheck_fails() {
 #[test]
 fn eq_typechecks() {
     assert_typechecks_empty_schema(
-        Expr::is_eq(Expr::val(2), Expr::val(1)),
-        Type::primitive_boolean(),
+        &Expr::is_eq(Expr::val(2), Expr::val(1)),
+        &Type::primitive_boolean(),
     );
 }
 
@@ -439,7 +442,7 @@ fn entity_eq_is_false() {
     .expect("Expected that schema would parse");
     assert_typechecks(
         schema,
-        Expr::is_eq(
+        &Expr::is_eq(
             Expr::get_attr(
                 Expr::val(
                     EntityUID::with_eid_and_type("Baz", "buz").expect("Expected EntityUID parse."),
@@ -453,7 +456,7 @@ fn entity_eq_is_false() {
                 "bar".into(),
             ),
         ),
-        Type::False,
+        &Type::False,
     );
 }
 
@@ -489,7 +492,7 @@ fn set_eq_is_not_false() {
     .expect("Expected that schema would parse");
     assert_typechecks_for_mode(
         schema,
-        Expr::is_eq(
+        &Expr::is_eq(
             Expr::get_attr(
                 Expr::val(
                     EntityUID::with_eid_and_type("some_type", "a")
@@ -505,7 +508,7 @@ fn set_eq_is_not_false() {
                 "bool_set".into(),
             ),
         ),
-        Type::primitive_boolean(),
+        &Type::primitive_boolean(),
         ValidationMode::Permissive,
     );
 }
@@ -525,7 +528,7 @@ fn eq_typecheck_action_literals_false() {
     .expect("Expected that schema would parse");
     assert_typechecks(
         schema,
-        Expr::is_eq(
+        &Expr::is_eq(
             Expr::val(
                 EntityUID::with_eid_and_type("Action", "view_photo")
                     .expect("Expected EntityUID parse."),
@@ -535,7 +538,7 @@ fn eq_typecheck_action_literals_false() {
                     .expect("Expected EntityUID parse."),
             ),
         ),
-        Type::singleton_boolean(false),
+        &Type::singleton_boolean(false),
     );
 }
 
@@ -554,93 +557,93 @@ fn eq_typecheck_entity_literals_false() {
     .expect("Expected that schema would parse");
     assert_typechecks(
         schema,
-        Expr::is_eq(
+        &Expr::is_eq(
             Expr::val(EntityUID::with_eid_and_type("A", "foo").expect("Expected EntityUID parse.")),
             Expr::val(EntityUID::with_eid_and_type("B", "foo").expect("Expected EntityUID parse.")),
         ),
-        Type::singleton_boolean(false),
+        &Type::singleton_boolean(false),
     );
 }
 
 #[test]
 fn entity_has_typechecks() {
     assert_typechecks_empty_schema(
-        Expr::has_attr(Expr::var(Var::Principal), "attr".into()),
-        Type::primitive_boolean(),
+        &Expr::has_attr(Expr::var(Var::Principal), "attr".into()),
+        &Type::primitive_boolean(),
     );
 }
 
 #[test]
 fn record_has_typechecks() {
     assert_typechecks_empty_schema(
-        Expr::has_attr(Expr::var(Var::Context), "attr".into()),
-        Type::singleton_boolean(false),
+        &Expr::has_attr(Expr::var(Var::Context), "attr".into()),
+        &Type::singleton_boolean(false),
     );
     assert_typechecks_empty_schema(
-        Expr::has_attr(Expr::record([]).unwrap(), "attr".into()),
-        Type::singleton_boolean(false),
+        &Expr::has_attr(Expr::record([]).unwrap(), "attr".into()),
+        &Type::singleton_boolean(false),
     );
     assert_typechecks_empty_schema(
-        Expr::from_str("{a: 1} has a").unwrap(),
-        Type::singleton_boolean(true),
+        &Expr::from_str("{a: 1} has a").unwrap(),
+        &Type::singleton_boolean(true),
     );
 }
 
 #[test]
 fn record_lub_has_typechecks_strict() {
     assert_typechecks_empty_schema(
-        Expr::from_str("(if 1 > 0 then {a: 1} else {a: 2}) has a").unwrap(),
-        Type::singleton_boolean(true),
+        &Expr::from_str("(if 1 > 0 then {a: 1} else {a: 2}) has a").unwrap(),
+        &Type::singleton_boolean(true),
     );
     assert_typechecks_empty_schema(
-        Expr::from_str("(if 1 > 0 then {a: 1} else {a: 2}) has b").unwrap(),
-        Type::singleton_boolean(false),
+        &Expr::from_str("(if 1 > 0 then {a: 1} else {a: 2}) has b").unwrap(),
+        &Type::singleton_boolean(false),
     );
     assert_typechecks_empty_schema(
-        Expr::from_str("(if 1 > 0 then {a: true} else {a: false}) has b").unwrap(),
-        Type::singleton_boolean(false),
+        &Expr::from_str("(if 1 > 0 then {a: true} else {a: false}) has b").unwrap(),
+        &Type::singleton_boolean(false),
     );
     assert_typechecks_empty_schema(
-        Expr::from_str("(if 1 > 0 then {a: true} else {a: false}) has a").unwrap(),
-        Type::singleton_boolean(true),
+        &Expr::from_str("(if 1 > 0 then {a: true} else {a: false}) has a").unwrap(),
+        &Type::singleton_boolean(true),
     );
 }
 
 #[test]
 fn record_lub_has_typechecks_permissive() {
     assert_typechecks_empty_schema_permissive(
-        Expr::from_str("(if 1 > 0 then {a: 1} else {a: 2, b: 3}) has a").unwrap(),
-        Type::singleton_boolean(true),
+        &Expr::from_str("(if 1 > 0 then {a: 1} else {a: 2, b: 3}) has a").unwrap(),
+        &Type::singleton_boolean(true),
     );
     assert_typechecks_empty_schema_permissive(
-        Expr::from_str("(if 1 > 0 then {a: 1, b: 2} else {a: 1, c: 2}) has a").unwrap(),
-        Type::singleton_boolean(true),
+        &Expr::from_str("(if 1 > 0 then {a: 1, b: 2} else {a: 1, c: 2}) has a").unwrap(),
+        &Type::singleton_boolean(true),
     );
     assert_typechecks_empty_schema_permissive(
-        Expr::from_str("(if 1 > 0 then {a: 1} else {}) has a").unwrap(),
-        Type::primitive_boolean(),
+        &Expr::from_str("(if 1 > 0 then {a: 1} else {}) has a").unwrap(),
+        &Type::primitive_boolean(),
     );
     assert_typechecks_empty_schema_permissive(
-        Expr::from_str("(if 1 > 0 then {a: 1, b: 2} else {a: 1, c: 2}) has b").unwrap(),
-        Type::primitive_boolean(),
+        &Expr::from_str("(if 1 > 0 then {a: 1, b: 2} else {a: 1, c: 2}) has b").unwrap(),
+        &Type::primitive_boolean(),
     );
     assert_typechecks_empty_schema_permissive(
-        Expr::from_str("(if 1 > 0 then (if 1 > 0 then {a: 1} else {}) else {}) has a").unwrap(),
-        Type::primitive_boolean(),
+        &Expr::from_str("(if 1 > 0 then (if 1 > 0 then {a: 1} else {}) else {}) has a").unwrap(),
+        &Type::primitive_boolean(),
     );
 
     // These cases are imprecise.
     assert_typechecks_empty_schema_permissive(
-        Expr::from_str("(if 1 > 0 then {a: 1} else {}) has c").unwrap(),
-        Type::primitive_boolean(),
+        &Expr::from_str("(if 1 > 0 then {a: 1} else {}) has c").unwrap(),
+        &Type::primitive_boolean(),
     );
     assert_typechecks_empty_schema_permissive(
-        Expr::from_str("(if 1 > 0 then {a: 1} else {b: 2}) has c").unwrap(),
-        Type::primitive_boolean(),
+        &Expr::from_str("(if 1 > 0 then {a: 1} else {b: 2}) has c").unwrap(),
+        &Type::primitive_boolean(),
     );
     assert_typechecks_empty_schema_permissive(
-        Expr::from_str("(if 1 > 0 then {a: 1} else {a : false}) has a").unwrap(),
-        Type::primitive_boolean(),
+        &Expr::from_str("(if 1 > 0 then {a: 1} else {a : false}) has a").unwrap(),
+        &Type::primitive_boolean(),
     );
 }
 
@@ -648,7 +651,7 @@ fn record_lub_has_typechecks_permissive() {
 fn has_typecheck_fails() {
     let src = "true has attr";
     let errors =
-        assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_boolean());
+        assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_boolean());
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
@@ -666,8 +669,8 @@ fn has_typecheck_fails() {
 fn record_get_attr_typechecks() {
     let attr: SmolStr = "foo".into();
     assert_typechecks_empty_schema(
-        Expr::get_attr(Expr::record([(attr.clone(), Expr::val(1))]).unwrap(), attr),
-        Type::primitive_long(),
+        &Expr::get_attr(Expr::record([(attr.clone(), Expr::val(1))]).unwrap(), attr),
+        &Type::primitive_long(),
     );
 }
 
@@ -676,7 +679,7 @@ fn record_get_attr_incompatible() {
     let src = "(if (1 > 0) then {foo: true} else {foo: 1}).foo";
     let errors = assert_typecheck_fails_for_mode(
         empty_schema_file(),
-        src.parse().unwrap(),
+        &src.parse().unwrap(),
         None,
         crate::ValidationMode::Permissive,
     );
@@ -696,7 +699,7 @@ fn record_get_attr_incompatible() {
 #[test]
 fn record_get_attr_typecheck_fails() {
     let src = "2.foo";
-    let errors = assert_typecheck_fails_empty_schema_without_type(src.parse().unwrap());
+    let errors = assert_typecheck_fails_empty_schema_without_type(&src.parse().unwrap());
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
@@ -713,7 +716,7 @@ fn record_get_attr_typecheck_fails() {
 #[test]
 fn record_get_attr_lub_typecheck_fails() {
     let src = "(if (0 < 1) then {foo: true} else 1).foo";
-    let errors = assert_typecheck_fails_empty_schema_without_type(src.parse().unwrap());
+    let errors = assert_typecheck_fails_empty_schema_without_type(&src.parse().unwrap());
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
@@ -736,7 +739,7 @@ fn record_get_attr_lub_typecheck_fails() {
 #[test]
 fn record_get_attr_does_not_exist() {
     let src = "{}.foo";
-    let errors = assert_typecheck_fails_empty_schema_without_type(src.parse().unwrap());
+    let errors = assert_typecheck_fails_empty_schema_without_type(&src.parse().unwrap());
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
@@ -753,7 +756,7 @@ fn record_get_attr_does_not_exist() {
 #[test]
 fn record_get_attr_lub_does_not_exist() {
     let src = "(if true then {} else {foo: 1}).foo";
-    let errors = assert_typecheck_fails_empty_schema_without_type(src.parse().unwrap());
+    let errors = assert_typecheck_fails_empty_schema_without_type(&src.parse().unwrap());
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
@@ -770,38 +773,38 @@ fn record_get_attr_lub_does_not_exist() {
 #[test]
 fn in_typechecks_permissive() {
     assert_typechecks_empty_schema_permissive(
-        Expr::is_in(Expr::var(Var::Principal), Expr::var(Var::Resource)),
-        Type::primitive_boolean(),
+        &Expr::is_in(Expr::var(Var::Principal), Expr::var(Var::Resource)),
+        &Type::primitive_boolean(),
     );
 }
 
 #[test]
 fn in_typechecks() {
     assert_typechecks_empty_schema(
-        Expr::is_in(Expr::var(Var::Principal), Expr::var(Var::Principal)),
-        Type::primitive_boolean(),
+        &Expr::is_in(Expr::var(Var::Principal), Expr::var(Var::Principal)),
+        &Type::primitive_boolean(),
     );
 }
 
 #[test]
 fn in_set_typechecks_permissive() {
     assert_typechecks_empty_schema_permissive(
-        Expr::is_in(
+        &Expr::is_in(
             Expr::var(Var::Principal),
             Expr::set([Expr::var(Var::Resource)]),
         ),
-        Type::primitive_boolean(),
+        &Type::primitive_boolean(),
     );
 }
 
 #[test]
 fn in_set_typechecks_strict() {
     assert_typechecks_empty_schema(
-        Expr::is_in(
+        &Expr::is_in(
             Expr::var(Var::Principal),
             Expr::set([Expr::var(Var::Principal)]),
         ),
-        Type::primitive_boolean(),
+        &Type::primitive_boolean(),
     );
 }
 
@@ -809,7 +812,7 @@ fn in_set_typechecks_strict() {
 fn in_typecheck_fails() {
     let src = "0 in true";
     let errors =
-        assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_boolean());
+        assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_boolean());
     assert_sets_equal(
         errors,
         [
@@ -837,8 +840,8 @@ fn in_typecheck_fails() {
 #[test]
 fn contains_typechecks() {
     assert_typechecks_empty_schema(
-        Expr::contains(Expr::set([Expr::val(1)]), Expr::val(2)),
-        Type::primitive_boolean(),
+        &Expr::contains(Expr::set([Expr::val(1)]), Expr::val(2)),
+        &Type::primitive_boolean(),
     );
 }
 
@@ -847,7 +850,7 @@ fn contains_typecheck_fails() {
     use crate::types::AttributeType;
     let src = r#""foo".contains("bar")"#;
     let errors =
-        assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_boolean());
+        assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_boolean());
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
@@ -862,7 +865,7 @@ fn contains_typecheck_fails() {
 
     let src = r#"1.contains("bar")"#;
     let errors =
-        assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_boolean());
+        assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_boolean());
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
@@ -877,7 +880,7 @@ fn contains_typecheck_fails() {
 
     let src = r#"{foo: 1}.contains("foo")"#;
     let errors =
-        assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_boolean());
+        assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_boolean());
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
@@ -907,7 +910,7 @@ fn contains_typecheck_literals_false() {
     .expect("Expected that schema would parse");
     assert_typechecks(
         schema,
-        Expr::contains(
+        &Expr::contains(
             Expr::set([Expr::val(
                 EntityUID::with_eid_and_type("Action", "view_photo")
                     .expect("Expected EntityUID parse."),
@@ -919,15 +922,15 @@ fn contains_typecheck_literals_false() {
         ),
         // Previously had type `False`. This case might become false again if we
         // decide to restore some of the special cases for `contains`.
-        Type::primitive_boolean(),
+        &Type::primitive_boolean(),
     );
 }
 
 #[test]
 fn contains_all_typechecks() {
     assert_typechecks_empty_schema(
-        Expr::contains_all(Expr::set([Expr::val(1)]), Expr::set([Expr::val(1)])),
-        Type::primitive_boolean(),
+        &Expr::contains_all(Expr::set([Expr::val(1)]), Expr::set([Expr::val(1)])),
+        &Type::primitive_boolean(),
     );
 }
 
@@ -935,7 +938,7 @@ fn contains_all_typechecks() {
 fn contains_all_typecheck_fails() {
     let src = "1.containsAll(true)";
     let errors =
-        assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_boolean());
+        assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_boolean());
     assert_sets_equal(
         errors,
         [
@@ -970,7 +973,7 @@ fn contains_all_typecheck_literals_false() {
     .expect("Expected that schema would parse");
     assert_typechecks(
         schema,
-        Expr::contains_all(
+        &Expr::contains_all(
             Expr::set([Expr::val(
                 EntityUID::with_eid_and_type("Action", "view_photo")
                     .expect("Expected EntityUID parse."),
@@ -982,15 +985,15 @@ fn contains_all_typecheck_literals_false() {
         ),
         // Previously had type `False`. This case might become false again if we
         // decide to restore some of the special cases for `containsAll`.
-        Type::primitive_boolean(),
+        &Type::primitive_boolean(),
     );
 }
 
 #[test]
 fn is_empty_typechecks() {
     assert_typechecks_empty_schema(
-        Expr::is_empty(Expr::set([Expr::val(1)])),
-        Type::primitive_boolean(),
+        &Expr::is_empty(Expr::set([Expr::val(1)])),
+        &Type::primitive_boolean(),
     );
 }
 
@@ -998,7 +1001,7 @@ fn is_empty_typechecks() {
 fn is_empty_typecheck_fails() {
     let src = "\"crab\".isEmpty()";
     let errors =
-        assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_boolean());
+        assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_boolean());
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
@@ -1015,7 +1018,7 @@ fn is_empty_typecheck_fails() {
 #[test]
 fn like_typechecks() {
     assert_typechecks_empty_schema(
-        Expr::like(
+        &Expr::like(
             Expr::val("foo"),
             Pattern::from(vec![
                 PatternElem::Char('b'),
@@ -1023,7 +1026,7 @@ fn like_typechecks() {
                 PatternElem::Char('r'),
             ]),
         ),
-        Type::primitive_boolean(),
+        &Type::primitive_boolean(),
     );
 }
 
@@ -1031,7 +1034,7 @@ fn like_typechecks() {
 fn like_typecheck_fails() {
     let src = r#"1 like "bar""#;
     let errors =
-        assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_boolean());
+        assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_boolean());
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
@@ -1048,8 +1051,8 @@ fn like_typecheck_fails() {
 #[test]
 fn less_than_typechecks() {
     assert_typechecks_empty_schema(
-        Expr::less(Expr::val(1), Expr::val(2)),
-        Type::primitive_boolean(),
+        &Expr::less(Expr::val(1), Expr::val(2)),
+        &Type::primitive_boolean(),
     );
 }
 
@@ -1064,7 +1067,7 @@ fn less_than_typecheck_fails() {
         .collect_vec();
     let src = "true < false";
     let errors =
-        assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_boolean());
+        assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_boolean());
     assert_sets_equal(
         errors,
         [
@@ -1087,7 +1090,7 @@ fn less_than_typecheck_fails() {
 
     let src = "true < \"\"";
     let errors =
-        assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_boolean());
+        assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_boolean());
     assert_sets_equal(
         errors,
         [
@@ -1110,7 +1113,7 @@ fn less_than_typecheck_fails() {
 
     let src = "true < 1";
     let errors =
-        assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_boolean());
+        assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_boolean());
     assert_sets_equal(
         errors,
         [ValidationError::expected_type(
@@ -1125,15 +1128,15 @@ fn less_than_typecheck_fails() {
 
 #[test]
 fn not_typechecks() {
-    assert_typechecks_empty_schema(Expr::not(Expr::val(true)), Type::singleton_boolean(false));
-    assert_typechecks_empty_schema(Expr::not(Expr::val(false)), Type::singleton_boolean(true));
+    assert_typechecks_empty_schema(&Expr::not(Expr::val(true)), &Type::singleton_boolean(false));
+    assert_typechecks_empty_schema(&Expr::not(Expr::val(false)), &Type::singleton_boolean(true));
 }
 
 #[test]
 fn not_typecheck_fails() {
     let src = "!1";
     let errors =
-        assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_boolean());
+        assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_boolean());
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
@@ -1150,31 +1153,31 @@ fn not_typecheck_fails() {
 #[test]
 fn if_typechecks() {
     assert_typechecks_empty_schema(
-        Expr::ite(Expr::val(true), Expr::val(1), Expr::val(22)),
-        Type::primitive_long(),
+        &Expr::ite(Expr::val(true), Expr::val(1), Expr::val(22)),
+        &Type::primitive_long(),
     );
 }
 
 #[test]
 fn if_true_ignore_else() {
     assert_typechecks_empty_schema(
-        Expr::ite(Expr::val(true), Expr::val(1), Expr::not(Expr::val(22))),
-        Type::primitive_long(),
+        &Expr::ite(Expr::val(true), Expr::val(1), Expr::not(Expr::val(22))),
+        &Type::primitive_long(),
     );
 }
 
 #[test]
 fn if_false_ignores_then() {
     assert_typechecks_empty_schema(
-        Expr::ite(Expr::val(false), Expr::not(Expr::val(1)), Expr::val(22)),
-        Type::primitive_long(),
+        &Expr::ite(Expr::val(false), Expr::not(Expr::val(1)), Expr::val(22)),
+        &Type::primitive_long(),
     );
 }
 
 #[test]
 fn if_no_lub_error() {
     let src = r#"if (1 < 2) then 1 else "test""#;
-    let errors = assert_typecheck_fails_empty_schema_without_type(src.parse().unwrap());
+    let errors = assert_typecheck_fails_empty_schema_without_type(&src.parse().unwrap());
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
@@ -1191,7 +1194,7 @@ fn if_no_lub_error() {
 #[test]
 fn if_typecheck_fails() {
     let src = r#"if "fail" then 1 else "test""#;
-    let errors = assert_typecheck_fails_empty_schema_without_type(src.parse().unwrap());
+    let errors = assert_typecheck_fails_empty_schema_without_type(&src.parse().unwrap());
     assert_sets_equal(
         errors,
         [
@@ -1216,13 +1219,14 @@ fn if_typecheck_fails() {
 #[test]
 fn neg_typechecks() {
     let neg_expr = Expr::neg(Expr::val(1));
-    assert_typechecks_empty_schema(neg_expr, Type::primitive_long());
+    assert_typechecks_empty_schema(&neg_expr, &Type::primitive_long());
 }
 
 #[test]
 fn neg_typecheck_fails() {
     let src = r#"-"foo""#;
-    let errors = assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_long());
+    let errors =
+        assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_long());
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
@@ -1239,13 +1243,14 @@ fn neg_typecheck_fails() {
 #[test]
 fn mul_typechecks() {
     let neg_expr = Expr::mul(Expr::val(1), Expr::val(2));
-    assert_typechecks_empty_schema(neg_expr, Type::primitive_long());
+    assert_typechecks_empty_schema(&neg_expr, &Type::primitive_long());
 }
 
 #[test]
 fn mul_typecheck_fails() {
     let src = r#""foo" * 2"#;
-    let errors = assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_long());
+    let errors =
+        assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_long());
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
@@ -1262,15 +1267,16 @@ fn mul_typecheck_fails() {
 #[test]
 fn add_sub_typechecks() {
     let add_expr = Expr::add(Expr::val(1), Expr::val(2));
-    assert_typechecks_empty_schema(add_expr, Type::primitive_long());
+    assert_typechecks_empty_schema(&add_expr, &Type::primitive_long());
     let sub_expr = Expr::sub(Expr::val(1), Expr::val(2));
-    assert_typechecks_empty_schema(sub_expr, Type::primitive_long());
+    assert_typechecks_empty_schema(&sub_expr, &Type::primitive_long());
 }
 
 #[test]
 fn add_sub_typecheck_fails() {
     let src = r#"1 + "foo""#;
-    let errors = assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_long());
+    let errors =
+        assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_long());
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
@@ -1284,7 +1290,8 @@ fn add_sub_typecheck_fails() {
     );
 
     let src = r#""bar" - 2"#;
-    let errors = assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_long());
+    let errors =
+        assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_long());
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
@@ -1305,8 +1312,8 @@ fn is_typecheck_fails() {
     let src = r#"1 is User"#;
     let errors = assert_typecheck_fails(
         schema,
-        src.parse().unwrap(),
-        Some(Type::primitive_boolean()),
+        &src.parse().unwrap(),
+        Some(&Type::primitive_boolean()),
     );
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
@@ -1330,23 +1337,23 @@ fn is_typechecks() {
     .unwrap();
     assert_typechecks(
         schema.clone(),
-        r#"User::"alice" is User"#.parse().unwrap(),
-        Type::singleton_boolean(true),
+        &r#"User::"alice" is User"#.parse().unwrap(),
+        &Type::singleton_boolean(true),
     );
     assert_typechecks(
         schema.clone(),
-        r#"User::"alice" is Photo"#.parse().unwrap(),
-        Type::singleton_boolean(false),
+        &r#"User::"alice" is Photo"#.parse().unwrap(),
+        &Type::singleton_boolean(false),
     );
     assert_typechecks(
         schema.clone(),
-        r#"N::S::Foo::"alice" is N::S::Foo"#.parse().unwrap(),
-        Type::singleton_boolean(true),
+        &r#"N::S::Foo::"alice" is N::S::Foo"#.parse().unwrap(),
+        &Type::singleton_boolean(true),
     );
     assert_typechecks(
         schema,
-        r#"N::S::Foo::"alice" is User"#.parse().unwrap(),
-        Type::singleton_boolean(false),
+        &r#"N::S::Foo::"alice" is User"#.parse().unwrap(),
+        &Type::singleton_boolean(false),
     );
 }
 
@@ -1381,11 +1388,11 @@ mod datetime {
     #[test]
     fn less_than_typechecks() {
         assert_typechecks_empty_schema(
-            Expr::less(Expr::val(1), Expr::val(2)),
-            Type::primitive_boolean(),
+            &Expr::less(Expr::val(1), Expr::val(2)),
+            &Type::primitive_boolean(),
         );
         assert_typechecks_empty_schema(
-            Expr::less(
+            &Expr::less(
                 Expr::call_extension_fn(
                     get_datetime_constructor_name(),
                     vec![Value::from("1970-01-01").into()],
@@ -1395,10 +1402,10 @@ mod datetime {
                     vec![Value::from("1970-01-02").into()],
                 ),
             ),
-            Type::primitive_boolean(),
+            &Type::primitive_boolean(),
         );
         assert_typechecks_empty_schema(
-            Expr::lesseq(
+            &Expr::lesseq(
                 Expr::call_extension_fn(
                     get_datetime_constructor_name(),
                     vec![Value::from("1970-01-01").into()],
@@ -1408,10 +1415,10 @@ mod datetime {
                     vec![Value::from("1970-01-02").into()],
                 ),
             ),
-            Type::primitive_boolean(),
+            &Type::primitive_boolean(),
         );
         assert_typechecks_empty_schema(
-            Expr::less(
+            &Expr::less(
                 Expr::call_extension_fn(
                     get_duration_constructor_name(),
                     vec![Value::from("1h").into()],
@@ -1421,10 +1428,10 @@ mod datetime {
                     vec![Value::from("2h").into()],
                 ),
             ),
-            Type::primitive_boolean(),
+            &Type::primitive_boolean(),
         );
         assert_typechecks_empty_schema(
-            Expr::lesseq(
+            &Expr::lesseq(
                 Expr::call_extension_fn(
                     get_duration_constructor_name(),
                     vec![Value::from("1h").into()],
@@ -1434,7 +1441,7 @@ mod datetime {
                     vec![Value::from("2h").into()],
                 ),
             ),
-            Type::primitive_boolean(),
+            &Type::primitive_boolean(),
         );
     }
 
@@ -1449,7 +1456,7 @@ mod datetime {
             .collect_vec();
         let src = "true < false";
         let errors =
-            assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_boolean());
+            assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_boolean());
         assert_sets_equal(
             errors,
             [
@@ -1472,7 +1479,7 @@ mod datetime {
 
         let src = "true < \"\"";
         let errors =
-            assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_boolean());
+            assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_boolean());
         assert_sets_equal(
             errors,
             [
@@ -1495,7 +1502,7 @@ mod datetime {
 
         let src = "true < 1";
         let errors =
-            assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_boolean());
+            assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_boolean());
         assert_sets_equal(
             errors,
             [ValidationError::expected_type(
@@ -1509,7 +1516,7 @@ mod datetime {
 
         let src = r#"true < duration("1h")"#;
         let errors =
-            assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_boolean());
+            assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_boolean());
         assert_sets_equal(
             errors,
             [ValidationError::expected_type(
@@ -1526,7 +1533,7 @@ mod datetime {
         // Error reporting favors long
         let src = r#"duration("1d") < 1"#;
         let errors =
-            assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_boolean());
+            assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_boolean());
         assert_sets_equal(
             errors,
             [ValidationError::expected_type(
@@ -1542,7 +1549,7 @@ mod datetime {
 
         let src = r#"1 < duration("1d")"#;
         let errors =
-            assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_boolean());
+            assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_boolean());
         assert_sets_equal(
             errors,
             [ValidationError::expected_type(
@@ -1558,7 +1565,7 @@ mod datetime {
 
         let src = r#"datetime("1970-01-01") < duration("1d")"#;
         let errors =
-            assert_typecheck_fails_empty_schema(src.parse().unwrap(), Type::primitive_boolean());
+            assert_typecheck_fails_empty_schema(&src.parse().unwrap(), &Type::primitive_boolean());
         assert_sets_equal(
             errors,
             [ValidationError::expected_type(
diff --git a/cedar-policy-validator/src/typecheck/test/extensions.rs b/cedar-policy-validator/src/typecheck/test/extensions.rs
index 3215b9bd..e2eb6439 100644
--- a/cedar-policy-validator/src/typecheck/test/extensions.rs
+++ b/cedar-policy-validator/src/typecheck/test/extensions.rs
@@ -33,12 +33,12 @@ fn ip_extension_typechecks() {
 
     let ipaddr_name = Name::parse_unqualified_name("ipaddr").expect("should be a valid identifier");
     let expr = Expr::from_str("ip(\"127.0.0.1\")").expect("parsing should succeed");
-    assert_typechecks_empty_schema(expr, Type::extension(ipaddr_name));
+    assert_typechecks_empty_schema(&expr, &Type::extension(ipaddr_name));
     let expr = Expr::from_str("ip(\"1:2:3:4::/48\").isIpv4()").expect("parsing should succeed");
-    assert_typechecks_empty_schema(expr, Type::primitive_boolean());
+    assert_typechecks_empty_schema(&expr, &Type::primitive_boolean());
     let expr = Expr::from_str("ip(\"127.0.0.1\").isInRange(ip(\"1:2:3:4::/48\"))")
         .expect("parsing should succeed");
-    assert_typechecks_empty_schema(expr, Type::primitive_boolean());
+    assert_typechecks_empty_schema(&expr, &Type::primitive_boolean());
 }
 
 #[test]
@@ -51,7 +51,7 @@ fn ip_extension_typecheck_fails() {
     let ipaddr_name = Name::parse_unqualified_name("ipaddr").expect("should be a valid identifier");
     let src = "ip(3)";
     let expr = Expr::from_str(src).expect("parsing should succeed");
-    let errors = assert_typecheck_fails_empty_schema(expr, Type::extension(ipaddr_name.clone()));
+    let errors = assert_typecheck_fails_empty_schema(&expr, &Type::extension(ipaddr_name.clone()));
     let type_error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         type_error,
@@ -65,7 +65,7 @@ fn ip_extension_typecheck_fails() {
     );
     let src = "ip(\"foo\")";
     let expr = Expr::from_str(src).expect("parsing should succeed");
-    let errors = assert_typecheck_fails_empty_schema(expr, Type::extension(ipaddr_name.clone()));
+    let errors = assert_typecheck_fails_empty_schema(&expr, &Type::extension(ipaddr_name.clone()));
     let type_error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         type_error,
@@ -77,7 +77,7 @@ fn ip_extension_typecheck_fails() {
     );
     let src = "ip(\"127.0.0.1\").isIpv4(3)";
     let expr = Expr::from_str(src).expect("parsing should succeed");
-    let errors = assert_typecheck_fails_empty_schema(expr, Type::primitive_boolean());
+    let errors = assert_typecheck_fails_empty_schema(&expr, &Type::primitive_boolean());
     let type_error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         type_error,
@@ -85,7 +85,7 @@ fn ip_extension_typecheck_fails() {
     );
     let src = "ip(\"127.0.0.1\").isInRange(3)";
     let expr = Expr::from_str(src).expect("parsing should succeed");
-    let errors = assert_typecheck_fails_empty_schema(expr, Type::primitive_boolean());
+    let errors = assert_typecheck_fails_empty_schema(&expr, &Type::primitive_boolean());
     let type_error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         type_error,
@@ -107,19 +107,19 @@ fn decimal_extension_typechecks() {
     let decimal_name =
         Name::parse_unqualified_name("decimal").expect("should be a valid identifier");
     let expr = Expr::from_str("decimal(\"1.23\")").expect("parsing should succeed");
-    assert_typechecks_empty_schema(expr, Type::extension(decimal_name));
+    assert_typechecks_empty_schema(&expr, &Type::extension(decimal_name));
     let expr = Expr::from_str("decimal(\"1.23\").lessThan(decimal(\"1.24\"))")
         .expect("parsing should succeed");
-    assert_typechecks_empty_schema(expr, Type::primitive_boolean());
+    assert_typechecks_empty_schema(&expr, &Type::primitive_boolean());
     let expr = Expr::from_str("decimal(\"1.23\").lessThanOrEqual(decimal(\"1.24\"))")
         .expect("parsing should succeed");
-    assert_typechecks_empty_schema(expr, Type::primitive_boolean());
+    assert_typechecks_empty_schema(&expr, &Type::primitive_boolean());
     let expr = Expr::from_str("decimal(\"1.23\").greaterThan(decimal(\"1.24\"))")
         .expect("parsing should succeed");
-    assert_typechecks_empty_schema(expr, Type::primitive_boolean());
+    assert_typechecks_empty_schema(&expr, &Type::primitive_boolean());
     let expr = Expr::from_str("decimal(\"1.23\").greaterThanOrEqual(decimal(\"1.24\"))")
         .expect("parsing should succeed");
-    assert_typechecks_empty_schema(expr, Type::primitive_boolean());
+    assert_typechecks_empty_schema(&expr, &Type::primitive_boolean());
 }
 
 #[test]
@@ -131,7 +131,7 @@ fn decimal_extension_typecheck_fails() {
         Name::parse_unqualified_name("decimal").expect("should be a valid identifier");
     let src = "decimal(3)";
     let expr = Expr::from_str(src).expect("parsing should succeed");
-    let errors = assert_typecheck_fails_empty_schema(expr, Type::extension(decimal_name.clone()));
+    let errors = assert_typecheck_fails_empty_schema(&expr, &Type::extension(decimal_name.clone()));
     let type_error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         type_error,
@@ -145,7 +145,7 @@ fn decimal_extension_typecheck_fails() {
     );
     let src = "decimal(\"foo\")";
     let expr = Expr::from_str(src).expect("parsing should succeed");
-    let errors = assert_typecheck_fails_empty_schema(expr, Type::extension(decimal_name.clone()));
+    let errors = assert_typecheck_fails_empty_schema(&expr, &Type::extension(decimal_name.clone()));
     let type_error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         type_error,
@@ -157,7 +157,7 @@ fn decimal_extension_typecheck_fails() {
     );
     let src = "decimal(\"1.23\").lessThan(3, 4)";
     let expr = Expr::from_str(src).expect("parsing should succeed");
-    let errors = assert_typecheck_fails_empty_schema(expr, Type::primitive_boolean());
+    let errors = assert_typecheck_fails_empty_schema(&expr, &Type::primitive_boolean());
     let type_error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         type_error,
@@ -165,7 +165,7 @@ fn decimal_extension_typecheck_fails() {
     );
     let src = "decimal(\"1.23\").lessThan(4)";
     let expr = Expr::from_str(src).expect("parsing should succeed");
-    let errors = assert_typecheck_fails_empty_schema(expr, Type::primitive_boolean());
+    let errors = assert_typecheck_fails_empty_schema(&expr, &Type::primitive_boolean());
     let type_error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         type_error,
@@ -190,51 +190,51 @@ fn datetime_extension_typechecks() {
         Name::parse_unqualified_name("duration").expect("should be a valid identifier");
 
     let expr = Expr::from_str("datetime(\"2024-10-28\")").expect("parsing should succeed");
-    assert_typechecks_empty_schema(expr, Type::extension(datetime_name.clone()));
+    assert_typechecks_empty_schema(&expr, &Type::extension(datetime_name.clone()));
     let expr = Expr::from_str(r#"datetime("2024-10-28").offset(duration("1d"))"#)
         .expect("parsing should succeed");
-    assert_typechecks_empty_schema(expr, Type::extension(datetime_name.clone()));
+    assert_typechecks_empty_schema(&expr, &Type::extension(datetime_name.clone()));
     let expr = Expr::from_str(r#"datetime("2024-10-28").durationSince(datetime("2024-10-28"))"#)
         .expect("parsing should succeed");
-    assert_typechecks_empty_schema(expr, Type::extension(duration_name.clone()));
+    assert_typechecks_empty_schema(&expr, &Type::extension(duration_name.clone()));
     let expr =
         Expr::from_str(r#"datetime("2024-10-28").toDate()"#).expect("parsing should succeed");
-    assert_typechecks_empty_schema(expr, Type::extension(datetime_name));
+    assert_typechecks_empty_schema(&expr, &Type::extension(datetime_name));
     let expr =
         Expr::from_str(r#"datetime("2024-10-28").toTime()"#).expect("parsing should succeed");
-    assert_typechecks_empty_schema(expr, Type::extension(duration_name.clone()));
+    assert_typechecks_empty_schema(&expr, &Type::extension(duration_name.clone()));
     let expr = Expr::from_str(r#"datetime("2024-10-28") < datetime("2024-10-28")"#)
         .expect("parsing should succeed");
-    assert_typechecks_empty_schema(expr, Type::primitive_boolean());
+    assert_typechecks_empty_schema(&expr, &Type::primitive_boolean());
     let expr = Expr::from_str(r#"datetime("2024-10-28") <= datetime("2024-10-28")"#)
         .expect("parsing should succeed");
-    assert_typechecks_empty_schema(expr, Type::primitive_boolean());
+    assert_typechecks_empty_schema(&expr, &Type::primitive_boolean());
     let expr = Expr::from_str(r#"datetime("2024-10-28") > datetime("2024-10-28")"#)
         .expect("parsing should succeed");
-    assert_typechecks_empty_schema(expr, Type::primitive_boolean());
+    assert_typechecks_empty_schema(&expr, &Type::primitive_boolean());
     let expr = Expr::from_str(r#"datetime("2024-10-28") >= datetime("2024-10-28")"#)
         .expect("parsing should succeed");
-    assert_typechecks_empty_schema(expr, Type::primitive_boolean());
+    assert_typechecks_empty_schema(&expr, &Type::primitive_boolean());
     let expr = Expr::from_str(r#"datetime("2024-10-28") == datetime("2024-10-28")"#)
         .expect("parsing should succeed");
-    assert_typechecks_empty_schema(expr, Type::primitive_boolean());
+    assert_typechecks_empty_schema(&expr, &Type::primitive_boolean());
     let expr = Expr::from_str(r#"datetime("2024-10-28") != datetime("2024-10-28")"#)
         .expect("parsing should succeed");
-    assert_typechecks_empty_schema(expr, Type::primitive_boolean());
+    assert_typechecks_empty_schema(&expr, &Type::primitive_boolean());
 
     let expr = Expr::from_str("duration(\"1h\")").expect("parsing should succeed");
-    assert_typechecks_empty_schema(expr, Type::extension(duration_name));
+    assert_typechecks_empty_schema(&expr, &Type::extension(duration_name));
     let expr =
         Expr::from_str(r#"duration("1h").toMilliseconds()"#).expect("parsing should succeed");
-    assert_typechecks_empty_schema(expr, Type::primitive_long());
+    assert_typechecks_empty_schema(&expr, &Type::primitive_long());
     let expr = Expr::from_str(r#"duration("1h").toSeconds()"#).expect("parsing should succeed");
-    assert_typechecks_empty_schema(expr, Type::primitive_long());
+    assert_typechecks_empty_schema(&expr, &Type::primitive_long());
     let expr = Expr::from_str(r#"duration("1h").toMinutes()"#).expect("parsing should succeed");
-    assert_typechecks_empty_schema(expr, Type::primitive_long());
+    assert_typechecks_empty_schema(&expr, &Type::primitive_long());
     let expr = Expr::from_str(r#"duration("1h").toHours()"#).expect("parsing should succeed");
-    assert_typechecks_empty_schema(expr, Type::primitive_long());
+    assert_typechecks_empty_schema(&expr, &Type::primitive_long());
     let expr = Expr::from_str(r#"duration("1h").toDays()"#).expect("parsing should succeed");
-    assert_typechecks_empty_schema(expr, Type::primitive_long());
+    assert_typechecks_empty_schema(&expr, &Type::primitive_long());
 }
 
 #[test]
@@ -249,7 +249,8 @@ fn datetime_extension_typecheck_fails() {
 
     let src = "datetime(3)";
     let expr = Expr::from_str(src).expect("parsing should succeed");
-    let errors = assert_typecheck_fails_empty_schema(expr, Type::extension(datetime_name.clone()));
+    let errors =
+        assert_typecheck_fails_empty_schema(&expr, &Type::extension(datetime_name.clone()));
     let type_error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         type_error,
@@ -263,7 +264,8 @@ fn datetime_extension_typecheck_fails() {
     );
     let src = "datetime(\"foo\")";
     let expr = Expr::from_str(src).expect("parsing should succeed");
-    let errors = assert_typecheck_fails_empty_schema(expr, Type::extension(datetime_name.clone()));
+    let errors =
+        assert_typecheck_fails_empty_schema(&expr, &Type::extension(datetime_name.clone()));
     let type_error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         type_error,
@@ -276,7 +278,8 @@ fn datetime_extension_typecheck_fails() {
 
     let src = "duration(3)";
     let expr = Expr::from_str(src).expect("parsing should succeed");
-    let errors = assert_typecheck_fails_empty_schema(expr, Type::extension(duration_name.clone()));
+    let errors =
+        assert_typecheck_fails_empty_schema(&expr, &Type::extension(duration_name.clone()));
     let type_error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         type_error,
@@ -290,7 +293,8 @@ fn datetime_extension_typecheck_fails() {
     );
     let src = "duration(\"foo\")";
     let expr = Expr::from_str(src).expect("parsing should succeed");
-    let errors = assert_typecheck_fails_empty_schema(expr, Type::extension(duration_name.clone()));
+    let errors =
+        assert_typecheck_fails_empty_schema(&expr, &Type::extension(duration_name.clone()));
     let type_error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         type_error,
@@ -303,7 +307,8 @@ fn datetime_extension_typecheck_fails() {
 
     let src = r#"datetime("2024-10-28").offset(3, 4)"#;
     let expr = Expr::from_str(src).expect("parsing should succeed");
-    let errors = assert_typecheck_fails_empty_schema(expr, Type::extension(datetime_name.clone()));
+    let errors =
+        assert_typecheck_fails_empty_schema(&expr, &Type::extension(datetime_name.clone()));
     let type_error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         type_error,
@@ -311,7 +316,8 @@ fn datetime_extension_typecheck_fails() {
     );
     let src = r#"datetime("2024-10-28").offset(9)"#;
     let expr = Expr::from_str(src).expect("parsing should succeed");
-    let errors = assert_typecheck_fails_empty_schema(expr, Type::extension(datetime_name.clone()));
+    let errors =
+        assert_typecheck_fails_empty_schema(&expr, &Type::extension(datetime_name.clone()));
     let type_error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         type_error,
@@ -326,7 +332,7 @@ fn datetime_extension_typecheck_fails() {
 
     let src = r#"datetime("2024-10-29") < duration("1h")"#;
     let expr = Expr::from_str(src).expect("parsing should succeed");
-    let errors = assert_typecheck_fails_empty_schema(expr, Type::primitive_boolean());
+    let errors = assert_typecheck_fails_empty_schema(&expr, &Type::primitive_boolean());
     let type_error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         type_error,
diff --git a/cedar-policy-validator/src/typecheck/test/namespace.rs b/cedar-policy-validator/src/typecheck/test/namespace.rs
index c3d5c0a8..9babfe70 100644
--- a/cedar-policy-validator/src/typecheck/test/namespace.rs
+++ b/cedar-policy-validator/src/typecheck/test/namespace.rs
@@ -76,24 +76,24 @@ fn namespaced_entity_type_schema() -> json_schema::Fragment<RawName> {
 fn namespaced_entity_eq() {
     assert_typechecks(
         namespaced_entity_type_schema(),
-        Expr::from_str(r#"N::S::Foo::"alice" == N::S::Foo::"alice""#).expect("Expr should parse."),
-        Type::True,
+        &Expr::from_str(r#"N::S::Foo::"alice" == N::S::Foo::"alice""#).expect("Expr should parse."),
+        &Type::True,
     );
     assert_typechecks(
         namespaced_entity_type_schema(),
-        Expr::from_str(r#"N::S::Foo::"alice" == N::S::Foo::"bob""#).expect("Expr should parse."),
-        Type::False,
+        &Expr::from_str(r#"N::S::Foo::"alice" == N::S::Foo::"bob""#).expect("Expr should parse."),
+        &Type::False,
     );
     assert_typechecks(
         namespaced_entity_type_schema(),
-        Expr::from_str(r#"N::S::Foo::"alice" == N::S::Bar::"bob""#).expect("Expr should parse."),
-        Type::False,
+        &Expr::from_str(r#"N::S::Foo::"alice" == N::S::Bar::"bob""#).expect("Expr should parse."),
+        &Type::False,
     );
     assert_typechecks(
         namespaced_entity_type_schema(),
-        Expr::from_str(r#"N::S::Action::"baz" == N::S::Action::"baz""#)
+        &Expr::from_str(r#"N::S::Action::"baz" == N::S::Action::"baz""#)
             .expect("Expr should parse."),
-        Type::True,
+        &Type::True,
     );
 }
 
@@ -101,13 +101,13 @@ fn namespaced_entity_eq() {
 fn namespaced_entity_in() {
     assert_typechecks(
         namespaced_entity_type_schema(),
-        Expr::from_str(r#"N::S::Foo::"alice" in N::S::Foo::"bob""#).expect("Expr should parse."),
-        Type::primitive_boolean(),
+        &Expr::from_str(r#"N::S::Foo::"alice" in N::S::Foo::"bob""#).expect("Expr should parse."),
+        &Type::primitive_boolean(),
     );
     assert_typechecks(
         namespaced_entity_type_schema(),
-        Expr::from_str(r#"N::S::Foo::"alice" in N::S::Bar::"bob""#).expect("Expr should parse."),
-        Type::False,
+        &Expr::from_str(r#"N::S::Foo::"alice" in N::S::Bar::"bob""#).expect("Expr should parse."),
+        &Type::False,
     );
 }
 
@@ -115,13 +115,13 @@ fn namespaced_entity_in() {
 fn namespaced_entity_has() {
     assert_typechecks(
         namespaced_entity_type_schema(),
-        Expr::from_str(r#"N::S::Foo::"alice" has foo"#).expect("Expr should parse."),
-        Type::False,
+        &Expr::from_str(r#"N::S::Foo::"alice" has foo"#).expect("Expr should parse."),
+        &Type::False,
     );
     assert_typechecks(
         namespaced_entity_type_schema(),
-        Expr::from_str(r#"N::S::Foo::"alice" has name"#).expect("Expr should parse."),
-        Type::primitive_boolean(),
+        &Expr::from_str(r#"N::S::Foo::"alice" has name"#).expect("Expr should parse."),
+        &Type::primitive_boolean(),
     );
 }
 
@@ -129,8 +129,8 @@ fn namespaced_entity_has() {
 fn namespaced_entity_get_attr() {
     assert_typechecks(
         namespaced_entity_type_schema(),
-        Expr::from_str(r#"N::S::Foo::"alice".name"#).expect("Expr should parse."),
-        Type::primitive_string(),
+        &Expr::from_str(r#"N::S::Foo::"alice".name"#).expect("Expr should parse."),
+        &Type::primitive_string(),
     );
 }
 
@@ -139,8 +139,8 @@ fn namespaced_entity_can_type_error() {
     let src = r#"N::S::Foo::"alice" > 1"#;
     let errors = assert_typecheck_fails(
         namespaced_entity_type_schema(),
-        Expr::from_str(src).expect("Expr should parse."),
-        Some(Type::primitive_boolean()),
+        &Expr::from_str(src).expect("Expr should parse."),
+        Some(&Type::primitive_boolean()),
     );
     let type_error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
@@ -159,37 +159,37 @@ fn namespaced_entity_can_type_error() {
 fn namespaced_entity_wrong_namespace() {
     let errors = assert_typecheck_fails(
         namespaced_entity_type_schema(),
-        Expr::from_str(r#"N::S::T::Foo::"alice""#).expect("Expr should parse."),
+        &Expr::from_str(r#"N::S::T::Foo::"alice""#).expect("Expr should parse."),
         None,
     );
     assert_sets_equal(errors, []);
     let errors = assert_typecheck_fails(
         namespaced_entity_type_schema(),
-        Expr::from_str(r#"N::Foo::"alice""#).expect("Expr should parse."),
+        &Expr::from_str(r#"N::Foo::"alice""#).expect("Expr should parse."),
         None,
     );
     assert_sets_equal(errors, []);
     let errors = assert_typecheck_fails(
         namespaced_entity_type_schema(),
-        Expr::from_str(r#"Foo::"alice""#).expect("Expr should parse."),
+        &Expr::from_str(r#"Foo::"alice""#).expect("Expr should parse."),
         None,
     );
     assert_sets_equal(errors, []);
     let errors = assert_typecheck_fails(
         namespaced_entity_type_schema(),
-        Expr::from_str(r#"N::Action::"baz""#).expect("Expr should parse."),
+        &Expr::from_str(r#"N::Action::"baz""#).expect("Expr should parse."),
         None,
     );
     assert_sets_equal(errors, []);
     let errors = assert_typecheck_fails(
         namespaced_entity_type_schema(),
-        Expr::from_str(r#"Action::N::S::"baz""#).expect("Expr should parse."),
+        &Expr::from_str(r#"Action::N::S::"baz""#).expect("Expr should parse."),
         None,
     );
     assert_sets_equal(errors, []);
     let errors = assert_typecheck_fails(
         namespaced_entity_type_schema(),
-        Expr::from_str(r#"Action::"baz""#).expect("Expr should parse."),
+        &Expr::from_str(r#"Action::"baz""#).expect("Expr should parse."),
         None,
     );
     assert_sets_equal(errors, []);
@@ -221,25 +221,25 @@ fn namespaced_entity_type_in_attribute() {
     // comparison.
     assert_typechecks(
         schema.clone(),
-        Expr::from_str(r#"N::S::Foo::"foo".bar == N::S::Bar::"bar""#).expect("Expr should parse."),
-        Type::primitive_boolean(),
+        &Expr::from_str(r#"N::S::Foo::"foo".bar == N::S::Bar::"bar""#).expect("Expr should parse."),
+        &Type::primitive_boolean(),
     );
     assert_typechecks(
         schema.clone(),
-        Expr::from_str(r#"N::S::Foo::"foo".bar == N::S::Foo::"foo""#).expect("Expr should parse."),
-        Type::singleton_boolean(false),
+        &Expr::from_str(r#"N::S::Foo::"foo".bar == N::S::Foo::"foo""#).expect("Expr should parse."),
+        &Type::singleton_boolean(false),
     );
     // Implicit namespace is applied to the attribute type and correctly used in
     // comparison.
     assert_typechecks(
         schema.clone(),
-        Expr::from_str(r#"N::S::Foo::"foo".baz == N::S::Bar::"bar""#).expect("Expr should parse."),
-        Type::primitive_boolean(),
+        &Expr::from_str(r#"N::S::Foo::"foo".baz == N::S::Bar::"bar""#).expect("Expr should parse."),
+        &Type::primitive_boolean(),
     );
     assert_typechecks(
         schema,
-        Expr::from_str(r#"N::S::Foo::"foo".baz == N::S::Foo::"foo""#).expect("Expr should parse."),
-        Type::singleton_boolean(false),
+        &Expr::from_str(r#"N::S::Foo::"foo".baz == N::S::Foo::"foo""#).expect("Expr should parse."),
+        &Type::singleton_boolean(false),
     );
 }
 
@@ -325,18 +325,18 @@ fn multiple_namespaces_literals() {
 
     assert_typechecks(
         schema.clone(),
-        Expr::from_str("A::Foo::\"foo\"").unwrap(),
-        Type::named_entity_reference_from_str("A::Foo"),
+        &Expr::from_str("A::Foo::\"foo\"").unwrap(),
+        &Type::named_entity_reference_from_str("A::Foo"),
     );
     assert_typechecks(
         schema.clone(),
-        Expr::from_str("B::Foo::\"foo\"").unwrap(),
-        Type::named_entity_reference_from_str("B::Foo"),
+        &Expr::from_str("B::Foo::\"foo\"").unwrap(),
+        &Type::named_entity_reference_from_str("B::Foo"),
     );
     assert_typechecks(
         schema,
-        Expr::from_str("C::Foo::\"foo\"").unwrap(),
-        Type::named_entity_reference_from_str("C::Foo"),
+        &Expr::from_str("C::Foo::\"foo\"").unwrap(),
+        &Type::named_entity_reference_from_str("C::Foo"),
     );
 }
 
@@ -368,11 +368,11 @@ fn multiple_namespaces_attributes() {
 
     assert_typechecks(
         schema.clone(),
-        Expr::from_str("A::Foo::\"foo\".x").unwrap(),
-        Type::named_entity_reference_from_str("B::Foo"),
+        &Expr::from_str("A::Foo::\"foo\".x").unwrap(),
+        &Type::named_entity_reference_from_str("B::Foo"),
     );
     let src = "B::Foo::\"foo\".x";
-    let errors = assert_typecheck_fails(schema, Expr::from_str(src).unwrap(), None);
+    let errors = assert_typecheck_fails(schema, &Expr::from_str(src).unwrap(), None);
     let type_error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         type_error,
diff --git a/cedar-policy-validator/src/typecheck/test/policy.rs b/cedar-policy-validator/src/typecheck/test/policy.rs
index 3719be27..237bb647 100644
--- a/cedar-policy-validator/src/typecheck/test/policy.rs
+++ b/cedar-policy-validator/src/typecheck/test/policy.rs
@@ -117,11 +117,11 @@ fn assert_policy_typechecks_permissive_simple_schema(p: impl Into<Arc<Template>>
 fn entity_literal_typechecks() {
     assert_typechecks(
         simple_schema_file(),
-        Expr::val(
+        &Expr::val(
             EntityUID::with_eid_and_type("Group", "friends")
                 .expect("EUID component failed to parse."),
         ),
-        Type::named_entity_reference_from_str("Group"),
+        &Type::named_entity_reference_from_str("Group"),
     )
 }
 
diff --git a/cedar-policy-validator/src/typecheck/test/strict.rs b/cedar-policy-validator/src/typecheck/test/strict.rs
index 3ae934d4..b8dea080 100644
--- a/cedar-policy-validator/src/typecheck/test/strict.rs
+++ b/cedar-policy-validator/src/typecheck/test/strict.rs
@@ -45,7 +45,7 @@ use super::test_utils::{
 fn assert_typechecks_strict(
     schema: json_schema::Fragment<RawName>,
     request_env: &RequestEnv<'_>,
-    e: Expr,
+    e: &Expr,
     expected_type: Type,
 ) {
     let schema = schema.try_into().expect("Failed to construct schema.");
@@ -58,9 +58,7 @@ fn assert_typechecks_strict(
     };
     let mut errs = Vec::new();
     let answer =
-        typechecker.expect_type(&CapabilitySet::new(), &e, expected_type, &mut errs, |_| {
-            None
-        });
+        typechecker.expect_type(&CapabilitySet::new(), e, expected_type, &mut errs, |_| None);
 
     assert_eq!(errs, vec![], "Expression should not contain any errors.");
     assert_matches!(
@@ -73,7 +71,7 @@ fn assert_typechecks_strict(
 fn assert_strict_type_error(
     schema: json_schema::Fragment<RawName>,
     request_env: &RequestEnv<'_>,
-    e: Expr,
+    e: &Expr,
     expected_type: Type,
     expected_error: ValidationError,
 ) {
@@ -87,9 +85,7 @@ fn assert_strict_type_error(
     };
     let mut errs = Vec::new();
     let answer =
-        typechecker.expect_type(&CapabilitySet::new(), &e, expected_type, &mut errs, |_| {
-            None
-        });
+        typechecker.expect_type(&CapabilitySet::new(), e, expected_type, &mut errs, |_| None);
 
     assert_eq!(errs.into_iter().collect::<Vec<_>>(), vec![expected_error]);
     assert_matches!(
@@ -102,7 +98,7 @@ fn assert_strict_type_error(
 fn assert_types_must_match(
     schema: json_schema::Fragment<RawName>,
     env: &RequestEnv<'_>,
-    e: Expr,
+    e: &Expr,
     snippet: impl AsRef<str>,
     expected_type: Type,
     unequal_types: impl IntoIterator<Item = Type>,
@@ -202,7 +198,7 @@ fn false_eq_rewrites_to_false() {
         assert_typechecks_strict(
             s,
             &q,
-            Expr::from_str(r#"principal == Photo::"image.jpg""#).unwrap(),
+            &Expr::from_str(r#"principal == Photo::"image.jpg""#).unwrap(),
             Type::primitive_boolean(),
         )
     })
@@ -214,7 +210,7 @@ fn true_eq_rewrites_to_true() {
         assert_typechecks_strict(
             s,
             &q,
-            Expr::from_str(r#"action == Action::"view_photo""#).unwrap(),
+            &Expr::from_str(r#"action == Action::"view_photo""#).unwrap(),
             Type::primitive_boolean(),
         )
     })
@@ -226,7 +222,7 @@ fn bool_eq_types_match() {
         assert_typechecks_strict(
             s,
             &q,
-            Expr::from_str(r#"1 == 1"#).unwrap(),
+            &Expr::from_str(r#"1 == 1"#).unwrap(),
             Type::primitive_boolean(),
         )
     })
@@ -238,7 +234,7 @@ fn eq_strict_types_mismatch() {
         assert_types_must_match(
             s,
             &q,
-            Expr::from_str(r#"1 == "foo""#).unwrap(),
+            &Expr::from_str(r#"1 == "foo""#).unwrap(),
             r#"1 == "foo""#,
             Type::primitive_boolean(),
             [Type::primitive_string(), Type::primitive_long()],
@@ -254,7 +250,7 @@ fn contains_strict_types_mismatch() {
         assert_types_must_match(
             s,
             &q,
-            Expr::from_str(r#"[1].contains("test")"#).unwrap(),
+            &Expr::from_str(r#"[1].contains("test")"#).unwrap(),
             r#"[1].contains("test")"#,
             Type::primitive_boolean(),
             [Type::primitive_long(), Type::primitive_string()],
@@ -270,7 +266,7 @@ fn contains_any_strict_types_mismatch() {
         assert_types_must_match(
             s,
             &q,
-            Expr::from_str(r#"[principal].containsAny([1])"#).unwrap(),
+            &Expr::from_str(r#"[principal].containsAny([1])"#).unwrap(),
             r#"[principal].containsAny([1])"#,
             Type::primitive_boolean(),
             [
@@ -289,7 +285,7 @@ fn contains_all_strict_types_mismatch() {
         assert_types_must_match(
             s,
             &q,
-            Expr::from_str(r#"[principal].containsAll([1])"#).unwrap(),
+            &Expr::from_str(r#"[principal].containsAll([1])"#).unwrap(),
             r#"[principal].containsAll([1])"#,
             Type::primitive_boolean(),
             [
@@ -308,7 +304,7 @@ fn if_false_else_only() {
         assert_typechecks_strict(
             s,
             &q,
-            Expr::from_str(r#"if resource == User::"alice" then 1 else "foo""#).unwrap(),
+            &Expr::from_str(r#"if resource == User::"alice" then 1 else "foo""#).unwrap(),
             Type::primitive_string(),
         )
     })
@@ -320,7 +316,7 @@ fn if_true_then_only() {
         assert_typechecks_strict(
             s,
             &q,
-            Expr::from_str(r#"if action == Action::"view_photo" then 1 else "foo""#).unwrap(),
+            &Expr::from_str(r#"if action == Action::"view_photo" then 1 else "foo""#).unwrap(),
             Type::primitive_long(),
         )
     })
@@ -332,7 +328,7 @@ fn if_bool_keeps_both() {
         assert_typechecks_strict(
             s,
             &q,
-            Expr::from_str(r#"if principal == User::"alice" then 1 else 2"#).unwrap(),
+            &Expr::from_str(r#"if principal == User::"alice" then 1 else 2"#).unwrap(),
             Type::primitive_long(),
         )
     })
@@ -344,7 +340,7 @@ fn if_bool_strict_type_mismatch() {
         assert_types_must_match(
             s,
             &q,
-            Expr::from_str(
+            &Expr::from_str(
                 r#"if principal == User::"alice" then User::"alice" else Photo::"pie.jpg""#,
             )
             .unwrap(),
@@ -366,7 +362,7 @@ fn set_strict_types_mismatch() {
         assert_types_must_match(
             s,
             &q,
-            Expr::from_str(r#"[User::"alice", Photo::"foo.jpg"]"#).unwrap(),
+            &Expr::from_str(r#"[User::"alice", Photo::"foo.jpg"]"#).unwrap(),
             r#"[User::"alice", Photo::"foo.jpg"]"#,
             Type::set(Type::entity_lub(["User", "Photo"])),
             [
@@ -386,7 +382,7 @@ fn empty_set_literal() {
         assert_strict_type_error(
             s,
             &q,
-            Expr::from_str(src).unwrap(),
+            &Expr::from_str(src).unwrap(),
             Type::any_set(),
             ValidationError::empty_set_forbidden(
                 Some(Loc::new(0..2, Arc::from(src))),
@@ -404,7 +400,7 @@ fn ext_struct_non_lit() {
         assert_strict_type_error(
             s,
             &q,
-            Expr::from_str(src).unwrap(),
+            &Expr::from_str(src).unwrap(),
             Type::extension("ipaddr".parse().unwrap()),
             ValidationError::non_lit_ext_constructor(
                 Some(Loc::new(0..30, Arc::from(src))),
@@ -419,7 +415,7 @@ fn ext_struct_non_lit() {
         assert_strict_type_error(
             s,
             &q,
-            Expr::from_str(src).unwrap(),
+            &Expr::from_str(src).unwrap(),
             Type::extension("decimal".parse().unwrap()),
             ValidationError::non_lit_ext_constructor(
                 Some(Loc::new(0..39, Arc::from(src))),
@@ -438,7 +434,7 @@ fn entity_in_lub() {
         assert_types_must_match(
             s,
             &q,
-            Expr::from_str(
+            &Expr::from_str(
                 r#"User::"alice" in (if 1 > 0 then User::"alice" else Photo::"pie.jpg")"#,
             )
             .unwrap(),
@@ -464,13 +460,13 @@ fn test_and() {
         assert_typechecks_strict(
             s.clone(),
             &q,
-            Expr::from_str(r#"1 == 2 && 2 == 3"#).unwrap(),
+            &Expr::from_str(r#"1 == 2 && 2 == 3"#).unwrap(),
             Type::primitive_boolean(),
         );
         assert_types_must_match(
             s.clone(),
             &q,
-            Expr::from_str(r#"(1 == (2 > 0)) && true"#).unwrap(),
+            &Expr::from_str(r#"(1 == (2 > 0)) && true"#).unwrap(),
             r#"1 == (2 > 0)"#,
             Type::primitive_boolean(),
             [Type::primitive_long(), Type::primitive_boolean()],
@@ -480,7 +476,7 @@ fn test_and() {
         assert_types_must_match(
             s,
             &q,
-            Expr::from_str(r#"true && (1 == (2 > 0))"#).unwrap(),
+            &Expr::from_str(r#"true && (1 == (2 > 0))"#).unwrap(),
             r#"1 == (2 > 0)"#,
             Type::primitive_boolean(),
             [Type::primitive_long(), Type::primitive_boolean()],
@@ -496,13 +492,13 @@ fn test_or() {
         assert_typechecks_strict(
             s.clone(),
             &q,
-            Expr::from_str(r#"1 == 2 || 2 == 3"#).unwrap(),
+            &Expr::from_str(r#"1 == 2 || 2 == 3"#).unwrap(),
             Type::primitive_boolean(),
         );
         assert_types_must_match(
             s.clone(),
             &q,
-            Expr::from_str(r#"(1 == (2 > 0)) || false"#).unwrap(),
+            &Expr::from_str(r#"(1 == (2 > 0)) || false"#).unwrap(),
             r#"1 == (2 > 0)"#,
             Type::primitive_boolean(),
             [Type::primitive_boolean(), Type::primitive_long()],
@@ -512,7 +508,7 @@ fn test_or() {
         assert_types_must_match(
             s,
             &q,
-            Expr::from_str(r#"false || (1 == (2 > 0))"#).unwrap(),
+            &Expr::from_str(r#"false || (1 == (2 > 0))"#).unwrap(),
             r#"1 == (2 > 0)"#,
             Type::primitive_boolean(),
             [Type::primitive_boolean(), Type::primitive_long()],
@@ -528,13 +524,13 @@ fn test_unary() {
         assert_typechecks_strict(
             s.clone(),
             &q,
-            Expr::from_str(r#"!(1 == 2)"#).unwrap(),
+            &Expr::from_str(r#"!(1 == 2)"#).unwrap(),
             Type::primitive_boolean(),
         );
         assert_types_must_match(
             s,
             &q,
-            Expr::from_str(r#"!(1 == "foo")"#).unwrap(),
+            &Expr::from_str(r#"!(1 == "foo")"#).unwrap(),
             r#"1 == "foo""#,
             Type::primitive_boolean(),
             [Type::primitive_long(), Type::primitive_string()],
@@ -550,13 +546,13 @@ fn test_mul() {
         assert_typechecks_strict(
             s.clone(),
             &q,
-            Expr::from_str(r#"2*(if 1 == 2 then 3 else 4)"#).unwrap(),
+            &Expr::from_str(r#"2*(if 1 == 2 then 3 else 4)"#).unwrap(),
             Type::primitive_long(),
         );
         assert_types_must_match(
             s,
             &q,
-            Expr::from_str(r#"2*(if 1 == false then 3 else 4)"#).unwrap(),
+            &Expr::from_str(r#"2*(if 1 == false then 3 else 4)"#).unwrap(),
             "1 == false",
             Type::primitive_long(),
             [Type::primitive_long(), Type::singleton_boolean(false)],
@@ -572,13 +568,13 @@ fn test_like() {
         assert_typechecks_strict(
             s.clone(),
             &q,
-            Expr::from_str(r#""a" like "a""#).unwrap(),
+            &Expr::from_str(r#""a" like "a""#).unwrap(),
             Type::primitive_boolean(),
         );
         assert_types_must_match(
             s,
             &q,
-            Expr::from_str(r#"(if 1 == false then "foo" else "bar") like "bar""#).unwrap(),
+            &Expr::from_str(r#"(if 1 == false then "foo" else "bar") like "bar""#).unwrap(),
             r#"1 == false"#,
             Type::primitive_boolean(),
             [Type::primitive_long(), Type::singleton_boolean(false)],
@@ -594,13 +590,13 @@ fn test_get_attr() {
         assert_typechecks_strict(
             s.clone(),
             &q,
-            Expr::from_str(r#"{name: "foo"}.name"#).unwrap(),
+            &Expr::from_str(r#"{name: "foo"}.name"#).unwrap(),
             Type::primitive_string(),
         );
         assert_types_must_match(
             s,
             &q,
-            Expr::from_str(r#"{name: 1 == "foo"}.name"#).unwrap(),
+            &Expr::from_str(r#"{name: 1 == "foo"}.name"#).unwrap(),
             r#"1 == "foo""#,
             Type::primitive_boolean(),
             [Type::primitive_long(), Type::primitive_string()],
@@ -616,19 +612,19 @@ fn test_has_attr() {
         assert_typechecks_strict(
             s.clone(),
             &q,
-            Expr::from_str(r#"{name: "foo"} has bar"#).unwrap(),
+            &Expr::from_str(r#"{name: "foo"} has bar"#).unwrap(),
             Type::primitive_boolean(),
         );
         assert_typechecks_strict(
             s.clone(),
             &q,
-            Expr::from_str(r#"{name: "foo"} has name"#).unwrap(),
+            &Expr::from_str(r#"{name: "foo"} has name"#).unwrap(),
             Type::primitive_boolean(),
         );
         assert_types_must_match(
             s,
             &q,
-            Expr::from_str(r#"(if 1 == 2 then {name: 1} else {bar: 2}) has bar"#).unwrap(),
+            &Expr::from_str(r#"(if 1 == 2 then {name: 1} else {bar: 2}) has bar"#).unwrap(),
             "if 1 == 2 then {name: 1} else {bar: 2}",
             Type::primitive_boolean(),
             [
@@ -654,13 +650,13 @@ fn test_extension() {
         assert_typechecks_strict(
             s.clone(),
             &q,
-            Expr::from_str(r#"ip("127.0.0.1")"#).unwrap(),
+            &Expr::from_str(r#"ip("127.0.0.1")"#).unwrap(),
             Type::extension("ipaddr".parse().unwrap()),
         );
         assert_types_must_match(
             s,
             &q,
-            Expr::from_str(r#"ip("192.168.1.0/8").isInRange(if 1 == false then ip("127.0.0.1") else ip("192.168.1.1"))"#).unwrap(),
+            &Expr::from_str(r#"ip("192.168.1.0/8").isInRange(if 1 == false then ip("127.0.0.1") else ip("192.168.1.1"))"#).unwrap(),
             r#"1 == false"#,
             Type::primitive_boolean(),
             [Type::primitive_long(), Type::singleton_boolean(false)],
@@ -676,7 +672,7 @@ fn true_false_equality() {
         assert_typechecks_strict(
             s,
             &q,
-            Expr::from_str(r#"[false] == [true, true]"#).unwrap(),
+            &Expr::from_str(r#"[false] == [true, true]"#).unwrap(),
             Type::primitive_boolean(),
         )
     });
@@ -684,7 +680,7 @@ fn true_false_equality() {
         assert_typechecks_strict(
             s,
             &q,
-            Expr::from_str(r#"[true].contains(false)"#).unwrap(),
+            &Expr::from_str(r#"[true].contains(false)"#).unwrap(),
             Type::primitive_boolean(),
         )
     })
@@ -696,7 +692,7 @@ fn true_false_set() {
         assert_typechecks_strict(
             s,
             &q,
-            Expr::from_str(r#"[true, false]"#).unwrap(),
+            &Expr::from_str(r#"[true, false]"#).unwrap(),
             Type::set(Type::primitive_boolean()),
         )
     });
@@ -704,7 +700,7 @@ fn true_false_set() {
         assert_typechecks_strict(
             s,
             &q,
-            Expr::from_str(r#"[[true], [false]]"#).unwrap(),
+            &Expr::from_str(r#"[[true], [false]]"#).unwrap(),
             Type::set(Type::set(Type::primitive_boolean())),
         )
     });
@@ -712,7 +708,7 @@ fn true_false_set() {
         assert_typechecks_strict(
             s,
             &q,
-            Expr::from_str(r#"[[[true, false], [true, true]], [[false, false]]]"#).unwrap(),
+            &Expr::from_str(r#"[[[true, false], [true, true]], [[false, false]]]"#).unwrap(),
             Type::set(Type::set(Type::set(Type::primitive_boolean()))),
         )
     })
diff --git a/cedar-policy-validator/src/typecheck/test/test_utils.rs b/cedar-policy-validator/src/typecheck/test/test_utils.rs
index 9768bdbf..d000c936 100644
--- a/cedar-policy-validator/src/typecheck/test/test_utils.rs
+++ b/cedar-policy-validator/src/typecheck/test/test_utils.rs
@@ -308,24 +308,24 @@ pub(crate) fn assert_policy_typecheck_warns_for_mode(
 /// Assert that expr type checks successfully with a particular type, and
 /// that it does not generate any type errors.
 #[track_caller] // report the caller's location as the location of the panic, not the location in this function
-pub(crate) fn assert_typechecks(schema: impl SchemaProvider, expr: Expr, expected: Type) {
+pub(crate) fn assert_typechecks(schema: impl SchemaProvider, expr: &Expr, expected: &Type) {
     assert_typechecks_for_mode(schema, expr, expected, ValidationMode::Strict);
 }
 
 #[track_caller] // report the caller's location as the location of the panic, not the location in this function
 pub(crate) fn assert_typechecks_for_mode(
     schema: impl SchemaProvider,
-    expr: Expr,
-    expected: Type,
+    expr: &Expr,
+    expected: &Type,
     mode: ValidationMode,
 ) {
     let schema = schema.schema();
     let typechecker = Typechecker::new(&schema, mode);
     let mut type_errors = HashSet::new();
     let pid = expr_id_placeholder();
-    let actual = typechecker.typecheck_expr(&expr, &pid, &mut type_errors);
+    let actual = typechecker.typecheck_expr(expr, &pid, &mut type_errors);
     assert_matches!(actual, TypecheckAnswer::TypecheckSuccess { expr_type, .. } => {
-        assert_types_eq(typechecker.schema, &expected, &expr_type.into_data().expect("Typechecked expression must have type"));
+        assert_types_eq(typechecker.schema, expected, &expr_type.into_data().expect("Typechecked expression must have type"));
     });
     assert_eq!(
         type_errors,
@@ -344,8 +344,8 @@ pub(crate) fn assert_typechecks_for_mode(
 #[track_caller] // report the caller's location as the location of the panic, not the location in this function
 pub(crate) fn assert_typecheck_fails(
     schema: impl SchemaProvider,
-    expr: Expr,
-    expected_ty: Option<Type>,
+    expr: &Expr,
+    expected_ty: Option<&Type>,
 ) -> HashSet<ValidationError> {
     assert_typecheck_fails_for_mode(schema, expr, expected_ty, ValidationMode::Strict)
 }
@@ -359,15 +359,15 @@ pub(crate) fn assert_typecheck_fails(
 #[track_caller] // report the caller's location as the location of the panic, not the location in this function
 pub(crate) fn assert_typecheck_fails_for_mode(
     schema: impl SchemaProvider,
-    expr: Expr,
-    expected_ty: Option<Type>,
+    expr: &Expr,
+    expected_ty: Option<&Type>,
     mode: ValidationMode,
 ) -> HashSet<ValidationError> {
     let schema = schema.schema();
     let typechecker = Typechecker::new(&schema, mode);
     let mut type_errors = HashSet::new();
     let pid = expr_id_placeholder();
-    let actual = typechecker.typecheck_expr(&expr, &pid, &mut type_errors);
+    let actual = typechecker.typecheck_expr(expr, &pid, &mut type_errors);
     assert_matches!(actual, TypecheckAnswer::TypecheckFail { expr_recovery_type } => {
         match (expected_ty.as_ref(), expr_recovery_type.data()) {
             (None, None) => (),
@@ -385,12 +385,12 @@ pub(crate) fn empty_schema_file() -> json_schema::NamespaceDefinition<RawName> {
 }
 
 #[track_caller] // report the caller's location as the location of the panic, not the location in this function
-pub(crate) fn assert_typechecks_empty_schema(expr: Expr, expected: Type) {
+pub(crate) fn assert_typechecks_empty_schema(expr: &Expr, expected: &Type) {
     assert_typechecks(empty_schema_file(), expr, expected)
 }
 
 #[track_caller] // report the caller's location as the location of the panic, not the location in this function
-pub(crate) fn assert_typechecks_empty_schema_permissive(expr: Expr, expected: Type) {
+pub(crate) fn assert_typechecks_empty_schema_permissive(expr: &Expr, expected: &Type) {
     assert_typechecks_for_mode(
         empty_schema_file(),
         expr,
@@ -401,15 +401,15 @@ pub(crate) fn assert_typechecks_empty_schema_permissive(expr: Expr, expected: Ty
 
 #[track_caller] // report the caller's location as the location of the panic, not the location in this function
 pub(crate) fn assert_typecheck_fails_empty_schema(
-    expr: Expr,
-    expected: Type,
+    expr: &Expr,
+    expected: &Type,
 ) -> HashSet<ValidationError> {
     assert_typecheck_fails(empty_schema_file(), expr, Some(expected))
 }
 
 #[track_caller] // report the caller's location as the location of the panic, not the location in this function
 pub(crate) fn assert_typecheck_fails_empty_schema_without_type(
-    expr: Expr,
+    expr: &Expr,
 ) -> HashSet<ValidationError> {
     assert_typecheck_fails(empty_schema_file(), expr, None)
 }
diff --git a/cedar-policy/src/tests.rs b/cedar-policy/src/tests.rs
index e2892002..89ed83c8 100644
--- a/cedar-policy/src/tests.rs
+++ b/cedar-policy/src/tests.rs
@@ -4432,18 +4432,18 @@ mod issue_604 {
     #[track_caller]
     fn make_policy_with_get_attr(attr: &str) -> String {
         format!(
-            r#"
+            r"
         permit(principal, action, resource) when {{ principal == resource.{attr} }};
-        "#
+        "
         )
     }
 
     #[track_caller]
     fn make_policy_with_has_attr(attr: &str) -> String {
         format!(
-            r#"
+            r"
         permit(principal, action, resource) when {{ resource has {attr} }};
-        "#
+        "
         )
     }
 
@@ -4593,7 +4593,7 @@ mod issue_596 {
 
     fn test_single_int_with_dashes(x: i64, num_dashes: usize) {
         let dashes = vec!['-'; num_dashes].into_iter().collect::<String>();
-        let src = format!(r#"permit(principal, action, resource) when {{ {dashes}{x} }};"#);
+        let src = format!(r"permit(principal, action, resource) when {{ {dashes}{x} }};");
         let p: Policy = src.parse().unwrap();
         let json = p.to_json().unwrap();
         let round_trip = Policy::from_json(None, json).unwrap();
@@ -6571,11 +6571,10 @@ mod schema_annotations {
     fn namespace_annotations() {
         let schema = example_schema();
         let namespace: EntityNamespace = "N".parse().expect("should be a valid name");
-        let annotations = BTreeMap::from_iter(
-            schema
-                .namespace_annotations(namespace.clone())
-                .expect("should get annotations"),
-        );
+        let annotations = schema
+            .namespace_annotations(namespace.clone())
+            .expect("should get annotations")
+            .collect::<BTreeMap<_, _>>();
         assert_eq!(annotations, BTreeMap::from_iter([("m", "m"), ("n", "")]));
         assert_matches!(
             schema
@@ -6592,7 +6591,7 @@ mod schema_annotations {
             schema.namespace_annotation(namespace.clone(), "n"),
             Some("")
         );
-        assert_matches!(schema.namespace_annotation(namespace.clone(), "x"), None);
+        assert_matches!(schema.namespace_annotation(namespace, "x"), None);
         assert_matches!(
             schema.namespace_annotation("NM".parse().unwrap(), "n"),
             None
@@ -6605,41 +6604,31 @@ mod schema_annotations {
         let annotations = BTreeMap::from_iter([("a", "a"), ("b", "")]);
         assert_eq!(
             annotations,
-            BTreeMap::from_iter(
-                schema
-                    .entity_type_annotations(None, "A1")
-                    .expect("should get annotations")
-            )
+            schema
+                .entity_type_annotations(None, "A1")
+                .expect("should get annotations")
+                .collect::<BTreeMap<_, _>>()
         );
         assert_eq!(
             annotations,
-            BTreeMap::from_iter(
-                schema
-                    .entity_type_annotations(None, "A2")
-                    .expect("should get annotations")
-            )
+            schema
+                .entity_type_annotations(None, "A2")
+                .expect("should get annotations")
+                .collect::<BTreeMap<_, _>>()
         );
         assert_eq!(
             annotations,
-            BTreeMap::from_iter(
-                schema
-                    .entity_type_annotations(
-                        Some("N".parse().expect("should be a valid name")),
-                        "A1"
-                    )
-                    .expect("should get annotations")
-            )
+            schema
+                .entity_type_annotations(Some("N".parse().expect("should be a valid name")), "A1")
+                .expect("should get annotations")
+                .collect::<BTreeMap<_, _>>()
         );
         assert_eq!(
             annotations,
-            BTreeMap::from_iter(
-                schema
-                    .entity_type_annotations(
-                        Some("N".parse().expect("should be a valid name")),
-                        "A2"
-                    )
-                    .expect("should get annotations")
-            )
+            schema
+                .entity_type_annotations(Some("N".parse().expect("should be a valid name")), "A2")
+                .expect("should get annotations")
+                .collect::<BTreeMap<_, _>>()
         );
 
         assert_matches!(schema.entity_type_annotation(None, "A1", "b",), Some(""));
@@ -6694,22 +6683,17 @@ mod schema_annotations {
         let annotations = BTreeMap::from_iter([("c", "c"), ("d", "")]);
         assert_eq!(
             annotations,
-            BTreeMap::from_iter(
-                schema
-                    .common_type_annotations(None, "T")
-                    .expect("should get annotations")
-            )
+            schema
+                .common_type_annotations(None, "T")
+                .expect("should get annotations")
+                .collect::<BTreeMap<_, _>>()
         );
         assert_eq!(
             annotations,
-            BTreeMap::from_iter(
-                schema
-                    .common_type_annotations(
-                        Some("N".parse().expect("should be a valid name")),
-                        "T"
-                    )
-                    .expect("should get annotations")
-            )
+            schema
+                .common_type_annotations(Some("N".parse().expect("should be a valid name")), "T")
+                .expect("should get annotations")
+                .collect::<BTreeMap<_, _>>()
         );
         assert_matches!(schema.common_type_annotation(None, "T", "c",), Some("c"));
         assert_matches!(schema.common_type_annotation(None, "T", "d",), Some(""));
@@ -6764,64 +6748,60 @@ mod schema_annotations {
         let annotations = BTreeMap::from_iter([("e", "e"), ("f", "")]);
         assert_eq!(
             annotations,
-            BTreeMap::from_iter(
-                schema
-                    .action_annotations(None, "a1".parse().unwrap(),)
-                    .expect("should get annotations")
-            )
+            schema
+                .action_annotations(None, &"a1".parse().unwrap(),)
+                .expect("should get annotations")
+                .collect::<BTreeMap<_, _>>()
         );
         assert_eq!(
             annotations,
-            BTreeMap::from_iter(
-                schema
-                    .action_annotations(None, "a2".parse().unwrap(),)
-                    .expect("should get annotations")
-            )
+            schema
+                .action_annotations(None, &"a2".parse().unwrap(),)
+                .expect("should get annotations")
+                .collect::<BTreeMap<_, _>>()
         );
         assert_eq!(
             annotations,
-            BTreeMap::from_iter(
-                schema
-                    .action_annotations(
-                        Some("N".parse().expect("should be a valid name")),
-                        "a1".parse().unwrap(),
-                    )
-                    .expect("should get annotations")
-            )
+            schema
+                .action_annotations(
+                    Some("N".parse().expect("should be a valid name")),
+                    &"a1".parse().unwrap(),
+                )
+                .expect("should get annotations")
+                .collect::<BTreeMap<_, _>>()
         );
         assert_eq!(
             annotations,
-            BTreeMap::from_iter(
-                schema
-                    .action_annotations(
-                        Some("N".parse().expect("should be a valid name")),
-                        "a2".parse().unwrap(),
-                    )
-                    .expect("should get annotations")
-            )
+            schema
+                .action_annotations(
+                    Some("N".parse().expect("should be a valid name")),
+                    &"a2".parse().unwrap(),
+                )
+                .expect("should get annotations")
+                .collect::<BTreeMap<_, _>>()
         );
 
         assert_matches!(
-            schema.action_annotation(None, "a1".parse().unwrap(), "e",),
+            schema.action_annotation(None, &"a1".parse().unwrap(), "e",),
             Some("e")
         );
         assert_matches!(
-            schema.action_annotation(None, "a2".parse().unwrap(), "f",),
+            schema.action_annotation(None, &"a2".parse().unwrap(), "f",),
             Some("")
         );
         assert_matches!(
-            schema.action_annotation(None, "a3".parse().unwrap(), "e",),
+            schema.action_annotation(None, &"a3".parse().unwrap(), "e",),
             None
         );
         assert_matches!(
-            schema.action_annotation(None, "a2".parse().unwrap(), "x",),
+            schema.action_annotation(None, &"a2".parse().unwrap(), "x",),
             None
         );
 
         assert_matches!(
             schema.action_annotation(
                 Some("N".parse().expect("should be a valid name")),
-                "a1".parse().unwrap(),
+                &"a1".parse().unwrap(),
                 "e",
             ),
             Some("e")
@@ -6829,7 +6809,7 @@ mod schema_annotations {
         assert_matches!(
             schema.action_annotation(
                 Some("N".parse().expect("should be a valid name")),
-                "a2".parse().unwrap(),
+                &"a2".parse().unwrap(),
                 "f",
             ),
             Some("")
@@ -6837,7 +6817,7 @@ mod schema_annotations {
         assert_matches!(
             schema.action_annotation(
                 Some("N".parse().expect("should be a valid name")),
-                "a3".parse().unwrap(),
+                &"a3".parse().unwrap(),
                 "e",
             ),
             None
@@ -6845,7 +6825,7 @@ mod schema_annotations {
         assert_matches!(
             schema.action_annotation(
                 Some("N".parse().expect("should be a valid name")),
-                "a2".parse().unwrap(),
+                &"a2".parse().unwrap(),
                 "x",
             ),
             None
@@ -6853,7 +6833,7 @@ mod schema_annotations {
         assert_matches!(
             schema.action_annotation(
                 Some("NM".parse().expect("should be a valid name")),
-                "a1".parse().unwrap(),
+                &"a1".parse().unwrap(),
                 "e",
             ),
             None
diff --git a/cedar-testing/src/integration_testing.rs b/cedar-testing/src/integration_testing.rs
index 21d89bd8..43bcecd7 100644
--- a/cedar-testing/src/integration_testing.rs
+++ b/cedar-testing/src/integration_testing.rs
@@ -184,7 +184,7 @@ pub fn parse_entities_from_test(test: &JsonTest, schema: &ValidatorSchema) -> En
 
 // PANIC SAFETY this is testing code
 #[allow(clippy::panic)]
-fn parse_entity_uid(json: JsonValueWithNoDuplicateKeys, error_string: String) -> EntityUID {
+fn parse_entity_uid(json: JsonValueWithNoDuplicateKeys, error_string: &str) -> EntityUID {
     let parsed: entities::EntityUidJson =
         serde_json::from_value(json.into()).unwrap_or_else(|e| panic!("{}: {e}", error_string));
     parsed
@@ -206,17 +206,17 @@ pub fn parse_request_from_test(
         "Failed to parse principal for request \"{}\" in {}",
         json_request.description, test_name
     );
-    let principal = parse_entity_uid(json_request.principal.clone(), error_string);
+    let principal = parse_entity_uid(json_request.principal.clone(), &error_string);
     let error_string = format!(
         "Failed to parse action for request \"{}\" in {}",
         json_request.description, test_name
     );
-    let action = parse_entity_uid(json_request.action.clone(), error_string);
+    let action = parse_entity_uid(json_request.action.clone(), &error_string);
     let error_string = format!(
         "Failed to parse resource for request \"{}\" in {}",
         json_request.description, test_name
     );
-    let resource = parse_entity_uid(json_request.resource.clone(), error_string);
+    let resource = parse_entity_uid(json_request.resource.clone(), &error_string);
 
     let context_schema = cedar_policy_validator::context_schema_for_action(schema, &action)
         .unwrap_or_else(|| {
@@ -257,9 +257,9 @@ pub fn parse_request_from_test(
 /// Asserts that the test response matches the json request,
 /// including errors when the error comparison mode is enabled.
 fn check_matches_json(
-    response: TestResponse,
+    response: &TestResponse,
     json_request: &JsonRequest,
-    error_comparison_mode: ErrorComparisonMode,
+    error_comparison_mode: &ErrorComparisonMode,
     test_name: &str,
 ) {
     // check decision
@@ -303,16 +303,16 @@ fn check_matches_json(
 // PANIC SAFETY this is testing code
 #[allow(clippy::panic)]
 pub fn perform_integration_test(
-    policies: PolicySet,
-    entities: Entities,
-    schema: ValidatorSchema,
+    policies: &PolicySet,
+    entities: &Entities,
+    schema: &ValidatorSchema,
     should_validate: bool,
     requests: Vec<JsonRequest>,
     test_name: &str,
     test_impl: &impl CedarTestImplementation,
 ) {
     let validation_result = test_impl
-        .validate(&schema, &policies, ValidationMode::default().into())
+        .validate(schema, policies, ValidationMode::default().into())
         .expect("Validation failed");
     if should_validate {
         assert!(
@@ -333,14 +333,14 @@ pub fn perform_integration_test(
     }
 
     for json_request in requests {
-        let request = parse_request_from_test(&json_request, &schema, test_name);
+        let request = parse_request_from_test(&json_request, schema, test_name);
         let response = test_impl
-            .is_authorized(&request, &policies, &entities)
+            .is_authorized(&request, policies, entities)
             .expect("Authorization failed");
         check_matches_json(
-            response,
+            &response,
             &json_request,
-            test_impl.error_comparison_mode(),
+            &test_impl.error_comparison_mode(),
             test_name,
         );
 
@@ -355,9 +355,9 @@ pub fn perform_integration_test(
                 .is_authorized(&request, &policies, &entity_slice)
                 .expect("Authorization failed");
             check_matches_json(
-                slice_response,
+                &slice_response,
                 &json_request,
-                test_impl.error_comparison_mode(),
+                &test_impl.error_comparison_mode(),
                 test_name,
             );
         }
@@ -390,9 +390,9 @@ pub fn perform_integration_test_from_json_custom(
     let schema = parse_schema_from_test(&test);
     let entities = parse_entities_from_test(&test, &schema);
     perform_integration_test(
-        policies,
-        entities,
-        schema,
+        &policies,
+        &entities,
+        &schema,
         test.should_validate,
         test.requests,
         test_name.as_ref(),