Rollup merge of #123931 - compiler-errors:variance-unnameables, r=fmease

Don't leak unnameable types in `-> _` recover

Fixes #123899
This commit is contained in:
许杰友 Jieyou Xu (Joe) 2024-04-15 16:56:17 +01:00 committed by GitHub
commit 313b02a86b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 37 additions and 17 deletions

View File

@ -1373,16 +1373,16 @@ fn infer_return_ty_for_fn_sig<'tcx>(
// Don't leak types into signatures unless they're nameable! // Don't leak types into signatures unless they're nameable!
// For example, if a function returns itself, we don't want that // For example, if a function returns itself, we don't want that
// recursive function definition to leak out into the fn sig. // recursive function definition to leak out into the fn sig.
let mut should_recover = false; let mut recovered_ret_ty = 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( diag.span_suggestion(
ty.span, ty.span,
"replace with the correct return type", "replace with the correct return type",
ret_ty, suggestable_ret_ty,
Applicability::MachineApplicable, Applicability::MachineApplicable,
); );
should_recover = true; recovered_ret_ty = Some(suggestable_ret_ty);
} else if let Some(sugg) = } else if let Some(sugg) =
suggest_impl_trait(&tcx.infer_ctxt().build(), tcx.param_env(def_id), ret_ty) suggest_impl_trait(&tcx.infer_ctxt().build(), tcx.param_env(def_id), ret_ty)
{ {
@ -1404,18 +1404,13 @@ fn infer_return_ty_for_fn_sig<'tcx>(
} }
let guar = diag.emit(); let guar = diag.emit();
ty::Binder::dummy(tcx.mk_fn_sig(
if should_recover { fn_sig.inputs().iter().copied(),
ty::Binder::dummy(fn_sig) recovered_ret_ty.unwrap_or_else(|| Ty::new_error(tcx, guar)),
} else { fn_sig.c_variadic,
ty::Binder::dummy(tcx.mk_fn_sig( fn_sig.unsafety,
fn_sig.inputs().iter().copied(), fn_sig.abi,
Ty::new_error(tcx, guar), ))
fn_sig.c_variadic,
fn_sig.unsafety,
fn_sig.abi,
))
}
} }
None => icx.lowerer().lower_fn_ty( None => icx.lowerer().lower_fn_ty(
hir_id, hir_id,

View File

@ -236,7 +236,7 @@ fn add_constraints_from_ty(
} }
ty::FnDef(..) | ty::Coroutine(..) | ty::Closure(..) | ty::CoroutineClosure(..) => { 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) => { ty::Ref(region, ty, mutbl) => {

View File

@ -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() {}

View File

@ -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`.