Skip to content

Commit 572b53f

Browse files
authored
Rollup merge of rust-lang#152661 - BartSimpson001:fix-next-solver-from-ice, r=petrochenkov
Avoid ICE in From/TryFrom diagnostic under -Znext-solver Fixes rust-lang#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.
2 parents 331a785 + b55673b commit 572b53f

3 files changed

Lines changed: 51 additions & 13 deletions

File tree

compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -282,23 +282,31 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
282282
if self.tcx.is_diagnostic_item(sym::From, trait_def_id)
283283
|| self.tcx.is_diagnostic_item(sym::TryFrom, trait_def_id)
284284
{
285-
let found_ty = leaf_trait_predicate.skip_binder().trait_ref.args.type_at(1);
286-
let ty = main_trait_predicate.skip_binder().self_ty();
287-
if let Some(cast_ty) = self.find_explicit_cast_type(
288-
obligation.param_env,
289-
found_ty,
290-
ty,
291-
) {
292-
let found_ty_str = self.tcx.short_string(found_ty, &mut long_ty_file);
293-
let cast_ty_str = self.tcx.short_string(cast_ty, &mut long_ty_file);
294-
err.help(
295-
format!(
285+
let trait_ref = leaf_trait_predicate.skip_binder().trait_ref;
286+
287+
// Defensive: next-solver may produce fewer args than expected.
288+
if trait_ref.args.len() > 1 {
289+
let found_ty = trait_ref.args.type_at(1);
290+
let ty = main_trait_predicate.skip_binder().self_ty();
291+
292+
if let Some(cast_ty) = self.find_explicit_cast_type(
293+
obligation.param_env,
294+
found_ty,
295+
ty,
296+
) {
297+
let found_ty_str =
298+
self.tcx.short_string(found_ty, &mut long_ty_file);
299+
let cast_ty_str =
300+
self.tcx.short_string(cast_ty, &mut long_ty_file);
301+
302+
err.help(format!(
296303
"consider casting the `{found_ty_str}` value to `{cast_ty_str}`",
297-
),
298-
);
304+
));
305+
}
299306
}
300307
}
301308

309+
302310
*err.long_ty_path() = long_ty_file;
303311

304312
let mut suggested = false;

tests/ui/traits/next-solver-ice.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//@compile-flags: -Znext-solver=globally
2+
//@check-fail
3+
4+
fn check<T: Iterator>() {
5+
<f32 as From<<T as Iterator>::Item>>::from;
6+
//~^ ERROR the trait bound `f32: From<<T as Iterator>::Item>` is not satisfied
7+
}
8+
9+
fn main() {}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0277]: the trait bound `f32: From<<T as Iterator>::Item>` is not satisfied
2+
--> $DIR/next-solver-ice.rs:5:6
3+
|
4+
LL | <f32 as From<<T as Iterator>::Item>>::from;
5+
| ^^^ the nightly-only, unstable trait `ZeroablePrimitive` is not implemented for `f32`
6+
|
7+
= help: the following other types implement trait `ZeroablePrimitive`:
8+
i128
9+
i16
10+
i32
11+
i64
12+
i8
13+
isize
14+
u128
15+
u16
16+
and 4 others
17+
= note: required for `f32` to implement `From<<T as Iterator>::Item>`
18+
19+
error: aborting due to 1 previous error
20+
21+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)