From 8a49eb76865feb77a516b268758e194e5882a1fb Mon Sep 17 00:00:00 2001 From: mark Date: Sun, 8 Jul 2018 19:49:34 -0500 Subject: [PATCH] fix all the not-en-dashes --- README.md | 4 +-- src/appendix/background.md | 4 +-- src/compiletest.md | 2 +- src/conventions.md | 6 ++--- src/incrcomp-debugging.md | 2 +- src/mir/borrowck.md | 2 +- src/mir/index.md | 10 +++---- src/mir/passes.md | 6 ++--- src/mir/regionck.md | 36 ++++++++++++------------- src/mir/visitor.md | 2 +- src/query.md | 2 +- src/tests/adding.md | 8 +++--- src/tests/intro.md | 48 ++++++++++++++++----------------- src/tests/running.md | 4 +-- src/traits/associated-types.md | 10 +++---- src/traits/canonical-queries.md | 12 ++++----- src/traits/canonicalization.md | 2 +- src/traits/goals-and-clauses.md | 4 +-- src/traits/index.md | 2 +- src/traits/lowering-module.md | 4 +-- src/traits/lowering-rules.md | 10 +++---- src/traits/lowering-to-logic.md | 10 +++---- src/type-checking.md | 4 +-- src/variance.md | 6 ++--- 24 files changed, 100 insertions(+), 100 deletions(-) diff --git a/README.md b/README.md index 5dc64ed4..a01758d4 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,8 @@ Once it gets more complete, the plan is probably to move it into the If you'd like to help finish the guide, we'd love to have you! The main tracking issue for the guide [can be found here](https://github.com/rust-lang-nursery/rustc-guide/issues/6). From -there, you can find a list of all the planned chapters and subsections --- if you think something is missing, please open an issue about it! +there, you can find a list of all the planned chapters and subsections. +If you think something is missing, please open an issue about it! Otherwise, find a chapter that sounds interesting to you and then go to its associated issue. There should be a list of things to do. diff --git a/src/appendix/background.md b/src/appendix/background.md index 06913194..efdce4f2 100644 --- a/src/appendix/background.md +++ b/src/appendix/background.md @@ -15,7 +15,7 @@ exposes the underlying control flow in a very clear way. A control-flow graph is structured as a set of **basic blocks** connected by edges. The key idea of a basic block is that it is a set -of statements that execute "together" -- that is, whenever you branch +of statements that execute "together" – that is, whenever you branch to a basic block, you start at the first statement and then execute all the remainder. Only at the end of the block is there the possibility of branching to more than one place (in MIR, we call that @@ -119,7 +119,7 @@ variables, since that's the thing we're most familiar with. So there you have it: a variable "appears free" in some expression/statement/whatever if it refers to something defined outside of that expressions/statement/whatever. Equivalently, we can -then refer to the "free variables" of an expression -- which is just +then refer to the "free variables" of an expression – which is just the set of variables that "appear free". So what does this have to do with regions? Well, we can apply the diff --git a/src/compiletest.md b/src/compiletest.md index cdcede33..0837fb81 100644 --- a/src/compiletest.md +++ b/src/compiletest.md @@ -16,7 +16,7 @@ expect, and more. If you are unfamiliar with the compiler testing framework, see [this chapter](./tests/intro.html) for additional background. The tests themselves are typically (but not always) organized into -"suites"--for example, `run-pass`, a folder representing tests that should +"suites" – for example, `run-pass`, a folder representing tests that should succeed, `run-fail`, a folder holding tests that should compile successfully, but return a failure (non-zero status), `compile-fail`, a folder holding tests that should fail to compile, and many more. The various suites are defined in diff --git a/src/conventions.md b/src/conventions.md index 5b2b7b7f..3f30dac7 100644 --- a/src/conventions.md +++ b/src/conventions.md @@ -44,8 +44,8 @@ current year if you like, but you don't have to. Lines should be at most 100 characters. It's even better if you can keep things to 80. -**Ignoring the line length limit.** Sometimes -- in particular for -tests -- it can be necessary to exempt yourself from this limit. In +**Ignoring the line length limit.** Sometimes – in particular for +tests – it can be necessary to exempt yourself from this limit. In that case, you can add a comment towards the top of the file (after the copyright notice) like so: @@ -141,7 +141,7 @@ command like `git rebase -i rust-lang/master` (presuming you use the name `rust-lang` for your remote). **Individual commits do not have to build (but it's nice).** We do not -require that every intermediate commit successfully builds -- we only +require that every intermediate commit successfully builds – we only expect to be able to bisect at a PR level. However, if you *can* make individual commits build, that is always helpful. diff --git a/src/incrcomp-debugging.md b/src/incrcomp-debugging.md index 2488aa32..ecb29d54 100644 --- a/src/incrcomp-debugging.md +++ b/src/incrcomp-debugging.md @@ -90,7 +90,7 @@ path that should not exist, but you will not be quite sure how it came to be. **When the compiler is built with debug assertions,** it can help you track that down. Simply set the `RUST_FORBID_DEP_GRAPH_EDGE` environment variable to a filter. Every edge created in the dep-graph -will be tested against that filter -- if it matches, a `bug!` is +will be tested against that filter – if it matches, a `bug!` is reported, so you can easily see the backtrace (`RUST_BACKTRACE=1`). The syntax for these filters is the same as described in the previous diff --git a/src/mir/borrowck.md b/src/mir/borrowck.md index cd83843f..d5fea618 100644 --- a/src/mir/borrowck.md +++ b/src/mir/borrowck.md @@ -1,6 +1,6 @@ # MIR borrow check -The borrow check is Rust's "secret sauce" -- it is tasked with +The borrow check is Rust's "secret sauce" – it is tasked with enforcing a number of properties: - That all variables are initialized before they are used. diff --git a/src/mir/index.md b/src/mir/index.md index 838048b8..ea72decd 100644 --- a/src/mir/index.md +++ b/src/mir/index.md @@ -3,7 +3,7 @@ MIR is Rust's _Mid-level Intermediate Representation_. It is constructed from [HIR](./hir.html). MIR was introduced in [RFC 1211]. It is a radically simplified form of Rust that is used for -certain flow-sensitive safety checks -- notably the borrow checker! -- +certain flow-sensitive safety checks – notably the borrow checker! – and also for optimization and code generation. If you'd like a very high-level introduction to MIR, as well as some @@ -122,7 +122,7 @@ StorageLive(_1); ``` This statement indicates that the variable `_1` is "live", meaning -that it may be used later -- this will persist until we encounter a +that it may be used later – this will persist until we encounter a `StorageDead(_1)` statement, which indicates that the variable `_1` is done being used. These "storage statements" are used by LLVM to allocate stack space. @@ -134,7 +134,7 @@ _1 = const >::new() -> bb2; ``` Terminators are different from statements because they can have more -than one successor -- that is, control may flow to different +than one successor – that is, control may flow to different places. Function calls like the call to `Vec::new` are always terminators because of the possibility of unwinding, although in the case of `Vec::new` we are able to see that indeed unwinding is not @@ -163,7 +163,7 @@ Assignments in general have the form: = ``` -A place is an expression like `_3`, `_3.f` or `*_3` -- it denotes a +A place is an expression like `_3`, `_3.f` or `*_3` – it denotes a location in memory. An **Rvalue** is an expression that creates a value: in this case, the rvalue is a mutable borrow expression, which looks like `&mut `. So we can kind of define a grammar for @@ -180,7 +180,7 @@ rvalues like so: | move Place ``` -As you can see from this grammar, rvalues cannot be nested -- they can +As you can see from this grammar, rvalues cannot be nested – they can only reference places and constants. Moreover, when you use a place, we indicate whether we are **copying it** (which requires that the place have a type `T` where `T: Copy`) or **moving it** (which works diff --git a/src/mir/passes.md b/src/mir/passes.md index a5b5df10..c48ef457 100644 --- a/src/mir/passes.md +++ b/src/mir/passes.md @@ -100,8 +100,8 @@ that appeared within the `main` function.) ### Implementing and registering a pass -A `MirPass` is some bit of code that processes the MIR, typically -- -but not always -- transforming it along the way somehow. For example, +A `MirPass` is some bit of code that processes the MIR, typically – +but not always – transforming it along the way somehow. For example, it might perform an optimization. The `MirPass` trait itself is found in in [the `rustc_mir::transform` module][mirtransform], and it basically consists of one method, `run_pass`, that simply gets an @@ -110,7 +110,7 @@ came from). The MIR is therefore modified in place (which helps to keep things efficient). A good example of a basic MIR pass is [`NoLandingPads`], which walks -the MIR and removes all edges that are due to unwinding -- this is +the MIR and removes all edges that are due to unwinding – this is used when configured with `panic=abort`, which never unwinds. As you can see from its source, a MIR pass is defined by first defining a dummy type, a struct with no fields, something like: diff --git a/src/mir/regionck.md b/src/mir/regionck.md index 90f6fa27..9034af8a 100644 --- a/src/mir/regionck.md +++ b/src/mir/regionck.md @@ -12,13 +12,13 @@ The MIR-based region analysis consists of two major functions: - `replace_regions_in_mir`, invoked first, has two jobs: - First, it finds the set of regions that appear within the signature of the function (e.g., `'a` in `fn foo<'a>(&'a u32) { - ... }`). These are called the "universal" or "free" regions -- in + ... }`). These are called the "universal" or "free" regions – in particular, they are the regions that [appear free][fvb] in the function body. - Second, it replaces all the regions from the function body with fresh inference variables. This is because (presently) those regions are the results of lexical region inference and hence are - not of much interest. The intention is that -- eventually -- they + not of much interest. The intention is that – eventually – they will be "erased regions" (i.e., no information at all), since we won't be doing lexical region inference at all. - `compute_regions`, invoked second: this is given as argument the @@ -40,11 +40,11 @@ The MIR-based region analysis consists of two major functions: ## Universal regions -*to be written* -- explain the `UniversalRegions` type +*to be written* – explain the `UniversalRegions` type ## Region variables and constraints -*to be written* -- describe the `RegionInferenceContext` and +*to be written* – describe the `RegionInferenceContext` and the role of `liveness_constraints` vs other `constraints`, plus ## Closures @@ -79,13 +79,13 @@ The kinds of region elements are as follows: - Similarly, there is an element denoted `end('static)` corresponding to the remainder of program execution after this function returns. - There is an element `!1` for each skolemized region `!1`. This - corresponds (intuitively) to some unknown set of other elements -- + corresponds (intuitively) to some unknown set of other elements – for details on skolemization, see the section [skolemization and universes](#skol). ## Causal tracking -*to be written* -- describe how we can extend the values of a variable +*to be written* – describe how we can extend the values of a variable with causal tracking etc @@ -133,7 +133,7 @@ bound in the supertype and **skolemizing** them: this means that we replace them with [universally quantified](appendix/background.html#quantified) representatives, written like `!1`. We call these regions "skolemized -regions" -- they represent, basically, "some unknown region". +regions" – they represent, basically, "some unknown region". Once we've done that replacement, we have the following relation: @@ -156,9 +156,9 @@ we swap the left and right here): ``` According to the basic subtyping rules for a reference, this will be -true if `'!1: 'static`. That is -- if "some unknown region `!1`" lives -outlives `'static`. Now, this *might* be true -- after all, `'!1` -could be `'static` -- but we don't *know* that it's true. So this +true if `'!1: 'static`. That is – if "some unknown region `!1`" lives +outlives `'static`. Now, this *might* be true – after all, `'!1` +could be `'static` – but we don't *know* that it's true. So this should yield up an error (eventually). ### What is a universe @@ -238,8 +238,8 @@ not U1. **Giving existential variables a universe.** Now that we have this notion of universes, we can use it to extend our type-checker and things to prevent illegal names from leaking out. The idea is that we -give each inference (existential) variable -- whether it be a type or -a lifetime -- a universe. That variable's value can then only +give each inference (existential) variable – whether it be a type or +a lifetime – a universe. That variable's value can then only reference names visible from that universe. So for example is a lifetime variable is created in U0, then it cannot be assigned a value of `!1` or `!2`, because those names are not visible from the universe @@ -247,7 +247,7 @@ U0. **Representing universes with just a counter.** You might be surprised to see that the compiler doesn't keep track of a full tree of -universes. Instead, it just keeps a counter -- and, to determine if +universes. Instead, it just keeps a counter – and, to determine if one universe can see another one, it just checks if the index is greater. For example, U2 can see U0 because 2 >= 0. But U0 cannot see U2, because 0 >= 2 is false. @@ -323,12 +323,12 @@ Now there are two ways that could happen. First, if `U(V1)` can see the universe `x` (i.e., `x <= U(V1)`), then we can just add `skol(x)` to `value(V1)` and be done. But if not, then we have to approximate: we may not know what set of elements `skol(x)` represents, but we -should be able to compute some sort of **upper bound** B for it -- +should be able to compute some sort of **upper bound** B for it – some region B that outlives `skol(x)`. For now, we'll just use -`'static` for that (since it outlives everything) -- in the future, we +`'static` for that (since it outlives everything) – in the future, we can sometimes be smarter here (and in fact we have code for doing this already in other contexts). Moreover, since `'static` is in the root -universe U0, we know that all variables can see it -- so basically if +universe U0, we know that all variables can see it – so basically if we find that `value(V2)` contains `skol(x)` for some universe `x` that `V1` can't see, then we force `V1` to `'static`. @@ -398,8 +398,8 @@ outlives relationships are satisfied. Then we would go to the "check universal regions" portion of the code, which would test that no universal region grew too large. -In this case, `V1` *did* grow too large -- it is not known to outlive -`end('static)`, nor any of the CFG -- so we would report an error. +In this case, `V1` *did* grow too large – it is not known to outlive +`end('static)`, nor any of the CFG – so we would report an error. ## Another example diff --git a/src/mir/visitor.md b/src/mir/visitor.md index 265769b3..ad00bc3f 100644 --- a/src/mir/visitor.md +++ b/src/mir/visitor.md @@ -2,7 +2,7 @@ The MIR visitor is a convenient tool for traversing the MIR and either looking for things or making changes to it. The visitor traits are -defined in [the `rustc::mir::visit` module][m-v] -- there are two of +defined in [the `rustc::mir::visit` module][m-v] – there are two of them, generated via a single macro: `Visitor` (which operates on a `&Mir` and gives back shared references) and `MutVisitor` (which operates on a `&mut Mir` and gives back mutable references). diff --git a/src/query.md b/src/query.md index 7ed299b7..a0c0d628 100644 --- a/src/query.md +++ b/src/query.md @@ -5,7 +5,7 @@ Rust compiler is current transitioning from a traditional "pass-based" setup to a "demand-driven" system. **The Compiler Query System is the key to our new demand-driven organization.** The idea is pretty simple. You have various queries that compute things about the input --- for example, there is a query called `type_of(def_id)` that, given +– for example, there is a query called `type_of(def_id)` that, given the def-id of some item, will compute the type of that item and return it to you. diff --git a/src/tests/adding.md b/src/tests/adding.md index fac13fca..a9400c59 100644 --- a/src/tests/adding.md +++ b/src/tests/adding.md @@ -49,8 +49,8 @@ considered an ideal setup. [`src/test/run-pass`]: https://github.com/rust-lang/rust/tree/master/src/test/run-pass/ -For regression tests -- basically, some random snippet of code that -came in from the internet -- we often just name the test after the +For regression tests – basically, some random snippet of code that +came in from the internet – we often just name the test after the issue. For example, `src/test/run-pass/issue-12345.rs`. If possible, though, it is better if you can put the test into a directory that helps identify what piece of code is being tested here (e.g., @@ -267,9 +267,9 @@ can also make UI tests where compilation is expected to succeed, and you can even run the resulting program. Just add one of the following [header commands](#header_commands): -- `// compile-pass` -- compilation should succeed but do +- `// compile-pass` – compilation should succeed but do not run the resulting binary -- `// run-pass` -- compilation should succeed and we should run the +- `// run-pass` – compilation should succeed and we should run the resulting binary diff --git a/src/tests/intro.md b/src/tests/intro.md index bc84c972..69d9ed05 100644 --- a/src/tests/intro.md +++ b/src/tests/intro.md @@ -15,7 +15,7 @@ on [how to run tests](./tests/running.html#ui) as well as The compiletest tests are located in the tree in the [`src/test`] directory. Immediately within you will see a series of subdirectories (e.g. `ui`, `run-make`, and so forth). Each of those directories is -called a **test suite** -- they house a group of tests that are run in +called a **test suite** – they house a group of tests that are run in a distinct mode. [`src/test`]: https://github.com/rust-lang/rust/tree/master/src/test @@ -24,31 +24,31 @@ Here is a brief summary of the test suites as of this writing and what they mean. In some cases, the test suites are linked to parts of the manual that give more details. -- [`ui`](./tests/adding.html#ui) -- tests that check the exact +- [`ui`](./tests/adding.html#ui) – tests that check the exact stdout/stderr from compilation and/or running the test -- `run-pass` -- tests that are expected to compile and execute +- `run-pass` – tests that are expected to compile and execute successfully (no panics) - - `run-pass-valgrind` -- tests that ought to run with valgrind -- `run-fail` -- tests that are expected to compile but then panic + - `run-pass-valgrind` – tests that ought to run with valgrind +- `run-fail` – tests that are expected to compile but then panic during execution -- `compile-fail` -- tests that are expected to fail compilation. -- `parse-fail` -- tests that are expected to fail to parse -- `pretty` -- tests targeting the Rust "pretty printer", which +- `compile-fail` – tests that are expected to fail compilation. +- `parse-fail` – tests that are expected to fail to parse +- `pretty` – tests targeting the Rust "pretty printer", which generates valid Rust code from the AST -- `debuginfo` -- tests that run in gdb or lldb and query the debug info -- `codegen` -- tests that compile and then test the generated LLVM +- `debuginfo` – tests that run in gdb or lldb and query the debug info +- `codegen` – tests that compile and then test the generated LLVM code to make sure that the optimizations we want are taking effect. -- `mir-opt` -- tests that check parts of the generated MIR to make +- `mir-opt` – tests that check parts of the generated MIR to make sure we are building things correctly or doing the optimizations we expect. -- `incremental` -- tests for incremental compilation, checking that +- `incremental` – tests for incremental compilation, checking that when certain modifications are performed, we are able to reuse the results from previous compilations. -- `run-make` -- tests that basically just execute a `Makefile`; the +- `run-make` – tests that basically just execute a `Makefile`; the ultimate in flexibility but quite annoying to write. -- `rustdoc` -- tests for rustdoc, making sure that the generated files +- `rustdoc` – tests for rustdoc, making sure that the generated files contain the expected documentation. -- `*-fulldeps` -- same as above, but indicates that the test depends +- `*-fulldeps` – same as above, but indicates that the test depends on things other than `libstd` (and hence those things must be built) ## Other Tests @@ -56,44 +56,44 @@ that give more details. The Rust build system handles running tests for various other things, including: -- **Tidy** -- This is a custom tool used for validating source code +- **Tidy** – This is a custom tool used for validating source code style and formatting conventions, such as rejecting long lines. There is more information in the [section on coding conventions](./conventions.html#formatting). Example: `./x.py test src/tools/tidy` -- **Unittests** -- The Rust standard library and many of the Rust packages +- **Unittests** – The Rust standard library and many of the Rust packages include typical Rust `#[test]` unittests. Under the hood, `x.py` will run `cargo test` on each package to run all the tests. Example: `./x.py test src/libstd` -- **Doctests** -- Example code embedded within Rust documentation is executed +- **Doctests** – Example code embedded within Rust documentation is executed via `rustdoc --test`. Examples: - `./x.py test src/doc` -- Runs `rustdoc --test` for all documentation in + `./x.py test src/doc` – Runs `rustdoc --test` for all documentation in `src/doc`. - `./x.py test --doc src/libstd` -- Runs `rustdoc --test` on the standard + `./x.py test --doc src/libstd` – Runs `rustdoc --test` on the standard library. -- **Linkchecker** -- A small tool for verifying `href` links within +- **Linkchecker** – A small tool for verifying `href` links within documentation. Example: `./x.py test src/tools/linkchecker` -- **Distcheck** -- This verifies that the source distribution tarball created +- **Distcheck** – This verifies that the source distribution tarball created by the build system will unpack, build, and run all tests. Example: `./x.py test distcheck` -- **Tool tests** -- Packages that are included with Rust have all of their +- **Tool tests** – Packages that are included with Rust have all of their tests run as well (typically by running `cargo test` within their directory). This includes things such as cargo, clippy, rustfmt, rls, miri, bootstrap (testing the Rust build system itself), etc. -- **Cargotest** -- This is a small tool which runs `cargo test` on a few +- **Cargotest** – This is a small tool which runs `cargo test` on a few significant projects (such as `servo`, `ripgrep`, `tokei`, etc.) just to ensure there aren't any significant regressions. diff --git a/src/tests/running.md b/src/tests/running.md index 03eb8ccc..e55b6ec7 100644 --- a/src/tests/running.md +++ b/src/tests/running.md @@ -1,7 +1,7 @@ # Running tests -You can run the tests using `x.py`. The most basic command -- which -you will almost never want to use! -- is as follows: +You can run the tests using `x.py`. The most basic command – which +you will almost never want to use! – is as follows: ```bash > ./x.py test diff --git a/src/traits/associated-types.md b/src/traits/associated-types.md index ec20985f..1972a70e 100644 --- a/src/traits/associated-types.md +++ b/src/traits/associated-types.md @@ -15,7 +15,7 @@ When a trait defines an associated type (e.g., [the `Item` type in the `IntoIterator` trait][intoiter-item]), that type can be referenced by the user using an **associated type projection** like ` as IntoIterator>::Item`. (Often, -though, people will use the shorthand syntax `T::Item` -- presently, +though, people will use the shorthand syntax `T::Item` – presently, that syntax is expanded during ["type collection"](./type-checking.html) into the explicit form, though that is something we may want to change in the future.) @@ -24,8 +24,8 @@ though that is something we may want to change in the future.) -In some cases, associated type projections can be **normalized** -- -that is, simplified -- based on the types given in an impl. So, to +In some cases, associated type projections can be **normalized** – +that is, simplified – based on the types given in an impl. So, to continue with our example, the impl of `IntoIterator` for `Option` declares (among other things) that `Item = T`: @@ -39,9 +39,9 @@ impl IntoIterator for Option { This means we can normalize the projection ` as IntoIterator>::Item` to just `u32`. -In this case, the projection was a "monomorphic" one -- that is, it +In this case, the projection was a "monomorphic" one – that is, it did not have any type parameters. Monomorphic projections are special -because they can **always** be fully normalized -- but often we can +because they can **always** be fully normalized – but often we can normalize other associated type projections as well. For example, ` as IntoIterator>::Item` (where `?T` is an inference variable) can be normalized to just `?T`. diff --git a/src/traits/canonical-queries.md b/src/traits/canonical-queries.md index 56637dac..c58fe369 100644 --- a/src/traits/canonical-queries.md +++ b/src/traits/canonical-queries.md @@ -1,8 +1,8 @@ # Canonical queries The "start" of the trait system is the **canonical query** (these are -both queries in the more general sense of the word -- something you -would like to know the answer to -- and in the +both queries in the more general sense of the word – something you +would like to know the answer to – and in the [rustc-specific sense](./query.html)). The idea is that the type checker or other parts of the system, may in the course of doing their thing want to know whether some trait is implemented for some type @@ -35,7 +35,7 @@ solver is finding **all possible** instantiations of your query that are true. In this case, if we instantiate `?U = [i32]`, then the query is true (note that a traditional Prolog interface does not, directly, tell us a value for `?U`, but we can infer one by unifying the -response with our original query -- Rust's solver gives back a +response with our original query – Rust's solver gives back a substitution instead). If we were to hit `y`, the solver might then give us another possible answer: @@ -135,7 +135,7 @@ we did find. It consists of four parts: [section on handling regions in traits](./traits/regions.html) for more details. - **Value:** The query result also comes with a value of type `T`. For - some specialized queries -- like normalizing associated types -- + some specialized queries – like normalizing associated types – this is used to carry back an extra result, but it's often just `()`. @@ -187,8 +187,8 @@ for example: Therefore, the result we get back would be as follows (I'm going to ignore region constraints and the "value"): -- Certainty: `Ambiguous` -- we're not sure yet if this holds -- Var values: `[?T = ?T, ?U = ?U]` -- we learned nothing about the values of +- Certainty: `Ambiguous` – we're not sure yet if this holds +- Var values: `[?T = ?T, ?U = ?U]` – we learned nothing about the values of the variables In short, the query result says that it is too soon to say much about diff --git a/src/traits/canonicalization.md b/src/traits/canonicalization.md index f87de5f8..1ef1da71 100644 --- a/src/traits/canonicalization.md +++ b/src/traits/canonicalization.md @@ -24,7 +24,7 @@ form of `X` would be `(?0, ?1)`, where `?0` and `?1` represent these **canonical placeholders**. Note that the type `Y = (?U, ?T)` also canonicalizes to `(?0, ?1)`. But the type `Z = (?T, ?T)` would canonicalize to `(?0, ?0)` (as would `(?U, ?U)`). In other words, the -exact identity of the inference variables is not important -- unless +exact identity of the inference variables is not important – unless they are repeated. We use this to improve caching as well as to detect cycles and other diff --git a/src/traits/goals-and-clauses.md b/src/traits/goals-and-clauses.md index 5844e8d4..93bafe33 100644 --- a/src/traits/goals-and-clauses.md +++ b/src/traits/goals-and-clauses.md @@ -197,7 +197,7 @@ Implemented(Foo: Send) :- As you can probably imagine, proving that `Option>: Send` is going to wind up circularly requiring us to prove that `Foo: Send` -again. So this would be an example where we wind up in a cycle -- but +again. So this would be an example where we wind up in a cycle – but that's ok, we *do* consider `Foo: Send` to hold, even though it references itself. @@ -219,4 +219,4 @@ as described in the section on [implied bounds]. Some topics yet to be written: - Elaborate on the proof procedure -- SLG solving -- introduce negative reasoning +- SLG solving – introduce negative reasoning diff --git a/src/traits/index.md b/src/traits/index.md index 2dabd0b6..c070d1b8 100644 --- a/src/traits/index.md +++ b/src/traits/index.md @@ -28,7 +28,7 @@ Trait solving is based around a few key ideas: whether types are equal. - [Region constraints](./traits/regions.html), which are accumulated during trait solving but mostly ignored. This means that trait - solving effectively ignores the precise regions involved, always -- + solving effectively ignores the precise regions involved, always – but we still remember the constraints on them so that those constraints can be checked by thet type checker. diff --git a/src/traits/lowering-module.md b/src/traits/lowering-module.md index 205e9a17..030e1986 100644 --- a/src/traits/lowering-module.md +++ b/src/traits/lowering-module.md @@ -8,8 +8,8 @@ created in the [`rustc_traits::lowering`][lowering] module. ## The `program_clauses_for` query -The main entry point is the `program_clauses_for` [query], which -- -given a def-id -- produces a set of Chalk program clauses. These +The main entry point is the `program_clauses_for` [query], which – +given a def-id – produces a set of Chalk program clauses. These queries are tested using a [dedicated unit-testing mechanism, described below](#unit-tests). The query is invoked on a `DefId` that identifies something like a trait, diff --git a/src/traits/lowering-rules.md b/src/traits/lowering-rules.md index d8b73989..e37999e5 100644 --- a/src/traits/lowering-rules.md +++ b/src/traits/lowering-rules.md @@ -52,11 +52,11 @@ from the Rust syntax into goals. In addition, in the rules below, we sometimes do some transformations on the lowered where clauses, as defined here: -- `FromEnv(WC)` -- this indicates that: +- `FromEnv(WC)` – this indicates that: - `Implemented(TraitRef)` becomes `FromEnv(TraitRef)` - `ProjectionEq(Projection = Ty)` becomes `FromEnv(Projection = Ty)` - other where-clauses are left intact -- `WellFormed(WC)` -- this indicates that: +- `WellFormed(WC)` – this indicates that: - `Implemented(TraitRef)` becomes `WellFormed(TraitRef)` - `ProjectionEq(Projection = Ty)` becomes `WellFormed(Projection = Ty)` @@ -121,8 +121,8 @@ trait Eq: PartialEq { ... } In this case, the `PartialEq` supertrait is equivalent to a `where Self: PartialEq` where clause, in our simplified model. The program -clause above therefore states that if we can prove `FromEnv(T: Eq)` -- -e.g., if we are in some function with `T: Eq` in its where clauses -- +clause above therefore states that if we can prove `FromEnv(T: Eq)` – +e.g., if we are in some function with `T: Eq` in its where clauses – then we also know that `FromEnv(T: PartialEq)`. Thus the set of things that follow from the environment are not only the **direct where clauses** but also things that follow from them. @@ -169,7 +169,7 @@ have to prove each one of those: - `WellFormed(T: Foo)` -- cycle, true coinductively This `WellFormed` predicate is only used when proving that impls are -well-formed -- basically, for each impl of some trait ref `TraitRef`, +well-formed – basically, for each impl of some trait ref `TraitRef`, we must show that `WellFormed(TraitRef)`. This in turn justifies the implied bounds rules that allow us to extend the set of `FromEnv` items. diff --git a/src/traits/lowering-to-logic.md b/src/traits/lowering-to-logic.md index 2de28ce4..cf8c1c25 100644 --- a/src/traits/lowering-to-logic.md +++ b/src/traits/lowering-to-logic.md @@ -15,8 +15,8 @@ One of the first observations is that the Rust trait system is basically a kind of logic. As such, we can map our struct, trait, and impl declarations into logical inference rules. For the most part, these are basically Horn clauses, though we'll see that to capture the -full richness of Rust -- and in particular to support generic -programming -- we have to go a bit further than standard Horn clauses. +full richness of Rust – and in particular to support generic +programming – we have to go a bit further than standard Horn clauses. To see how this mapping works, let's start with an example. Imagine we declare a trait and a few impls, like so: @@ -38,8 +38,8 @@ Clone(Vec) :- Clone(?T). // Or, put another way, B implies A. ``` -In Prolog terms, we might say that `Clone(Foo)` -- where `Foo` is some -Rust type -- is a *predicate* that represents the idea that the type +In Prolog terms, we might say that `Clone(Foo)` – where `Foo` is some +Rust type – is a *predicate* that represents the idea that the type `Foo` implements `Clone`. These rules are **program clauses**; they state the conditions under which that predicate can be proven (i.e., considered true). So the first rule just says "Clone is implemented @@ -162,7 +162,7 @@ notation but a bit Rustified. Anyway, the problem is that standard Horn clauses don't allow universal quantification (`forall`) or implication (`if`) in goals (though many Prolog engines do support them, as an extension). For this reason, we need to accept something -called "first-order hereditary harrop" (FOHH) clauses -- this long +called "first-order hereditary harrop" (FOHH) clauses – this long name basically means "standard Horn clauses with `forall` and `if` in the body". But it's nice to know the proper name, because there is a lot of work describing how to efficiently handle FOHH clauses; see for diff --git a/src/type-checking.md b/src/type-checking.md index 9a161abd..d4f4bf11 100644 --- a/src/type-checking.md +++ b/src/type-checking.md @@ -12,7 +12,7 @@ draws heavily on the [type inference] and [trait solving].) Type "collection" is the process of converting the types found in the HIR (`hir::Ty`), which represent the syntactic things that the user wrote, into the -**internal representation** used by the compiler (`Ty<'tcx>`) -- we also do +**internal representation** used by the compiler (`Ty<'tcx>`) – we also do similar conversions for where-clauses and other bits of the function signature. To try and get a sense for the difference, consider this function: @@ -30,7 +30,7 @@ they encode the path somewhat differently. But once they are "collected" into Collection is defined as a bundle of [queries] for computing information about the various functions, traits, and other items in the crate being compiled. -Note that each of these queries is concerned with *interprocedural* things -- +Note that each of these queries is concerned with *interprocedural* things – for example, for a function definition, collection will figure out the type and signature of the function, but it will not visit the *body* of the function in any way, nor examine type annotations on local variables (that's the job of diff --git a/src/variance.md b/src/variance.md index 05a286c0..9fe98b4a 100644 --- a/src/variance.md +++ b/src/variance.md @@ -167,7 +167,7 @@ one could interpret variance and trait matching. Just as with structs and enums, we can decide the subtyping relationship between two object types `&Trait` and `&Trait` based on the relationship of `A` and `B`. Note that for object -types we ignore the `Self` type parameter -- it is unknown, and +types we ignore the `Self` type parameter – it is unknown, and the nature of dynamic dispatch ensures that we will always call a function that is expected the appropriate `Self` type. However, we must be careful with the other type parameters, or else we could @@ -274,8 +274,8 @@ These conditions are satisfied and so we are happy. ### Variance and associated types -Traits with associated types -- or at minimum projection -expressions -- must be invariant with respect to all of their +Traits with associated types – or at minimum projection +expressions – must be invariant with respect to all of their inputs. To see why this makes sense, consider what subtyping for a trait reference means: