about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCaleb Cartwright <caleb.cartwright@outlook.com>2024-07-19 18:12:08 -0500
committerCaleb Cartwright <calebcartwright@users.noreply.github.com>2024-07-28 19:37:36 -0500
commitc2c9be5b2d1e319bcd43cfc000a68b17b2cd3b95 (patch)
tree09503f97e6384b17f40fc81336f184ce9346babf
parentd8ae6a99e623fdecff6f2d7d9feb157c8ff0e3f8 (diff)
downloadrust-c2c9be5b2d1e319bcd43cfc000a68b17b2cd3b95.tar.gz
rust-c2c9be5b2d1e319bcd43cfc000a68b17b2cd3b95.zip
feat: implement Style Edition support
Adds the 'style_edition' configuration option along with
documentation, 'version' option deprecation, and mapping
of 'edition' and 'version' values for backwards compatibility
and adherence to the style evolution RFC
-rw-r--r--Configurations.md17
-rw-r--r--rustfmt.toml2
-rw-r--r--src/config/config_type.rs44
-rw-r--r--src/config/mod.rs5
-rw-r--r--src/config/options.rs37
5 files changed, 97 insertions, 8 deletions
diff --git a/Configurations.md b/Configurations.md
index f52c2573154..ec95c82fdb1 100644
--- a/Configurations.md
+++ b/Configurations.md
@@ -534,7 +534,7 @@ Note that this option may be soft-deprecated in the future once the [ignore](#ig
 Specifies which edition is used by the parser.
 
 - **Default value**: `"2015"`
-- **Possible values**: `"2015"`, `"2018"`, `"2021"`
+- **Possible values**: `"2015"`, `"2018"`, `"2021"`, `"2024"`
 - **Stable**: Yes
 
 Rustfmt is able to pick up the edition used by reading the `Cargo.toml` file if executed
@@ -2692,6 +2692,17 @@ By default this option is set as a percentage of [`max_width`](#max_width) provi
 
 See also [`max_width`](#max_width) and [`use_small_heuristics`](#use_small_heuristics)
 
+## `style_edition`
+
+Controls the edition of the [Rust Style Guide] to use for formatting ([RFC 3338])
+
+- **Default value**: `"2015"`
+- **Possible values**: `"2015"`, `"2018"`, `"2021"`, `"2024"` (unstable variant)
+- **Stable**: Yes
+
+[Rust Style Guide]: https://doc.rust-lang.org/nightly/style-guide/
+[RFC 3338]: https://rust-lang.github.io/rfcs/3338-style-evolution.html
+
 ## `tab_spaces`
 
 Number of spaces per tab
@@ -3051,9 +3062,7 @@ fn main() {
 
 ## `version`
 
-Which version of the formatting rules to use. `Version::One` is backwards-compatible
-with Rustfmt 1.0. Other versions are only backwards compatible within a major
-version number.
+This option is deprecated and has been replaced by [`style_edition`](#style_edition)
 
 - **Default value**: `One`
 - **Possible values**: `One`, `Two`
diff --git a/rustfmt.toml b/rustfmt.toml
index eccd5f9bd19..52e4d728b64 100644
--- a/rustfmt.toml
+++ b/rustfmt.toml
@@ -1,3 +1,3 @@
 error_on_line_overflow = true
 error_on_unformatted = true
-version = "Two"
+style_edition = "2024"
diff --git a/src/config/config_type.rs b/src/config/config_type.rs
index c3d5b7a43cf..3a3500e4ef8 100644
--- a/src/config/config_type.rs
+++ b/src/config/config_type.rs
@@ -133,6 +133,8 @@ macro_rules! create_config {
                     "merge_imports" => self.0.set_merge_imports(),
                     "fn_args_layout" => self.0.set_fn_args_layout(),
                     "hide_parse_errors" => self.0.set_hide_parse_errors(),
+                    "version" => self.0.set_version(),
+                    "edition" => self.0.set_edition(),
                     &_ => (),
                 }
             }
@@ -259,6 +261,8 @@ macro_rules! create_config {
                 self.set_merge_imports();
                 self.set_fn_args_layout();
                 self.set_hide_parse_errors();
+                self.set_version();
+                self.set_edition();
                 self
             }
 
@@ -360,6 +364,8 @@ macro_rules! create_config {
                     "merge_imports" => self.set_merge_imports(),
                     "fn_args_layout" => self.set_fn_args_layout(),
                     "hide_parse_errors" => self.set_hide_parse_errors(),
+                    "version" => self.set_version(),
+                    "edition" => self.set_edition(),
                     &_ => (),
                 }
             }
@@ -560,6 +566,44 @@ macro_rules! create_config {
                 }
             }
 
+            fn set_version(&mut self) {
+                if !self.was_set().version() {
+                    return;
+                }
+
+                eprintln!(
+                    "Warning: the `version` option is deprecated. \
+                    Use `style_edition` instead."
+                );
+
+                if self.was_set().style_edition() {
+                    eprintln!(
+                        "Warning: the deprecated `version` option was \
+                        used in conjunction with the `edition` or \
+                        `style_edition` options which take precedence. \
+                        The value of the `version` option will be ignored."
+                    );
+                } else if matches!(self.version(), Version::Two) {
+                    self.style_edition.2 = StyleEdition::Edition2024;
+                } else {
+                    self.style_edition.2 = StyleEdition::Edition2015;
+                }
+            }
+
+            fn set_edition(&mut self) {
+                if self.was_set().style_edition() || self.was_set().version() {
+                    return;
+                }
+
+                // User has explicitly specified an Edition value without
+                // explicitly specifying a Style Edition value, so the Style Edition
+                // must default to whatever value was provided for Edition
+                // as per: https://rust-lang.github.io/rfcs/3338-style-evolution.html#explanation
+                self.style_edition.2 = self.edition().into();
+            }
+
+
+
             #[allow(unreachable_pub)]
             /// Returns `true` if the config key was explicitly set and is the default value.
             pub fn is_default(&self, key: &str) -> bool {
diff --git a/src/config/mod.rs b/src/config/mod.rs
index b60b2f10ba2..9103a4859ab 100644
--- a/src/config/mod.rs
+++ b/src/config/mod.rs
@@ -149,6 +149,7 @@ create_config! {
     blank_lines_lower_bound: BlankLinesLowerBound, false,
         "Minimum number of blank lines which must be put between items";
     edition: EditionConfig, true, "The edition of the parser (RFC 2052)";
+    style_edition: StyleEditionConfig, false, "The edition of the Style Guide (RFC 3338)";
     version: VersionConfig, false, "Version of formatting rules";
     inline_attribute_width: InlineAttributeWidth, false,
         "Write an item and its attribute on the same line \
@@ -502,6 +503,9 @@ mod test {
             stable_option: StableOption, true, "A stable option";
             unstable_option: UnstableOption, false, "An unstable option";
             partially_unstable_option: PartiallyUnstable, true, "A partially unstable option";
+            edition: EditionConfig, true, "blah";
+            style_edition: StyleEditionConfig, true, "blah";
+            version: VersionConfig, false, "blah blah"
         }
 
         #[cfg(test)]
@@ -685,6 +689,7 @@ match_block_trailing_comma = false
 blank_lines_upper_bound = 1
 blank_lines_lower_bound = 0
 edition = "2015"
+style_edition = "2015"
 version = "One"
 inline_attribute_width = 0
 format_generated_files = true
diff --git a/src/config/options.rs b/src/config/options.rs
index e674aba86f8..7c0a3609775 100644
--- a/src/config/options.rs
+++ b/src/config/options.rs
@@ -456,6 +456,17 @@ impl From<Edition> for rustc_span::edition::Edition {
     }
 }
 
+impl From<Edition> for StyleEdition {
+    fn from(edition: Edition) -> Self {
+        match edition {
+            Edition::Edition2015 => StyleEdition::Edition2015,
+            Edition::Edition2018 => StyleEdition::Edition2018,
+            Edition::Edition2021 => StyleEdition::Edition2021,
+            Edition::Edition2024 => StyleEdition::Edition2024,
+        }
+    }
+}
+
 impl PartialOrd for Edition {
     fn partial_cmp(&self, other: &Edition) -> Option<std::cmp::Ordering> {
         rustc_span::edition::Edition::partial_cmp(&(*self).into(), &(*other).into())
@@ -473,10 +484,11 @@ pub enum MatchArmLeadingPipe {
     Preserve,
 }
 
-/// Defines the default values for each config according to [the style guide].
-/// rustfmt output may differ between style editions.
+/// Defines the default values for each config according to the edition of the
+/// [Style Guide] as per [RFC 3338]. Rustfmt output may differ between Style editions.
 ///
-/// [the style guide]: https://doc.rust-lang.org/nightly/style-guide/
+/// [Style Guide]: https://doc.rust-lang.org/nightly/style-guide/
+/// [RFC 3338]: https://rust-lang.github.io/rfcs/3338-style-evolution.html
 #[config_type]
 pub enum StyleEdition {
     #[value = "2015"]
@@ -493,10 +505,28 @@ pub enum StyleEdition {
     Edition2021,
     #[value = "2024"]
     #[doc_hint = "2024"]
+    #[unstable_variant]
     /// [Edition 2024]().
     Edition2024,
 }
 
+impl From<StyleEdition> for rustc_span::edition::Edition {
+    fn from(edition: StyleEdition) -> Self {
+        match edition {
+            StyleEdition::Edition2015 => Self::Edition2015,
+            StyleEdition::Edition2018 => Self::Edition2018,
+            StyleEdition::Edition2021 => Self::Edition2021,
+            StyleEdition::Edition2024 => Self::Edition2024,
+        }
+    }
+}
+
+impl PartialOrd for StyleEdition {
+    fn partial_cmp(&self, other: &StyleEdition) -> Option<std::cmp::Ordering> {
+        rustc_span::edition::Edition::partial_cmp(&(*self).into(), &(*other).into())
+    }
+}
+
 /// Defines unit structs to implement `StyleEditionDefault` for.
 #[macro_export]
 macro_rules! config_option_with_style_edition_default {
@@ -608,6 +638,7 @@ config_option_with_style_edition_default!(
     BlankLinesUpperBound, usize, _ => 1;
     BlankLinesLowerBound, usize, _ => 0;
     EditionConfig, Edition, _ => Edition::Edition2015;
+    StyleEditionConfig, StyleEdition, _ => StyleEdition::Edition2015;
     VersionConfig, Version, Edition2024 => Version::Two, _ => Version::One;
     InlineAttributeWidth, usize, _ => 0;
     FormatGeneratedFiles, bool, _ => true;