Skip to content

Commit b09c177

Browse files
Don't leak unnameable types in -> _ recover
1 parent 78bc0a5 commit b09c177

File tree

4 files changed

+37
-17
lines changed

4 files changed

+37
-17
lines changed

compiler/rustc_hir_analysis/src/collect.rs

+11-16
Original file line numberDiff line numberDiff line change
@@ -1373,16 +1373,16 @@ fn infer_return_ty_for_fn_sig<'tcx>(
13731373
// Don't leak types into signatures unless they're nameable!
13741374
// For example, if a function returns itself, we don't want that
13751375
// recursive function definition to leak out into the fn sig.
1376-
let mut should_recover = false;
1376+
let mut recovered_ret_ty = None;
13771377

1378-
if let Some(ret_ty) = ret_ty.make_suggestable(tcx, false, None) {
1378+
if let Some(suggestable_ret_ty) = ret_ty.make_suggestable(tcx, false, None) {
13791379
diag.span_suggestion(
13801380
ty.span,
13811381
"replace with the correct return type",
1382-
ret_ty,
1382+
suggestable_ret_ty,
13831383
Applicability::MachineApplicable,
13841384
);
1385-
should_recover = true;
1385+
recovered_ret_ty = Some(suggestable_ret_ty);
13861386
} else if let Some(sugg) =
13871387
suggest_impl_trait(&tcx.infer_ctxt().build(), tcx.param_env(def_id), ret_ty)
13881388
{
@@ -1404,18 +1404,13 @@ fn infer_return_ty_for_fn_sig<'tcx>(
14041404
}
14051405

14061406
let guar = diag.emit();
1407-
1408-
if should_recover {
1409-
ty::Binder::dummy(fn_sig)
1410-
} else {
1411-
ty::Binder::dummy(tcx.mk_fn_sig(
1412-
fn_sig.inputs().iter().copied(),
1413-
Ty::new_error(tcx, guar),
1414-
fn_sig.c_variadic,
1415-
fn_sig.unsafety,
1416-
fn_sig.abi,
1417-
))
1418-
}
1407+
ty::Binder::dummy(tcx.mk_fn_sig(
1408+
fn_sig.inputs().iter().copied(),
1409+
recovered_ret_ty.unwrap_or_else(|| Ty::new_error(tcx, guar)),
1410+
fn_sig.c_variadic,
1411+
fn_sig.unsafety,
1412+
fn_sig.abi,
1413+
))
14191414
}
14201415
None => icx.lowerer().lower_fn_ty(
14211416
hir_id,

compiler/rustc_hir_analysis/src/variance/constraints.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
236236
}
237237

238238
ty::FnDef(..) | ty::Coroutine(..) | ty::Closure(..) | ty::CoroutineClosure(..) => {
239-
bug!("Unexpected coroutine/closure type in variance computation");
239+
bug!("Unexpected unnameable type in variance computation: {ty}");
240240
}
241241

242242
ty::Ref(region, ty, mutbl) => {
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Test variance computation doesn't explode when we leak unnameable
2+
// types due to `-> _` recovery.
3+
4+
pub struct Type<'a>(&'a ());
5+
6+
pub fn g() {}
7+
8+
pub fn f<T>() -> _ {
9+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures
10+
g
11+
}
12+
13+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
2+
--> $DIR/leaking-unnameables.rs:8:18
3+
|
4+
LL | pub fn f<T>() -> _ {
5+
| ^
6+
| |
7+
| not allowed in type signatures
8+
| help: replace with the correct return type: `fn()`
9+
10+
error: aborting due to 1 previous error
11+
12+
For more information about this error, try `rustc --explain E0121`.

0 commit comments

Comments
 (0)