Prevent ranges from getting collapsed in patterns (#6871)
diff --git a/src/expr.rs b/src/expr.rs
index b79137c..76eb6d5 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -23,6 +23,7 @@
 use crate::matches::rewrite_match;
 use crate::overflow::{self, IntoOverflowableItem, OverflowableItem};
 use crate::pairs::{PairParts, rewrite_all_pairs, rewrite_pair};
+use crate::range::rewrite_range;
 use crate::rewrite::{Rewrite, RewriteContext, RewriteError, RewriteErrorExt, RewriteResult};
 use crate::shape::{Indent, Shape};
 use crate::source_map::{LineRangeUtils, SpanUtils};
@@ -315,78 +316,13 @@
             shape,
             SeparatorPlace::Back,
         ),
-        ast::ExprKind::Range(ref lhs, ref rhs, limits) => {
-            let delim = match limits {
-                ast::RangeLimits::HalfOpen => "..",
-                ast::RangeLimits::Closed => "..=",
-            };
-
-            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, 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)
-                    }
-                    _ => false,
-                }
-            }
-
-            fn needs_space_after_range(rhs: &ast::Expr) -> bool {
-                // Don't format `.. ..` into `....`, which is invalid.
-                //
-                // This check is unnecessary for `lhs`, because a range
-                // starting from another range needs parentheses as `(x ..) ..`
-                // (`x .. ..` is a range from `x` to `..`).
-                matches!(rhs.kind, ast::ExprKind::Range(None, _, _))
-            }
-
-            let default_sp_delim = |lhs: Option<&ast::Expr>, rhs: Option<&ast::Expr>| {
-                let space_if = |b: bool| if b { " " } else { "" };
-
-                format!(
-                    "{}{}{}",
-                    lhs.map_or("", |lhs| space_if(needs_space_before_range(context, lhs))),
-                    delim,
-                    rhs.map_or("", |rhs| space_if(needs_space_after_range(rhs))),
-                )
-            };
-
-            match (lhs.as_ref().map(|x| &**x), rhs.as_ref().map(|x| &**x)) {
-                (Some(lhs), Some(rhs)) => {
-                    let sp_delim = if context.config.spaces_around_ranges() {
-                        format!(" {delim} ")
-                    } else {
-                        default_sp_delim(Some(lhs), Some(rhs))
-                    };
-                    rewrite_pair(
-                        &*lhs,
-                        &*rhs,
-                        PairParts::infix(&sp_delim),
-                        context,
-                        shape,
-                        context.config.binop_separator(),
-                    )
-                }
-                (None, Some(rhs)) => {
-                    let sp_delim = if context.config.spaces_around_ranges() {
-                        format!("{delim} ")
-                    } else {
-                        default_sp_delim(None, Some(rhs))
-                    };
-                    rewrite_unary_prefix(context, &sp_delim, &*rhs, shape)
-                }
-                (Some(lhs), None) => {
-                    let sp_delim = if context.config.spaces_around_ranges() {
-                        format!(" {delim}")
-                    } else {
-                        default_sp_delim(Some(lhs), None)
-                    };
-                    rewrite_unary_suffix(context, &sp_delim, &*lhs, shape)
-                }
-                (None, None) => Ok(delim.to_owned()),
-            }
-        }
+        ast::ExprKind::Range(ref lhs, ref rhs, limits) => rewrite_range(
+            context,
+            shape,
+            lhs.as_deref(),
+            rhs.as_deref(),
+            limits.as_str(),
+        ),
         // We do not format these expressions yet, but they should still
         // satisfy our width restrictions.
         // Style Guide RFC for InlineAsm variant pending
diff --git a/src/lib.rs b/src/lib.rs
index d3379a4..45aefc2 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -84,6 +84,7 @@
 mod pairs;
 mod parse;
 mod patterns;
+mod range;
 mod release_channel;
 mod reorder;
 mod rewrite;
diff --git a/src/patterns.rs b/src/patterns.rs
index df2a8dc..2fad1d4 100644
--- a/src/patterns.rs
+++ b/src/patterns.rs
@@ -1,4 +1,4 @@
-use rustc_ast::ast::{self, BindingMode, ByRef, Pat, PatField, PatKind, RangeEnd, RangeSyntax};
+use rustc_ast::ast::{self, BindingMode, ByRef, Pat, PatField, PatKind};
 use rustc_span::{BytePos, Span};
 
 use crate::comment::{FindUncommented, combine_strs_with_missing_comments};
@@ -11,14 +11,15 @@
 };
 use crate::macros::{MacroPosition, rewrite_macro};
 use crate::overflow;
-use crate::pairs::{PairParts, rewrite_pair};
+use crate::range::rewrite_range;
 use crate::rewrite::{Rewrite, RewriteContext, RewriteError, RewriteErrorExt, RewriteResult};
 use crate::shape::Shape;
 use crate::source_map::SpanUtils;
 use crate::spanned::Spanned;
 use crate::types::{PathContext, rewrite_path};
 use crate::utils::{
-    format_mutability, format_pinnedness_and_mutability, mk_sp, mk_sp_lo_plus_one, rewrite_ident,
+    format_mutability, format_pinnedness_and_mutability, format_range_end, mk_sp,
+    mk_sp_lo_plus_one, rewrite_ident,
 };
 
 /// Returns `true` if the given pattern is "short".
@@ -77,24 +78,6 @@
     }
 }
 
-pub(crate) struct RangeOperand<'a, T> {
-    pub operand: &'a Option<Box<T>>,
-    pub span: Span,
-}
-
-impl<'a, T: Rewrite> Rewrite for RangeOperand<'a, T> {
-    fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
-        self.rewrite_result(context, shape).ok()
-    }
-
-    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
-        match &self.operand {
-            None => Ok("".to_owned()),
-            Some(ref exp) => exp.rewrite_result(context, shape),
-        }
-    }
-}
-
 impl Rewrite for Pat {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
         self.rewrite_result(context, shape).ok()
@@ -291,9 +274,13 @@
                 }
             }
             PatKind::Never => Err(RewriteError::Unknown),
-            PatKind::Range(ref lhs, ref rhs, ref end_kind) => {
-                rewrite_range_pat(context, shape, lhs, rhs, end_kind, self.span)
-            }
+            PatKind::Range(ref lhs, ref rhs, ref end_kind) => rewrite_range(
+                context,
+                shape,
+                lhs.as_deref(),
+                rhs.as_deref(),
+                format_range_end(end_kind.node),
+            ),
             PatKind::Ref(ref pat, pinnedness, mutability) => {
                 let (pin_prefix, mut_prefix) =
                     format_pinnedness_and_mutability(pinnedness, mutability);
@@ -356,50 +343,6 @@
     }
 }
 
-pub(crate) fn rewrite_range_pat<T: Rewrite>(
-    context: &RewriteContext<'_>,
-    shape: Shape,
-    lhs: &Option<Box<T>>,
-    rhs: &Option<Box<T>>,
-    end_kind: &rustc_span::source_map::Spanned<RangeEnd>,
-    span: Span,
-) -> RewriteResult {
-    let infix = match end_kind.node {
-        RangeEnd::Included(RangeSyntax::DotDotDot) => "...",
-        RangeEnd::Included(RangeSyntax::DotDotEq) => "..=",
-        RangeEnd::Excluded => "..",
-    };
-    let infix = if context.config.spaces_around_ranges() {
-        let lhs_spacing = match lhs {
-            None => "",
-            Some(_) => " ",
-        };
-        let rhs_spacing = match rhs {
-            None => "",
-            Some(_) => " ",
-        };
-        format!("{lhs_spacing}{infix}{rhs_spacing}")
-    } else {
-        infix.to_owned()
-    };
-    let lspan = span.with_hi(end_kind.span.lo());
-    let rspan = span.with_lo(end_kind.span.hi());
-    rewrite_pair(
-        &RangeOperand {
-            operand: lhs,
-            span: lspan,
-        },
-        &RangeOperand {
-            operand: rhs,
-            span: rspan,
-        },
-        PairParts::infix(&infix),
-        context,
-        shape,
-        SeparatorPlace::Front,
-    )
-}
-
 fn rewrite_struct_pat(
     qself: &Option<Box<ast::QSelf>>,
     path: &ast::Path,
diff --git a/src/range.rs b/src/range.rs
new file mode 100644
index 0000000..0cc7c7f
--- /dev/null
+++ b/src/range.rs
@@ -0,0 +1,78 @@
+use crate::expr::{lit_ends_in_dot, rewrite_unary_prefix, rewrite_unary_suffix};
+use crate::pairs::{PairParts, rewrite_pair};
+use crate::rewrite::{RewriteContext, RewriteResult};
+use crate::shape::Shape;
+
+use rustc_ast::ast;
+
+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, 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),
+        _ => false,
+    }
+}
+
+fn needs_space_after_range(rhs: &ast::Expr) -> bool {
+    // Don't format `.. ..` into `....`, which is invalid.
+    //
+    // This check is unnecessary for `lhs`, because a range
+    // starting from another range needs parentheses as `(x ..) ..`
+    // (`x .. ..` is a range from `x` to `..`).
+    matches!(rhs.kind, ast::ExprKind::Range(None, _, _))
+}
+
+pub(crate) fn rewrite_range(
+    context: &RewriteContext<'_>,
+    shape: Shape,
+    lhs: Option<&ast::Expr>,
+    rhs: Option<&ast::Expr>,
+    delim: &str,
+) -> RewriteResult {
+    let default_sp_delim = |lhs: Option<&ast::Expr>, rhs: Option<&ast::Expr>| {
+        let space_if = |b: bool| if b { " " } else { "" };
+
+        format!(
+            "{}{}{}",
+            lhs.map_or("", |lhs| space_if(needs_space_before_range(context, lhs))),
+            delim,
+            rhs.map_or("", |rhs| space_if(needs_space_after_range(rhs))),
+        )
+    };
+
+    match (lhs, rhs) {
+        (Some(lhs), Some(rhs)) => {
+            let sp_delim = if context.config.spaces_around_ranges() {
+                format!(" {delim} ")
+            } else {
+                default_sp_delim(Some(lhs), Some(rhs))
+            };
+            rewrite_pair(
+                lhs,
+                rhs,
+                PairParts::infix(&sp_delim),
+                context,
+                shape,
+                context.config.binop_separator(),
+            )
+        }
+        (None, Some(rhs)) => {
+            let sp_delim = if context.config.spaces_around_ranges() {
+                format!("{delim} ")
+            } else {
+                default_sp_delim(None, Some(rhs))
+            };
+            rewrite_unary_prefix(context, &sp_delim, rhs, shape)
+        }
+        (Some(lhs), None) => {
+            let sp_delim = if context.config.spaces_around_ranges() {
+                format!(" {delim}")
+            } else {
+                default_sp_delim(Some(lhs), None)
+            };
+            rewrite_unary_suffix(context, &sp_delim, lhs, shape)
+        }
+        (None, None) => Ok(delim.to_owned()),
+    }
+}
diff --git a/src/spanned.rs b/src/spanned.rs
index 020651e..f7486e1 100644
--- a/src/spanned.rs
+++ b/src/spanned.rs
@@ -4,7 +4,6 @@
 use rustc_span::{Span, source_map};
 
 use crate::macros::MacroArg;
-use crate::patterns::RangeOperand;
 use crate::utils::{mk_sp, outer_attributes};
 
 /// Spanned returns a span including attributes, if available.
@@ -205,9 +204,3 @@
         }
     }
 }
-
-impl<'a, T> Spanned for RangeOperand<'a, T> {
-    fn span(&self) -> Span {
-        self.span
-    }
-}
diff --git a/src/types.rs b/src/types.rs
index 94ed42c..3ce9955 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -16,14 +16,14 @@
 use crate::macros::{MacroPosition, rewrite_macro};
 use crate::overflow;
 use crate::pairs::{PairParts, rewrite_pair};
-use crate::patterns::rewrite_range_pat;
+use crate::range::rewrite_range;
 use crate::rewrite::{Rewrite, RewriteContext, RewriteError, RewriteErrorExt, RewriteResult};
 use crate::shape::Shape;
 use crate::source_map::SpanUtils;
 use crate::spanned::Spanned;
 use crate::utils::{
     colon_spaces, extra_offset, first_line_width, format_extern, format_mutability,
-    last_line_extendable, last_line_width, mk_sp, rewrite_ident,
+    format_range_end, last_line_extendable, last_line_width, mk_sp, rewrite_ident,
 };
 
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
@@ -1067,9 +1067,13 @@
 
     fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         match self.kind {
-            ast::TyPatKind::Range(ref lhs, ref rhs, ref end_kind) => {
-                rewrite_range_pat(context, shape, lhs, rhs, end_kind, self.span)
-            }
+            ast::TyPatKind::Range(ref lhs, ref rhs, ref end_kind) => rewrite_range(
+                context,
+                shape,
+                lhs.as_deref().map(|x| x.value.as_ref()),
+                rhs.as_deref().map(|x| x.value.as_ref()),
+                format_range_end(end_kind.node),
+            ),
             ast::TyPatKind::Or(ref variants) => {
                 let mut first = true;
                 let mut s = String::new();
diff --git a/src/utils.rs b/src/utils.rs
index b676803..e763303 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -147,6 +147,15 @@
 }
 
 #[inline]
+pub(crate) fn format_range_end(end: ast::RangeEnd) -> &'static str {
+    match end {
+        ast::RangeEnd::Included(ast::RangeSyntax::DotDotDot) => "...",
+        ast::RangeEnd::Included(ast::RangeSyntax::DotDotEq) => "..=",
+        ast::RangeEnd::Excluded => "..",
+    }
+}
+
+#[inline]
 pub(crate) fn format_extern(ext: ast::Extern, explicit_abi: bool) -> Cow<'static, str> {
     match ext {
         ast::Extern::None => Cow::from(""),
diff --git a/tests/source/configs/float_literal_trailing_zero/always.rs b/tests/source/configs/float_literal_trailing_zero/always.rs
index 47b0443..8ac9737 100644
--- a/tests/source/configs/float_literal_trailing_zero/always.rs
+++ b/tests/source/configs/float_literal_trailing_zero/always.rs
@@ -1,4 +1,5 @@
 // rustfmt-float_literal_trailing_zero: Always
+// spaces_around_ranges: false is implied since it's the default
 
 fn float_literals() {
     let a = 0.;
@@ -43,3 +44,6 @@
     ];
     println!("This is floaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaat {}", 10e3);
 }
+
+fn pattern_in_function_parameters_exactly_max_width_before_zero___(2. ..10.: std::ops::Range<f32>) {
+}
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
index 45e0b87..4889203 100644
--- a/tests/source/configs/float_literal_trailing_zero/if-no-postfix.rs
+++ b/tests/source/configs/float_literal_trailing_zero/if-no-postfix.rs
@@ -1,4 +1,5 @@
 // rustfmt-float_literal_trailing_zero: IfNoPostfix
+// spaces_around_ranges: false is implied since it's the default
 
 fn float_literals() {
     let a = 0.;
@@ -46,3 +47,6 @@
         10.0e3
     );
 }
+
+fn pattern_in_function_parameters_exactly_max_width_before_zero___(2. ..10.: std::ops::Range<f32>) {
+}
diff --git a/tests/source/configs/float_literal_trailing_zero/never.rs b/tests/source/configs/float_literal_trailing_zero/never.rs
index 2fe5fe2..f07bc4d 100644
--- a/tests/source/configs/float_literal_trailing_zero/never.rs
+++ b/tests/source/configs/float_literal_trailing_zero/never.rs
@@ -1,4 +1,5 @@
 // rustfmt-float_literal_trailing_zero: Never
+// spaces_around_ranges: false is implied since it's the default
 
 fn float_literals() {
     let a = 0.;
@@ -47,3 +48,6 @@
         10.0e3
     );
 }
+
+fn pattern_in_function_parameters_exactly_max_width_before_zero___(2.0..10.: std::ops::Range<f32>) {
+}
diff --git a/tests/source/configs/spaces_around_ranges/false.rs b/tests/source/configs/spaces_around_ranges/false.rs
index 1878c68..b478dad 100644
--- a/tests/source/configs/spaces_around_ranges/false.rs
+++ b/tests/source/configs/spaces_around_ranges/false.rs
@@ -7,16 +7,19 @@
 
     match lorem {
         1 .. 5 => foo(),
+        1. .. 5. => (),
         _ => bar,
     }
 
     match lorem {
         1 ..= 5 => foo(),
+        1. ..= 5. => (),
         _ => bar,
     }
 
     match lorem {
         1 ... 5 => foo(),
+        1. ... 0.5 => foo(),
         _ => bar,
     }
 }
@@ -25,10 +28,18 @@
     match [5 .. 4, 99 .. 105, 43 .. 44] {
         [_, 99 .., _] => {}
         [_, .. 105, _] => {}
+        [_, 1. .., _] => {}
         _ => {}
     };
 
     if let ..=   5 = 0 {}
     if let .. 5 = 0 {}
+    // For now `.. .5` fails parsing with `float literals must have an integer part`
+    if let .. 0.5 = 0 {}
     if let 5 .. = 0 {}
+    if let 5. .. = 0 {}
+}
+
+fn pattern_in_function_parameters_exactly_max_width_before_space__(2. .. 10.: std::ops::Range<f32>) {
+
 }
diff --git a/tests/source/configs/spaces_around_ranges/true.rs b/tests/source/configs/spaces_around_ranges/true.rs
index 0eadfb2..fe324ee 100644
--- a/tests/source/configs/spaces_around_ranges/true.rs
+++ b/tests/source/configs/spaces_around_ranges/true.rs
@@ -7,16 +7,19 @@
 
     match lorem {
         1..5 => foo(),
+        1. ..5. => (),
         _ => bar,
     }
 
     match lorem {
         1..=5 => foo(),
+        1. ..=5. => (),
         _ => bar,
     }
 
     match lorem {
         1...5 => foo(),
+        1. ... 0.5 => foo(),
         _ => bar,
     }
 }
@@ -25,10 +28,17 @@
     match [5..4, 99..105, 43..44] {
         [_, 99.., _] => {}
         [_, ..105, _] => {}
+        [_, 1. .., _] => {}
         _ => {}
     };
 
     if let ..=5 = 0 {}
     if let ..5 = 0 {}
+    // For now `.. .5` fails parsing with `float literals must have an integer part`
+    if let .. 0.5 = 0 {}
     if let 5.. = 0 {}
+    if let 5. .. = 0 {}
+}
+
+fn pattern_in_function_parameters_exactly_max_width_before_space__(2. ..10.: std::ops::Range<f32>) {
 }
diff --git a/tests/target/configs/float_literal_trailing_zero/always.rs b/tests/target/configs/float_literal_trailing_zero/always.rs
index e6d643a..2d64ec8 100644
--- a/tests/target/configs/float_literal_trailing_zero/always.rs
+++ b/tests/target/configs/float_literal_trailing_zero/always.rs
@@ -1,4 +1,5 @@
 // rustfmt-float_literal_trailing_zero: Always
+// spaces_around_ranges: false is implied since it's the default
 
 fn float_literals() {
     let a = 0.0;
@@ -47,3 +48,8 @@
         10.0e3
     );
 }
+
+fn pattern_in_function_parameters_exactly_max_width_before_zero___(
+    2.0..10.0: std::ops::Range<f32>,
+) {
+}
diff --git a/tests/target/configs/float_literal_trailing_zero/always_spaces_around_ranges_true.rs b/tests/target/configs/float_literal_trailing_zero/always_spaces_around_ranges_true.rs
new file mode 100644
index 0000000..087e495
--- /dev/null
+++ b/tests/target/configs/float_literal_trailing_zero/always_spaces_around_ranges_true.rs
@@ -0,0 +1,55 @@
+// rustfmt-float_literal_trailing_zero: Always
+// rustfmt-spaces_around_ranges: true
+
+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
+    );
+}
+
+fn pattern_in_function_parameters_exactly_max_width_before_zero___(
+    2.0 .. 10.0: std::ops::Range<f32>,
+) {
+}
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
index d81f5c0..f4a36e9 100644
--- a/tests/target/configs/float_literal_trailing_zero/if-no-postfix.rs
+++ b/tests/target/configs/float_literal_trailing_zero/if-no-postfix.rs
@@ -1,4 +1,5 @@
 // rustfmt-float_literal_trailing_zero: IfNoPostfix
+// spaces_around_ranges: false is implied since it's the default
 
 fn float_literals() {
     let a = 0.0;
@@ -44,3 +45,8 @@
     ];
     println!("This is floaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaat {}", 10e3);
 }
+
+fn pattern_in_function_parameters_exactly_max_width_before_zero___(
+    2.0..10.0: std::ops::Range<f32>,
+) {
+}
diff --git a/tests/target/configs/float_literal_trailing_zero/if-no-postfix_spaces_around_ranges_true.rs b/tests/target/configs/float_literal_trailing_zero/if-no-postfix_spaces_around_ranges_true.rs
new file mode 100644
index 0000000..b073c34
--- /dev/null
+++ b/tests/target/configs/float_literal_trailing_zero/if-no-postfix_spaces_around_ranges_true.rs
@@ -0,0 +1,52 @@
+// rustfmt-float_literal_trailing_zero: IfNoPostfix
+// rustfmt-spaces_around_ranges: true
+
+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);
+}
+
+fn pattern_in_function_parameters_exactly_max_width_before_zero___(
+    2.0 .. 10.0: std::ops::Range<f32>,
+) {
+}
diff --git a/tests/target/configs/float_literal_trailing_zero/never.rs b/tests/target/configs/float_literal_trailing_zero/never.rs
index 6391890..a0640a6 100644
--- a/tests/target/configs/float_literal_trailing_zero/never.rs
+++ b/tests/target/configs/float_literal_trailing_zero/never.rs
@@ -1,4 +1,5 @@
 // rustfmt-float_literal_trailing_zero: Never
+// spaces_around_ranges: false is implied since it's the default
 
 fn float_literals() {
     let a = 0.;
@@ -43,3 +44,6 @@
     ];
     println!("This is floaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaat {}", 10e3);
 }
+
+fn pattern_in_function_parameters_exactly_max_width_before_zero___(2. ..10.: std::ops::Range<f32>) {
+}
diff --git a/tests/target/configs/float_literal_trailing_zero/never_spaces_around_ranges_true.rs b/tests/target/configs/float_literal_trailing_zero/never_spaces_around_ranges_true.rs
new file mode 100644
index 0000000..939e206
--- /dev/null
+++ b/tests/target/configs/float_literal_trailing_zero/never_spaces_around_ranges_true.rs
@@ -0,0 +1,51 @@
+// rustfmt-float_literal_trailing_zero: Never
+// rustfmt-spaces_around_ranges: true
+
+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);
+}
+
+fn pattern_in_function_parameters_exactly_max_width_before_zero___(
+    2. .. 10.: std::ops::Range<f32>,
+) {
+}
diff --git a/tests/target/configs/float_literal_trailing_zero/preserve_spaces_around_ranges_true.rs b/tests/target/configs/float_literal_trailing_zero/preserve_spaces_around_ranges_true.rs
new file mode 100644
index 0000000..36371bd
--- /dev/null
+++ b/tests/target/configs/float_literal_trailing_zero/preserve_spaces_around_ranges_true.rs
@@ -0,0 +1,44 @@
+// rustfmt-float_literal_trailing_zero: Preserve
+// rustfmt-spaces_around_ranges: true
+
+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. .. 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 pattern_in_function_parameters_exactly_max_width_before_zero___(
+    2. .. 10.0: std::ops::Range<f32>,
+) {
+}
diff --git a/tests/target/configs/spaces_around_ranges/false.rs b/tests/target/configs/spaces_around_ranges/false.rs
index 72b1be4..9b4ae1e 100644
--- a/tests/target/configs/spaces_around_ranges/false.rs
+++ b/tests/target/configs/spaces_around_ranges/false.rs
@@ -7,16 +7,19 @@
 
     match lorem {
         1..5 => foo(),
+        1. ..5. => (),
         _ => bar,
     }
 
     match lorem {
         1..=5 => foo(),
+        1. ..=5. => (),
         _ => bar,
     }
 
     match lorem {
         1...5 => foo(),
+        1. ...0.5 => foo(),
         _ => bar,
     }
 }
@@ -25,10 +28,17 @@
     match [5..4, 99..105, 43..44] {
         [_, 99.., _] => {}
         [_, ..105, _] => {}
+        [_, 1. .., _] => {}
         _ => {}
     };
 
     if let ..=5 = 0 {}
     if let ..5 = 0 {}
+    // For now `.. .5` fails parsing with `float literals must have an integer part`
+    if let ..0.5 = 0 {}
     if let 5.. = 0 {}
+    if let 5. .. = 0 {}
+}
+
+fn pattern_in_function_parameters_exactly_max_width_before_space__(2. ..10.: std::ops::Range<f32>) {
 }
diff --git a/tests/target/configs/spaces_around_ranges/true.rs b/tests/target/configs/spaces_around_ranges/true.rs
index c56fdbb..d450e7b 100644
--- a/tests/target/configs/spaces_around_ranges/true.rs
+++ b/tests/target/configs/spaces_around_ranges/true.rs
@@ -7,16 +7,19 @@
 
     match lorem {
         1 .. 5 => foo(),
+        1. .. 5. => (),
         _ => bar,
     }
 
     match lorem {
         1 ..= 5 => foo(),
+        1. ..= 5. => (),
         _ => bar,
     }
 
     match lorem {
         1 ... 5 => foo(),
+        1. ... 0.5 => foo(),
         _ => bar,
     }
 }
@@ -25,10 +28,19 @@
     match [5 .. 4, 99 .. 105, 43 .. 44] {
         [_, 99 .., _] => {}
         [_, .. 105, _] => {}
+        [_, 1. .., _] => {}
         _ => {}
     };
 
     if let ..= 5 = 0 {}
     if let .. 5 = 0 {}
+    // For now `.. .5` fails parsing with `float literals must have an integer part`
+    if let .. 0.5 = 0 {}
     if let 5 .. = 0 {}
+    if let 5. .. = 0 {}
+}
+
+fn pattern_in_function_parameters_exactly_max_width_before_space__(
+    2. .. 10.: std::ops::Range<f32>,
+) {
 }
diff --git a/tests/target/issue_6869.rs b/tests/target/issue_6869.rs
new file mode 100644
index 0000000..1f4b1df
--- /dev/null
+++ b/tests/target/issue_6869.rs
@@ -0,0 +1,8 @@
+fn main() {
+    let x = 0.5;
+
+    match x {
+        1. .. => println!("{x} >= 1"),
+        _ => println!("{x} < 1"),
+    }
+}