Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 838255b

Browse files
authoredMar 4, 2025
Rollup merge of rust-lang#137303 - compiler-errors:maybe-forgor, r=cjgillot
Remove `MaybeForgetReturn` suggestion rust-lang#115196 implemented a suggestion to add a missing `return` when there is an ambiguity error, when that ambiguity error could be constrained by the return type of the function. I initially reviewed it and thought it could be useful; however, looking back at that code now, I feel like it's a bit too much of a hack to be worth keeping around in typeck, especially given how rare it's expected to fire in practice. This is especially true because it depends on `StashKey::MaybeForgetReturn`, which is only stashed when we have *Sized* obligation ambiguity errors. Let's remove it for now. I'd like to note that it's basically impossible to get this suggestion to apply in its current state except for what I'd consider somewhat artificial examples, involving no generic trait bounds. For example, it's not triggered for: ```rust struct W<T>(T); fn bar<T: Default>() -> W<T> { todo!() } fn foo() -> W<i32> { if true { bar(); } W(0) } ``` Nor is it triggered for: ``` fn foo() -> i32 { if true { Default::default(); } 0 } ``` It's basically only triggered iff there's only one ambiguity error on the type, which is `Sized`. Generally, suggesting something that affects control flow is a pretty dramatic suggestion; therefore, both the accuracy and precision of this diagnostic should be pretty high. One other, somewhat unrelated observation is that this might be using stashed diagnostics incorrectly (or at least unnecessarily). Stashed diagnostics are used when error detection is fragmented over several major stages of the compiler, like a parse or resolver error which later can be recovered in typeck. However, this one is a bit different since it is fully handled within typeck -- perhaps that suggests that if this were to be reimplemented, it wouldn't need to be so complicated of an implementation.
2 parents a4d9b0e + 9323ba5 commit 838255b

File tree

7 files changed

+4
-83
lines changed

7 files changed

+4
-83
lines changed
 

‎compiler/rustc_errors/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,6 @@ pub enum StashKey {
626626
MaybeFruTypo,
627627
CallAssocMethod,
628628
AssociatedTypeSuggestion,
629-
MaybeForgetReturn,
630629
/// Query cycle detected, stashing in favor of a better error.
631630
Cycle,
632631
UndeterminedMacroResolution,

‎compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

-5
Original file line numberDiff line numberDiff line change
@@ -669,12 +669,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
669669

670670
if !errors.is_empty() {
671671
self.adjust_fulfillment_errors_for_expr_obligation(&mut errors);
672-
let errors_causecode = errors
673-
.iter()
674-
.map(|e| (e.obligation.cause.span, e.root_obligation.cause.code().clone()))
675-
.collect::<Vec<_>>();
676672
self.err_ctxt().report_fulfillment_errors(errors);
677-
self.collect_unused_stmts_for_coerce_return_ty(errors_causecode);
678673
}
679674
}
680675

‎compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+1-59
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ use std::{fmt, iter, mem};
33
use itertools::Itertools;
44
use rustc_data_structures::fx::FxIndexSet;
55
use rustc_errors::codes::*;
6-
use rustc_errors::{
7-
Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey, a_or_an, listify, pluralize,
8-
};
6+
use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan, a_or_an, listify, pluralize};
97
use rustc_hir::def::{CtorOf, DefKind, Res};
108
use rustc_hir::def_id::DefId;
119
use rustc_hir::intravisit::Visitor;
@@ -2193,62 +2191,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21932191
}
21942192
}
21952193

2196-
pub(super) fn collect_unused_stmts_for_coerce_return_ty(
2197-
&self,
2198-
errors_causecode: Vec<(Span, ObligationCauseCode<'tcx>)>,
2199-
) {
2200-
for (span, code) in errors_causecode {
2201-
self.dcx().try_steal_modify_and_emit_err(span, StashKey::MaybeForgetReturn, |err| {
2202-
if let Some(fn_sig) = self.body_fn_sig()
2203-
&& let ObligationCauseCode::WhereClauseInExpr(_, _, binding_hir_id, ..) = code
2204-
&& !fn_sig.output().is_unit()
2205-
{
2206-
let mut block_num = 0;
2207-
let mut found_semi = false;
2208-
for (hir_id, node) in self.tcx.hir_parent_iter(binding_hir_id) {
2209-
// Don't proceed into parent bodies
2210-
if hir_id.owner != binding_hir_id.owner {
2211-
break;
2212-
}
2213-
match node {
2214-
hir::Node::Stmt(stmt) => {
2215-
if let hir::StmtKind::Semi(expr) = stmt.kind {
2216-
let expr_ty = self.typeck_results.borrow().expr_ty(expr);
2217-
let return_ty = fn_sig.output();
2218-
if !matches!(expr.kind, hir::ExprKind::Ret(..))
2219-
&& self.may_coerce(expr_ty, return_ty)
2220-
{
2221-
found_semi = true;
2222-
}
2223-
}
2224-
}
2225-
hir::Node::Block(_block) => {
2226-
if found_semi {
2227-
block_num += 1;
2228-
}
2229-
}
2230-
hir::Node::Item(item) => {
2231-
if let hir::ItemKind::Fn { .. } = item.kind {
2232-
break;
2233-
}
2234-
}
2235-
_ => {}
2236-
}
2237-
}
2238-
if block_num > 1 && found_semi {
2239-
err.span_suggestion_verbose(
2240-
// use the span of the *whole* expr
2241-
self.tcx.hir().span(binding_hir_id).shrink_to_lo(),
2242-
"you might have meant to return this to infer its type parameters",
2243-
"return ",
2244-
Applicability::MaybeIncorrect,
2245-
);
2246-
}
2247-
}
2248-
});
2249-
}
2250-
}
2251-
22522194
/// Given a vector of fulfillment errors, try to adjust the spans of the
22532195
/// errors to more accurately point at the cause of the failure.
22542196
///

‎compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
use std::ops::ControlFlow;
22

3-
use rustc_errors::{
4-
Applicability, Diag, E0283, E0284, E0790, MultiSpan, StashKey, struct_span_code_err,
5-
};
3+
use rustc_errors::{Applicability, Diag, E0283, E0284, E0790, MultiSpan, struct_span_code_err};
64
use rustc_hir as hir;
75
use rustc_hir::LangItem;
86
use rustc_hir::def::{DefKind, Res};
@@ -197,7 +195,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
197195
// be ignoring the fact that we don't KNOW the type works
198196
// out. Though even that would probably be harmless, given that
199197
// we're only talking about builtin traits, which are known to be
200-
// inhabited. We used to check for `self.tcx.sess.has_errors()` to
198+
// inhabited. We used to check for `self.tainted_by_errors()` to
201199
// avoid inundating the user with unnecessary errors, but we now
202200
// check upstream for type errors and don't add the obligations to
203201
// begin with in those cases.
@@ -211,7 +209,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
211209
TypeAnnotationNeeded::E0282,
212210
false,
213211
);
214-
return err.stash(span, StashKey::MaybeForgetReturn).unwrap();
212+
return err.emit();
215213
}
216214
Some(e) => return e,
217215
}

‎tests/ui/inference/issue-86094-suggest-add-return-to-coerce-ret-ty.stderr

-8
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@ help: consider specifying the generic arguments
88
|
99
LL | Err::<T, MyError>(MyError);
1010
| ++++++++++++++
11-
help: you might have meant to return this to infer its type parameters
12-
|
13-
LL | return Err(MyError);
14-
| ++++++
1511

1612
error[E0282]: type annotations needed
1713
--> $DIR/issue-86094-suggest-add-return-to-coerce-ret-ty.rs:14:9
@@ -23,10 +19,6 @@ help: consider specifying the generic arguments
2319
|
2420
LL | Ok::<(), E>(());
2521
| +++++++++
26-
help: you might have meant to return this to infer its type parameters
27-
|
28-
LL | return Ok(());
29-
| ++++++
3022

3123
error[E0308]: mismatched types
3224
--> $DIR/issue-86094-suggest-add-return-to-coerce-ret-ty.rs:21:20

‎tests/ui/return/tail-expr-as-potential-return.rs

-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ fn method() -> Option<i32> {
6060
Receiver.generic();
6161
//~^ ERROR type annotations needed
6262
//~| HELP consider specifying the generic argument
63-
//~| HELP you might have meant to return this to infer its type parameters
6463
}
6564

6665
None

‎tests/ui/return/tail-expr-as-potential-return.stderr

-4
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,6 @@ help: consider specifying the generic argument
5757
|
5858
LL | Receiver.generic::<T>();
5959
| +++++
60-
help: you might have meant to return this to infer its type parameters
61-
|
62-
LL | return Receiver.generic();
63-
| ++++++
6460

6561
error: aborting due to 4 previous errors
6662

0 commit comments

Comments
 (0)
Failed to load comments.