Change:
It's underlining the wrong argument. No response No response
I'm getting an entirely different and much more helpful error:
Are you sure you minimized the code correctly? Not sure how to repro the example you shared,
Arf, sorry about that... Also important to note, I'm using: I pushed the code with this issue . However it requires a mac to enter this code. Just running is enough to trigger it.
This should be re-minimized by someone who has a Mac then. label +E-needs-mcve
Minimization: Note that: in all cases (including when I ran the original code), there is now a more sensible type error, and the unsized local error is not actually pointing at the wrong thing, it's talking about the type of the part of the tuple unrelated to the if/else type mismatch. It seems like the type mismatch is causing the compiler to fail to properly perform the deref coercion of the , even though it's not the part of the tuple that has the type mismatch. Tested on versions:
label -E-needs-mcve

Discussion:
#[inline] pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) { debug!("write_ty({:?}, {:?}) in fcx {}", id, self.resolve_vars_if_possible(ty), self.tag()); <del> self.typeck_results.borrow_mut().node_types_mut().insert(id, ty); </del> <ins> let mut typeck = self.typeck_results.borrow_mut(); let mut node_ty = typeck.node_types_mut(); if let Some(ty) = node_ty.get(id) && let Err(e) = ty.error_reported() { // Do not overwrite nodes that were already marked as `{type error}`. This allows us to // silence unnecessary errors from obligations that were set earlier than a type error // was produced, but that is overwritten by later analysis. This happens in particular // for `Sized` obligations introduced in gather_locals. (#117846) self.set_tainted_by_errors(e); return; } node_ty.insert(id, ty); </ins> if let Err(e) = ty.error_reported() { self.set_tainted_by_errors(e);

pat: &'tcx hir::Pat<'tcx>, ty: Ty<'tcx>, ) { <ins> struct V<'tcx> { tcx: TyCtxt<'tcx>, pat_hir_ids: Vec<hir::HirId>, } impl<'tcx> Visitor<'tcx> for V<'tcx> { type NestedFilter = rustc_middle::hir::nested_filter::All; fn nested_visit_map(&mut self) -> Self::Map { self.tcx.hir() } fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) { self.pat_hir_ids.push(p.hir_id); hir::intravisit::walk_pat(self, p); } } </ins> if let Err(guar) = ty.error_reported() { // Override the types everywhere with `err()` to avoid knock on errors. let err = Ty::new_error(self.tcx, guar); self.write_ty(hir_id, err); self.write_ty(pat.hir_id, err); <ins> let mut visitor = V { tcx: self.tcx, pat_hir_ids: vec![] }; hir::intravisit::walk_pat(&mut visitor, pat); // Mark all the subpatterns as `{type error}` as well. This allows errors for specific // subpatterns to be silenced. for hir_id in visitor.pat_hir_ids { self.write_ty(hir_id, err); } </ins> self.locals.borrow_mut().insert(hir_id, err); self.locals.borrow_mut().insert(pat.hir_id, err); }

self.data.get_mut(&id.local_id) } <ins> pub fn get(&mut self, id: hir::HirId) -> Option<&V> { validate_hir_id_for_typeck_results(self.hir_owner, id); self.data.get(&id.local_id) } </ins> pub fn entry(&mut self, id: hir::HirId) -> Entry<'_, hir::ItemLocalId, V> { validate_hir_id_for_typeck_results(self.hir_owner, id); self.data.entry(id.local_id)

} } ObligationCauseCode::VariableType(hir_id) => { <ins> if let Some(typeck_results) = &self.typeck_results && let Some(ty) = typeck_results.node_type_opt(hir_id) && let ty::Error(_) = ty.kind() { err.note(format!( "`{predicate}` isn't satisfied, but the type of this pattern is  `{{type error}}`", )); err.downgrade_to_delayed_bug(); } </ins> match tcx.parent_hir_node(hir_id) { Node::Local(hir::Local { ty: Some(ty), .. }) => { err.span_suggestion_verbose(

<ins> #![allow(warnings)] fn issue_117846_repro() { let (a, _) = if true { produce() } else { (Vec::new(), &[]) //~ ERROR E0308 }; accept(&a); } struct Foo; struct Bar; fn produce() -> (Vec<Foo>, &'static [Bar]) { todo!() } fn accept(c: &[Foo]) {} fn main() {} </ins>

<ins> error[E0308]: `if` and `else` have incompatible types --> $DIR/expr-type-error-plus-sized-obligation.rs:7:9 | LL |       let (a, _) = if true { |  __________________- LL | |         produce() | |         --------- expected because of this LL | |     } else { LL | |         (Vec::new(), &[]) | |         ^^^^^^^^^^^^^^^^^ expected `(Vec<Foo>, &[Bar])`, found `(Vec<_>, &[_; 0])` LL | |     }; | |_____- `if` and `else` have incompatible types | = note: expected tuple `(Vec<Foo>, &[Bar])` found tuple `(Vec<_>, &[_; 0])` error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0308`. </ins>