From df5a3414e7b66d1485844d02b6c68481272eb4ff Mon Sep 17 00:00:00 2001 From: xizheyin Date: Thu, 21 Aug 2025 19:09:56 +0800 Subject: [PATCH 1/2] Add test type-mismatch-suggest-wrap-issue-145634 Signed-off-by: xizheyin --- .../type-mismatch-suggest-wrap-issue-145634.rs | 9 +++++++++ ...e-mismatch-suggest-wrap-issue-145634.stderr | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 tests/ui/type/type-mismatch-suggest-wrap-issue-145634.rs create mode 100644 tests/ui/type/type-mismatch-suggest-wrap-issue-145634.stderr diff --git a/tests/ui/type/type-mismatch-suggest-wrap-issue-145634.rs b/tests/ui/type/type-mismatch-suggest-wrap-issue-145634.rs new file mode 100644 index 0000000000000..a587417148543 --- /dev/null +++ b/tests/ui/type/type-mismatch-suggest-wrap-issue-145634.rs @@ -0,0 +1,9 @@ +// We should not suggest wrapping rhs with `Some` +// when the found type is an unresolved type variable +// +// See https://github.com/rust-lang/rust/issues/145634 + +fn main() { + let foo = Some(&(1, 2)); + assert!(matches!(foo, &Some((1, 2)))); //~ ERROR mismatched types [E0308] +} diff --git a/tests/ui/type/type-mismatch-suggest-wrap-issue-145634.stderr b/tests/ui/type/type-mismatch-suggest-wrap-issue-145634.stderr new file mode 100644 index 0000000000000..0fad4b27028e6 --- /dev/null +++ b/tests/ui/type/type-mismatch-suggest-wrap-issue-145634.stderr @@ -0,0 +1,18 @@ +error[E0308]: mismatched types + --> $DIR/type-mismatch-suggest-wrap-issue-145634.rs:8:27 + | +LL | assert!(matches!(foo, &Some((1, 2)))); + | --- ^^^^^^^^^^^^^ expected `Option<&({integer}, {integer})>`, found `&_` + | | + | this expression has type `Option<&({integer}, {integer})>` + | + = note: expected enum `Option<&({integer}, {integer})>` + found reference `&_` +help: try wrapping the pattern in `Some` + | +LL | assert!(matches!(foo, Some(&Some((1, 2))))); + | +++++ + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. From 906b6e88c1f4bfd48b0cc514435d14c1094b1220 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Thu, 21 Aug 2025 19:15:38 +0800 Subject: [PATCH 2/2] Suppress suggest try wrap when found is unresolved var Signed-off-by: xizheyin --- .../src/error_reporting/infer/suggest.rs | 9 ++++++++- compiler/rustc_type_ir/src/flags.rs | 10 +++++++--- tests/ui/issues/issue-3680.stderr | 4 ---- tests/ui/issues/issue-5358-1.stderr | 4 ---- tests/ui/match/issue-12552.stderr | 8 -------- .../ui/type/type-mismatch-suggest-wrap-issue-145634.rs | 2 +- .../type-mismatch-suggest-wrap-issue-145634.stderr | 4 ---- 7 files changed, 16 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs index 44baa213b2847..29e63f37e4932 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs @@ -11,7 +11,9 @@ use rustc_hir::{MatchSource, Node}; use rustc_middle::traits::{MatchExpressionArmCause, ObligationCause, ObligationCauseCode}; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::{self as ty, GenericArgKind, IsSuggestable, Ty, TypeVisitableExt}; +use rustc_middle::ty::{ + self as ty, GenericArgKind, IsSuggestable, Ty, TypeFlags, TypeVisitableExt, +}; use rustc_span::{Span, sym}; use tracing::debug; @@ -89,6 +91,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { exp_found: &ty::error::ExpectedFound>, diag: &mut Diag<'_>, ) { + // when found is unresolved var, we can't suggest anything + if exp_found.found.has_type_flags(TypeFlags::HAS_INFER_TY_VAR) { + return; + } + // Heavily inspired by `FnCtxt::suggest_compatible_variants`, with // some modifications due to that being in typeck and this being in infer. if let ObligationCauseCode::Pattern { .. } = cause.code() diff --git a/compiler/rustc_type_ir/src/flags.rs b/compiler/rustc_type_ir/src/flags.rs index 23b7f55fbbe53..df4d050fee7d3 100644 --- a/compiler/rustc_type_ir/src/flags.rs +++ b/compiler/rustc_type_ir/src/flags.rs @@ -133,6 +133,9 @@ bitflags::bitflags! { /// Does this type have any coroutines in it? const HAS_TY_CORO = 1 << 24; + + /// Does this type have any Infer(TyVar(_)) in it? + const HAS_INFER_TY_VAR = 1 << 25; } } @@ -267,9 +270,10 @@ impl FlagComputation { ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => { self.add_flags(TypeFlags::HAS_TY_FRESH) } - - ty::TyVar(_) | ty::IntVar(_) | ty::FloatVar(_) => { - self.add_flags(TypeFlags::HAS_TY_INFER) + ty::IntVar(_) | ty::FloatVar(_) => self.add_flags(TypeFlags::HAS_TY_INFER), + ty::TyVar(_) => { + self.add_flags(TypeFlags::HAS_INFER_TY_VAR); + self.add_flags(TypeFlags::HAS_TY_INFER); } }, diff --git a/tests/ui/issues/issue-3680.stderr b/tests/ui/issues/issue-3680.stderr index 2a757b44dc834..85beac9e2943a 100644 --- a/tests/ui/issues/issue-3680.stderr +++ b/tests/ui/issues/issue-3680.stderr @@ -8,10 +8,6 @@ LL | Err(_) => () | = note: expected enum `Option<_>` found enum `Result<_, _>` -help: try wrapping the pattern in `Some` - | -LL | Some(Err(_)) => () - | +++++ + error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-5358-1.stderr b/tests/ui/issues/issue-5358-1.stderr index e68db865dc414..1cafff19f077a 100644 --- a/tests/ui/issues/issue-5358-1.stderr +++ b/tests/ui/issues/issue-5358-1.stderr @@ -8,10 +8,6 @@ LL | Either::Right(_) => {} | = note: expected struct `S` found enum `Either<_, _>` -help: try wrapping the pattern in `S` - | -LL | S(Either::Right(_)) => {} - | ++ + help: you might have meant to use field `0` whose type is `Either` | LL | match S(Either::Left(5)).0 { diff --git a/tests/ui/match/issue-12552.stderr b/tests/ui/match/issue-12552.stderr index 195192fbd8240..58a8340f751de 100644 --- a/tests/ui/match/issue-12552.stderr +++ b/tests/ui/match/issue-12552.stderr @@ -8,10 +8,6 @@ LL | Some(k) => match k { | = note: expected enum `Result<_, {integer}>` found enum `Option<_>` -help: try wrapping the pattern in `Ok` - | -LL | Ok(Some(k)) => match k { - | +++ + error[E0308]: mismatched types --> $DIR/issue-12552.rs:9:5 @@ -24,10 +20,6 @@ LL | None => () | = note: expected enum `Result<_, {integer}>` found enum `Option<_>` -help: try wrapping the pattern in `Ok` - | -LL | Ok(None) => () - | +++ + error: aborting due to 2 previous errors diff --git a/tests/ui/type/type-mismatch-suggest-wrap-issue-145634.rs b/tests/ui/type/type-mismatch-suggest-wrap-issue-145634.rs index a587417148543..9ad9f2a9a7d6d 100644 --- a/tests/ui/type/type-mismatch-suggest-wrap-issue-145634.rs +++ b/tests/ui/type/type-mismatch-suggest-wrap-issue-145634.rs @@ -1,6 +1,6 @@ // We should not suggest wrapping rhs with `Some` // when the found type is an unresolved type variable -// +// // See https://github.com/rust-lang/rust/issues/145634 fn main() { diff --git a/tests/ui/type/type-mismatch-suggest-wrap-issue-145634.stderr b/tests/ui/type/type-mismatch-suggest-wrap-issue-145634.stderr index 0fad4b27028e6..9dfa1ef513c5e 100644 --- a/tests/ui/type/type-mismatch-suggest-wrap-issue-145634.stderr +++ b/tests/ui/type/type-mismatch-suggest-wrap-issue-145634.stderr @@ -8,10 +8,6 @@ LL | assert!(matches!(foo, &Some((1, 2)))); | = note: expected enum `Option<&({integer}, {integer})>` found reference `&_` -help: try wrapping the pattern in `Some` - | -LL | assert!(matches!(foo, Some(&Some((1, 2))))); - | +++++ + error: aborting due to 1 previous error