From 0d75b8c356f894d5b134226c309a3df254eff977 Mon Sep 17 00:00:00 2001 From: im-lunex Date: Thu, 6 Aug 2026 16:21:16 +0600 Subject: [PATCH] fix ICE in `suggest_add_reference_to_arg` for non-callable items --- .../src/error_reporting/traits/suggestions.rs | 13 +++- tests/ui/structs/ice-missing-field-fn-sig.rs | 14 +++++ .../structs/ice-missing-field-fn-sig.stderr | 61 +++++++++++++++++++ 3 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 tests/ui/structs/ice-missing-field-fn-sig.rs create mode 100644 tests/ui/structs/ice-missing-field-fn-sig.stderr diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 2a6e2a539c964..633b23a1f28ca 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -13,7 +13,7 @@ use rustc_errors::{ Applicability, Diag, EmissionGuarantee, MultiSpan, Style, SuggestionStyle, pluralize, struct_span_code_err, }; -use rustc_hir::def::{CtorOf, DefKind, Res}; +use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{Visitor, VisitorExt}; use rustc_hir::lang_items::LangItem; @@ -1764,7 +1764,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // If we didn't return early here, we would instead suggest `&&str::from("")`. return false; } else if let hir::ExprKind::Call(_, args) = expr.kind { - if let Some(pred) = self + // The `def_id` can point at a struct, which has no fn sig. + if matches!( + self.tcx.def_kind(*def_id), + DefKind::AssocFn | DefKind::Fn | DefKind::Ctor(_, CtorKind::Fn) + ) && let Some(pred) = self .tcx .clauses_of(*def_id) .instantiate_identity(self.tcx) @@ -1799,6 +1803,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { c @ ObligationCauseCode::WhereClauseInExpr(def_id, _, hir_id, idx) if let hir::Node::Expr(expr) = self.tcx.hir_node(*hir_id) && let hir::ExprKind::MethodCall(_segment, rcvr, args, ..) = expr.kind + // The `def_id` can also point at the impl, which has no fn sig. + && matches!( + self.tcx.def_kind(*def_id), + DefKind::AssocFn | DefKind::Fn | DefKind::Ctor(_, CtorKind::Fn) + ) && let Some(pred) = self .tcx .clauses_of(*def_id) diff --git a/tests/ui/structs/ice-missing-field-fn-sig.rs b/tests/ui/structs/ice-missing-field-fn-sig.rs new file mode 100644 index 0000000000000..9ba48f6a6e795 --- /dev/null +++ b/tests/ui/structs/ice-missing-field-fn-sig.rs @@ -0,0 +1,14 @@ +// A struct literal that's missing fields shouldn't ICE when checking the fn sig. + +trait Context {} +struct Wrapper { + container: &'static C, +} +fn foobar(_: Wrapper<()>) { //~ ERROR the trait bound `(): Context` is not satisfied + foobar(Wrapper { /* missing */ }) +//~^ ERROR the trait bound `(): Context` is not satisfied +//~^^ ERROR missing field `container` in initializer of `Wrapper<_>` +//~^^^ ERROR the trait bound `(): Context` is not satisfied +} + +fn main() {} diff --git a/tests/ui/structs/ice-missing-field-fn-sig.stderr b/tests/ui/structs/ice-missing-field-fn-sig.stderr new file mode 100644 index 0000000000000..7be7886b2d975 --- /dev/null +++ b/tests/ui/structs/ice-missing-field-fn-sig.stderr @@ -0,0 +1,61 @@ +error[E0277]: the trait bound `(): Context` is not satisfied + --> $DIR/ice-missing-field-fn-sig.rs:7:14 + | +LL | fn foobar(_: Wrapper<()>) { + | ^^^^^^^^^^^ the trait `Context` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/ice-missing-field-fn-sig.rs:3:1 + | +LL | trait Context {} + | ^^^^^^^^^^^^^ +note: required by a bound in `Wrapper` + --> $DIR/ice-missing-field-fn-sig.rs:4:19 + | +LL | struct Wrapper { + | ^^^^^^^ required by this bound in `Wrapper` + +error[E0277]: the trait bound `(): Context` is not satisfied + --> $DIR/ice-missing-field-fn-sig.rs:8:12 + | +LL | foobar(Wrapper { /* missing */ }) + | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Context` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/ice-missing-field-fn-sig.rs:3:1 + | +LL | trait Context {} + | ^^^^^^^^^^^^^ +note: required by a bound in `Wrapper` + --> $DIR/ice-missing-field-fn-sig.rs:4:19 + | +LL | struct Wrapper { + | ^^^^^^^ required by this bound in `Wrapper` + +error[E0063]: missing field `container` in initializer of `Wrapper<_>` + --> $DIR/ice-missing-field-fn-sig.rs:8:12 + | +LL | foobar(Wrapper { /* missing */ }) + | ^^^^^^^ missing `container` + +error[E0277]: the trait bound `(): Context` is not satisfied + --> $DIR/ice-missing-field-fn-sig.rs:8:12 + | +LL | foobar(Wrapper { /* missing */ }) + | ^^^^^^^ the trait `Context` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/ice-missing-field-fn-sig.rs:3:1 + | +LL | trait Context {} + | ^^^^^^^^^^^^^ +note: required by a bound in `Wrapper` + --> $DIR/ice-missing-field-fn-sig.rs:4:19 + | +LL | struct Wrapper { + | ^^^^^^^ required by this bound in `Wrapper` + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0063, E0277. +For more information about an error, try `rustc --explain E0063`.