From 7fa713bad9681ca094f8135d0e17ee105a9d61c2 Mon Sep 17 00:00:00 2001 From: Aman Arora Date: Fri, 31 Jul 2020 18:12:45 -0400 Subject: [PATCH 1/5] Propose language changes Breif details about implementation: - Instead of pre-initializing `closure_captured` and `upvars_capture_map` using `upvars_mentioned` we will be rely on use within the closure. This will be handled as part of #7 - For coercing a closure to FnPtr, instead of relying on `upvars_mentioned` in typechk we will accept such code in typechk while setting a no-capture obligation that will be validated in trait selection post capture analysis. --- lang-changes.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 lang-changes.md diff --git a/lang-changes.md b/lang-changes.md new file mode 100644 index 0000000..b9cf21b --- /dev/null +++ b/lang-changes.md @@ -0,0 +1,29 @@ +# Language Changes + +This document lists changes that will be made to language along with RFC-2229. + +For this document let RS20 be the pre-RFC compiler and RS21 be the post-RFC compiler. + +## `_` pattern in closures + +Consider the following code +```rust +let x; +let c = || { + let _ = x; +}; +``` + +RS20 will result in the capture of x within the closure, but `_` is just an ignore/discard and that means x can't/won't be used within the closure and should not result in a capture. + +For RS21 we propose to ignore such captures allowing the following code to be accepted by RS21 +``` +let x; +let c = || { + let _ = x; +}; + +let f : fn() = c; +``` + +The above code works now because `x` isn't captured by `c` anymore making `c` a non-capturing closure, which can be coerced to a `FnPtr` From 25c8d4fcc1d6111a0b8cd86249d580d3d2330fce Mon Sep 17 00:00:00 2001 From: Aman Arora Date: Fri, 31 Jul 2020 18:16:27 -0400 Subject: [PATCH 2/5] Mark codeblock as rust --- lang-changes.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lang-changes.md b/lang-changes.md index b9cf21b..6d45b11 100644 --- a/lang-changes.md +++ b/lang-changes.md @@ -7,6 +7,7 @@ For this document let RS20 be the pre-RFC compiler and RS21 be the post-RFC comp ## `_` pattern in closures Consider the following code + ```rust let x; let c = || { @@ -17,7 +18,8 @@ let c = || { RS20 will result in the capture of x within the closure, but `_` is just an ignore/discard and that means x can't/won't be used within the closure and should not result in a capture. For RS21 we propose to ignore such captures allowing the following code to be accepted by RS21 -``` + +```rust let x; let c = || { let _ = x; From d8719dc5d7bef54a7c7b6a9178ded8e08f4c7db6 Mon Sep 17 00:00:00 2001 From: Aman Arora Date: Fri, 31 Jul 2020 19:06:13 -0400 Subject: [PATCH 3/5] minor changes --- lang-changes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lang-changes.md b/lang-changes.md index 6d45b11..8fe47a5 100644 --- a/lang-changes.md +++ b/lang-changes.md @@ -28,4 +28,4 @@ let c = || { let f : fn() = c; ``` -The above code works now because `x` isn't captured by `c` anymore making `c` a non-capturing closure, which can be coerced to a `FnPtr` +The above code works now because `x` isn't captured by `c` anymore, making `c` a non-capturing closure, which can be coerced to a `FnPtr`. From 00d0e230b789eed382b45f8651604c84cbec3c9a Mon Sep 17 00:00:00 2001 From: Aman Arora Date: Fri, 31 Jul 2020 19:21:09 -0400 Subject: [PATCH 4/5] Add another example --- lang-changes.md | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/lang-changes.md b/lang-changes.md index 8fe47a5..61beffe 100644 --- a/lang-changes.md +++ b/lang-changes.md @@ -17,7 +17,7 @@ let c = || { RS20 will result in the capture of x within the closure, but `_` is just an ignore/discard and that means x can't/won't be used within the closure and should not result in a capture. -For RS21 we propose to ignore such captures allowing the following code to be accepted by RS21 +For RS21 we propose to ignore such captures allowing the following pieces of code to be accepted by RS21 ```rust let x; @@ -26,6 +26,28 @@ let c = || { }; let f : fn() = c; + +f(); ``` The above code works now because `x` isn't captured by `c` anymore, making `c` a non-capturing closure, which can be coerced to a `FnPtr`. + +```rust +fn main() { + let mut x = String::from("1"); + + let c = || { + let _ = x; + }; + + + let mx = &mut x; + *mx = String::from("2"); + + c(); + + println!("{}", x); +} +``` +RS20 would immutably borrow x within the closure (even thought it's discarded), preventing a mutable borrow to exist outside the closure. +The above code works with RS21 because `x` isn't captured within the closure allowing the mutable borrow outside the closure to exist. From 70a0bc49e9fdd936aad3e744760d6bd200959e09 Mon Sep 17 00:00:00 2001 From: Aman Arora Date: Sat, 1 Aug 2020 13:52:27 -0400 Subject: [PATCH 5/5] Update lang-changes.md --- lang-changes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lang-changes.md b/lang-changes.md index 61beffe..ed57776 100644 --- a/lang-changes.md +++ b/lang-changes.md @@ -1,6 +1,6 @@ # Language Changes -This document lists changes that will be made to language along with RFC-2229. +This document lists changes that will be made to the language along with RFC-2229. For this document let RS20 be the pre-RFC compiler and RS21 be the post-RFC compiler.