Skip to content

Commit 3267e06

Browse files
estebankVardhan Thigle
authored andcommitted
Avoid pointing at multiple places on return type error
1 parent 12c25ed commit 3267e06

File tree

4 files changed

+23
-19
lines changed

4 files changed

+23
-19
lines changed

src/librustc_typeck/check/coercion.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,7 +1216,7 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
12161216
"supposed to be part of a block tail expression, but the \
12171217
expression is empty");
12181218
});
1219-
fcx.suggest_mismatched_types_on_tail(
1219+
let pointing_at_return_type = fcx.suggest_mismatched_types_on_tail(
12201220
&mut db,
12211221
expr,
12221222
expected,
@@ -1244,7 +1244,7 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
12441244
// as prior return coercions would not be relevant (#57664).
12451245
let parent_id = fcx.tcx.hir().get_parent_node(blk_id);
12461246
let parent = fcx.tcx.hir().get(fcx.tcx.hir().get_parent_node(parent_id));
1247-
if fcx.get_node_fn_decl(parent).is_some() {
1247+
if fcx.get_node_fn_decl(parent).is_some() && !pointing_at_return_type {
12481248
if let Some(sp) = fcx.ret_coercion_span.borrow().as_ref() {
12491249
db.span_label(*sp, reason_label);
12501250
}

src/librustc_typeck/check/mod.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5081,12 +5081,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
50815081
found: Ty<'tcx>,
50825082
cause_span: Span,
50835083
blk_id: ast::NodeId,
5084-
) {
5084+
) -> bool {
50855085
self.suggest_missing_semicolon(err, expression, expected, cause_span);
5086+
let mut pointing_at_return_type = false;
50865087
if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
5087-
self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest);
5088+
pointing_at_return_type = self.suggest_missing_return_type(
5089+
err, &fn_decl, expected, found, can_suggest);
50885090
}
50895091
self.suggest_ref_or_into(err, expression, expected, found);
5092+
pointing_at_return_type
50905093
}
50915094

50925095
pub fn suggest_ref_or_into(
@@ -5185,12 +5188,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
51855188
/// This routine checks if the return type is left as default, the method is not part of an
51865189
/// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
51875190
/// type.
5188-
fn suggest_missing_return_type(&self,
5189-
err: &mut DiagnosticBuilder<'tcx>,
5190-
fn_decl: &hir::FnDecl,
5191-
expected: Ty<'tcx>,
5192-
found: Ty<'tcx>,
5193-
can_suggest: bool) {
5191+
fn suggest_missing_return_type(
5192+
&self,
5193+
err: &mut DiagnosticBuilder<'tcx>,
5194+
fn_decl: &hir::FnDecl,
5195+
expected: Ty<'tcx>,
5196+
found: Ty<'tcx>,
5197+
can_suggest: bool,
5198+
) -> bool {
51945199
// Only suggest changing the return type for methods that
51955200
// haven't set a return type at all (and aren't `fn main()` or an impl).
51965201
match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
@@ -5200,16 +5205,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
52005205
"try adding a return type",
52015206
format!("-> {} ", self.resolve_type_vars_with_obligations(found)),
52025207
Applicability::MachineApplicable);
5208+
true
52035209
}
52045210
(&hir::FunctionRetTy::DefaultReturn(span), false, true, true) => {
52055211
err.span_label(span, "possibly return type missing here?");
5212+
true
52065213
}
52075214
(&hir::FunctionRetTy::DefaultReturn(span), _, false, true) => {
52085215
// `fn main()` must return `()`, do not suggest changing return type
52095216
err.span_label(span, "expected `()` because of default return type");
5217+
true
52105218
}
52115219
// expectation was caused by something else, not the default return
5212-
(&hir::FunctionRetTy::DefaultReturn(_), _, _, false) => {}
5220+
(&hir::FunctionRetTy::DefaultReturn(_), _, _, false) => false,
52135221
(&hir::FunctionRetTy::Return(ref ty), _, _, _) => {
52145222
// Only point to return type if the expected type is the return type, as if they
52155223
// are not, the expectation must have been caused by something else.
@@ -5221,7 +5229,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
52215229
if ty.sty == expected.sty {
52225230
err.span_label(sp, format!("expected `{}` because of return type",
52235231
expected));
5232+
return true;
52245233
}
5234+
false
52255235
}
52265236
}
52275237
}

src/test/ui/diverging-tuple-parts-39485.stderr

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,7 @@ error[E0308]: mismatched types
1515
LL | fn f() -> isize {
1616
| ----- expected `isize` because of return type
1717
LL | (return 1, return 2) //~ ERROR mismatched types
18-
| ^^^^^^^^^^^^^^^^^^-^
19-
| | |
20-
| | expected because of this statement
21-
| expected isize, found tuple
18+
| ^^^^^^^^^^^^^^^^^^^^ expected isize, found tuple
2219
|
2320
= note: expected type `isize`
2421
found type `(!, !)`

src/test/ui/issues/issue-10176.stderr

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ error[E0308]: mismatched types
44
LL | fn f() -> isize {
55
| ----- expected `isize` because of return type
66
LL | (return 1, return 2)
7-
| ^^^^^^^^^^^^^^^^^^-^
8-
| | |
9-
| | expected because of this statement
10-
| expected isize, found tuple
7+
| ^^^^^^^^^^^^^^^^^^^^ expected isize, found tuple
118
|
129
= note: expected type `isize`
1310
found type `(!, !)`

0 commit comments

Comments
 (0)