diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index d9c6d339328aa..d0dabd9824764 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -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; diff --git a/tests/ui/traits/next-solver-ice.rs b/tests/ui/traits/next-solver-ice.rs new file mode 100644 index 0000000000000..889d1094a1030 --- /dev/null +++ b/tests/ui/traits/next-solver-ice.rs @@ -0,0 +1,9 @@ +//@compile-flags: -Znext-solver=globally +//@check-fail + +fn check() { + ::Item>>::from; + //~^ ERROR the trait bound `f32: From<::Item>` is not satisfied +} + +fn main() {} diff --git a/tests/ui/traits/next-solver-ice.stderr b/tests/ui/traits/next-solver-ice.stderr new file mode 100644 index 0000000000000..d6b022d70175b --- /dev/null +++ b/tests/ui/traits/next-solver-ice.stderr @@ -0,0 +1,21 @@ +error[E0277]: the trait bound `f32: From<::Item>` is not satisfied + --> $DIR/next-solver-ice.rs:5:6 + | +LL | ::Item>>::from; + | ^^^ the nightly-only, unstable trait `ZeroablePrimitive` is not implemented for `f32` + | + = help: the following other types implement trait `ZeroablePrimitive`: + i128 + i16 + i32 + i64 + i8 + isize + u128 + u16 + and 4 others + = note: required for `f32` to implement `From<::Item>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`.