Change:
Source code:
Please provide the source code needed to reproduce this (or preferably a reduced version of that)
Sourced code provided at the end of the document. I'm willing to provide more info if needed.
Reconstructed from first principles:
The problem occurs here:
triage: has PR. P-high, removing nomination.

Discussion:
} } <del> pub fn demand_eqtype_pat( </del> <ins> pub fn demand_eqtype_pat_diag( </ins> &self, cause_span: Span, expected: Ty<'tcx>, actual: Ty<'tcx>, match_expr_span: Option<Span>, <del> ) { </del> <ins> ) -> Option<DiagnosticBuilder<'tcx>> { </ins> let cause = if let Some(span) = match_expr_span { self.cause( cause_span,

} else { self.misc(cause_span) }; <del> self.demand_eqtype_with_origin(&cause, expected, actual).map(|mut err| err.emit()); </del> <ins> self.demand_eqtype_with_origin(&cause, expected, actual) </ins> } <ins> pub fn demand_eqtype_pat( &self, cause_span: Span, expected: Ty<'tcx>, actual: Ty<'tcx>, match_expr_span: Option<Span>, ) { self.demand_eqtype_pat_diag(cause_span, expected, actual, match_expr_span) .map(|mut err| err.emit()); } </ins> pub fn demand_coerce(&self, expr: &hir::Expr,

let pat_ty = pat_ty.fn_sig(tcx).output(); let pat_ty = pat_ty.no_bound_vars().expect("expected fn type"); <del> self.demand_eqtype_pat(pat.span, expected, pat_ty, match_arm_pat_span); </del> <ins> // Type-check the tuple struct pattern against the expected type. let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, match_arm_pat_span); let had_err = diag.is_some(); diag.map(|mut err| err.emit()); </ins> // Type-check subpatterns. if subpats.len() == variant.fields.len()

} } else { // Pattern has wrong number of fields. <del> self.e0023(pat.span, res, qpath, subpats, &variant.fields, expected); </del> <ins> self.e0023(pat.span, res, qpath, subpats, &variant.fields, expected, had_err); </ins> on_error(); return tcx.types.err; }

res: Res, qpath: &hir::QPath, subpats: &'tcx [P<Pat>], <del> fields: &[ty::FieldDef], expected: Ty<'tcx> </del> <ins> fields: &'tcx [ty::FieldDef], expected: Ty<'tcx>, had_err: bool, </ins> ) { let subpats_ending = pluralize!(subpats.len()); let fields_ending = pluralize!(fields.len());

// More generally, the expected type wants a tuple variant with one field of an // N-arity-tuple, e.g., `V_i((p_0, .., p_N))`. Meanwhile, the user supplied a pattern // with the subpatterns directly in the tuple variant pattern, e.g., `V_i(p_0, .., p_N)`. <del> let missing_parenthesis = match expected.kind { ty::Adt(_, substs) if fields.len() == 1 => { let field_ty = fields[0].ty(self.tcx, substs); </del> <ins> let missing_parenthesis = match (&expected.kind, fields, had_err) { // #67037: only do this if we could sucessfully type-check the expected type against // the tuple struct pattern. Otherwise the substs could get out of range on e.g., // `let P() = U;` where `P != U` with `struct P<T>(T);`. (ty::Adt(_, substs), [field], false) => { let field_ty = self.field_ty(pat_span, field, substs); </ins> match field_ty.kind { ty::Tuple(_) => field_ty.tuple_fields().count() == subpats.len(), _ => false,

<ins> // Regression test for #67037. // // In type checking patterns, E0023 occurs when the tuple pattern and the expected // tuple pattern have different number of fields. For example, as below, `P()`, // the tuple struct pattern, has 0 fields, but requires 1 field. // // In emitting E0023, we try to see if this is a case of e.g., `Some(a, b, c)` but where // the scrutinee was of type `Some((a, b, c))`, and suggest that parenthesis be added. // // However, we did not account for the expected type being different than the tuple pattern type. // This caused an issue when the tuple pattern type (`P<T>`) was generic. // Specifically, we tried deriving the 0th field's type using the `substs` of the expected type. // When attempting to substitute `T`, there was no such substitution, so "out of range" occured. struct U {} // 0 type parameters offered struct P<T>(T); // 1 type parameter wanted fn main() { let P() = U {}; //~ ERROR mismatched types //~^ ERROR this pattern has 0 fields, but the corresponding tuple struct has 1 field } </ins>

<ins> error[E0308]: mismatched types --> $DIR/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs:19:9 | LL |     let P() = U {}; |         ^^^ expected struct `U`, found struct `P` | = note: expected struct `U` found struct `P<_>` error[E0023]: this pattern has 0 fields, but the corresponding tuple struct has 1 field --> $DIR/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs:19:9 | LL | struct P<T>(T); // 1 type parameter wanted | --------------- tuple struct defined here ... LL |     let P() = U {}; |         ^^^ expected 1 field, found 0 error: aborting due to 2 previous errors Some errors have detailed explanations: E0023, E0308. For more information about an error, try `rustc --explain E0023`. </ins>