Skip to content

Move checking placeholder types in return types to typeck#153243

Open
Zoxc wants to merge 3 commits intorust-lang:mainfrom
Zoxc:fn-sig-placeholder-move
Open

Move checking placeholder types in return types to typeck#153243
Zoxc wants to merge 3 commits intorust-lang:mainfrom
Zoxc:fn-sig-placeholder-move

Conversation

@Zoxc
Copy link
Contributor

@Zoxc Zoxc commented Mar 1, 2026

This moves checking placeholder types in return types from the fn_sig query to typeck. typeck computes the return value of the body which is used for error suggestions. This is done to prevent a query cycle between fn_sig and typeck.

Currently fn_sig is marked with cycle_delay_bug to deal with this cycle, but I'm not sure if it's sufficient as we need the query we resume to have a Value impl, which may not be fn_sig.

Functions such as fn foo() -> _ will now return as fn foo() -> <error> from fn_sig instead of using the return type of their bodies. This can hide some later errors, but that seems like a minor downside.

This is also a step towards removing query cycle recovery.

@rustbot
Copy link
Collaborator

rustbot commented Mar 1, 2026

HIR ty lowering was modified

cc @fmease

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Mar 1, 2026
@rustbot
Copy link
Collaborator

rustbot commented Mar 1, 2026

r? @dingxiangfei2009

rustbot has assigned @dingxiangfei2009.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 69 candidates
  • Random selection from 15 candidates


#[instrument(level = "debug", skip(tcx), ret)]
fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFnSig<'_>> {
/// We'll emit an error about the suggestable infer ty in `typeck` query if this is true.
Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry, what is true here by this?


_ => None,
};
sig.and_then(|sig| sig.decl.output.is_suggestable_infer_ty())
Copy link
Contributor

@dingxiangfei2009 dingxiangfei2009 Mar 1, 2026

Choose a reason for hiding this comment

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

Looks like we care only about if suggestable infer type exists downstream. Would you like to switch it to return just a boolean? Or do you have a plan for this function?

Nevermind, I did not search hard enough.

@dingxiangfei2009
Copy link
Contributor

dingxiangfei2009 commented Mar 1, 2026

Thank you for contribution! 🙇

@bors r+ rollup=always

@rust-bors
Copy link
Contributor

rust-bors bot commented Mar 1, 2026

📌 Commit 8ddc609 has been approved by dingxiangfei2009

It is now in the queue for this repository.

@rust-bors rust-bors bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 1, 2026
@fmease
Copy link
Member

fmease commented Mar 1, 2026

Currently fn_sig is marked with cycle_delay_bug to deal with this cycle, but I'm not sure if it's sufficient as we need the query we resume to have a Value impl, which may not be fn_sig.

I'm struggling to understand why you didn't remove cycle_delay_bug from query fn_sig then (plus the Value impl for PolyFnSig)? Is some other place still relying on fn_sig delaying cycle errors as bugs?

tcx: TyCtxt<'tcx>,
item_def_id: LocalDefId,
tainted_by_errors: Cell<Option<ErrorGuaranteed>>,
suppress_placeholder_errors: Cell<bool>,
Copy link
Member

@fmease fmease Mar 1, 2026

Choose a reason for hiding this comment

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

To be frank, I'm not super stoked about adding a hyper-specific field to ItemCtxt plus an "anonymous" Boolean parameter to various functions. This solution feels blunt(?) and slightly hacky.

I haven't had the time to think about alternative solutions yet if there are any. I believe it should be possible to localize this code a lot more even if that meant ~reverting parts of PR #125819 (before which this recovery was 'more local' IIRC).

(personally speaking I'm generally unhappy about this super invasive & complex recovery logic for an 'incredibly niche' user error; it's already caused me headaches in the past)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We could possibly split out placeholder errors into a separate HIR visitor, then just skip visiting return types as appropriate.

Copy link
Contributor

Choose a reason for hiding this comment

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

(personally speaking I'm generally unhappy about this super invasive & complex recovery logic for an 'incredibly niche' user error; it's already caused me headaches in the past)

I think we occasionally go too far in our quest for high quality error messages. If an obscure error message is causing problems for perf or code complexity I think removing it is totally reasonable.

Just to clarify: which user error is the incredibly niche one?

Copy link
Member

@fmease fmease Mar 3, 2026

Choose a reason for hiding this comment

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

Just to clarify: which user error is the incredibly niche one?

So I don't know how often beginner or average users encounter this error or how helpful they find the suggestion, I'm talking about code like const C = 1; (no type annotation), static S: _ = 1; (_ in item signatures), fn f() -> _ { 0 } but also static A: [&str; _] = [];.

I get that they can be quite useful, so maybe I've exaggerated. Still, personally speaking I just never use _ like this to obtain the right type from the compiler, so I'm a bit biased.

It's just that I know the implementation is quite unwieldy and hairy. Most crucially calling typeck instead of type_of on items that usually mandate a type signature is prone to query cycles (e.g, I most recently had to fight them in RUST-143029) which can be quite hindering when developing new features.

@fmease
Copy link
Member

fmease commented Mar 1, 2026

Sorry, I'm gonna unapprove this for now due to #153243 (comment) (question) and #153243 (comment) (semi-actionable concern)

@bors r-

@rust-bors rust-bors bot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Mar 1, 2026
@fmease fmease self-assigned this Mar 1, 2026
@Zoxc
Copy link
Contributor Author

Zoxc commented Mar 2, 2026

I'm struggling to understand why you didn't remove cycle_delay_bug from query fn_sig then (plus the Value impl for PolyFnSig)? Is some other place still relying on fn_sig delaying cycle errors as bugs?

It unhides unrelated cycle errors, so I kept it out here to keep the PR smaller.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants