diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 11c893a7cb6..e156930cc89 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -609,7 +609,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { if !matches!(ty.kind(), ty::Infer(ty::InferTy::TyVar(_) | ty::InferTy::FreshTy(_))) { // don't show type `_` - err.span_label(span, format!("this expression has type `{}`", ty)); + if span.desugaring_kind() == Some(DesugaringKind::ForLoop) + && let ty::Adt(def, substs) = ty.kind() + && Some(def.did()) == self.tcx.get_diagnostic_item(sym::Option) + { + err.span_label(span, format!("this is an iterator with items of type `{}`", substs.type_at(0))); + } else { + err.span_label(span, format!("this expression has type `{}`", ty)); + } } if let Some(ty::error::ExpectedFound { found, .. }) = exp_found && ty.is_box() && ty.boxed_ty() == found diff --git a/src/test/ui/pattern/for-loop-bad-item.rs b/src/test/ui/pattern/for-loop-bad-item.rs new file mode 100644 index 00000000000..9a56a399b9b --- /dev/null +++ b/src/test/ui/pattern/for-loop-bad-item.rs @@ -0,0 +1,20 @@ +struct Qux(i32); + +fn bad() { + let mut map = std::collections::HashMap::new(); + map.insert(('a', 'b'), ('c', 'd')); + + for ((_, _), (&mut c, _)) in &mut map { + //~^ ERROR mismatched types + if c == 'e' {} + } +} + +fn bad2() { + for Some(Qux(_)) | None in [Some(""), None] { + //~^ ERROR mismatched types + todo!(); + } +} + +fn main() {} diff --git a/src/test/ui/pattern/for-loop-bad-item.stderr b/src/test/ui/pattern/for-loop-bad-item.stderr new file mode 100644 index 00000000000..9410e4da8d2 --- /dev/null +++ b/src/test/ui/pattern/for-loop-bad-item.stderr @@ -0,0 +1,23 @@ +error[E0308]: mismatched types + --> $DIR/for-loop-bad-item.rs:7:19 + | +LL | for ((_, _), (&mut c, _)) in &mut map { + | ^^^^^^ -------- this is an iterator with items of type `(&(char, char), &mut (char, char))` + | | + | expected `char`, found `&mut _` + | help: you can probably remove the explicit borrow: `c` + | + = note: expected type `char` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/for-loop-bad-item.rs:14:14 + | +LL | for Some(Qux(_)) | None in [Some(""), None] { + | ^^^^^^ ---------------- this is an iterator with items of type `Option<&str>` + | | + | expected `str`, found struct `Qux` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`.