From e5efea4eb3a75db539fd267ae2574278ec6838bd Mon Sep 17 00:00:00 2001 From: mdinger Date: Wed, 13 May 2015 00:06:52 -0400 Subject: [PATCH 1/9] Delete `_book` folder if it exists from previous runs --- src/rustbook/build.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/rustbook/build.rs b/src/rustbook/build.rs index f96704ee12832..47bdc9335c401 100644 --- a/src/rustbook/build.rs +++ b/src/rustbook/build.rs @@ -183,6 +183,12 @@ impl Subcommand for Build { tgt = PathBuf::from(&env::args().nth(3).unwrap()); } + // `_book` directory may already exist from previous runs. Check and + // delete it if it exists. + for entry in try!(fs::read_dir(&cwd)) { + let path = try!(entry).path(); + if path == tgt { try!(fs::remove_dir_all(&tgt)) } + } try!(fs::create_dir(&tgt)); try!(File::create(&tgt.join("rust-book.css")).and_then(|mut f| { From 5f932e8ec81e508ad9d3962814d9ccf78f1561b8 Mon Sep 17 00:00:00 2001 From: Mathieu Rochette Date: Wed, 13 May 2015 22:31:36 +0200 Subject: [PATCH 2/9] make diagnostic message clearer when called from cargo --- src/libsyntax/diagnostic.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index 66ddd73101e26..0097bab2fea4d 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -506,7 +506,7 @@ fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, rsp: RenderSpan, match dst.registry.as_ref().and_then(|registry| registry.find_description(code)) { Some(_) => { try!(print_diagnostic(dst, &ss[..], Help, - &format!("pass `--explain {}` to see a detailed \ + &format!("run `rustc --explain {}` to see a detailed \ explanation", code), None)); } None => () From 809be9b7f454385e0ba689d73e4327c1621f45a6 Mon Sep 17 00:00:00 2001 From: Nick Hamann Date: Wed, 13 May 2015 19:07:19 -0500 Subject: [PATCH 3/9] Fix link to RFC 255 in Reference. --- src/doc/reference.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index 7d3cf64e9f031..21e9be59ebbdf 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -3529,7 +3529,9 @@ The actual implementation for each vtable entry can vary on an object-by-object basis. Note that for a trait object to be instantiated, the trait must be -_object-safe_. Object safety rules are defined in [RFC 255][rfc255]. +_object-safe_. Object safety rules are defined in [RFC 255]. + +[RFC 255]: https://github.com/rust-lang/rfcs/blob/master/text/0255-object-safety.md Given a pointer-typed expression `E` of type `&T` or `Box`, where `T` implements trait `R`, casting `E` to the corresponding pointer type `&R` or From a4444aa78079665658b0d656c6d243d88a9ac5cc Mon Sep 17 00:00:00 2001 From: Nick Hamann Date: Mon, 11 May 2015 23:36:54 -0500 Subject: [PATCH 4/9] Add error explanations for E0066 and E0069. This also updates the error messages for both. For E0066, it removes mention of "managed heap", which was removed in 8a91d33. For E0069, I just tweaked the wording to make it a bit more explicit. --- src/librustc_typeck/check/mod.rs | 9 +++++---- src/librustc_typeck/diagnostics.rs | 27 +++++++++++++++++++++++++-- src/test/compile-fail/issue-14084.rs | 2 +- src/test/compile-fail/ret-non-nil.rs | 2 +- 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 554f3d4b5a0c7..3cdbaec15284b 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3082,8 +3082,8 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, let mut checked = false; opt_place.as_ref().map(|place| match place.node { ast::ExprPath(None, ref path) => { - // FIXME(pcwalton): For now we hardcode the two permissible - // places: the exchange heap and the managed heap. + // FIXME(pcwalton): For now we hardcode the only permissible + // place: the exchange heap. let definition = lookup_full_def(tcx, path.span, place.id); let def_id = definition.def_id(); let referent_ty = fcx.expr_ty(&**subexpr); @@ -3097,7 +3097,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, if !checked { span_err!(tcx.sess, expr.span, E0066, - "only the managed heap and exchange heap are currently supported"); + "only the exchange heap is currently supported"); fcx.write_ty(id, tcx.types.err); } } @@ -3317,7 +3317,8 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, if let Err(_) = fcx.mk_eqty(false, infer::Misc(expr.span), result_type, ty::mk_nil(fcx.tcx())) { span_err!(tcx.sess, expr.span, E0069, - "`return;` in function returning non-nil"); + "`return;` in a function whose return type is \ + not `()`"); }, Some(ref e) => { check_expr_coercable_to_type(fcx, &**e, result_type); diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index a11a4edbd316b..1613122ecced2 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -91,6 +91,16 @@ enum variant, one of the fields was not provided. Each field should be specified exactly once. "##, +E0066: r##" +Box placement expressions (like C++'s "placement new") do not support any +place expression except the exchange heap (i.e. `std::boxed::HEAP`). +Furthermore, the syntax is changing to use `in` instead of `box`. See [RFC +470][rfc470] and [RFC 809][rfc809] for more details. + +[rfc470]: https://github.com/rust-lang/rfcs/pull/470 +[rfc809]: https://github.com/rust-lang/rfcs/pull/809 +"##, + E0067: r##" The left-hand side of an assignment operator must be an lvalue expression. An lvalue expression represents a memory location and includes item paths (ie, @@ -108,6 +118,21 @@ LinkedList::new() += 1; ``` "##, +E0069: r##" +The compiler found a function whose body contains a `return;` statement but +whose return type is not `()`. An example of this is: + +``` +// error +fn foo() -> u8 { + return; +} +``` + +Since `return;` is just like `return ();`, there is a mismatch between the +function's return type and the value being returned. +"##, + E0081: r##" Enum discriminants are used to differentiate enum variants stored in memory. This error indicates that the same value was used for two or more variants, @@ -484,9 +509,7 @@ register_diagnostics! { E0059, E0060, E0061, - E0066, E0068, - E0069, E0070, E0071, E0072, diff --git a/src/test/compile-fail/issue-14084.rs b/src/test/compile-fail/issue-14084.rs index 92e0dd3ad0e52..003c6644f7f02 100644 --- a/src/test/compile-fail/issue-14084.rs +++ b/src/test/compile-fail/issue-14084.rs @@ -12,5 +12,5 @@ fn main() { box ( () ) 0; - //~^ ERROR: only the managed heap and exchange heap are currently supported + //~^ ERROR: only the exchange heap is currently supported } diff --git a/src/test/compile-fail/ret-non-nil.rs b/src/test/compile-fail/ret-non-nil.rs index 4ee3cf4abac4e..6be98fbd82773 100644 --- a/src/test/compile-fail/ret-non-nil.rs +++ b/src/test/compile-fail/ret-non-nil.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: `return;` in function returning non-nil +// error-pattern: `return;` in a function whose return type is not `()` fn f() { return; } From 71f7fb2b59663ca12e531b3dc8703070431bc78a Mon Sep 17 00:00:00 2001 From: David Reid Date: Wed, 13 May 2015 20:03:56 -0700 Subject: [PATCH 5/9] Fix table syntax. --- src/doc/trpl/the-stack-and-the-heap.md | 46 +++++++++++++------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/doc/trpl/the-stack-and-the-heap.md b/src/doc/trpl/the-stack-and-the-heap.md index f5654d6293991..9622a92303f1e 100644 --- a/src/doc/trpl/the-stack-and-the-heap.md +++ b/src/doc/trpl/the-stack-and-the-heap.md @@ -80,7 +80,7 @@ This memory is kind of like a giant array: addresses start at zero and go up to the final number. So here’s a diagram of our first stack frame: | Address | Name | Value | -+---------+------+-------+ +|---------|------|-------| | 0 | x | 42 | We’ve got `x` located at address `0`, with the value `42`. @@ -88,7 +88,7 @@ We’ve got `x` located at address `0`, with the value `42`. When `foo()` is called, a new stack frame is allocated: | Address | Name | Value | -+---------+------+-------+ +|---------|------|-------| | 2 | z | 100 | | 1 | y | 5 | | 0 | x | 42 | @@ -107,7 +107,7 @@ value being stored. After `foo()` is over, its frame is deallocated: | Address | Name | Value | -+---------+------+-------+ +|---------|------|-------| | 0 | x | 42 | And then, after `main()`, even this last value goes away. Easy! @@ -142,13 +142,13 @@ fn main() { Okay, first, we call `main()`: | Address | Name | Value | -+---------+------+-------+ +|---------|------|-------| | 0 | x | 42 | Next up, `main()` calls `foo()`: | Address | Name | Value | -+---------+------+-------+ +|---------|------|-------| | 3 | c | 1 | | 2 | b | 100 | | 1 | a | 5 | @@ -157,7 +157,7 @@ Next up, `main()` calls `foo()`: And then `foo()` calls `bar()`: | Address | Name | Value | -+---------+------+-------+ +|---------|------|-------| | 4 | i | 6 | | 3 | c | 1 | | 2 | b | 100 | @@ -170,7 +170,7 @@ After `bar()` is over, its frame is deallocated, leaving just `foo()` and `main()`: | Address | Name | Value | -+---------+------+-------+ +|---------|------|-------| | 3 | c | 1 | | 2 | b | 100 | | 1 | a | 5 | @@ -179,7 +179,7 @@ After `bar()` is over, its frame is deallocated, leaving just `foo()` and And then `foo()` ends, leaving just `main()` | Address | Name | Value | -+---------+------+-------+ +|---------|------|-------| | 0 | x | 42 | And then we’re done. Getting the hang of it? It’s like piling up dishes: you @@ -206,7 +206,7 @@ fn main() { Here’s what happens in memory when `main()` is called: | Address | Name | Value | -+---------+------+--------+ +|---------|------|--------| | 1 | y | 42 | | 0 | x | ?????? | @@ -218,7 +218,7 @@ it allocates some memory for the heap, and puts `5` there. The memory now looks like this: | Address | Name | Value | -+-----------------+------+----------------+ +|-----------------|------|----------------| | 230 | | 5 | | ... | ... | ... | | 1 | y | 42 | @@ -243,7 +243,7 @@ layout of a program which has been running for a while now: | Address | Name | Value | -+----------------------+------+----------------------+ +|----------------------|------|----------------------| | 230 | | 5 | | (230) - 1 | | | | (230) - 2 | | | @@ -272,7 +272,7 @@ when it was created. Great! So when `x` goes away, it first frees the memory allocated on the heap: | Address | Name | Value | -+---------+------+--------+ +|---------|------|--------| | 1 | y | 42 | | 0 | x | ?????? | @@ -305,7 +305,7 @@ fn main() { When we enter `main()`, memory looks like this: | Address | Name | Value | -+---------+------+-------+ +|---------|------|-------| | 1 | y | 0 | | 0 | x | 5 | @@ -315,7 +315,7 @@ memory location that `x` lives at, which in this case is `0`. What about when we call `foo()`, passing `y` as an argument? | Address | Name | Value | -+---------+------+-------+ +|---------|------|-------| | 3 | z | 42 | | 2 | i | 0 | | 1 | y | 0 | @@ -367,7 +367,7 @@ fn main() { First, we call `main()`: | Address | Name | Value | -+-----------------+------+----------------+ +|-----------------|------|----------------| | 230 | | 20 | | ... | ... | ... | | 2 | j | 0 | @@ -380,7 +380,7 @@ value pointing there. Next, at the end of `main()`, `foo()` gets called: | Address | Name | Value | -+-----------------+------+----------------+ +|-----------------|------|----------------| | 230 | | 20 | | ... | ... | ... | | 5 | z | 4 | @@ -397,7 +397,7 @@ since `j` points at `h`. Next, `foo()` calls `baz()`, passing `z`: | Address | Name | Value | -+-----------------+------+----------------+ +|-----------------|------|----------------| | 230 | | 20 | | ... | ... | ... | | 7 | g | 100 | @@ -413,7 +413,7 @@ We’ve allocated memory for `f` and `g`. `baz()` is very short, so when it’s over, we get rid of its stack frame: | Address | Name | Value | -+-----------------+------+----------------+ +|-----------------|------|----------------| | 230 | | 20 | | ... | ... | ... | | 5 | z | 4 | @@ -426,7 +426,7 @@ over, we get rid of its stack frame: Next, `foo()` calls `bar()` with `x` and `z`: | Address | Name | Value | -+----------------------+------+----------------------+ +|----------------------|------|----------------------| | 230 | | 20 | | (230) - 1 | | 5 | | ... | ... | ... | @@ -449,7 +449,7 @@ case, we set up the variables as usual. At the end of `bar()`, it calls `baz()`: | Address | Name | Value | -+----------------------+------+----------------------+ +|----------------------|------|----------------------| | 230 | | 20 | | (230) - 1 | | 5 | | ... | ... | ... | @@ -473,7 +473,7 @@ far. After `baz()` is over, we get rid of `f` and `g`: | Address | Name | Value | -+----------------------+------+----------------------+ +|----------------------|------|----------------------| | 230 | | 20 | | (230) - 1 | | 5 | | ... | ... | ... | @@ -493,7 +493,7 @@ Next, we return from `bar()`. `d` in this case is a `Box`, so it also frees what it points to: (230) - 1. | Address | Name | Value | -+-----------------+------+----------------+ +|-----------------|------|----------------| | 230 | | 20 | | ... | ... | ... | | 5 | z | 4 | @@ -506,7 +506,7 @@ what it points to: (230) - 1. And after that, `foo()` returns: | Address | Name | Value | -+-----------------+------+----------------+ +|-----------------|------|----------------| | 230 | | 20 | | ... | ... | ... | | 2 | j | 0 | From f539c416a0ef87c645de26b67e01a047afcb0b2a Mon Sep 17 00:00:00 2001 From: David Reid Date: Wed, 13 May 2015 20:41:03 -0700 Subject: [PATCH 6/9] Fix automatic substitution of task->thread. --- src/doc/trpl/iterators.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/trpl/iterators.md b/src/doc/trpl/iterators.md index e0cc45c254b99..a93f622e9c529 100644 --- a/src/doc/trpl/iterators.md +++ b/src/doc/trpl/iterators.md @@ -42,7 +42,7 @@ loop is just a handy way to write this `loop`/`match`/`break` construct. `for` loops aren't the only thing that uses iterators, however. Writing your own iterator involves implementing the `Iterator` trait. While doing that is outside of the scope of this guide, Rust provides a number of useful iterators -to accomplish various threads. Before we talk about those, we should talk about a +to accomplish various tasks. Before we talk about those, we should talk about a Rust anti-pattern. And that's using ranges like this. Yes, we just talked about how ranges are cool. But ranges are also very From 06aef339f11091f178957350b5159081e7b4534a Mon Sep 17 00:00:00 2001 From: Nick Hamann Date: Wed, 13 May 2015 22:32:52 -0500 Subject: [PATCH 7/9] Add error explanations for E0053, E0251, E0252, E0255, E0256, E0368. --- src/librustc_resolve/diagnostics.rs | 90 +++++++++++++++++++++++++++-- src/librustc_typeck/diagnostics.rs | 82 +++++++++++++++++++++++++- 2 files changed, 164 insertions(+), 8 deletions(-) diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 1e0b627a8e031..cd941c65b9da3 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -49,6 +49,88 @@ about what constitutes an Item declaration and what does not: http://doc.rust-lang.org/reference.html#statements "##, +E0251: r##" +Two items of the same name cannot be imported without rebinding one of the +items under a new local name. + +An example of this error: + +``` +use foo::baz; +use bar::*; // error, do `use foo::baz as quux` instead on the previous line + +fn main() {} + +mod foo { + pub struct baz; +} + +mod bar { + pub mod baz {} +} +``` +"##, + +E0252: r##" +Two items of the same name cannot be imported without rebinding one of the +items under a new local name. + +An example of this error: + +``` +use foo::baz; +use bar::baz; // error, do `use bar::baz as quux` instead + +fn main() {} + +mod foo { + pub struct baz; +} + +mod bar { + pub mod baz {} +} +``` +"##, + +E0255: r##" +You can't import a value whose name is the same as another value defined in the +module. + +An example of this error: + +``` +use foo::FOO; // error, do `use foo::FOO as BAR` instead + +fn FOO() {} + +mod foo { + pub const FOO: bool = true; +} + +fn main() {} +``` +"##, + +E0256: r##" +You can't import a type or module when the name of the item being imported is +the same as another type or submodule defined in the module. + +An example of this error: + +``` +use foo::Bar; // error + +struct Bar; + +mod foo { + pub mod Bar { } +} + +fn main() {} +``` +"##, + E0259: r##" The name chosen for an external crate conflicts with another external crate that has been imported into the current module. @@ -122,14 +204,10 @@ http://doc.rust-lang.org/reference.html#types register_diagnostics! { E0157, E0153, - E0251, // a named type or value has already been imported in this module - E0252, // a named type or value has already been imported in this module E0253, // not directly importable E0254, // import conflicts with imported crate in this module - E0255, // import conflicts with value in this module - E0256, // import conflicts with type in this module - E0257, // inherent implementations are only allowed on types defined in the current module - E0258, // import conflicts with existing submodule + E0257, + E0258, E0364, // item is private E0365 // item is private } diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 1613122ecced2..d19bb859c7750 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -64,6 +64,44 @@ impl Foo for Bar { ``` "##, +E0053: r##" +In a trait method implementation, the function signature must match exactly. +This error indicates a mutability mismatch between a trait method signature +and the signature of the implementation. + +Here's an example where the mutability of the `self` parameter is wrong: + +``` +trait Foo { fn foo(&self); } + +struct Bar; + +impl Foo for Bar { + // error, the signature should be `fn foo(&self)` instead + fn foo(&mut self) { } +} + +fn main() {} +``` + +Here's another example, this time for a non-`self` parameter: + +``` +trait Foo { fn foo(x: &mut bool) -> bool; } + +struct Bar; + +impl Foo for Bar { + // error, the type of `x` should be `&mut bool` instead + fn foo(x: &bool) -> bool { *x } +} + +fn main() {} +``` + + +"##, + E0054: r##" It is not allowed to cast to a bool. If you are trying to cast a numeric type to a bool, you can compare it with zero instead: @@ -483,6 +521,48 @@ The `Sized` trait is a special trait built-in to the compiler for types with a constant size known at compile-time. This trait is automatically implemented for types as needed by the compiler, and it is currently disallowed to explicitly implement it for a type. +"##, + +E0368: r##" +This error indicates that a binary assignment operator like `+=` or `^=` was +applied to the wrong types. + +A couple examples of this are as follows: + +``` +let mut x: u16 = 5; +x ^= true; // error, `^=` cannot be applied to types `u16` and `bool` +x += (); // error, `+=` cannot be applied to types `u16` and `()` +``` + +Another problem you might be facing is this: suppose you've overloaded the `+` +operator for some type `Foo` by implementing the `std::ops::Add` trait for +`Foo`, but you find that using `+=` does not work, as in this example: + +``` +use std::ops::Add; + +struct Foo(u32); + +impl Add for Foo { + type Output = Foo; + + fn add(self, rhs: Foo) -> Foo { + Foo(self.0 + rhs.0) + } +} + +fn main() { + let mut x: Foo = Foo(5); + x += Foo(7); // error, `+= cannot be applied to types `Foo` and `Foo` +} +``` + +This is because the binary assignment operators currently do not work off of +traits, so it is not possible to overload them. See [RFC 953] for a proposal +to change this. + +[RFC 953]: https://github.com/rust-lang/rfcs/pull/953 "## } @@ -503,7 +583,6 @@ register_diagnostics! { E0040, // explicit use of destructor method E0044, // foreign items may not have type parameters E0045, // variadic function must have C calling convention - E0053, E0055, // method has an incompatible type for trait E0057, // method has an incompatible type for trait E0059, @@ -629,7 +708,6 @@ register_diagnostics! { E0328, // cannot implement Unsize explicitly E0366, // dropck forbid specialization to concrete type or region E0367, // dropck forbid specialization to predicate not in struct/enum - E0368, // binary operation `=` cannot be applied to types E0369, // binary operation `` cannot be applied to types E0371, // impl Trait for Trait is illegal E0372, // impl Trait for Trait where Trait is not object safe From d636b5cf659771d74a5e225b751898f69a35ae9a Mon Sep 17 00:00:00 2001 From: Nick Hamann Date: Thu, 14 May 2015 02:50:39 -0500 Subject: [PATCH 8/9] Improve examples in the E0255/E0256 error explanations. --- src/librustc_resolve/diagnostics.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index cd941c65b9da3..15ddcbc80749c 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -100,12 +100,12 @@ module. An example of this error: ``` -use foo::FOO; // error, do `use foo::FOO as BAR` instead +use bar::foo; // error, do `use bar::foo as baz` instead -fn FOO() {} +fn foo() {} -mod foo { - pub const FOO: bool = true; +mod bar { + pub fn foo() {} } fn main() {} @@ -121,7 +121,7 @@ An example of this error: ``` use foo::Bar; // error -struct Bar; +type Bar = u32; mod foo { pub mod Bar { } From 588777f5471db2d03b5a376efbc21c1dc10fc364 Mon Sep 17 00:00:00 2001 From: Nick Hamann Date: Thu, 14 May 2015 03:22:55 -0500 Subject: [PATCH 9/9] Improve E0053 and E0066 error explanations. --- src/librustc_typeck/diagnostics.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index d19bb859c7750..2e5b389c2850e 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -65,9 +65,8 @@ impl Foo for Bar { "##, E0053: r##" -In a trait method implementation, the function signature must match exactly. -This error indicates a mutability mismatch between a trait method signature -and the signature of the implementation. +For any given method of a trait, the mutabilities of the parameters must match +between the trait definition and the implementation. Here's an example where the mutability of the `self` parameter is wrong: @@ -130,13 +129,13 @@ exactly once. "##, E0066: r##" -Box placement expressions (like C++'s "placement new") do not support any +Box placement expressions (like C++'s "placement new") do not yet support any place expression except the exchange heap (i.e. `std::boxed::HEAP`). -Furthermore, the syntax is changing to use `in` instead of `box`. See [RFC -470][rfc470] and [RFC 809][rfc809] for more details. +Furthermore, the syntax is changing to use `in` instead of `box`. See [RFC 470] +and [RFC 809] for more details. -[rfc470]: https://github.com/rust-lang/rfcs/pull/470 -[rfc809]: https://github.com/rust-lang/rfcs/pull/809 +[RFC 470]: https://github.com/rust-lang/rfcs/pull/470 +[RFC 809]: https://github.com/rust-lang/rfcs/pull/809 "##, E0067: r##"