Skip to content

Commit

Permalink
Don't leak unnameable types in -> _ recover
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Apr 14, 2024
1 parent 78bc0a5 commit aaad71b
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 17 deletions.
27 changes: 11 additions & 16 deletions compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1373,16 +1373,16 @@ fn infer_return_ty_for_fn_sig<'tcx>(
// 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;
let mut should_recover = None;

if let Some(ret_ty) = ret_ty.make_suggestable(tcx, false, None) {
if let Some(suggestable_ret_ty) = ret_ty.make_suggestable(tcx, false, None) {
diag.span_suggestion(
ty.span,
"replace with the correct return type",
ret_ty,
suggestable_ret_ty,
Applicability::MachineApplicable,
);
should_recover = true;
should_recover = Some(suggestable_ret_ty);
} else if let Some(sugg) =
suggest_impl_trait(&tcx.infer_ctxt().build(), tcx.param_env(def_id), ret_ty)
{
Expand All @@ -1404,18 +1404,13 @@ fn infer_return_ty_for_fn_sig<'tcx>(
}

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(),
Ty::new_error(tcx, guar),
fn_sig.c_variadic,
fn_sig.unsafety,
fn_sig.abi,
))
}
ty::Binder::dummy(tcx.mk_fn_sig(
fn_sig.inputs().iter().copied(),
should_recover.unwrap_or_else(|| Ty::new_error(tcx, guar)),
fn_sig.c_variadic,
fn_sig.unsafety,
fn_sig.abi,
))
}
None => icx.lowerer().lower_fn_ty(
hir_id,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/variance/constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
}

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

ty::Ref(region, ty, mutbl) => {
Expand Down
13 changes: 13 additions & 0 deletions tests/ui/variance/leaking-unnameables.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Test variance computation doesn't explode when we leak unnameable
// types due to `-> _` recovery.

pub struct Type<'a>(&'a ());

pub fn g() {}

pub fn f<T>() -> _ {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures
g
}

fn main() {}
12 changes: 12 additions & 0 deletions tests/ui/variance/leaking-unnameables.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
--> $DIR/leaking-unnameables.rs:8:18
|
LL | pub fn f<T>() -> _ {
| ^
| |
| not allowed in type signatures
| help: replace with the correct return type: `fn()`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0121`.

0 comments on commit aaad71b

Please sign in to comment.