Change:
or The current error message does not tell me the mismatch is in rather than in . It is also inconsistent with the error message I would get if has without the default types. When removing the default for the first parameter (which is not the mismatched one) like this: the error message is clearer: <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim

Discussion:
(&ty::Adt(def1, sub1), &ty::Adt(def2, sub2)) => { let did1 = def1.did(); let did2 = def2.did(); <del> let sub_no_defaults_1 = self.tcx.generics_of(did1).own_args_no_defaults(self.tcx, sub1); let sub_no_defaults_2 = self.tcx.generics_of(did2).own_args_no_defaults(self.tcx, sub2); </del> <ins> let generics1 = self.tcx.generics_of(did1); let generics2 = self.tcx.generics_of(did2); let non_default_after_default = generics1 .check_concrete_type_after_default(self.tcx, sub1) || generics2.check_concrete_type_after_default(self.tcx, sub2); let sub_no_defaults_1 = if non_default_after_default { generics1.own_args(sub1) } else { generics1.own_args_no_defaults(self.tcx, sub1) }; let sub_no_defaults_2 = if non_default_after_default { generics2.own_args(sub2) } else { generics2.own_args_no_defaults(self.tcx, sub2) }; </ins> let mut values = (DiagStyledString::new(), DiagStyledString::new()); let path1 = self.tcx.def_path_str(did1); let path2 = self.tcx.def_path_str(did2);

let own = &args[self.parent_count..][..self.params.len()]; if self.has_self && self.parent.is_none() { &own[1..] } else { own } } <ins> /// Returns true if a concrete type is specified after a default type. /// For example, consider `struct T<W = usize, X = Vec<W>>(W, X)` /// `T<usize, String>` will return true /// `T<usize>` will return false pub fn check_concrete_type_after_default( &'tcx self, tcx: TyCtxt<'tcx>, args: &'tcx [ty::GenericArg<'tcx>], ) -> bool { let mut default_param_seen = false; for param in self.params.iter() { if let Some(inst) = param.default_value(tcx).map(|default| default.instantiate(tcx, args)) { if inst == args[param.index as usize] { default_param_seen = true; } else if default_param_seen { return true; } } } false } </ins> } /// Bounds on generics.

<ins> struct What<W = usize, X = Vec<W>>(W, X); fn main() { let mut b: What<usize> = What(5, vec![1, 2, 3]); let c: What<usize, String> = What(1, String::from("meow")); b = c; //~ ERROR mismatched types let mut f: What<usize, Vec<String>> = What(1, vec![String::from("meow")]); let e: What<usize> = What(5, vec![1, 2, 3]); f = e; //~ ERROR mismatched types } </ins>

<ins> error[E0308]: mismatched types --> $DIR/clarify-error-for-generics-with-default-issue-120785.rs:6:9 | LL |     let mut b: What<usize> = What(5, vec![1, 2, 3]); |                ----------- expected due to this type LL |     let c: What<usize, String> = What(1, String::from("meow")); LL |     b = c; |         ^ expected `What`, found `What<usize, String>` | = note: expected struct `What<_, Vec<usize>>` found struct `What<_, String>` error[E0308]: mismatched types --> $DIR/clarify-error-for-generics-with-default-issue-120785.rs:10:9 | LL |     let mut f: What<usize, Vec<String>> = What(1, vec![String::from("meow")]); |                ------------------------ expected due to this type LL |     let e: What<usize> = What(5, vec![1, 2, 3]); LL |     f = e; |         ^ expected `What<usize, Vec<String>>`, found `What` | = note: expected struct `What<_, Vec<String>>` found struct `What<_, Vec<usize>>` error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. </ins>