Rollup merge of #116296 - compiler-errors:default-return, r=estebank
More accurately point to where default return type should go When getting the "default return type" span, instead of pointing to the low span of the next token, point to the high span of the previous token. This: 1. Makes forming return type suggestions more uniform, since we expect them all in the same place. 2. Arguably makes labels easier to understand, since we're pointing to where the implicit `-> ()` would've gone, rather than the starting brace or the semicolon. r? ```@estebank```
This commit is contained in:
commit
cfce3a919d
42 changed files with 105 additions and 89 deletions
|
@ -1189,7 +1189,7 @@ fn report_trait_method_mismatch<'tcx>(
|
|||
let ap = Applicability::MachineApplicable;
|
||||
match sig.decl.output {
|
||||
hir::FnRetTy::DefaultReturn(sp) => {
|
||||
let sugg = format!("-> {} ", trait_sig.output());
|
||||
let sugg = format!(" -> {}", trait_sig.output());
|
||||
diag.span_suggestion_verbose(sp, msg, sugg, ap);
|
||||
}
|
||||
hir::FnRetTy::Return(hir_ty) => {
|
||||
|
|
|
@ -113,7 +113,11 @@ pub(super) fn check_fn<'a, 'tcx>(
|
|||
|
||||
fcx.typeck_results.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
|
||||
|
||||
fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
|
||||
let return_or_body_span = match decl.output {
|
||||
hir::FnRetTy::DefaultReturn(_) => body.value.span,
|
||||
hir::FnRetTy::Return(ty) => ty.span,
|
||||
};
|
||||
fcx.require_type_is_sized(declared_ret_ty, return_or_body_span, traits::SizedReturnType);
|
||||
fcx.check_return_expr(&body.value, false);
|
||||
|
||||
// We insert the deferred_generator_interiors entry after visiting the body.
|
||||
|
|
|
@ -110,7 +110,7 @@ pub struct AddressOfTemporaryTaken {
|
|||
pub enum AddReturnTypeSuggestion {
|
||||
#[suggestion(
|
||||
hir_typeck_add_return_type_add,
|
||||
code = "-> {found} ",
|
||||
code = " -> {found}",
|
||||
applicability = "machine-applicable"
|
||||
)]
|
||||
Add {
|
||||
|
@ -120,7 +120,7 @@ pub enum AddReturnTypeSuggestion {
|
|||
},
|
||||
#[suggestion(
|
||||
hir_typeck_add_return_type_missing_here,
|
||||
code = "-> _ ",
|
||||
code = " -> _",
|
||||
applicability = "has-placeholders"
|
||||
)]
|
||||
MissingHere {
|
||||
|
|
|
@ -782,8 +782,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
hir::FnRetTy::Return(hir_ty) => {
|
||||
let span = hir_ty.span;
|
||||
|
||||
if let hir::TyKind::OpaqueDef(item_id, ..) = hir_ty.kind
|
||||
&& let hir::Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::OpaqueTy(op_ty),
|
||||
|
@ -799,14 +797,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
debug!(?found);
|
||||
if found.is_suggestable(self.tcx, false) {
|
||||
if term.span.is_empty() {
|
||||
err.subdiagnostic(errors::AddReturnTypeSuggestion::Add { span, found: found.to_string() });
|
||||
err.subdiagnostic(errors::AddReturnTypeSuggestion::Add { span: term.span, found: found.to_string() });
|
||||
return true;
|
||||
} else {
|
||||
err.subdiagnostic(errors::ExpectedReturnTypeLabel::Other { span, expected });
|
||||
err.subdiagnostic(errors::ExpectedReturnTypeLabel::Other { span: term.span, expected });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// Only point to return type if the expected type is the return type, as if they
|
||||
// are not, the expectation must have been caused by something else.
|
||||
debug!("return type {:?}", hir_ty);
|
||||
|
@ -815,14 +812,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
debug!("expected type {:?}", expected);
|
||||
let bound_vars = self.tcx.late_bound_vars(hir_ty.hir_id.owner.into());
|
||||
let ty = Binder::bind_with_vars(ty, bound_vars);
|
||||
let ty = self.normalize(span, ty);
|
||||
let ty = self.normalize(hir_ty.span, ty);
|
||||
let ty = self.tcx.erase_late_bound_regions(ty);
|
||||
if self.can_coerce(expected, ty) {
|
||||
err.subdiagnostic(errors::ExpectedReturnTypeLabel::Other { span, expected });
|
||||
err.subdiagnostic(errors::ExpectedReturnTypeLabel::Other { span: hir_ty.span, expected });
|
||||
self.try_suggest_return_impl_trait(err, expected, ty, fn_id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
false
|
||||
|
|
|
@ -194,13 +194,13 @@ impl<'a> SourceKindMultiSuggestion<'a> {
|
|||
data: &'a FnRetTy<'a>,
|
||||
should_wrap_expr: Option<Span>,
|
||||
) -> Self {
|
||||
let (arrow, post) = match data {
|
||||
FnRetTy::DefaultReturn(_) => ("-> ", " "),
|
||||
_ => ("", ""),
|
||||
let arrow = match data {
|
||||
FnRetTy::DefaultReturn(_) => " -> ",
|
||||
_ => "",
|
||||
};
|
||||
let (start_span, start_span_code, end_span) = match should_wrap_expr {
|
||||
Some(end_span) => (data.span(), format!("{arrow}{ty_info}{post}{{ "), Some(end_span)),
|
||||
None => (data.span(), format!("{arrow}{ty_info}{post}"), None),
|
||||
Some(end_span) => (data.span(), format!("{arrow}{ty_info} {{"), Some(end_span)),
|
||||
None => (data.span(), format!("{arrow}{ty_info}"), None),
|
||||
};
|
||||
Self::ClosureReturn { start_span, start_span_code, end_span }
|
||||
}
|
||||
|
|
|
@ -247,7 +247,7 @@ impl<'a> Parser<'a> {
|
|||
)?;
|
||||
FnRetTy::Ty(ty)
|
||||
} else {
|
||||
FnRetTy::Default(self.token.span.shrink_to_lo())
|
||||
FnRetTy::Default(self.prev_token.span.shrink_to_hi())
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -102,14 +102,10 @@ pub(super) fn check(
|
|||
]),
|
||||
("None", "unwrap_or_else", _) => match args[0].kind {
|
||||
hir::ExprKind::Closure(hir::Closure {
|
||||
fn_decl:
|
||||
hir::FnDecl {
|
||||
output: hir::FnRetTy::DefaultReturn(span) | hir::FnRetTy::Return(hir::Ty { span, .. }),
|
||||
..
|
||||
},
|
||||
body,
|
||||
..
|
||||
}) => Some(vec![
|
||||
(expr.span.with_hi(span.hi()), String::new()),
|
||||
(expr.span.with_hi(cx.tcx.hir().body(*body).value.span.lo()), String::new()),
|
||||
(expr.span.with_lo(args[0].span.hi()), String::new()),
|
||||
]),
|
||||
_ => None,
|
||||
|
|
|
@ -2,7 +2,7 @@ error: this function has too many arguments (11/10)
|
|||
--> $DIR/too_many_arguments.rs:4:1
|
||||
|
|
||||
LL | fn too_many(p1: u8, p2: u8, p3: u8, p4: u8, p5: u8, p6: u8, p7: u8, p8: u8, p9: u8, p10: u8, p11: u8) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `-D clippy::too-many-arguments` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::too_many_arguments)]`
|
||||
|
|
|
@ -2,7 +2,7 @@ error: this function has too many arguments (8/7)
|
|||
--> $DIR/functions.rs:8:1
|
||||
|
|
||||
LL | fn bad(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `-D clippy::too-many-arguments` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::too_many_arguments)]`
|
||||
|
@ -17,7 +17,7 @@ LL | | two: u32,
|
|||
... |
|
||||
LL | | eight: ()
|
||||
LL | | ) {
|
||||
| |__^
|
||||
| |_^
|
||||
|
||||
error: this function has too many arguments (8/7)
|
||||
--> $DIR/functions.rs:48:5
|
||||
|
@ -29,7 +29,7 @@ error: this function has too many arguments (8/7)
|
|||
--> $DIR/functions.rs:58:5
|
||||
|
|
||||
LL | fn bad_method(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: this public function might dereference a raw pointer but is not marked `unsafe`
|
||||
--> $DIR/functions.rs:68:34
|
||||
|
|
|
@ -4,7 +4,7 @@ error: this unit-returning function has a `#[must_use]` attribute
|
|||
LL | #[must_use]
|
||||
| ----------- help: remove the attribute
|
||||
LL | pub fn must_use_default() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `-D clippy::must-use-unit` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::must_use_unit)]`
|
||||
|
@ -23,7 +23,7 @@ error: this unit-returning function has a `#[must_use]` attribute
|
|||
LL | #[must_use = "With note"]
|
||||
| ------------------------- help: remove the attribute
|
||||
LL | pub fn must_use_with_note() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
@ -2599,7 +2599,8 @@ fn rewrite_fn_base(
|
|||
if where_clause_str.is_empty() {
|
||||
if let ast::FnRetTy::Default(ret_span) = fd.output {
|
||||
match recover_missing_comment_in_span(
|
||||
mk_sp(params_span.hi(), ret_span.hi()),
|
||||
// from after the closing paren to right before block or semicolon
|
||||
mk_sp(ret_span.lo(), span.hi()),
|
||||
shape,
|
||||
context,
|
||||
last_line_width(&result),
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: implicit types in closure signatures are forbidden when `for<...>` is present
|
||||
--> $DIR/implicit-return.rs:4:34
|
||||
--> $DIR/implicit-return.rs:4:33
|
||||
|
|
||||
LL | let _f = for<'a> |_: &'a ()| {};
|
||||
| ------- ^
|
||||
|
|
|
@ -41,7 +41,7 @@ LL | let _ = for<'a> |x: &'a ()| -> &() { x };
|
|||
| ^ explicit lifetime name needed here
|
||||
|
||||
error: implicit types in closure signatures are forbidden when `for<...>` is present
|
||||
--> $DIR/implicit-stuff.rs:5:22
|
||||
--> $DIR/implicit-stuff.rs:5:21
|
||||
|
|
||||
LL | let _ = for<> || {};
|
||||
| ----- ^
|
||||
|
|
|
@ -28,7 +28,7 @@ LL | fn foo(self);
|
|||
found signature `fn(Box<MyFuture>)`
|
||||
|
||||
error[E0053]: method `bar` has an incompatible type for trait
|
||||
--> $DIR/bad-self-type.rs:24:18
|
||||
--> $DIR/bad-self-type.rs:24:17
|
||||
|
|
||||
LL | fn bar(self) {}
|
||||
| ^ expected `Option<()>`, found `()`
|
||||
|
|
|
@ -30,7 +30,7 @@ LL | fn bar() {}
|
|||
= note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
|
||||
help: replace the return type so that it matches the trait
|
||||
|
|
||||
LL | fn bar() -> impl Sized {}
|
||||
LL | fn bar()-> impl Sized {}
|
||||
| +++++++++++++
|
||||
|
||||
error: impl trait in impl method signature does not match trait method signature
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error[E0308]: lang item `start` function has wrong type
|
||||
--> $DIR/start_lang_item_args.rs:29:84
|
||||
--> $DIR/start_lang_item_args.rs:29:83
|
||||
|
|
||||
LL | fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) {}
|
||||
| ^ expected `isize`, found `()`
|
||||
|
|
|
@ -25,7 +25,7 @@ LL | for <Foo>::Bar in x {}
|
|||
= help: consider removing `for<...>`
|
||||
|
||||
error: implicit types in closure signatures are forbidden when `for<...>` is present
|
||||
--> $DIR/recover-quantified-closure.rs:2:25
|
||||
--> $DIR/recover-quantified-closure.rs:2:24
|
||||
|
|
||||
LL | for<'a> |x: &'a u8| *x + 1;
|
||||
| ------- ^
|
||||
|
|
14
tests/ui/suggestions/suggest-ret-on-async-w-late.fixed
Normal file
14
tests/ui/suggestions/suggest-ret-on-async-w-late.fixed
Normal file
|
@ -0,0 +1,14 @@
|
|||
// edition: 2021
|
||||
// run-rustfix
|
||||
|
||||
#![allow(unused)]
|
||||
|
||||
// Make sure we don't ICE when suggesting a return type
|
||||
// for an async fn that has late-bound vars...
|
||||
|
||||
async fn ice(_: &i32) -> bool {
|
||||
true
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -1,4 +1,7 @@
|
|||
// edition: 2021
|
||||
// run-rustfix
|
||||
|
||||
#![allow(unused)]
|
||||
|
||||
// Make sure we don't ICE when suggesting a return type
|
||||
// for an async fn that has late-bound vars...
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/suggest-ret-on-async-w-late.rs:7:5
|
||||
--> $DIR/suggest-ret-on-async-w-late.rs:10:5
|
||||
|
|
||||
LL | async fn ice(_: &i32) {
|
||||
| --------------------- help: try adding a return type: `-> bool`
|
||||
| - help: try adding a return type: `-> bool`
|
||||
LL | true
|
||||
| ^^^^ expected `()`, found `bool`
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ error[E0308]: mismatched types
|
|||
--> $DIR/issue-90027-async-fn-return-suggestion.rs:4:5
|
||||
|
|
||||
LL | async fn hello() {
|
||||
| ---------------- help: try adding a return type: `-> i32`
|
||||
| - help: try adding a return type: `-> i32`
|
||||
LL | 0
|
||||
| ^ expected `()`, found integer
|
||||
|
||||
|
@ -10,7 +10,7 @@ error[E0308]: mismatched types
|
|||
--> $DIR/issue-90027-async-fn-return-suggestion.rs:9:5
|
||||
|
|
||||
LL | async fn world() -> () {
|
||||
| ---------------------- expected `()` because of return type
|
||||
| -- expected `()` because of return type
|
||||
LL | 0
|
||||
| ^ expected `()`, found integer
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue