{"id":16851889,"url":"https://github.com/cad97/generativity","last_synced_at":"2026-04-26T23:00:22.977Z","repository":{"id":34896595,"uuid":"187897392","full_name":"CAD97/generativity","owner":"CAD97","description":null,"archived":false,"fork":false,"pushed_at":"2026-04-26T21:01:45.000Z","size":67,"stargazers_count":57,"open_issues_count":1,"forks_count":7,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-04-26T21:10:02.759Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CAD97.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2019-05-21T19:02:52.000Z","updated_at":"2026-04-26T21:00:04.000Z","dependencies_parsed_at":"2024-10-27T12:08:06.768Z","dependency_job_id":"4556553d-633e-475f-86fc-cd742de17f78","html_url":"https://github.com/CAD97/generativity","commit_stats":{"total_commits":24,"total_committers":2,"mean_commits":12.0,"dds":0.04166666666666663,"last_synced_commit":"54ba22e3f2ca6be100d41cb4059120b4e089e44f"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/CAD97/generativity","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CAD97%2Fgenerativity","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CAD97%2Fgenerativity/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CAD97%2Fgenerativity/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CAD97%2Fgenerativity/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CAD97","download_url":"https://codeload.github.com/CAD97/generativity/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CAD97%2Fgenerativity/sbom","scorecard":{"id":25581,"data":{"date":"2025-08-11","repo":{"name":"github.com/CAD97/generativity","commit":"1013ba59c5191ccc562646a93ff9fae0840fc1f2"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.3,"checks":[{"name":"Code-Review","score":0,"reason":"Found 1/18 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yaml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/CAD97/generativity/ci.yaml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yaml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/CAD97/generativity/ci.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yaml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/CAD97/generativity/ci.yaml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yaml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/CAD97/generativity/ci.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish.yaml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/CAD97/generativity/publish.yaml/main?enable=pin","Info:   0 out of   3 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Maintained","score":5,"reason":"5 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 5","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/ci.yaml:1","Warn: no topLevel permission defined: .github/workflows/publish.yaml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE-APACHE:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 15 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-14T17:47:53.186Z","repository_id":34896595,"created_at":"2025-08-14T17:47:53.186Z","updated_at":"2025-08-14T17:47:53.186Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32315712,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T21:09:39.134Z","status":"ssl_error","status_checked_at":"2026-04-26T21:09:21.240Z","response_time":129,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-13T13:34:00.009Z","updated_at":"2026-04-26T23:00:22.965Z","avatar_url":"https://github.com/CAD97.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Generativity [![Chat on Discord](https://img.shields.io/discord/496481045684944897?style=flat\u0026logo=discord)][Discord]\n\nGenerativity refers to the creation of a unique lifetime: one that the Rust\nborrow checker will not unify with any other lifetime. This can be used to\nbrand types such that you know that you, and not another copy of you, created\nthem. This is required for sound unchecked indexing and similar tricks.\n\nThe first step of achieving generativity is an [invariant][variance] lifetime.\nThen the consumer must not be able to unify that lifetime with any other lifetime.\n\nTraditionally, this is achieved with a closure. If you have the user write their code in a\n`for\u003c'a\u003e fn(Invariant\u003c'a\u003e) -\u003e _` callback, the local typechecking within this callback\nis forced to assume that it can be handed _any_ lifetime (the `for\u003c'a\u003e` bound), and that\nit cannot possibly use another lifetime, even `'static`, in its place (the invariance).\n\nThis crate implements a different approach using macros and a `Drop`-based scope guard.\nWhen you call `generativity::make_guard!` to make a unique lifetime guard, the macro\nfirst creates an `Id` holding an invariant lifetime. It then puts within a `Drop` type\na `\u0026'id Id\u003c'id\u003e` reference. A different invocation of the macro has a different end timing\nto its tag lifetime, so the lifetimes cannot be unified. These types have no safe way to\nconstruct them other than via `make_guard!`, thus the lifetime is guaranteed unique.\n\nThis effectively does the same thing as wrapping the rest of the function in an\nimmediately invoked closure. We do some pre-work (create the tag and give the caller the\nguard), run the user code (the code after here, the closure previously), and then run\nsome cleanup code after (in the drop implementation). This same technique of a macro\nhygiene hidden `impl Drop` can be used by most APIs that would normally use a closure\nargument, enabling them to avoid introducing a closure boundary to control flow \"effect\"s\nsuch as `async.await` and `?`. But this also comes with a subtle downside: being able to\n`.await` means that locals could be forgotten instead of dropped, and thus the drop glue\nmust not be relied on to run for soundness. This is okay for this crate, since the actual\ndrop impl is a no-op that just exists for the lifetime analysis impacts, but it means that\nmore interesting cases like scoped threads still need to use a closure callback to ensure\ntheir soundness-critical cleanup gets run (e.g. to wait on and join the scoped threads).\n\nIt's important to note that lifetimes are only trusted to carry lifetime brands when they\nare in fact invariant. Variant lifetimes, such as `\u0026'a T`, can still be shrunk to fit the\nbranded lifetime; `\u0026'static T` can be used where `\u0026'a T` is expected, for *any* `'a`.\n\n## How does it work?\n\n```rust\n// SAFETY: The lifetime given to `$name` is unique among trusted brands.\n// We know this because of how we carefully control drop timing here.\n// The branded lifetime's end is bound to be no later than when the\n// `branded_place` is invalidated at the end of scope, but also must be\n// no sooner than `lifetime_brand` is dropped, also at the end of scope.\n// Some other variant lifetime could be constrained to be equal to the\n// brand lifetime, but no other lifetime branded by `make_guard!` can,\n// as its brand lifetime has a distinct drop time from this one. QED\nlet branded_place = unsafe { $crate::Id::new() };\n#[allow(unused)]\nlet lifetime_brand = unsafe { $crate::LifetimeBrand::new(\u0026branded_place) };\n// implicit when exiting scope: drop(lifetime_brand), as LifetimeBrand: Drop\nlet $name = unsafe { $crate::Guard::new(branded_place) };\n```\n\nA previous version of this crate emitted more code in the macro, and defined the\n`LifetimeBrand` type inline. This improved compiler errors on compiler versions\nfrom the time, but the current compiler produces an equivalently good or better\nerror with `LifetimeBrand` defined in the `generativity` crate.\n\nThe `LifetimeBrand` type is *not public API* and must not be used directly. It\nis not covered by stability guarantees; only usage of `make_guard!` and other\ndocumented APIs are considered stable.\n\n## Huge generativity disclaimer\n\nThat last point above is ***VERY*** important. We _cannot_ guarantee that the\nlifetime is fully unique. We can only guarantee that it's unique among trusted\ncarriers. This applies equally to the traditional method:\n\n```rust\nfn scope\u003cF\u003e(f: F)\nwhere F: for\u003c'id\u003e FnOnce(Guard\u003c'id\u003e)\n{\n    make_guard!(guard);\n    f(guard);\n}\n\nfn unify\u003c'a\u003e(_: \u0026'a (), _: \u0026Guard\u003c'a\u003e) {\n    // here, you have two `'a` which are equivalent to `guard`'s `'id`\n}\n\nfn main() {\n    let place = ();\n    make_guard!(guard);\n    unify(\u0026place, \u0026guard);\n    scope(|guard| {\n        unify(\u0026place, \u0026guard);\n    })\n}\n```\n\nOther variant lifetimes can still shrink to unify with `'id`. What all this\nmeans is that you can't just trust any old `'id` lifetime floating around. It\nhas to be carried in a trusted carrier, and one that wasn't created from an\nuntrusted lifetime.\n\n## Impl Disclaimer\n\nThis relies on dead code (an `#[inline(always)]` no-op drop) to impact borrow\nchecking. In theory, a sufficiently advanced borrow checker looking at the CFG\nafter some inlining would be able to see that dropping `lifetime_brand` doesn't\nrequire the captured lifetime to be live, and destroy the uniqueness guarantee\nwhich we've created. This would be much more difficult with the higher-ranked\nclosure formulation, but would still theoretically be possible with sufficient\ninlining. Thankfully, based on the direction around the unstable \"borrowck\neyepatch\" which is the reason e.g. `Box\u003c\u0026'a T\u003e` can be dropped at end of scope\ndespite the `\u0026'a T` borrow being invalidated beforehand, and the further\nstability implications of inferring whether a generic is \"used\" by `Drop::drop`,\nit seems like any such weakening of an explicit `impl Drop` \"using\" captured\nlifetimes in the eyes of borrowck will be opt-in. This crate won't opt in to\nsuch a feature, and thus will remain sound.\n\nHowever, in the specific case that the containing function returns `!` (is known\nto diverge at the type level), it is possible to get borrow checking to ignore\nthe impact of drop glue, if it is never reached in any arm. `make_guard!` will\nrefuse to compile in this case; in the case of any other return type, we ensure\nthat the drop glue is considered in determining the full lifetime of the brand.\n\n## Minimum supported Rust version\n\nThe crate currently requires Rust 1.85. I have no intent of increasing the\ncompiler version requirement of this crate beyond this. However, this is only\nguaranteed within a given minor version number.\n\n## License\n\nLicensed under either of\n\n- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or \u003chttp://www.apache.org/licenses/LICENSE-2.0\u003e)\n- MIT license ([LICENSE-MIT](LICENSE-MIT) or \u003chttp://opensource.org/licenses/MIT\u003e)\n\nat your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n\n  [Discord]: \u003chttps://discord.gg/FuPE9JE\u003e\n  [variance]: \u003chttps://doc.rust-lang.org/nomicon/subtyping.html#variance\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcad97%2Fgenerativity","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcad97%2Fgenerativity","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcad97%2Fgenerativity/lists"}