diff --git a/Configurations.md b/Configurations.md index 61b9995e7b9..e27c40ff0df 100644 --- a/Configurations.md +++ b/Configurations.md @@ -1256,6 +1256,56 @@ Control the case of the letters in hexadecimal literal values - **Possible values**: `Preserve`, `Upper`, `Lower` - **Stable**: No (tracking issue: [#5081](https://github.com/rust-lang/rustfmt/issues/5081)) +## `float_literal_trailing_zero` + +Control the presence of trailing zero in floating-point literal values + +- **Default value**: `Preserve` +- **Possible values**: `Preserve`, `Always`, `IfNoPostfix`, `Never` +- **Stable**: No (tracking issue: [#6471](https://github.com/rust-lang/rustfmt/issues/6471)) + +#### `Preserve` (default): + +Leave the literal as-is. + +```rust +fn main() { + let values = [1.0, 2., 3.0e10, 4f32]; +} +``` + +#### `Always`: + +Add a trailing zero to the literal: + +```rust +fn main() { + let values = [1.0, 2.0, 3.0e10, 4.0f32]; +} +``` + +#### `IfNoPostfix`: + +Add a trailing zero by default. If the literal contains an exponent or a suffix, the zero +and the preceding period are removed: + +```rust +fn main() { + let values = [1.0, 2.0, 3e10, 4f32]; +} +``` + +#### `Never`: + +Remove the trailing zero. If the literal contains an exponent or a suffix, the preceding +period is also removed: + +```rust +fn main() { + let values = [1., 2., 3e10, 4f32]; +} +``` + ## `hide_parse_errors` This option is deprecated and has been renamed to `show_parse_errors` to avoid confusion around the double negative default of `hide_parse_errors=false`. diff --git a/src/chains.rs b/src/chains.rs index acd0c2961b1..50a129b695f 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -264,7 +264,7 @@ impl ChainItemKind { return ( ChainItemKind::Parent { expr: expr.clone(), - parens: is_method_call_receiver && should_add_parens(expr), + parens: is_method_call_receiver && should_add_parens(expr, context), }, expr.span, ); @@ -1049,12 +1049,12 @@ fn trim_tries(s: &str) -> String { /// 1. .method(); /// ``` /// Which all need parenthesis or a space before `.method()`. -fn should_add_parens(expr: &ast::Expr) -> bool { +fn should_add_parens(expr: &ast::Expr, context: &RewriteContext<'_>) -> bool { match expr.kind { - ast::ExprKind::Lit(ref lit) => crate::expr::lit_ends_in_dot(lit), + ast::ExprKind::Lit(ref lit) => crate::expr::lit_ends_in_dot(lit, context), ast::ExprKind::Closure(ref cl) => match cl.body.kind { ast::ExprKind::Range(_, _, ast::RangeLimits::HalfOpen) => true, - ast::ExprKind::Lit(ref lit) => crate::expr::lit_ends_in_dot(lit), + ast::ExprKind::Lit(ref lit) => crate::expr::lit_ends_in_dot(lit, context), _ => false, }, _ => false, diff --git a/src/config/mod.rs b/src/config/mod.rs index 7355adc9f9d..439a5765ff9 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -79,6 +79,8 @@ create_config! { skip_macro_invocations: SkipMacroInvocations, false, "Skip formatting the bodies of macros invoked with the following names."; hex_literal_case: HexLiteralCaseConfig, false, "Format hexadecimal integer literals"; + float_literal_trailing_zero: FloatLiteralTrailingZeroConfig, false, + "Add or remove trailing zero in floating-point literals"; // Single line expressions and items empty_item_single_line: EmptyItemSingleLine, false, @@ -739,6 +741,7 @@ format_macro_matchers = false format_macro_bodies = true skip_macro_invocations = [] hex_literal_case = "Preserve" +float_literal_trailing_zero = "Preserve" empty_item_single_line = true struct_lit_single_line = true fn_single_line = false @@ -829,6 +832,7 @@ format_macro_matchers = false format_macro_bodies = true skip_macro_invocations = [] hex_literal_case = "Preserve" +float_literal_trailing_zero = "Preserve" empty_item_single_line = true struct_lit_single_line = true fn_single_line = false diff --git a/src/config/options.rs b/src/config/options.rs index b9b4713046c..3f86999c30b 100644 --- a/src/config/options.rs +++ b/src/config/options.rs @@ -146,6 +146,21 @@ pub enum HexLiteralCase { Lower, } +/// How to treat trailing zeros in floating-point literals. +#[config_type] +pub enum FloatLiteralTrailingZero { + /// Leave the literal as-is. + Preserve, + /// Add a trailing zero to the literal. + Always, + /// Add a trailing zero by default. If the literal contains an exponent or a suffix, the zero + /// and the preceding period are removed. + IfNoPostfix, + /// Remove the trailing zero. If the literal contains an exponent or a suffix, the preceding + /// period is also removed. + Never, +} + #[config_type] pub enum ReportTactic { Always, @@ -613,6 +628,8 @@ config_option_with_style_edition_default!( FormatMacroBodies, bool, _ => true; SkipMacroInvocations, MacroSelectors, _ => MacroSelectors::default(); HexLiteralCaseConfig, HexLiteralCase, _ => HexLiteralCase::Preserve; + FloatLiteralTrailingZeroConfig, FloatLiteralTrailingZero, _ => + FloatLiteralTrailingZero::Preserve; // Single line expressions and items EmptyItemSingleLine, bool, _ => true; diff --git a/src/expr.rs b/src/expr.rs index 8031ab68290..0c5752380f6 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -13,8 +13,8 @@ use crate::comment::{ CharClasses, FindUncommented, combine_strs_with_missing_comments, contains_comment, recover_comment_removed, rewrite_comment, rewrite_missing_comment, }; -use crate::config::lists::*; use crate::config::{Config, ControlBraceStyle, HexLiteralCase, IndentStyle, StyleEdition}; +use crate::config::{FloatLiteralTrailingZero, lists::*}; use crate::lists::{ ListFormatting, Separator, definitive_tactic, itemize_list, shape_for_tactic, struct_lit_formatting, struct_lit_shape, struct_lit_tactic, write_list, @@ -54,8 +54,32 @@ pub(crate) enum ExprType { SubExpression, } -pub(crate) fn lit_ends_in_dot(lit: &Lit) -> bool { - matches!(lit, Lit { kind: LitKind::Float, suffix: None, symbol } if symbol.as_str().ends_with('.')) +pub(crate) fn lit_ends_in_dot(lit: &Lit, context: &RewriteContext<'_>) -> bool { + match lit.kind { + LitKind::Float => float_lit_ends_in_dot( + lit.symbol.as_str(), + lit.suffix.as_ref().map(|s| s.as_str()), + context.config.float_literal_trailing_zero(), + ), + _ => false, + } +} + +pub(crate) fn float_lit_ends_in_dot( + symbol: &str, + suffix: Option<&str>, + float_literal_trailing_zero: FloatLiteralTrailingZero, +) -> bool { + match float_literal_trailing_zero { + FloatLiteralTrailingZero::Preserve => symbol.ends_with('.') && suffix.is_none(), + FloatLiteralTrailingZero::IfNoPostfix | FloatLiteralTrailingZero::Always => false, + FloatLiteralTrailingZero::Never => { + let float_parts = parse_float_symbol(symbol).unwrap(); + let has_postfix = float_parts.exponent.is_some() || suffix.is_some(); + let fractional_part_zero = float_parts.is_fractional_part_zero(); + !has_postfix && fractional_part_zero + } + } } pub(crate) fn format_expr( @@ -297,7 +321,7 @@ pub(crate) fn format_expr( fn needs_space_before_range(context: &RewriteContext<'_>, lhs: &ast::Expr) -> bool { match lhs.kind { - ast::ExprKind::Lit(token_lit) => lit_ends_in_dot(&token_lit), + ast::ExprKind::Lit(token_lit) => lit_ends_in_dot(&token_lit, context), ast::ExprKind::Unary(_, ref expr) => needs_space_before_range(context, expr), ast::ExprKind::Binary(_, _, ref rhs_expr) => { needs_space_before_range(context, rhs_expr) @@ -1276,6 +1300,7 @@ pub(crate) fn rewrite_literal( match token_lit.kind { token::LitKind::Str => rewrite_string_lit(context, span, shape), token::LitKind::Integer => rewrite_int_lit(context, token_lit, span, shape), + token::LitKind::Float => rewrite_float_lit(context, token_lit, span, shape), _ => wrap_str( context.snippet(span).to_owned(), context.config.max_width(), @@ -1319,6 +1344,10 @@ fn rewrite_int_lit( span: Span, shape: Shape, ) -> RewriteResult { + if token_lit.is_semantic_float() { + return rewrite_float_lit(context, token_lit, span, shape); + } + let symbol = token_lit.symbol.as_str(); if let Some(symbol_stripped) = symbol.strip_prefix("0x") { @@ -1349,6 +1378,72 @@ fn rewrite_int_lit( .max_width_error(shape.width, span) } +fn rewrite_float_lit( + context: &RewriteContext<'_>, + token_lit: token::Lit, + span: Span, + shape: Shape, +) -> RewriteResult { + if matches!( + context.config.float_literal_trailing_zero(), + FloatLiteralTrailingZero::Preserve + ) { + return wrap_str( + context.snippet(span).to_owned(), + context.config.max_width(), + shape, + ) + .max_width_error(shape.width, span); + } + + let symbol = token_lit.symbol.as_str(); + let suffix = token_lit.suffix.as_ref().map(|s| s.as_str()); + + let float_parts = parse_float_symbol(symbol).unwrap(); + let FloatSymbolParts { + integer_part, + fractional_part, + exponent, + } = float_parts; + + let has_postfix = exponent.is_some() || suffix.is_some(); + let fractional_part_nonzero = !float_parts.is_fractional_part_zero(); + + let (include_period, include_fractional_part) = + match context.config.float_literal_trailing_zero() { + FloatLiteralTrailingZero::Preserve => unreachable!("handled above"), + FloatLiteralTrailingZero::Always => (true, true), + FloatLiteralTrailingZero::IfNoPostfix => ( + fractional_part_nonzero || !has_postfix, + fractional_part_nonzero || !has_postfix, + ), + FloatLiteralTrailingZero::Never => ( + fractional_part_nonzero || !has_postfix, + fractional_part_nonzero, + ), + }; + + let period = if include_period { "." } else { "" }; + let fractional_part = if include_fractional_part { + fractional_part.unwrap_or("0") + } else { + "" + }; + wrap_str( + format!( + "{}{}{}{}{}", + integer_part, + period, + fractional_part, + exponent.unwrap_or(""), + suffix.unwrap_or(""), + ), + context.config.max_width(), + shape, + ) + .max_width_error(shape.width, span) +} + fn choose_separator_tactic(context: &RewriteContext<'_>, span: Span) -> Option { if context.inside_macro() { if span_ends_with_comma(context, span) { @@ -2274,9 +2369,45 @@ pub(crate) fn is_method_call(expr: &ast::Expr) -> bool { } } +/// Indicates the parts of a float literal specified as a string. +struct FloatSymbolParts<'a> { + /// The integer part, e.g. `123` in `123.456e789`. + /// Always non-empty, because in Rust `.1` is not a valid floating-point literal: + /// + integer_part: &'a str, + /// The fractional part excluding the decimal point, e.g. `456` in `123.456e789`. + fractional_part: Option<&'a str>, + /// The exponent part including the `e` or `E`, e.g. `e789` in `123.456e789`. + exponent: Option<&'a str>, +} + +impl FloatSymbolParts<'_> { + fn is_fractional_part_zero(&self) -> bool { + let zero_literal_regex = static_regex!(r"^[0_]+$"); + self.fractional_part + .is_none_or(|s| zero_literal_regex.is_match(s)) + } +} + +/// Parses a float literal. The `symbol` must be a valid floating point literal without a type +/// suffix. Otherwise the function may panic or return wrong result. +fn parse_float_symbol(symbol: &str) -> Result, &'static str> { + // This regex may accept invalid float literals (such as `1`, `_` or `2.e3`). That's ok. + // We only use it to parse literals whose validity has already been established. + let float_literal_regex = static_regex!(r"^([0-9_]+)(?:\.([0-9_]+)?)?([eE][+-]?[0-9_]+)?$"); + let caps = float_literal_regex + .captures(symbol) + .ok_or("invalid float literal")?; + Ok(FloatSymbolParts { + integer_part: caps.get(1).ok_or("missing integer part")?.as_str(), + fractional_part: caps.get(2).map(|m| m.as_str()), + exponent: caps.get(3).map(|m| m.as_str()), + }) +} + #[cfg(test)] mod test { - use super::last_line_offsetted; + use super::*; #[test] fn test_last_line_offsetted() { @@ -2298,4 +2429,93 @@ mod test { let lines = "one\n two three"; assert_eq!(last_line_offsetted(2, lines), false); } + + #[test] + fn test_parse_float_symbol() { + let parts = parse_float_symbol("123.456e789").unwrap(); + assert_eq!(parts.integer_part, "123"); + assert_eq!(parts.fractional_part, Some("456")); + assert_eq!(parts.exponent, Some("e789")); + + let parts = parse_float_symbol("123.456e+789").unwrap(); + assert_eq!(parts.integer_part, "123"); + assert_eq!(parts.fractional_part, Some("456")); + assert_eq!(parts.exponent, Some("e+789")); + + let parts = parse_float_symbol("123.456e-789").unwrap(); + assert_eq!(parts.integer_part, "123"); + assert_eq!(parts.fractional_part, Some("456")); + assert_eq!(parts.exponent, Some("e-789")); + + let parts = parse_float_symbol("123e789").unwrap(); + assert_eq!(parts.integer_part, "123"); + assert_eq!(parts.fractional_part, None); + assert_eq!(parts.exponent, Some("e789")); + + let parts = parse_float_symbol("123E789").unwrap(); + assert_eq!(parts.integer_part, "123"); + assert_eq!(parts.fractional_part, None); + assert_eq!(parts.exponent, Some("E789")); + + let parts = parse_float_symbol("123.").unwrap(); + assert_eq!(parts.integer_part, "123"); + assert_eq!(parts.fractional_part, None); + assert_eq!(parts.exponent, None); + } + + #[test] + fn test_parse_float_symbol_with_underscores() { + let parts = parse_float_symbol("_123._456e_789").unwrap(); + assert_eq!(parts.integer_part, "_123"); + assert_eq!(parts.fractional_part, Some("_456")); + assert_eq!(parts.exponent, Some("e_789")); + + let parts = parse_float_symbol("123_.456_e789_").unwrap(); + assert_eq!(parts.integer_part, "123_"); + assert_eq!(parts.fractional_part, Some("456_")); + assert_eq!(parts.exponent, Some("e789_")); + + let parts = parse_float_symbol("1_23.4_56e7_89").unwrap(); + assert_eq!(parts.integer_part, "1_23"); + assert_eq!(parts.fractional_part, Some("4_56")); + assert_eq!(parts.exponent, Some("e7_89")); + + let parts = parse_float_symbol("_1_23_._4_56_e_7_89_").unwrap(); + assert_eq!(parts.integer_part, "_1_23_"); + assert_eq!(parts.fractional_part, Some("_4_56_")); + assert_eq!(parts.exponent, Some("e_7_89_")); + } + + #[test] + fn test_float_lit_ends_in_dot() { + type TZ = FloatLiteralTrailingZero; + + assert!(float_lit_ends_in_dot("1.", None, TZ::Preserve)); + assert!(!float_lit_ends_in_dot("1.0", None, TZ::Preserve)); + assert!(!float_lit_ends_in_dot("1.e2", None, TZ::Preserve)); + assert!(!float_lit_ends_in_dot("1.0e2", None, TZ::Preserve)); + assert!(!float_lit_ends_in_dot("1.", Some("f32"), TZ::Preserve)); + assert!(!float_lit_ends_in_dot("1.0", Some("f32"), TZ::Preserve)); + + assert!(!float_lit_ends_in_dot("1.", None, TZ::Always)); + assert!(!float_lit_ends_in_dot("1.0", None, TZ::Always)); + assert!(!float_lit_ends_in_dot("1.e2", None, TZ::Always)); + assert!(!float_lit_ends_in_dot("1.0e2", None, TZ::Always)); + assert!(!float_lit_ends_in_dot("1.", Some("f32"), TZ::Always)); + assert!(!float_lit_ends_in_dot("1.0", Some("f32"), TZ::Always)); + + assert!(!float_lit_ends_in_dot("1.", None, TZ::IfNoPostfix)); + assert!(!float_lit_ends_in_dot("1.0", None, TZ::IfNoPostfix)); + assert!(!float_lit_ends_in_dot("1.e2", None, TZ::IfNoPostfix)); + assert!(!float_lit_ends_in_dot("1.0e2", None, TZ::IfNoPostfix)); + assert!(!float_lit_ends_in_dot("1.", Some("f32"), TZ::IfNoPostfix)); + assert!(!float_lit_ends_in_dot("1.0", Some("f32"), TZ::IfNoPostfix)); + + assert!(float_lit_ends_in_dot("1.", None, TZ::Never)); + assert!(float_lit_ends_in_dot("1.0", None, TZ::Never)); + assert!(!float_lit_ends_in_dot("1.e2", None, TZ::Never)); + assert!(!float_lit_ends_in_dot("1.0e2", None, TZ::Never)); + assert!(!float_lit_ends_in_dot("1.", Some("f32"), TZ::Never)); + assert!(!float_lit_ends_in_dot("1.0", Some("f32"), TZ::Never)); + } } diff --git a/tests/source/configs/float_literal_trailing_zero/always.rs b/tests/source/configs/float_literal_trailing_zero/always.rs new file mode 100644 index 00000000000..47b0443137a --- /dev/null +++ b/tests/source/configs/float_literal_trailing_zero/always.rs @@ -0,0 +1,45 @@ +// rustfmt-float_literal_trailing_zero: Always + +fn float_literals() { + let a = 0.; + let b = 0.0; + let c = 100.; + let d = 100.0; + let e = 5e3; + let f = 5.0e3; + let g = 5e+3; + let h = 5.0e+3; + let i = 5e-3; + let j = 5.0e-3; + let k = 5E3; + let l = 5.0E3; + let m = 7f32; + let n = 7.0f32; + let o = 9e3f32; + let p = 9.0e3f32; + let q = 1000.00; + let r = 1_000_.; + let s = 1_000_.000_000; +} + +fn range_bounds() { + if (1.0..2.0).contains(&1.0) {} + if (1.1..2.2).contains(&1.1) {} + if (1.0e1..2.0e1).contains(&1.0e1) {} + let _binop_range = 3.0 / 2.0..4.0; +} + +fn method_calls() { + let x = 1.0.neg(); + let y = 2.3.neg(); + let z = (4.).neg(); + let u = 5.0f32.neg(); + let v = -6.0.neg(); +} + +fn line_wrapping() { + let array = [ + 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., 17., 18., + ]; + println!("This is floaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaat {}", 10e3); +} diff --git a/tests/source/configs/float_literal_trailing_zero/if-no-postfix.rs b/tests/source/configs/float_literal_trailing_zero/if-no-postfix.rs new file mode 100644 index 00000000000..45e0b87bbae --- /dev/null +++ b/tests/source/configs/float_literal_trailing_zero/if-no-postfix.rs @@ -0,0 +1,48 @@ +// rustfmt-float_literal_trailing_zero: IfNoPostfix + +fn float_literals() { + let a = 0.; + let b = 0.0; + let c = 100.; + let d = 100.0; + let e = 5e3; + let f = 5.0e3; + let g = 5e+3; + let h = 5.0e+3; + let i = 5e-3; + let j = 5.0e-3; + let k = 5E3; + let l = 5.0E3; + let m = 7f32; + let n = 7.0f32; + let o = 9e3f32; + let p = 9.0e3f32; + let q = 1000.00; + let r = 1_000_.; + let s = 1_000_.000_000; +} + +fn range_bounds() { + if (1.0..2.0).contains(&1.0) {} + if (1.1..2.2).contains(&1.1) {} + if (1.0e1..2.0e1).contains(&1.0e1) {} + let _binop_range = 3.0 / 2.0..4.0; +} + +fn method_calls() { + let x = 1.0.neg(); + let y = 2.3.neg(); + let z = (4.).neg(); + let u = 5.0f32.neg(); + let v = -6.0.neg(); +} + +fn line_wrapping() { + let array = [ + 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11., 12., 13., 14., 15., 16., 17., 18., + ]; + println!( + "This is floaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaat {}", + 10.0e3 + ); +} diff --git a/tests/source/configs/float_literal_trailing_zero/never.rs b/tests/source/configs/float_literal_trailing_zero/never.rs new file mode 100644 index 00000000000..2fe5fe2f438 --- /dev/null +++ b/tests/source/configs/float_literal_trailing_zero/never.rs @@ -0,0 +1,49 @@ +// rustfmt-float_literal_trailing_zero: Never + +fn float_literals() { + let a = 0.; + let b = 0.0; + let c = 100.; + let d = 100.0; + let e = 5e3; + let f = 5.0e3; + let g = 5e+3; + let h = 5.0e+3; + let i = 5e-3; + let j = 5.0e-3; + let k = 5E3; + let l = 5.0E3; + let m = 7f32; + let n = 7.0f32; + let o = 9e3f32; + let p = 9.0e3f32; + let q = 1000.00; + let r = 1_000_.; + let s = 1_000_.000_000; +} + +fn range_bounds() { + if (1.0..2.0).contains(&1.0) {} + if (1.1..2.2).contains(&1.1) {} + if (1.0e1..2.0e1).contains(&1.0e1) {} + let _binop_range = 3.0 / 2.0..4.0; +} + +fn method_calls() { + let x = 1.0.neg(); + let y = 2.3.neg(); + let z = (4.).neg(); + let u = 5.0f32.neg(); + let v = -6.0.neg(); +} + +fn line_wrapping() { + let array = [ + 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, + 17.0, 18.0, + ]; + println!( + "This is floaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaat {}", + 10.0e3 + ); +} diff --git a/tests/target/configs/float_literal_trailing_zero/always.rs b/tests/target/configs/float_literal_trailing_zero/always.rs new file mode 100644 index 00000000000..e6d643ad43f --- /dev/null +++ b/tests/target/configs/float_literal_trailing_zero/always.rs @@ -0,0 +1,49 @@ +// rustfmt-float_literal_trailing_zero: Always + +fn float_literals() { + let a = 0.0; + let b = 0.0; + let c = 100.0; + let d = 100.0; + let e = 5.0e3; + let f = 5.0e3; + let g = 5.0e+3; + let h = 5.0e+3; + let i = 5.0e-3; + let j = 5.0e-3; + let k = 5.0E3; + let l = 5.0E3; + let m = 7.0f32; + let n = 7.0f32; + let o = 9.0e3f32; + let p = 9.0e3f32; + let q = 1000.00; + let r = 1_000_.0; + let s = 1_000_.000_000; +} + +fn range_bounds() { + if (1.0..2.0).contains(&1.0) {} + if (1.1..2.2).contains(&1.1) {} + if (1.0e1..2.0e1).contains(&1.0e1) {} + let _binop_range = 3.0 / 2.0..4.0; +} + +fn method_calls() { + let x = 1.0.neg(); + let y = 2.3.neg(); + let z = (4.0).neg(); + let u = 5.0f32.neg(); + let v = -6.0.neg(); +} + +fn line_wrapping() { + let array = [ + 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, + 17.0, 18.0, + ]; + println!( + "This is floaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaat {}", + 10.0e3 + ); +} diff --git a/tests/target/configs/float_literal_trailing_zero/if-no-postfix.rs b/tests/target/configs/float_literal_trailing_zero/if-no-postfix.rs new file mode 100644 index 00000000000..d81f5c07ccf --- /dev/null +++ b/tests/target/configs/float_literal_trailing_zero/if-no-postfix.rs @@ -0,0 +1,46 @@ +// rustfmt-float_literal_trailing_zero: IfNoPostfix + +fn float_literals() { + let a = 0.0; + let b = 0.0; + let c = 100.0; + let d = 100.0; + let e = 5e3; + let f = 5e3; + let g = 5e+3; + let h = 5e+3; + let i = 5e-3; + let j = 5e-3; + let k = 5E3; + let l = 5E3; + let m = 7f32; + let n = 7f32; + let o = 9e3f32; + let p = 9e3f32; + let q = 1000.00; + let r = 1_000_.0; + let s = 1_000_.000_000; +} + +fn range_bounds() { + if (1.0..2.0).contains(&1.0) {} + if (1.1..2.2).contains(&1.1) {} + if (1e1..2e1).contains(&1e1) {} + let _binop_range = 3.0 / 2.0..4.0; +} + +fn method_calls() { + let x = 1.0.neg(); + let y = 2.3.neg(); + let z = (4.0).neg(); + let u = 5f32.neg(); + let v = -6.0.neg(); +} + +fn line_wrapping() { + let array = [ + 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, + 17.0, 18.0, + ]; + println!("This is floaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaat {}", 10e3); +} diff --git a/tests/target/configs/float_literal_trailing_zero/never.rs b/tests/target/configs/float_literal_trailing_zero/never.rs new file mode 100644 index 00000000000..6391890e535 --- /dev/null +++ b/tests/target/configs/float_literal_trailing_zero/never.rs @@ -0,0 +1,45 @@ +// rustfmt-float_literal_trailing_zero: Never + +fn float_literals() { + let a = 0.; + let b = 0.; + let c = 100.; + let d = 100.; + let e = 5e3; + let f = 5e3; + let g = 5e+3; + let h = 5e+3; + let i = 5e-3; + let j = 5e-3; + let k = 5E3; + let l = 5E3; + let m = 7f32; + let n = 7f32; + let o = 9e3f32; + let p = 9e3f32; + let q = 1000.; + let r = 1_000_.; + let s = 1_000_.; +} + +fn range_bounds() { + if (1. ..2.).contains(&1.) {} + if (1.1..2.2).contains(&1.1) {} + if (1e1..2e1).contains(&1e1) {} + let _binop_range = 3. / 2. ..4.; +} + +fn method_calls() { + let x = (1.).neg(); + let y = 2.3.neg(); + let z = (4.).neg(); + let u = 5f32.neg(); + let v = -(6.).neg(); +} + +fn line_wrapping() { + let array = [ + 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16., 17., 18., + ]; + println!("This is floaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaat {}", 10e3); +} diff --git a/tests/target/configs/float_literal_trailing_zero/preserve.rs b/tests/target/configs/float_literal_trailing_zero/preserve.rs new file mode 100644 index 00000000000..3f0f764796c --- /dev/null +++ b/tests/target/configs/float_literal_trailing_zero/preserve.rs @@ -0,0 +1,38 @@ +// rustfmt-float_literal_trailing_zero: Preserve + +fn float_literals() { + let a = 0.; + let b = 0.0; + let c = 100.; + let d = 100.0; + let e = 5e3; + let f = 5.0e3; + let g = 5e+3; + let h = 5.0e+3; + let i = 5e-3; + let j = 5.0e-3; + let k = 5E3; + let l = 5.0E3; + let m = 7f32; + let n = 7.0f32; + let o = 9e3f32; + let p = 9.0e3f32; + let q = 1000.00; + let r = 1_000_.; + let s = 1_000_.000_000; +} + +fn range_bounds() { + if (1.0..2.0).contains(&1.0) {} + if (1.1..2.2).contains(&1.1) {} + if (1.0e1..2.0e1).contains(&1.0e1) {} + let _binop_range = 3.0 / 2.0..4.0; +} + +fn method_calls() { + let x = 1.0.neg(); + let y = 2.3.neg(); + let z = (4.).neg(); + let u = 5.0f32.neg(); + let v = -6.0.neg(); +}