]> git.lizzy.rs Git - rust.git/commitdiff
Stabilize format_args_capture
authorJosh Triplett <josh@joshtriplett.org>
Mon, 1 Nov 2021 15:18:36 +0000 (16:18 +0100)
committerJosh Triplett <josh@joshtriplett.org>
Mon, 15 Nov 2021 09:14:29 +0000 (10:14 +0100)
Works as expected, and there are widespread reports of success with it,
as well as interest in it.

18 files changed:
compiler/rustc_borrowck/src/lib.rs
compiler/rustc_builtin_macros/src/format.rs
compiler/rustc_errors/src/lib.rs
compiler/rustc_expand/src/lib.rs
compiler/rustc_feature/src/accepted.rs
compiler/rustc_feature/src/active.rs
compiler/rustc_lint/src/lib.rs
compiler/rustc_passes/src/lib.rs
compiler/rustc_resolve/src/lib.rs
compiler/rustc_typeck/src/lib.rs
library/alloc/src/lib.rs
src/doc/unstable-book/src/library-features/format-args-capture.md [deleted file]
src/test/ui/fmt/feature-gate-format-args-capture.rs [deleted file]
src/test/ui/fmt/feature-gate-format-args-capture.stderr [deleted file]
src/test/ui/fmt/format-args-capture-macro-hygiene.rs
src/test/ui/fmt/format-args-capture-missing-variables.rs
src/test/ui/fmt/format-args-capture.rs
src/test/ui/fmt/ifmt-bad-arg.stderr

index aca7d3174f6cd567080aafd61b38949ba1154439..76d3a83b48daa45d7a4da26c3b847ef5ccbdd0d1 100644 (file)
@@ -3,7 +3,7 @@
 #![feature(bool_to_option)]
 #![feature(box_patterns)]
 #![feature(crate_visibility_modifier)]
-#![feature(format_args_capture)]
+#![cfg_attr(bootstrap, feature(format_args_capture))]
 #![feature(in_band_lifetimes)]
 #![feature(iter_zip)]
 #![feature(let_else)]
index 52b00a2bc74746d9d0fddbe3ff592ebd4f690774..097eaddb874083ec2895f553eaf16fecfff555ef 100644 (file)
@@ -527,17 +527,9 @@ fn verify_arg_type(&mut self, arg: Position, ty: ArgumentType) {
                         self.verify_arg_type(Exact(idx), ty)
                     }
                     None => {
-                        let capture_feature_enabled = self
-                            .ecx
-                            .ecfg
-                            .features
-                            .map_or(false, |features| features.format_args_capture);
-
                         // For the moment capturing variables from format strings expanded from macros is
                         // disabled (see RFC #2795)
-                        let can_capture = capture_feature_enabled && self.is_literal;
-
-                        if can_capture {
+                        if self.is_literal {
                             // Treat this name as a variable to capture from the surrounding scope
                             let idx = self.args.len();
                             self.arg_types.push(Vec::new());
@@ -559,23 +551,15 @@ fn verify_arg_type(&mut self, arg: Position, ty: ArgumentType) {
                             };
                             let mut err = self.ecx.struct_span_err(sp, &msg[..]);
 
-                            if capture_feature_enabled && !self.is_literal {
-                                err.note(&format!(
-                                    "did you intend to capture a variable `{}` from \
-                                     the surrounding scope?",
-                                    name
-                                ));
-                                err.note(
-                                    "to avoid ambiguity, `format_args!` cannot capture variables \
-                                     when the format string is expanded from a macro",
-                                );
-                            } else if self.ecx.parse_sess().unstable_features.is_nightly_build() {
-                                err.help(&format!(
-                                    "if you intended to capture `{}` from the surrounding scope, add \
-                                     `#![feature(format_args_capture)]` to the crate attributes",
-                                    name
-                                ));
-                            }
+                            err.note(&format!(
+                                "did you intend to capture a variable `{}` from \
+                                 the surrounding scope?",
+                                name
+                            ));
+                            err.note(
+                                "to avoid ambiguity, `format_args!` cannot capture variables \
+                                 when the format string is expanded from a macro",
+                            );
 
                             err.emit();
                         }
index 21a2eb771c8e2b7c282c5f0445bc38c9a4c0b632..bb3d3a415e7d5c939a80234d32919a7f2bc346ba 100644 (file)
@@ -6,7 +6,7 @@
 #![feature(crate_visibility_modifier)]
 #![feature(backtrace)]
 #![feature(if_let_guard)]
-#![feature(format_args_capture)]
+#![cfg_attr(bootstrap, feature(format_args_capture))]
 #![feature(iter_zip)]
 #![feature(let_else)]
 #![feature(nll)]
index 521ca2135c6f217ad573c1ffbf437ade2652c08b..4e84a9df6c978ff2793787434b844da19bd0b34a 100644 (file)
@@ -1,7 +1,7 @@
 #![feature(crate_visibility_modifier)]
 #![feature(decl_macro)]
 #![feature(destructuring_assignment)]
-#![feature(format_args_capture)]
+#![cfg_attr(bootstrap, feature(format_args_capture))]
 #![feature(if_let_guard)]
 #![feature(iter_zip)]
 #![feature(let_else)]
index 3bd1272c7cb47dcb8038efd809c02dae492cd1aa..3cb543fe3ab98c006a9e420da0f8f1ed30d570e2 100644 (file)
@@ -301,6 +301,8 @@ macro_rules! declare_features {
     (accepted, relaxed_struct_unsize, "1.58.0", Some(81793), None),
     /// Allows dereferencing raw pointers during const eval.
     (accepted, const_raw_ptr_deref, "1.58.0", Some(51911), None),
+    /// Allows capturing variables in scope using format_args!
+    (accepted, format_args_capture, "1.58.0", Some(67984), None),
 
     // -------------------------------------------------------------------------
     // feature-group-end: accepted features
index d8b4539d831bb8dff367979e48d89be58e149af0..61dd505e1e912485eb85d859a101b82d0daa8844 100644 (file)
@@ -539,9 +539,6 @@ pub fn set(&self, features: &mut Features, span: Span) {
     /// Be more precise when looking for live drops in a const context.
     (active, const_precise_live_drops, "1.46.0", Some(73255), None),
 
-    /// Allows capturing variables in scope using format_args!
-    (active, format_args_capture, "1.46.0", Some(67984), None),
-
     /// Allows `if let` guard in match arms.
     (active, if_let_guard, "1.47.0", Some(51114), None),
 
index f6514ddca9f57c26bf54647f7e1485520c5c237c..507b4421fa160266c860d468c0e5ec1f5eaed56f 100644 (file)
@@ -30,7 +30,7 @@
 #![feature(bool_to_option)]
 #![feature(box_patterns)]
 #![feature(crate_visibility_modifier)]
-#![feature(format_args_capture)]
+#![cfg_attr(bootstrap, feature(format_args_capture))]
 #![feature(iter_order_by)]
 #![feature(iter_zip)]
 #![feature(never_type)]
index 4adec3c4f608d78e93c412ccb6a5476a370fad7d..af1c724410037e13c624891ea67d34cabc974fca 100644 (file)
@@ -7,7 +7,7 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![feature(crate_visibility_modifier)]
 #![feature(in_band_lifetimes)]
-#![feature(format_args_capture)]
+#![cfg_attr(bootstrap, feature(format_args_capture))]
 #![feature(iter_zip)]
 #![feature(map_try_insert)]
 #![feature(min_specialization)]
index f5bea83bdcf654f68aa8d109151ae573039ad1b7..d17e8875a1ec0d9d58354143f6189a8a9ac3927a 100644 (file)
@@ -13,7 +13,7 @@
 #![feature(drain_filter)]
 #![feature(bool_to_option)]
 #![feature(crate_visibility_modifier)]
-#![feature(format_args_capture)]
+#![cfg_attr(bootstrap, feature(format_args_capture))]
 #![feature(iter_zip)]
 #![feature(let_else)]
 #![feature(never_type)]
index ba0fd12a2755f480568093ea79f6ee7acde5c994..0881cf07586b367b88210919adef6be38f15c779 100644 (file)
@@ -58,7 +58,7 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![feature(bool_to_option)]
 #![feature(crate_visibility_modifier)]
-#![feature(format_args_capture)]
+#![cfg_attr(bootstrap, feature(format_args_capture))]
 #![feature(if_let_guard)]
 #![feature(in_band_lifetimes)]
 #![feature(is_sorted)]
index 746dd50ad2224f305fce2576f057dd694755accf..4a66c3f6b2e26f71dd1ea13860a7bcd1d260f6ad 100644 (file)
 #![feature(fmt_internals)]
 #![feature(fn_traits)]
 #![feature(inherent_ascii_escape)]
-#![feature(format_args_capture)]
+#![cfg_attr(bootstrap, feature(format_args_capture))]
 #![feature(inplace_iteration)]
 #![feature(iter_advance_by)]
 #![feature(iter_zip)]
diff --git a/src/doc/unstable-book/src/library-features/format-args-capture.md b/src/doc/unstable-book/src/library-features/format-args-capture.md
deleted file mode 100644 (file)
index 64b1b3d..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-# `format_args_capture`
-
-The tracking issue for this feature is: [#67984]
-
-[#67984]: https://github.com/rust-lang/rust/issues/67984
-
-------------------------
-
-Enables `format_args!` (and macros which use `format_args!` in their implementation, such
-as `format!`, `print!` and `panic!`) to capture variables from the surrounding scope.
-This avoids the need to pass named parameters when the binding in question
-already exists in scope.
-
-```rust
-#![feature(format_args_capture)]
-
-let (person, species, name) = ("Charlie Brown", "dog", "Snoopy");
-
-// captures named argument `person`
-print!("Hello {person}");
-
-// captures named arguments `species` and `name`
-format!("The {species}'s name is {name}.");
-```
-
-This also works for formatting parameters such as width and precision:
-
-```rust
-#![feature(format_args_capture)]
-
-let precision = 2;
-let s = format!("{:.precision$}", 1.324223);
-
-assert_eq!(&s, "1.32");
-```
-
-A non-exhaustive list of macros which benefit from this functionality include:
-- `format!`
-- `print!` and `println!`
-- `eprint!` and `eprintln!`
-- `write!` and `writeln!`
-- `panic!`
-- `unreachable!`
-- `unimplemented!`
-- `todo!`
-- `assert!` and similar
-- macros in many thirdparty crates, such as `log`
diff --git a/src/test/ui/fmt/feature-gate-format-args-capture.rs b/src/test/ui/fmt/feature-gate-format-args-capture.rs
deleted file mode 100644 (file)
index 21af916..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-fn main() {
-    format!("{foo}");                //~ ERROR: there is no argument named `foo`
-
-    // panic! doesn't hit format_args! unless there are two or more arguments.
-    panic!("{foo} {bar}", bar=1);    //~ ERROR: there is no argument named `foo`
-}
diff --git a/src/test/ui/fmt/feature-gate-format-args-capture.stderr b/src/test/ui/fmt/feature-gate-format-args-capture.stderr
deleted file mode 100644 (file)
index f08f165..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-error: there is no argument named `foo`
-  --> $DIR/feature-gate-format-args-capture.rs:2:14
-   |
-LL |     format!("{foo}");
-   |              ^^^^^
-   |
-   = help: if you intended to capture `foo` from the surrounding scope, add `#![feature(format_args_capture)]` to the crate attributes
-
-error: there is no argument named `foo`
-  --> $DIR/feature-gate-format-args-capture.rs:5:13
-   |
-LL |     panic!("{foo} {bar}", bar=1);
-   |             ^^^^^
-   |
-   = help: if you intended to capture `foo` from the surrounding scope, add `#![feature(format_args_capture)]` to the crate attributes
-
-error: aborting due to 2 previous errors
-
index 6ca7dcc216f3a9d7cd90cef900974b7bd88439e0..fdbd93836ef9fde7eea50622464bced7cdcbbefc 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(format_args_capture)]
-
 fn main() {
     format!(concat!("{foo}"));         //~ ERROR: there is no argument named `foo`
     format!(concat!("{ba", "r} {}"), 1);     //~ ERROR: there is no argument named `bar`
index 3a4b6144b04dbf9928a0fd7efcea5559953b6251..46fc083cb7301f8f2284203255442a8bad4e1a72 100644 (file)
@@ -1,5 +1,3 @@
-#![feature(format_args_capture)]
-
 fn main() {
     format!("{} {foo} {} {bar} {}", 1, 2, 3);
     //~^ ERROR: cannot find value `foo` in this scope
index b30e9a47a13e8bc4a76d13ae3208fd458cad0445..e830a5bc9c5c86947d40cbb331377b23beb9b233 100644 (file)
@@ -1,5 +1,4 @@
 // run-pass
-#![feature(format_args_capture)]
 #![feature(cfg_panic)]
 
 fn main() {
index f4c84e22faaa38e1c3ea0cddb9ac0059e9b11491..a6c7aa33e291b859bfc756eed8b49748f392e45e 100644 (file)
@@ -64,7 +64,6 @@ error: there is no argument named `foo`
 LL |     format!("{} {foo} {} {bar} {}", 1, 2, 3);
    |                 ^^^^^
    |
-   = help: if you intended to capture `foo` from the surrounding scope, add `#![feature(format_args_capture)]` to the crate attributes
 
 error: there is no argument named `bar`
   --> $DIR/ifmt-bad-arg.rs:27:26
@@ -72,7 +71,6 @@ error: there is no argument named `bar`
 LL |     format!("{} {foo} {} {bar} {}", 1, 2, 3);
    |                          ^^^^^
    |
-   = help: if you intended to capture `bar` from the surrounding scope, add `#![feature(format_args_capture)]` to the crate attributes
 
 error: there is no argument named `foo`
   --> $DIR/ifmt-bad-arg.rs:31:14
@@ -80,7 +78,6 @@ error: there is no argument named `foo`
 LL |     format!("{foo}");
    |              ^^^^^
    |
-   = help: if you intended to capture `foo` from the surrounding scope, add `#![feature(format_args_capture)]` to the crate attributes
 
 error: multiple unused formatting arguments
   --> $DIR/ifmt-bad-arg.rs:32:17
@@ -162,7 +159,6 @@ error: there is no argument named `valueb`
 LL |     format!("{valuea} {valueb}", valuea=5, valuec=7);
    |                       ^^^^^^^^
    |
-   = help: if you intended to capture `valueb` from the surrounding scope, add `#![feature(format_args_capture)]` to the crate attributes
 
 error: named argument never used
   --> $DIR/ifmt-bad-arg.rs:45:51
@@ -214,7 +210,6 @@ error: there is no argument named `foo`
 LL |         {foo}
    |         ^^^^^
    |
-   = help: if you intended to capture `foo` from the surrounding scope, add `#![feature(format_args_capture)]` to the crate attributes
 
 error: invalid format string: expected `'}'`, found `'t'`
   --> $DIR/ifmt-bad-arg.rs:75:1