Change:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. If you cannot produce a minimal reproduction case (something that would work in isolation), please provide the steps or even link to a repository that causes the problematic output to occur. --Given the following code: The current output is: <!-- The following is not always necessary. --Ideally the output should suggest to the user that they need to initialize the enum variant's value in order to use the . <!-- If the problem is not self-explanatory, please provide a rationale for the change. --<!-- If dramatically different output is caused by small changes, consider also adding them here. If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. The output might also be different depending on the Edition. --<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Can you give the output of what it should look like?
It should probably look similar to the suggestion given for and So I guess sth. like: Edit: Or instead of saying “to instantiate this tuple variant” we could say “to call this function” like it's done for the erroneous snippet (where is a ).
claim
commit the fix

Discussion:
// #55810: Type check patterns first so we get types for all bindings. let scrut_span = scrut.span.find_ancestor_inside(expr.span).unwrap_or(scrut.span); for arm in arms { <del> self.check_pat_top(&arm.pat, scrutinee_ty, Some(scrut_span), true); </del> <ins> self.check_pat_top(&arm.pat, scrutinee_ty, Some(scrut_span), Some(scrut)); </ins> } // Now typecheck the blocks.

for (idx, (param_ty, param)) in inputs_fn.chain(maybe_va_list).zip(body.params).enumerate() { // Check the pattern. let ty_span = try { inputs_hir?.get(idx)?.span }; <del> fcx.check_pat_top(&param.pat, param_ty, ty_span, false); </del> <ins> fcx.check_pat_top(&param.pat, param_ty, ty_span, None); </ins> // Check that argument is Sized. // The check for a non-trivial pattern is a hack to avoid duplicate warnings

// Does the expected pattern type originate from an expression and what is the span? let (origin_expr, ty_span) = match (decl.ty, decl.init) { <del> (Some(ty), _) => (false, Some(ty.span)), // Bias towards the explicit user type. </del> <ins> (Some(ty), _) => (None, Some(ty.span)), // Bias towards the explicit user type. </ins> (_, Some(init)) => { <del> (true, Some(init.span.find_ancestor_inside(decl.span).unwrap_or(init.span))) </del> <ins> (Some(init), Some(init.span.find_ancestor_inside(decl.span).unwrap_or(init.span))) </ins> } // No explicit type; so use the scrutinee. <del> _ => (false, None), // We have `let $pat;`, so the expected type is unconstrained. </del> <ins> _ => (None, None), // We have `let $pat;`, so the expected type is unconstrained. </ins> }; // Type check the pattern. Override if necessary to avoid knock-on errors.

/// Was the origin of the `span` from a scrutinee expression? /// /// Otherwise there is no scrutinee and it could be e.g. from the type of a formal parameter. <del> origin_expr: bool, </del> <ins> origin_expr: Option<&'tcx hir::Expr<'tcx>>, </ins> /// The span giving rise to the `expected` type, if one could be provided. /// /// If `origin_expr` is `true`, then this is the span of the scrutinee as in:

impl<'tcx> FnCtxt<'_, 'tcx> { fn pattern_cause(&self, ti: TopInfo<'tcx>, cause_span: Span) -> ObligationCause<'tcx> { <del> let code = Pattern { span: ti.span, root_ty: ti.expected, origin_expr: ti.origin_expr }; </del> <ins> let code = Pattern { span: ti.span, root_ty: ti.expected, origin_expr: ti.origin_expr.is_some() }; </ins> self.cause(cause_span, code) }

actual: Ty<'tcx>, ti: TopInfo<'tcx>, ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { <del> self.demand_eqtype_with_origin(&self.pattern_cause(ti, cause_span), expected, actual) </del> <ins> let mut diag = self.demand_eqtype_with_origin(&self.pattern_cause(ti, cause_span), expected, actual)?; if let Some(expr) = ti.origin_expr { self.suggest_fn_call(&mut diag, expr, expected, |output| { self.can_eq(self.param_env, output, actual).is_ok() }); } Some(diag) </ins> } fn demand_eqtype_pat(

pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, span: Option<Span>, <del> origin_expr: bool, </del> <ins> origin_expr: Option<&'tcx hir::Expr<'tcx>>, </ins> ) { let info = TopInfo { expected, origin_expr, span }; self.check_pat(pat, expected, INITIAL_BM, info);

err.help("the semantics of slice patterns changed recently; see issue #62254"); } else if self.autoderef(span, expected_ty) .any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..))) <del> && let (Some(span), true) = (ti.span, ti.origin_expr) </del> <ins> && let Some(span) = ti.span && let Some(_) = ti.origin_expr </ins> && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { let ty = self.resolve_vars_if_possible(ti.expected);

<ins> enum E { One(i32, i32), } fn main() { let var = E::One; if let E::One(var1, var2) = var { //~^ ERROR mismatched types //~| HELP use parentheses to construct this tuple variant println!("{var1} {var2}"); } let Some(x) = Some; //~^ ERROR mismatched types //~| HELP use parentheses to construct this tuple variant } </ins>

<ins> error[E0308]: mismatched types --> $DIR/suggest-call-on-pat-mismatch.rs:7:12 | LL |     if let E::One(var1, var2) = var { |            ^^^^^^^^^^^^^^^^^^   --- this expression has type `fn(i32, i32) -> E {E::One}` |            | |            expected enum constructor, found `E` | = note: expected enum constructor `fn(i32, i32) -> E {E::One}` found enum `E` help: use parentheses to construct this tuple variant | LL |     if let E::One(var1, var2) = var(/* i32 */, /* i32 */) { |                                    ++++++++++++++++++++++ error[E0308]: mismatched types --> $DIR/suggest-call-on-pat-mismatch.rs:13:9 | LL |     let Some(x) = Some; |         ^^^^^^^   ---- this expression has type `fn(_) -> Option<_> {Option::<_>::Some}` |         | |         expected enum constructor, found `Option<_>` | = note: expected enum constructor `fn(_) -> Option<_> {Option::<_>::Some}` found enum `Option<_>` help: use parentheses to construct this tuple variant | LL |     let Some(x) = Some(/* value */); |                       +++++++++++++ error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. </ins>