Repository: cedar-policy/cedar
Pull request #1372 (2024-12-12 15:19:13)

Apply clippy lint suggestions
## Description of changes

Apply more clippy lints. Most of the `clone`s removed are just in test code, but they were automatic fixes by `clippy --fix` 

## Issue #, if available

## Checklist for requesting a review

The change in this PR is (choose one, and delete the other options):

- [ ] A breaking change requiring a major version bump to `cedar-policy` (e.g., changes to the signature of an existing API).
- [ ] A backwards-compatible change requiring a minor version bump to `cedar-policy` (e.g., addition of a new API).
- [ ] A bug fix or other functionality change requiring a patch to `cedar-policy`.
- [x] A change "invisible" to users (e.g., documentation, changes to "internal" crates like `cedar-policy-core`, `cedar-validator`, etc.)
- [ ] A change (breaking or otherwise) that only impacts unreleased or experimental code.

I confirm that this PR (choose one, and delete the other options):

- [ ] Updates the "Unreleased" section of the CHANGELOG with a description of my change (required for major/minor version bumps).
- [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.
- [ ] Requires updates, and I have made / will make these updates myself. (Please include in your description a timeline or link to the relevant PR in `cedar-spec`, and how you have tested that your updates are correct.)
- [ ] Requires updates, but I do not plan to make them in the near future. (Make sure that your changes are hidden behind a feature flag to mark them as experimental.)
- [ ] I'm not sure how my change impacts `cedar-spec`. (Post your PR anyways, and we'll discuss in the comments.)

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.
- [ ] Requires updates, and I have made / will make these updates myself. (Please include in your description a timeline or link to the relevant PR in [`cedar-docs`](https://github.com/cedar-policy/cedar-docs). PRs should be targeted at a `staging-X.Y` branch, not `main`.)
- [ ] I'm not sure how my change impacts the documentation. (Post your PR anyways, and we'll discuss in the comments.)



Patch:
diff --git a/cedar-policy-cli/src/main.rs b/cedar-policy-cli/src/main.rs
index 0890bf3d..56a8ba33 100644
--- a/cedar-policy-cli/src/main.rs
+++ b/cedar-policy-cli/src/main.rs
@@ -75,7 +75,7 @@ mod test {
         let test_data_root = PathBuf::from(r"../sample-data/sandbox_b");
         let mut schema_file = test_data_root.clone();
         schema_file.push("schema.cedarschema");
-        let mut old_policies_file = test_data_root.clone();
+        let mut old_policies_file = test_data_root;
         old_policies_file.push("policies_4.cedar");
         let new_policies_file = old_policies_file.clone();
 
diff --git a/cedar-policy-core/src/ast/policy.rs b/cedar-policy-core/src/ast/policy.rs
index 2c735bf5..22a75ceb 100644
--- a/cedar-policy-core/src/ast/policy.rs
+++ b/cedar-policy-core/src/ast/policy.rs
@@ -2246,7 +2246,7 @@ impl AsRef<str> for PolicyID {
 }
 
 #[cfg(feature = "arbitrary")]
-impl<'u> arbitrary::Arbitrary<'u> for PolicyID {
+impl arbitrary::Arbitrary<'_> for PolicyID {
     fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<PolicyID> {
         let s: String = u.arbitrary()?;
         Ok(PolicyID::from_string(s))
diff --git a/cedar-policy-core/src/parser/err.rs b/cedar-policy-core/src/parser/err.rs
index d12568a1..49b75052 100644
--- a/cedar-policy-core/src/parser/err.rs
+++ b/cedar-policy-core/src/parser/err.rs
@@ -259,7 +259,7 @@ pub enum ToASTErrorKind {
     InvalidPattern(String),
     /// Returned when the right hand side of a `is` expression is not an entity type name
     #[error("right hand side of an `is` expression must be an entity type name, but got `{rhs}`")]
-    #[diagnostic(help("{}", invalid_is_help(&.lhs, &.rhs)))]
+    #[diagnostic(help("{}", invalid_is_help(lhs, rhs)))]
     InvalidIsType {
         /// LHS of the invalid `is` expression, as a string
         lhs: String,
diff --git a/cedar-policy-validator/src/cedar_schema/err.rs b/cedar-policy-validator/src/cedar_schema/err.rs
index 232529cb..bbe7dcc4 100644
--- a/cedar-policy-validator/src/cedar_schema/err.rs
+++ b/cedar-policy-validator/src/cedar_schema/err.rs
@@ -635,7 +635,7 @@ pub mod schema_warnings {
     // CAUTION: this type is publicly exported in `cedar-policy`.
     // Don't make fields `pub`, don't make breaking changes, and use caution
     // when adding public methods.
-    #[derive(Debug, Clone, Error)]
+    #[derive(Eq, PartialEq, Debug, Clone, Error)]
     #[error("The name `{name}` shadows a builtin Cedar name. You'll have to refer to the builtin as `__cedar::{name}`.")]
     pub struct ShadowsBuiltinWarning {
         pub(crate) name: SmolStr,
@@ -655,7 +655,7 @@ pub mod schema_warnings {
     // CAUTION: this type is publicly exported in `cedar-policy`.
     // Don't make fields `pub`, don't make breaking changes, and use caution
     // when adding public methods.
-    #[derive(Debug, Clone, Error)]
+    #[derive(Eq, PartialEq, Debug, Clone, Error)]
     #[error("The common type name {name} shadows an entity name")]
     pub struct ShadowsEntityWarning {
         pub(crate) name: SmolStr,
@@ -690,7 +690,7 @@ pub mod schema_warnings {
 // CAUTION: this type is publicly exported in `cedar-policy`.
 // Don't make fields `pub`, don't make breaking changes, and use caution
 // when adding public methods.
-#[derive(Debug, Clone, Error, Diagnostic)]
+#[derive(Eq, PartialEq, Debug, Clone, Error, Diagnostic)]
 #[non_exhaustive]
 pub enum SchemaWarning {
     /// Warning when a declaration shadows a builtin type
diff --git a/cedar-policy-validator/src/coreschema.rs b/cedar-policy-validator/src/coreschema.rs
index 1b00694b..18c4c18d 100644
--- a/cedar-policy-validator/src/coreschema.rs
+++ b/cedar-policy-validator/src/coreschema.rs
@@ -358,7 +358,7 @@ pub mod request_validation_errors {
     /// not valid for the request action
     #[derive(Debug, Error, Diagnostic)]
     #[error("principal type `{principal_ty}` is not valid for `{action}`")]
-    #[diagnostic(help("{}", invalid_principal_type_help(&.valid_principal_tys, .action.as_ref())))]
+    #[diagnostic(help("{}", invalid_principal_type_help(valid_principal_tys, .action.as_ref())))]
     pub struct InvalidPrincipalTypeError {
         /// Principal type which is not valid
         pub(super) principal_ty: ast::EntityType,
@@ -407,7 +407,7 @@ pub mod request_validation_errors {
     /// not valid for the request action
     #[derive(Debug, Error, Diagnostic)]
     #[error("resource type `{resource_ty}` is not valid for `{action}`")]
-    #[diagnostic(help("{}", invalid_resource_type_help(&.valid_resource_tys, .action.as_ref())))]
+    #[diagnostic(help("{}", invalid_resource_type_help(valid_resource_tys, .action.as_ref())))]
     pub struct InvalidResourceTypeError {
         /// Resource type which is not valid
         pub(super) resource_ty: ast::EntityType,
@@ -888,7 +888,7 @@ mod test {
                 (ast::EntityUID::with_eid_and_type("User", "abc123").unwrap(), None),
                 (ast::EntityUID::with_eid_and_type("Action", "edit_photo").unwrap(), None),
                 (ast::EntityUID::with_eid_and_type("Photo", "vacationphoto94.jpg").unwrap(), None),
-                context_with_extra_attr.clone(),
+                context_with_extra_attr,
                 Some(&schema()),
                 Extensions::all_available(),
             ),
@@ -914,7 +914,7 @@ mod test {
                 (ast::EntityUID::with_eid_and_type("User", "abc123").unwrap(), None),
                 (ast::EntityUID::with_eid_and_type("Action", "edit_photo").unwrap(), None),
                 (ast::EntityUID::with_eid_and_type("Photo", "vacationphoto94.jpg").unwrap(), None),
-                context_with_wrong_type_attr.clone(),
+                context_with_wrong_type_attr,
                 Some(&schema()),
                 Extensions::all_available(),
             ),
@@ -943,7 +943,7 @@ mod test {
                 (ast::EntityUID::with_eid_and_type("User", "abc123").unwrap(), None),
                 (ast::EntityUID::with_eid_and_type("Action", "edit_photo").unwrap(), None),
                 (ast::EntityUID::with_eid_and_type("Photo", "vacationphoto94.jpg").unwrap(), None),
-                context_with_heterogeneous_set.clone(),
+                context_with_heterogeneous_set,
                 Some(&schema()),
                 Extensions::all_available(),
             ),
diff --git a/cedar-policy-validator/src/entity_manifest.rs b/cedar-policy-validator/src/entity_manifest.rs
index 209e542a..08a39f93 100644
--- a/cedar-policy-validator/src/entity_manifest.rs
+++ b/cedar-policy-validator/src/entity_manifest.rs
@@ -304,7 +304,7 @@ fn union_fields(first: &Fields, second: &Fields) -> Fields {
     for (key, value) in second {
         res.entry(key.clone())
             .and_modify(|existing| existing.union_mut(value))
-            .or_insert(value.clone());
+            .or_insert_with(|| value.clone());
     }
     res
 }
@@ -375,7 +375,7 @@ impl RootAccessTrie {
             self.trie
                 .entry(key.clone())
                 .and_modify(|existing| existing.union_mut(value))
-                .or_insert(value.clone());
+                .or_insert_with(|| value.clone());
         }
     }
 }
diff --git a/cedar-policy-validator/src/entity_manifest/loader.rs b/cedar-policy-validator/src/entity_manifest/loader.rs
index 902f80c3..bafc2e1c 100644
--- a/cedar-policy-validator/src/entity_manifest/loader.rs
+++ b/cedar-policy-validator/src/entity_manifest/loader.rs
@@ -58,7 +58,7 @@ pub(crate) struct EntityRequestRef<'a> {
     access_trie: &'a AccessTrie,
 }
 
-impl<'a> EntityRequestRef<'a> {
+impl EntityRequestRef<'_> {
     fn to_request(&self) -> EntityRequest {
         EntityRequest {
             entity_id: self.entity_id.clone(),
@@ -251,7 +251,7 @@ pub(crate) fn load_entities(
         }
 
         let mut next_to_load = vec![];
-        for (entity_request, loaded_maybe) in to_load.drain(..).zip(new_entities) {
+        for (entity_request, loaded_maybe) in to_load.into_iter().zip(new_entities) {
             if let Some(loaded) = loaded_maybe {
                 next_to_load.extend(find_remaining_entities(
                     &loaded,
@@ -435,7 +435,7 @@ fn compute_ancestors_request(
 
     while !to_visit.is_empty() {
         let mut next_to_visit = vec![];
-        for entity_request in to_visit.drain(..) {
+        for entity_request in to_visit {
             // check the is_ancestor flag for entities
             // the is_ancestor flag on sets of entities is handled by find_remaining_entities
             if entity_request.access_trie.is_ancestor {
diff --git a/cedar-policy-validator/src/entity_manifest/slicing.rs b/cedar-policy-validator/src/entity_manifest/slicing.rs
index 999f756e..73285db4 100644
--- a/cedar-policy-validator/src/entity_manifest/slicing.rs
+++ b/cedar-policy-validator/src/entity_manifest/slicing.rs
@@ -140,7 +140,7 @@ struct EntitySlicer<'a> {
     entities: &'a Entities,
 }
 
-impl<'a> EntityLoader for EntitySlicer<'a> {
+impl EntityLoader for EntitySlicer<'_> {
     fn load_entities(
         &mut self,
         to_load: &[EntityRequest],
diff --git a/cedar-policy-validator/src/entity_manifest/type_annotations.rs b/cedar-policy-validator/src/entity_manifest/type_annotations.rs
index 6ae2fde8..0c70e771 100644
--- a/cedar-policy-validator/src/entity_manifest/type_annotations.rs
+++ b/cedar-policy-validator/src/entity_manifest/type_annotations.rs
@@ -69,16 +69,16 @@ impl RootAccessTrie {
                         match key {
                             EntityRoot::Literal(lit) => slice.to_typed(
                                 request_type,
-                                &Type::euid_literal(lit.clone(), schema).ok_or(
+                                &Type::euid_literal(lit.clone(), schema).ok_or_else(|| {
                                     MismatchedMissingEntityError {
                                         entity: lit.clone(),
-                                    },
-                                )?,
+                                    }
+                                })?,
                                 schema,
                             )?,
                             EntityRoot::Var(Var::Action) => {
                                 let ty = Type::euid_literal(request_type.action.clone(), schema)
-                                    .ok_or(MismatchedMissingEntityError {
+                                    .ok_or_else(|| MismatchedMissingEntityError {
                                         entity: request_type.action.clone(),
                                     })?;
                                 slice.to_typed(request_type, &ty, schema)?
@@ -96,7 +96,7 @@ impl RootAccessTrie {
                             EntityRoot::Var(Var::Context) => {
                                 let ty = &schema
                                     .get_action_id(&request_type.action.clone())
-                                    .ok_or(MismatchedMissingEntityError {
+                                    .ok_or_else(|| MismatchedMissingEntityError {
                                         entity: request_type.action.clone(),
                                     })?
                                     .context;
diff --git a/cedar-policy-validator/src/lib.rs b/cedar-policy-validator/src/lib.rs
index d6782bf2..63abdc23 100644
--- a/cedar-policy-validator/src/lib.rs
+++ b/cedar-policy-validator/src/lib.rs
@@ -323,13 +323,13 @@ mod test {
         let policy_a_src = r#"permit(principal in foo_type::"a", action == Action::"actin", resource == bar_type::"b");"#;
         let policy_a = parser::parse_policy(Some(PolicyID::from_string("pola")), policy_a_src)
             .expect("Test Policy Should Parse");
-        set.add_static(policy_a.clone())
+        set.add_static(policy_a)
             .expect("Policy already present in PolicySet");
 
         let policy_b_src = r#"permit(principal in foo_tye::"a", action == Action::"action", resource == br_type::"b");"#;
         let policy_b = parser::parse_policy(Some(PolicyID::from_string("polb")), policy_b_src)
             .expect("Test Policy Should Parse");
-        set.add_static(policy_b.clone())
+        set.add_static(policy_b)
             .expect("Policy already present in PolicySet");
 
         let result = validator.validate(&set, ValidationMode::default());
@@ -508,7 +508,7 @@ mod test {
         // `result` contains the two prior error messages plus one new one
         assert_eq!(result.validation_errors().count(), 3);
         let invalid_action_err = ValidationError::invalid_action_application(
-            loc.clone(),
+            loc,
             PolicyID::from_string("link3"),
             false,
             false,
diff --git a/cedar-policy-validator/src/schema.rs b/cedar-policy-validator/src/schema.rs
index 8e0c8872..d93b012f 100644
--- a/cedar-policy-validator/src/schema.rs
+++ b/cedar-policy-validator/src/schema.rs
@@ -2788,8 +2788,7 @@ pub(crate) mod test {
                 }
               }
         );
-        let schema =
-            ValidatorSchema::from_json_value(src.clone(), Extensions::all_available()).unwrap();
+        let schema = ValidatorSchema::from_json_value(src, Extensions::all_available()).unwrap();
         let mut attributes = assert_entity_type_exists(&schema, "Demo::User").attributes();
         let (attr_name, attr_ty) = attributes.next().unwrap();
         assert_eq!(attr_name, "id");
@@ -3511,7 +3510,7 @@ pub(crate) mod test {
                 "actions": { },
             }
         });
-        let schema = ValidatorSchema::from_json_value(src.clone(), Extensions::all_available());
+        let schema = ValidatorSchema::from_json_value(src, Extensions::all_available());
         assert_matches!(schema, Err(SchemaError::JsonDeserialization(_)));
 
         let src: serde_json::Value = json!({
@@ -3521,7 +3520,7 @@ pub(crate) mod test {
                 "actions": { },
             }
         });
-        let schema = ValidatorSchema::from_json_value(src.clone(), Extensions::all_available());
+        let schema = ValidatorSchema::from_json_value(src, Extensions::all_available());
         assert_matches!(schema, Err(SchemaError::JsonDeserialization(_)));
 
         let src: serde_json::Value = json!({
@@ -3535,7 +3534,7 @@ pub(crate) mod test {
                 "actions": { },
             }
         });
-        let schema = ValidatorSchema::from_json_value(src.clone(), Extensions::all_available());
+        let schema = ValidatorSchema::from_json_value(src, Extensions::all_available());
         assert_matches!(schema, Err(SchemaError::JsonDeserialization(_)));
 
         let src: serde_json::Value = json!({
@@ -3549,7 +3548,7 @@ pub(crate) mod test {
                 "actions": { },
             }
         });
-        let schema = ValidatorSchema::from_json_value(src.clone(), Extensions::all_available());
+        let schema = ValidatorSchema::from_json_value(src, Extensions::all_available());
         assert_matches!(schema, Err(SchemaError::JsonDeserialization(_)));
 
         let src: serde_json::Value = json!({
@@ -4650,7 +4649,7 @@ mod entity_tags {
             },
             "actions": {}
         }});
-        assert_matches!(ValidatorSchema::from_json_value(json.clone(), Extensions::all_available()), Ok(schema) => {
+        assert_matches!(ValidatorSchema::from_json_value(json, Extensions::all_available()), Ok(schema) => {
             let user = assert_entity_type_exists(&schema, "User");
             assert_matches!(user.tag_type(), Some(Type::Set { element_type: Some(el_ty) }) => {
                 assert_matches!(&**el_ty, Type::Primitive { primitive_type: Primitive::String });
@@ -5136,8 +5135,8 @@ action CreateList in Create appliesTo {
     #[test]
     fn empty_schema_principals_and_resources() {
         let empty: ValidatorSchema = "".parse().unwrap();
-        assert!(empty.principals().collect::<Vec<_>>().is_empty());
-        assert!(empty.resources().collect::<Vec<_>>().is_empty());
+        assert!(empty.principals().next().is_none());
+        assert!(empty.resources().next().is_none());
     }
 
     #[test]
@@ -5350,8 +5349,8 @@ action CreateList in Create appliesTo {
     #[test]
     fn empty_schema_principals_and_resources() {
         let empty: ValidatorSchema = "".parse().unwrap();
-        assert!(empty.principals().collect::<Vec<_>>().is_empty());
-        assert!(empty.resources().collect::<Vec<_>>().is_empty());
+        assert!(empty.principals().next().is_none());
+        assert!(empty.resources().next().is_none());
     }
 
     #[test]
diff --git a/cedar-policy-validator/src/types.rs b/cedar-policy-validator/src/types.rs
index aaab3bd6..ade1f88b 100644
--- a/cedar-policy-validator/src/types.rs
+++ b/cedar-policy-validator/src/types.rs
@@ -1851,7 +1851,6 @@ mod test {
                             AsRef::<str>::as_ref(s).into(),
                             AttributeType::required_attribute(t.clone())
                         ))
-                        .collect::<BTreeMap<_, _>>()
                 ),
                 entity_lub.get_attribute_types(&schema),
                 "Incorrect computed record type for LUB for {mode:?}."
@@ -2613,7 +2612,7 @@ mod test {
         assert_least_upper_bound(
             action_schema(),
             ValidationMode::Permissive,
-            action_view_ty.clone(),
+            action_view_ty,
             Type::any_record(),
             Err(LubHelp::EntityRecord),
         );
diff --git a/cedar-policy/src/api.rs b/cedar-policy/src/api.rs
index c83ea676..91c859d9 100644
--- a/cedar-policy/src/api.rs
+++ b/cedar-policy/src/api.rs
@@ -2378,10 +2378,7 @@ impl Protobuf for PolicySet {
     fn decode(buf: impl prost::bytes::Buf) -> Result<Self, prost::DecodeError> {
         let ast = proto::try_decode::<ast::proto::LiteralPolicySet, _, _>(buf)?
             .expect("proto-encoded policy set should be a valid policy set");
-        Ok(
-            PolicySet::from_ast(ast)
-                .expect("proto-encoded policy set should be a valid policy set"),
-        )
+        Ok(Self::from_ast(ast).expect("proto-encoded policy set should be a valid policy set"))
     }
 }
 
diff --git a/cedar-policy/src/ffi/utils.rs b/cedar-policy/src/ffi/utils.rs
index 966f81e1..49dfe10d 100644
--- a/cedar-policy/src/ffi/utils.rs
+++ b/cedar-policy/src/ffi/utils.rs
@@ -296,6 +296,11 @@ impl Policy {
     }
 
     /// Get valid principals, actions, and resources.
+    ///
+    /// # Errors
+    ///
+    /// Returns an error result if `self` cannot be parsed as a
+    /// [`crate::Policy`] or if `s` cannot be parsed as a [`crate::Schema`].
     pub fn get_valid_request_envs(
         self,
         s: Schema,
@@ -375,6 +380,11 @@ impl Template {
     }
 
     /// Get valid principals, actions, and resources.
+    ///
+    /// # Errors
+    ///
+    /// Returns an error result if `self` cannot be parsed as a
+    /// [`crate::Template`] or if `s` cannot be parsed as a [`crate::Schema`].
     pub fn get_valid_request_envs(
         self,
         s: Schema,


Test patch:
diff --git a/cedar-policy-validator/src/cedar_schema/test.rs b/cedar-policy-validator/src/cedar_schema/test.rs
index ab416f75..158a602b 100644
--- a/cedar-policy-validator/src/cedar_schema/test.rs
+++ b/cedar-policy-validator/src/cedar_schema/test.rs
@@ -528,7 +528,7 @@ namespace Baz {action "Foo" appliesTo {
             Extensions::all_available(),
         )
         .expect("Schema should parse");
-        assert!(warnings.collect::<Vec<_>>().is_empty());
+        assert_eq!(warnings.collect::<Vec<_>>(), vec![]);
         let github = fragment
             .0
             .get(&Some("GitHub".parse().unwrap()))
@@ -657,7 +657,7 @@ namespace Baz {action "Foo" appliesTo {
             Extensions::all_available(),
         )
         .expect("failed to parse");
-        assert!(warnings.collect::<Vec<_>>().is_empty());
+        assert_eq!(warnings.collect::<Vec<_>>(), vec![]);
         let doccloud = fragment
             .0
             .get(&Some("DocCloud".parse().unwrap()))
@@ -785,7 +785,7 @@ namespace Baz {action "Foo" appliesTo {
         "#;
         let (_, warnings) =
             json_schema::Fragment::from_cedarschema_str(src, Extensions::all_available()).unwrap();
-        assert!(warnings.collect::<Vec<_>>().is_empty());
+        assert_eq!(warnings.collect::<Vec<_>>(), vec![]);
     }
 
     #[test]
@@ -855,7 +855,7 @@ namespace Baz {action "Foo" appliesTo {
 
         let (_, warnings) =
             json_schema::Fragment::from_cedarschema_str(src, Extensions::all_available()).unwrap();
-        assert!(warnings.collect::<Vec<_>>().is_empty());
+        assert_eq!(warnings.collect::<Vec<_>>(), vec![]);
     }
 
     #[test]
@@ -876,7 +876,7 @@ namespace Baz {action "Foo" appliesTo {
         "#;
         let (fragment, warnings) =
             json_schema::Fragment::from_cedarschema_str(src, Extensions::all_available()).unwrap();
-        assert!(warnings.collect::<Vec<_>>().is_empty());
+        assert_eq!(warnings.collect::<Vec<_>>(), vec![]);
         let service = fragment.0.get(&Some("Service".parse().unwrap())).unwrap();
         let resource = service
             .entity_types
diff --git a/cedar-policy-validator/src/typecheck/test/expr.rs b/cedar-policy-validator/src/typecheck/test/expr.rs
index 66584821..73a88e87 100644
--- a/cedar-policy-validator/src/typecheck/test/expr.rs
+++ b/cedar-policy-validator/src/typecheck/test/expr.rs
@@ -1158,7 +1158,7 @@ fn less_than_typecheck_fails() {
             ValidationError::expected_one_of_types(
                 get_loc(src, "\"\""),
                 expr_id_placeholder(),
-                expected_types.clone(),
+                expected_types,
                 Type::primitive_string(),
                 None,
             ),
diff --git a/cedar-policy-validator/src/typecheck/test/extensions.rs b/cedar-policy-validator/src/typecheck/test/extensions.rs
index b58c660f..3215b9bd 100644
--- a/cedar-policy-validator/src/typecheck/test/extensions.rs
+++ b/cedar-policy-validator/src/typecheck/test/extensions.rs
@@ -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.clone(), 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,
@@ -145,8 +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.clone(), 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,
@@ -158,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.clone(), 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,
@@ -200,7 +199,7 @@ fn datetime_extension_typechecks() {
     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.clone()));
+    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()));
@@ -224,7 +223,7 @@ fn datetime_extension_typechecks() {
     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.clone()));
+    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());
@@ -264,8 +263,7 @@ 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.clone(), 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,
@@ -292,8 +290,7 @@ 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.clone(), 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,
@@ -306,8 +303,7 @@ 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.clone(), 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,
diff --git a/cedar-policy-validator/src/typecheck/test/namespace.rs b/cedar-policy-validator/src/typecheck/test/namespace.rs
index 1766e0f0..e7ad8149 100644
--- a/cedar-policy-validator/src/typecheck/test/namespace.rs
+++ b/cedar-policy-validator/src/typecheck/test/namespace.rs
@@ -586,7 +586,7 @@ fn multi_namespace_action_eq() {
         r#"permit(principal, action, resource) when { NS1::Action::"B" == NS2::Action::"B" };"#,
     )
     .unwrap();
-    let warnings = assert_policy_typecheck_warns(schema.clone(), policy.clone());
+    let warnings = assert_policy_typecheck_warns(schema, policy.clone());
     let warning = assert_exactly_one_diagnostic(warnings);
     assert_eq!(
         warning,
@@ -653,7 +653,7 @@ fn multi_namespace_action_in() {
         r#"permit(principal, action in NS4::Action::"Group", resource);"#,
     )
     .unwrap();
-    let warnings = assert_policy_typecheck_warns(schema.clone(), policy.clone());
+    let warnings = assert_policy_typecheck_warns(schema, policy.clone());
     let warning = assert_exactly_one_diagnostic(warnings);
     assert_eq!(
         warning,
@@ -687,7 +687,7 @@ fn test_cedar_policy_642() {
     .unwrap();
 
     assert_policy_typechecks(
-        schema.clone(),
+        schema,
         parse_policy(
             None,
             r#"
diff --git a/cedar-policy-validator/src/typecheck/test/partial.rs b/cedar-policy-validator/src/typecheck/test/partial.rs
index aee372ab..1238f623 100644
--- a/cedar-policy-validator/src/typecheck/test/partial.rs
+++ b/cedar-policy-validator/src/typecheck/test/partial.rs
@@ -39,7 +39,7 @@ pub(crate) fn assert_partial_typecheck(
     let mut errors: HashSet<ValidationError> = HashSet::new();
     let mut warnings: HashSet<ValidationWarning> = HashSet::new();
     let typechecked = typechecker.typecheck_policy(
-        &Template::link_static_policy(policy.clone()).0,
+        &Template::link_static_policy(policy).0,
         &mut errors,
         &mut warnings,
     );
@@ -58,7 +58,7 @@ pub(crate) fn assert_partial_typecheck_fails(
     let mut errors: HashSet<ValidationError> = HashSet::new();
     let mut warnings: HashSet<ValidationWarning> = HashSet::new();
     let typechecked = typechecker.typecheck_policy(
-        &Template::link_static_policy(policy.clone()).0,
+        &Template::link_static_policy(policy).0,
         &mut errors,
         &mut warnings,
     );
@@ -77,7 +77,7 @@ pub(crate) fn assert_partial_typecheck_warns(
     let mut errors: HashSet<ValidationError> = HashSet::new();
     let mut warnings: HashSet<ValidationWarning> = HashSet::new();
     let typechecked = typechecker.typecheck_policy(
-        &Template::link_static_policy(policy.clone()).0,
+        &Template::link_static_policy(policy).0,
         &mut errors,
         &mut warnings,
     );
@@ -460,7 +460,7 @@ mod fails_empty_schema {
         let src = r#"permit(principal, action, resource) when { resource.bar && false };"#;
         let p = parse_policy(None, src).unwrap();
         assert_typecheck_warns_empty_schema(
-            p.clone(),
+            p,
             [ValidationWarning::impossible_policy(
                 get_loc(src, src),
                 PolicyID::from_string("policy0"),
@@ -473,7 +473,7 @@ mod fails_empty_schema {
         let src = r#"permit(principal, action, resource) when { {foo: 1}.bar };"#;
         let p = parse_policy(None, src).unwrap();
         assert_typecheck_fails_empty_schema(
-            p.clone(),
+            p,
             [ValidationError::unsafe_attribute_access(
                 get_loc(src, "{foo: 1}.bar"),
                 PolicyID::from_string("policy0"),
diff --git a/cedar-policy-validator/src/typecheck/test/policy.rs b/cedar-policy-validator/src/typecheck/test/policy.rs
index 57693bee..c10f1975 100644
--- a/cedar-policy-validator/src/typecheck/test/policy.rs
+++ b/cedar-policy-validator/src/typecheck/test/policy.rs
@@ -1138,7 +1138,7 @@ fn extended_has() {
     };
     "#;
     let policy = parse_policy(None, src).unwrap();
-    let errors = assert_policy_typecheck_fails(schema.clone(), policy);
+    let errors = assert_policy_typecheck_fails(schema, policy);
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
diff --git a/cedar-policy-validator/src/typecheck/test/strict.rs b/cedar-policy-validator/src/typecheck/test/strict.rs
index 98234012..8ec6178e 100644
--- a/cedar-policy-validator/src/typecheck/test/strict.rs
+++ b/cedar-policy-validator/src/typecheck/test/strict.rs
@@ -721,7 +721,7 @@ fn qualified_record_attr() {
 
     let src = "permit(principal, action, resource) when { context == {num_of_things: 1}};";
     let p = parse_policy_or_template(None, src).unwrap();
-    let errors = assert_policy_typecheck_fails(schema, p.clone());
+    let errors = assert_policy_typecheck_fails(schema, p);
     let error = assert_exactly_one_diagnostic(errors);
     assert_eq!(
         error,
diff --git a/cedar-policy-validator/src/typecheck/test/test_utils.rs b/cedar-policy-validator/src/typecheck/test/test_utils.rs
index a2304f7b..c45db448 100644
--- a/cedar-policy-validator/src/typecheck/test/test_utils.rs
+++ b/cedar-policy-validator/src/typecheck/test/test_utils.rs
@@ -167,7 +167,7 @@ impl SchemaProvider for NamespaceDefinitionWithActionAttributes<RawName> {
     }
 }
 
-impl<'a> SchemaProvider for &'a str {
+impl SchemaProvider for &str {
     fn schema(self) -> ValidatorSchema {
         ValidatorSchema::from_cedarschema_str(self, Extensions::all_available())
             .unwrap_or_else(|e| panic!("failed to construct schema: {:?}", miette::Report::new(e)))