diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 11c893a7cb6d9..f19c5b2358c6c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2010,7 +2010,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { { if let ObligationCauseCode::Pattern { span: Some(span), .. } = *cause.code() { if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { - let suggestion = if expected_def.is_struct() { + let suggestion = if exp_found.found.is_unit() { + let exp_str = format!("{:?}", expected_def); + + // `RangeInclusive`'s fields are private, we have to call methods instead. + if exp_str.contains("core::ops::RangeInclusive") + || exp_str.contains("std::ops::RangeInclusive") + { + format!("({}).{}()", snippet, name) + } else { + format!("({}).{}", snippet, name) + } + } else if expected_def.is_struct() { format!("{}.{}", snippet, name) } else if expected_def.is_union() { format!("unsafe {{ {}.{} }}", snippet, name) diff --git a/src/test/ui/range/issue-93122-bind-unit-range-to-unit.fixed b/src/test/ui/range/issue-93122-bind-unit-range-to-unit.fixed new file mode 100644 index 0000000000000..92492c640b673 --- /dev/null +++ b/src/test/ui/range/issue-93122-bind-unit-range-to-unit.fixed @@ -0,0 +1,9 @@ +// run-rustfix + +fn main() { + let () = (()..).start; //~ ERROR: mismatched types + let () = (..()).end; //~ ERROR: mismatched types + let () = (..=()).end; //~ ERROR: mismatched types + let () = (()..()).start; //~ ERROR: mismatched types + let () = (()..=()).start(); //~ ERROR: mismatched types +} diff --git a/src/test/ui/range/issue-93122-bind-unit-range-to-unit.rs b/src/test/ui/range/issue-93122-bind-unit-range-to-unit.rs new file mode 100644 index 0000000000000..ffe425b6500c5 --- /dev/null +++ b/src/test/ui/range/issue-93122-bind-unit-range-to-unit.rs @@ -0,0 +1,9 @@ +// run-rustfix + +fn main() { + let () = ()..; //~ ERROR: mismatched types + let () = ..(); //~ ERROR: mismatched types + let () = ..=(); //~ ERROR: mismatched types + let () = ()..(); //~ ERROR: mismatched types + let () = ()..=(); //~ ERROR: mismatched types +} diff --git a/src/test/ui/range/issue-93122-bind-unit-range-to-unit.stderr b/src/test/ui/range/issue-93122-bind-unit-range-to-unit.stderr new file mode 100644 index 0000000000000..6399b20cb4666 --- /dev/null +++ b/src/test/ui/range/issue-93122-bind-unit-range-to-unit.stderr @@ -0,0 +1,78 @@ +error[E0308]: mismatched types + --> $DIR/issue-93122-bind-unit-range-to-unit.rs:4:9 + | +LL | let () = ()..; + | ^^ ---- this expression has type `RangeFrom<()>` + | | + | expected struct `RangeFrom`, found `()` + | + = note: expected struct `RangeFrom<()>` + found unit type `()` +help: you might have meant to use field `start` whose type is `()` + | +LL | let () = (()..).start; + | ~~~~~~~~~~~~ + +error[E0308]: mismatched types + --> $DIR/issue-93122-bind-unit-range-to-unit.rs:5:9 + | +LL | let () = ..(); + | ^^ ---- this expression has type `RangeTo<()>` + | | + | expected struct `RangeTo`, found `()` + | + = note: expected struct `RangeTo<()>` + found unit type `()` +help: you might have meant to use field `end` whose type is `()` + | +LL | let () = (..()).end; + | ~~~~~~~~~~ + +error[E0308]: mismatched types + --> $DIR/issue-93122-bind-unit-range-to-unit.rs:6:9 + | +LL | let () = ..=(); + | ^^ ----- this expression has type `RangeToInclusive<()>` + | | + | expected struct `RangeToInclusive`, found `()` + | + = note: expected struct `RangeToInclusive<()>` + found unit type `()` +help: you might have meant to use field `end` whose type is `()` + | +LL | let () = (..=()).end; + | ~~~~~~~~~~~ + +error[E0308]: mismatched types + --> $DIR/issue-93122-bind-unit-range-to-unit.rs:7:9 + | +LL | let () = ()..(); + | ^^ ------ this expression has type `std::ops::Range<()>` + | | + | expected struct `std::ops::Range`, found `()` + | + = note: expected struct `std::ops::Range<()>` + found unit type `()` +help: you might have meant to use field `start` whose type is `()` + | +LL | let () = (()..()).start; + | ~~~~~~~~~~~~~~ + +error[E0308]: mismatched types + --> $DIR/issue-93122-bind-unit-range-to-unit.rs:8:9 + | +LL | let () = ()..=(); + | ^^ ------- this expression has type `RangeInclusive<()>` + | | + | expected struct `RangeInclusive`, found `()` + | + = note: expected struct `RangeInclusive<()>` + found unit type `()` +help: you might have meant to use field `start` whose type is `()` + | +LL | let () = (()..=()).start(); + | ~~~~~~~~~~~~~~~~~ + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0308`.