-
Notifications
You must be signed in to change notification settings - Fork 181
Goals and folding goals #325
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
jackh726
merged 10 commits into
rust-lang:master
from
nikomatsakis:goals-and-folding-goals
Feb 8, 2020
Merged
Changes from 6 commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
b930b31
introduce `Goals<TF>` type to replace `Vec<Goal<TF>>`
nikomatsakis 741aa1a
introduce `SuperFold` trait
nikomatsakis 4d5596f
introduce `SuperFold` derive
nikomatsakis 59929d1
merge the panolpy of folding traits into one trait
nikomatsakis da94001
introduce `fold_goal` and `fold_program_clause` callbacks
nikomatsakis 7a6116d
start to document folding
nikomatsakis 32a3b7d
remove super-fold derive
nikomatsakis 9bb1ac0
address nits
nikomatsakis 68393da
fix fold-trait ref in book
nikomatsakis 870e9c5
remove hard-coded vec and replace with `TypeFamily` assoc type
nikomatsakis File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| # Operations | ||
|
|
||
| This chapter describes various patterns and utilities for manipulating | ||
| Rust types. |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| # Fold and the Folder trait | ||
|
|
||
| The [`Fold`] trait permits one to traverse a type or other term in the | ||
| chalk-ir and make a copy of it, possibly making small substitutions or | ||
| alterations along the way. Folding also allows copying a term from one | ||
| type family to another. | ||
|
|
||
| [`Fold`]: http://rust-lang.github.io/chalk/chalk_ir/fold/trait.Fold.html | ||
|
|
||
| To use the fold-trait, one invokes the [`Fold::fold_with`] method, supplying some | ||
| "folder" as well as the number of "in scope binders" for that term (typically `0` | ||
| to start): | ||
|
|
||
| ```rust,ignore | ||
| let output_ty = input_ty.fold_with(&mut folder, 0); | ||
| ``` | ||
|
|
||
| [`Fold::fold_with`]: http://rust-lang.github.io/chalk/chalk_ir/fold/trait.Fold.html#tymethod.fold_with | ||
|
|
||
| The folder is some instance of the [`Folder`] trait. This trait | ||
| defines a few key callbacks that allow you to substitute different | ||
| values as the fold proceeds. For example, when a type is folded, the | ||
| folder can substitute a new type in its place. | ||
|
|
||
| [`Folder`]: http://rust-lang.github.io/chalk/chalk_ir/fold/trait.Folder.html | ||
|
|
||
| ## Uses for folders | ||
|
|
||
| A common use for `Fold` is to permit a substitution -- that is, | ||
| replacing generic type parameters with their values. | ||
|
|
||
| ## From Fold to Folder to SuperFold and back again | ||
|
|
||
| The overall flow of folding is like this. | ||
|
|
||
| 1. [`Fold::fold_with`] is invoked on the outermost term. It recursively | ||
| walks the term. | ||
| 2. For those sorts of terms (types, lifetimes, goals, program clauses) that have | ||
| callbacks in the [`Folder`] trait, invoking [`Fold::fold_with`] will in turn | ||
| invoke the corresponding method on the [`Folder`] trait, such as `Folder::fold_ty`. | ||
| 3. The default implementation of `Folder::fold_ty`, in turn, invokes | ||
| `SuperFold::super_fold_with`. This will recursively fold the | ||
| contents of the type. In some cases, the `super_fold_with` | ||
| implementation invokes more specialized methods on [`Folder`], such | ||
| as [`Folder::fold_free_var_ty`], which makes it easier to write | ||
| folders that just intercept *certain* types. | ||
|
|
||
| Thus, as a user, you can customize folding by: | ||
|
|
||
| * Defining your own `Folder` type | ||
| * Implementing the appropriate methods to "intercept" types/lifetimes/etc at the right level of | ||
| detail | ||
| * In those methods, if you find a case where you would prefer not to | ||
| substitute a new value, then invoke `SuperFold::super_fold_with` to | ||
| return to the default behavior. | ||
|
|
||
| ## The `binders` argument | ||
|
|
||
| Each callback in the [`Folder`] trait takes a `binders` argument. This indicates | ||
| the number of binders that we have traversed during folding, which is relevant for debruijn indices. | ||
| So e.g. a bound variable with depth 1, if invoked with a `binders` value of 1, indicates something that was bound to something external to the fold. | ||
|
|
||
| XXX explain with examples and in more detail | ||
|
|
||
| ## The `Fold::Result` associated type | ||
|
|
||
| The `Fold` trait defines a [`Result`] associated type, indicating the | ||
| type that will result from folding. | ||
|
|
||
| [`Result`]: http://rust-lang.github.io/chalk/chalk_ir/fold/trait.Fold.html#associatedtype.Result | ||
|
|
||
| ## When to implement the Fold and SuperFold traits | ||
|
|
||
| Any piece of IR that represents a kind of "term" (e.g., a type, part | ||
| of a type, or a goal, etc) in the logic should implement `Fold`. We | ||
| also implement `Fold` for common collection types like `Vec` as well | ||
| as tuples, references, etc. | ||
|
|
||
| The `SuperFold` trait should only be implemented for those types that | ||
| have a callback defined on the `Folder` trait (e.g., types and | ||
| lifetimes). | ||
|
|
||
| ## Derives | ||
|
|
||
| Using the `chalk-derive` crate, you can auto-derive the `Fold` and | ||
| `SuperFold` traits. The derives are a bit cludgy and require: | ||
|
|
||
| * You must import `Fold` (or `SuperFold`, respectively) into scope. | ||
| * The type you are deriving `Fold` on must have either: | ||
| * A type parameter that has a `TypeFamily` bound, like `TF: TypeFamily` | ||
| * A type parameter that has a `HasTypeFamily` bound, like `TF: HasTypeFamily` | ||
| * The `has_type_family(XXX)` attribute. | ||
|
|
||
|
|
||
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
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
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
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
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.