Don't infer fn return type to return itself
This commit is contained in:
parent
4396ceca05
commit
c8874e2445
@ -1146,8 +1146,14 @@ fn infer_return_ty_for_fn_sig<'tcx>(
|
|||||||
|
|
||||||
let mut visitor = HirPlaceholderCollector::default();
|
let mut visitor = HirPlaceholderCollector::default();
|
||||||
visitor.visit_ty(ty);
|
visitor.visit_ty(ty);
|
||||||
|
|
||||||
let mut diag = bad_placeholder(tcx, visitor.0, "return type");
|
let mut diag = bad_placeholder(tcx, visitor.0, "return type");
|
||||||
let ret_ty = fn_sig.output();
|
let ret_ty = fn_sig.output();
|
||||||
|
// Don't leak types into signatures unless they're nameable!
|
||||||
|
// For example, if a function returns itself, we don't want that
|
||||||
|
// recursive function definition to leak out into the fn sig.
|
||||||
|
let mut should_recover = false;
|
||||||
|
|
||||||
if let Some(ret_ty) = ret_ty.make_suggestable(tcx, false) {
|
if let Some(ret_ty) = ret_ty.make_suggestable(tcx, false) {
|
||||||
diag.span_suggestion(
|
diag.span_suggestion(
|
||||||
ty.span,
|
ty.span,
|
||||||
@ -1155,15 +1161,7 @@ fn infer_return_ty_for_fn_sig<'tcx>(
|
|||||||
ret_ty,
|
ret_ty,
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
} else if matches!(ret_ty.kind(), ty::FnDef(..))
|
should_recover = true;
|
||||||
&& let Some(fn_sig) = ret_ty.fn_sig(tcx).make_suggestable(tcx, false)
|
|
||||||
{
|
|
||||||
diag.span_suggestion(
|
|
||||||
ty.span,
|
|
||||||
"replace with the correct return type",
|
|
||||||
fn_sig,
|
|
||||||
Applicability::MachineApplicable,
|
|
||||||
);
|
|
||||||
} else if let Some(sugg) = suggest_impl_trait(tcx, ret_ty, ty.span, def_id) {
|
} else if let Some(sugg) = suggest_impl_trait(tcx, ret_ty, ty.span, def_id) {
|
||||||
diag.span_suggestion(
|
diag.span_suggestion(
|
||||||
ty.span,
|
ty.span,
|
||||||
@ -1181,9 +1179,20 @@ fn infer_return_ty_for_fn_sig<'tcx>(
|
|||||||
https://doc.rust-lang.org/book/ch13-01-closures.html",
|
https://doc.rust-lang.org/book/ch13-01-closures.html",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
diag.emit();
|
|
||||||
|
|
||||||
ty::Binder::dummy(fn_sig)
|
let guar = diag.emit();
|
||||||
|
|
||||||
|
if should_recover {
|
||||||
|
ty::Binder::dummy(fn_sig)
|
||||||
|
} else {
|
||||||
|
ty::Binder::dummy(tcx.mk_fn_sig(
|
||||||
|
fn_sig.inputs().iter().copied(),
|
||||||
|
tcx.ty_error(guar),
|
||||||
|
fn_sig.c_variadic,
|
||||||
|
fn_sig.unsafety,
|
||||||
|
fn_sig.abi,
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
None => icx.astconv().ty_of_fn(
|
None => icx.astconv().ty_of_fn(
|
||||||
hir_id,
|
hir_id,
|
||||||
|
11
tests/ui/typeck/bad-recursive-type-sig-infer.rs
Normal file
11
tests/ui/typeck/bad-recursive-type-sig-infer.rs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fn a() -> _ {
|
||||||
|
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
|
||||||
|
&a
|
||||||
|
}
|
||||||
|
|
||||||
|
fn b() -> _ {
|
||||||
|
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
|
||||||
|
&a
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
15
tests/ui/typeck/bad-recursive-type-sig-infer.stderr
Normal file
15
tests/ui/typeck/bad-recursive-type-sig-infer.stderr
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
|
||||||
|
--> $DIR/bad-recursive-type-sig-infer.rs:1:11
|
||||||
|
|
|
||||||
|
LL | fn a() -> _ {
|
||||||
|
| ^ not allowed in type signatures
|
||||||
|
|
||||||
|
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
|
||||||
|
--> $DIR/bad-recursive-type-sig-infer.rs:6:11
|
||||||
|
|
|
||||||
|
LL | fn b() -> _ {
|
||||||
|
| ^ not allowed in type signatures
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0121`.
|
Loading…
x
Reference in New Issue
Block a user