Defer tail call ret ty equality to check_tail_calls
This commit is contained in:
parent
16ad385579
commit
6a088fd584
5 changed files with 61 additions and 25 deletions
|
|
@ -1895,7 +1895,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
if !output_ty
|
||||
.is_privately_uninhabited(self.tcx(), self.infcx.typing_env(self.infcx.param_env))
|
||||
{
|
||||
span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig);
|
||||
span_mirbug!(self, term, "call to non-diverging function {:?} w/o dest", sig);
|
||||
}
|
||||
} else {
|
||||
let dest_ty = destination.ty(self.body, tcx).ty;
|
||||
|
|
|
|||
|
|
@ -135,30 +135,23 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> {
|
|||
self.report_abi_mismatch(expr.span, caller_sig.abi, callee_sig.abi);
|
||||
}
|
||||
|
||||
// FIXME(explicit_tail_calls): this currently fails for cases where opaques are used.
|
||||
// e.g.
|
||||
// ```
|
||||
// fn a() -> impl Sized { become b() } // ICE
|
||||
// fn b() -> u8 { 0 }
|
||||
// ```
|
||||
// we should think what is the expected behavior here.
|
||||
// (we should probably just accept this by revealing opaques?)
|
||||
if caller_sig.inputs_and_output != callee_sig.inputs_and_output {
|
||||
if caller_sig.inputs() != callee_sig.inputs() {
|
||||
self.report_arguments_mismatch(
|
||||
expr.span,
|
||||
self.tcx.liberate_late_bound_regions(
|
||||
CRATE_DEF_ID.to_def_id(),
|
||||
self.caller_ty.fn_sig(self.tcx),
|
||||
),
|
||||
self.tcx
|
||||
.liberate_late_bound_regions(CRATE_DEF_ID.to_def_id(), ty.fn_sig(self.tcx)),
|
||||
);
|
||||
}
|
||||
|
||||
// FIXME(explicit_tail_calls): this currently fails for cases where opaques are used.
|
||||
// e.g.
|
||||
// ```
|
||||
// fn a() -> impl Sized { become b() } // ICE
|
||||
// fn b() -> u8 { 0 }
|
||||
// ```
|
||||
// we should think what is the expected behavior here.
|
||||
// (we should probably just accept this by revealing opaques?)
|
||||
if caller_sig.output() != callee_sig.output() {
|
||||
span_bug!(expr.span, "hir typeck should have checked the return type already");
|
||||
}
|
||||
self.report_signature_mismatch(
|
||||
expr.span,
|
||||
self.tcx.liberate_late_bound_regions(
|
||||
CRATE_DEF_ID.to_def_id(),
|
||||
self.caller_ty.fn_sig(self.tcx),
|
||||
),
|
||||
self.tcx.liberate_late_bound_regions(CRATE_DEF_ID.to_def_id(), ty.fn_sig(self.tcx)),
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
|
|
@ -365,7 +358,7 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> {
|
|||
self.found_errors = Err(err);
|
||||
}
|
||||
|
||||
fn report_arguments_mismatch(
|
||||
fn report_signature_mismatch(
|
||||
&mut self,
|
||||
sp: Span,
|
||||
caller_sig: ty::FnSig<'_>,
|
||||
|
|
|
|||
15
tests/ui/explicit-tail-calls/ret-ty-hr-mismatch.rs
Normal file
15
tests/ui/explicit-tail-calls/ret-ty-hr-mismatch.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#![feature(explicit_tail_calls)]
|
||||
#![expect(incomplete_features)]
|
||||
|
||||
fn foo() -> for<'a> fn(&'a i32) {
|
||||
become bar();
|
||||
//~^ ERROR mismatched signatures
|
||||
}
|
||||
|
||||
fn bar() -> fn(&'static i32) {
|
||||
dummy
|
||||
}
|
||||
|
||||
fn dummy(_: &i32) {}
|
||||
|
||||
fn main() {}
|
||||
12
tests/ui/explicit-tail-calls/ret-ty-hr-mismatch.stderr
Normal file
12
tests/ui/explicit-tail-calls/ret-ty-hr-mismatch.stderr
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
error: mismatched signatures
|
||||
--> $DIR/ret-ty-hr-mismatch.rs:5:5
|
||||
|
|
||||
LL | become bar();
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= note: `become` requires caller and callee to have matching signatures
|
||||
= note: caller signature: `fn() -> for<'a> fn(&'a i32)`
|
||||
= note: callee signature: `fn() -> fn(&'static i32)`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
16
tests/ui/explicit-tail-calls/ret-ty-modulo-anonymization.rs
Normal file
16
tests/ui/explicit-tail-calls/ret-ty-modulo-anonymization.rs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
// Ensure that we anonymize the output of a function for tail call signature compatibility.
|
||||
|
||||
//@ check-pass
|
||||
|
||||
#![feature(explicit_tail_calls)]
|
||||
#![expect(incomplete_features)]
|
||||
|
||||
fn foo() -> for<'a> fn(&'a ()) {
|
||||
become bar();
|
||||
}
|
||||
|
||||
fn bar() -> for<'b> fn(&'b ()) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue