Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to have a test case for this change.
I think the current UI test only checks the struct case.

It's slightly odd that the method impl doesn't have a fn_sig, are you sure about that?
(This is a genuine question, because I don't know for sure.)

@im-lunex im-lunex Aug 8, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the def_id points to the clause owner (like an impl/struct) not the callee. tcx.fn_sig panics on those, and is_fn_like() doesnt work either since closures break fn_sig too since the diagnostic needs fn_sig to map params to args, guarding and skipping non-callables was the way out.

&& matches!(
self.tcx.def_kind(*def_id),
DefKind::AssocFn | DefKind::Fn | DefKind::Ctor(_, CtorKind::Fn)
)
&& let Some(pred) = self
.tcx
.clauses_of(*def_id)
Expand Down
14 changes: 14 additions & 0 deletions tests/ui/structs/ice-missing-field-fn-sig.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// A struct literal that's missing fields shouldn't ICE when checking the fn sig.

trait Context {}
struct Wrapper<C: Context + 'static> {
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() {}
61 changes: 61 additions & 0 deletions tests/ui/structs/ice-missing-field-fn-sig.stderr
Original file line number Diff line number Diff line change
@@ -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<C: Context + 'static> {
| ^^^^^^^ 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<C: Context + 'static> {
| ^^^^^^^ 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<C: Context + 'static> {
| ^^^^^^^ 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`.
Loading