Rollup merge of #152661 - BartSimpson001:fix-next-solver-from-ice, r=petrochenkov

Avoid ICE in From/TryFrom diagnostic under -Znext-solver

Fixes rust-lang/rust#152518.

Under `-Znext-solver=globally`, `trait_ref.args` may contain fewer
elements than expected. The diagnostic logic in
`fulfillment_errors.rs` assumed at least two elements and
unconditionally called `type_at(1)`, which could lead to an
index out-of-bounds panic during error reporting.

This change adds a defensive check before accessing the second
argument to avoid the ICE. A UI regression test has been added.
This commit is contained in:
Stuart Cook 2026-02-17 13:02:22 +11:00 committed by GitHub
commit 572b53fdaf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 51 additions and 13 deletions

View file

@ -282,23 +282,31 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
if self.tcx.is_diagnostic_item(sym::From, trait_def_id)
|| self.tcx.is_diagnostic_item(sym::TryFrom, trait_def_id)
{
let found_ty = leaf_trait_predicate.skip_binder().trait_ref.args.type_at(1);
let ty = main_trait_predicate.skip_binder().self_ty();
if let Some(cast_ty) = self.find_explicit_cast_type(
obligation.param_env,
found_ty,
ty,
) {
let found_ty_str = self.tcx.short_string(found_ty, &mut long_ty_file);
let cast_ty_str = self.tcx.short_string(cast_ty, &mut long_ty_file);
err.help(
format!(
let trait_ref = leaf_trait_predicate.skip_binder().trait_ref;
// Defensive: next-solver may produce fewer args than expected.
if trait_ref.args.len() > 1 {
let found_ty = trait_ref.args.type_at(1);
let ty = main_trait_predicate.skip_binder().self_ty();
if let Some(cast_ty) = self.find_explicit_cast_type(
obligation.param_env,
found_ty,
ty,
) {
let found_ty_str =
self.tcx.short_string(found_ty, &mut long_ty_file);
let cast_ty_str =
self.tcx.short_string(cast_ty, &mut long_ty_file);
err.help(format!(
"consider casting the `{found_ty_str}` value to `{cast_ty_str}`",
),
);
));
}
}
}
*err.long_ty_path() = long_ty_file;
let mut suggested = false;