Remove preset macros and constructs#242
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
AI Overview
This PR removes the entire CGP preset feature — the
cgp_preset!macro and every construct that existed to support it — because presets have been fully superseded by the newer CGP namespace feature. It is a pure deletion: a single commit on theremove-preset-macrosbranch that touches 48 files, removes roughly 3,360 lines, and adds only 3. No new functionality is introduced here, since the replacement (namespaces) already landed onmainearlier; this change simply retires the old mechanism now that nothing in the CGP ecosystem needs it.The headline consequence is that this is a breaking change. Any downstream crate that still writes presets will stop compiling after upgrading, and must migrate to namespaces. That migration has already been completed in the CGP projects that relied on presets, most notably Hypershell, whose contexts inherited their wiring from a
HypershellPreset.Why presets are being removed
Presets and namespaces solve the same problem — letting a context inherit and reuse a large bundle of component wirings — but they solve it in fundamentally different ways, and the namespace approach is strictly better. Understanding that difference explains why the whole preset subsystem can now be deleted rather than kept around.
Presets worked by copying mapping entries between modules at macro-expansion time. A preset was not a normal type; it was a module generated by
cgp_preset!that carried its component map plus extra macros and re-exports needed to "merge" itself into other presets. Because the merging happened in macros, which cannot see real type information, a preset's source module had to be wrapped in#[re_export_imports]so that its imports could be re-exported and made visible to the copying machinery. Inheritance (PresetB: PresetA + ...), conflict resolution (theoverridekeyword), and the underlying substitution (replace_with!) all existed to make this macro-level copying behave like real inheritance.Namespaces achieve the same composition through the trait system itself, with no macro copying. Instead of duplicating entries, a namespace sets up a path-based redirection: component traits are tagged with
#[prefix(@Key in Namespace)], acgp_namespace!block maps each component to a path key, and adelegate_components!block opts in with anamespace MyNamespace;directive. Lookups then resolve through ordinary trait resolution (RedirectLookupoverPathConspath keys) rather than through generated, module-local macros. The result is fewer moving parts, no re-export gymnastics, and inheritance that the compiler reasons about directly.Because namespaces never depended on any of the preset plumbing, removing presets does not weaken CGP — it removes a parallel, more fragile mechanism that namespaces had already made redundant.
What was removed
The change deletes both the user-facing macros and the internal machinery that backed them. At the public-API level, four constructs disappear from the
cgpandcgp-corepreludes and re-exports:cgp_preset!— the macro that defined a module-based, inheritable component map.#[cgp_inherit(Preset)]— the attribute that let a context delegate all of a preset's keys to that preset's provider.#[re_export_imports]— the wrapper attribute that re-exported a preset module's imports so the merging macros could find them. This is also dropped from the top-levelcgp::re_export_importsandcgp_core::re_export_importsre-export paths.replace_with!— the substitution helper used during preset merging.Underneath those macros, the procedural-macro crate (
cgp-macro-lib) loses the substantial body of code that implemented them. Entire modules are deleted: the preset parser (parse/, coveringdefine_preset,delegate_components,path, andtype_spec), the preset codegen (preset/, coveringimpl_is_presetandsubstitution_macro), thedelegate_components/impl_delegatehelper, thefor_each_replacesubstitution engine, and there_export_imports/replace_withentry points. The matchingcgp_presetandcgp_inheritentry points are removed fromcgp-macro. The net effect on the macro crate is a meaningful simplification — there is simply less metaprogramming to maintain.The test suite is pruned to match. The complete
preset_tests/tree is removed — thebasic,generics,generics_inheritance,inheritance,nested_inheritance, andwrappedscenarios, along with thepreset.rstest entry that included them. One preset-specific sub-test (test_delegate_new_value_in_preset) is also stripped out of the otherwise-unrelatednew_struct.rsdelegation test, which is the only edit to a file that survives.Impacts
The effects of this PR fall into three groups: a breaking change for users, a smaller public surface, and a lighter codebase to maintain.
Downstream code that uses presets will no longer compile. This is the only behavioral impact users will feel, and it is unavoidable for a removal of this kind. Projects must replace
cgp_preset!definitions,#[cgp_inherit]context wiring, and the surrounding#[re_export_imports]modules with the equivalent namespace constructs (cgp_namespace!,#[prefix(...)]on component traits, and thenamespace ...;directive indelegate_components!). The reference migration already exists in Hypershell, which moved itsHypershellPreset-based contexts over to namespaces, so adopters have a concrete example to follow.The public API of
cgpandcgp-coreshrinks by four macros. Anyone importing the prelude no longer receivescgp_preset,cgp_inherit,re_export_imports, orreplace_with, and the two crate-rootre_export_importsre-exports are gone. This makes the surface area smaller and the supported way to compose wirings unambiguous: namespaces.The macro implementation becomes significantly simpler. Removing roughly 3,360 lines — most of it intricate token-level parsing and substitution in
cgp-macro-lib— eliminates a whole class of macro-hygiene and merging edge cases that the preset feature was prone to. This lowers the long-term maintenance burden and reduces the risk surface of the procedural macros.