diff --git a/compiler/rustc_mir_build/src/check_tail_calls.rs b/compiler/rustc_mir_build/src/check_tail_calls.rs index b4c8b20e50f9c..2b2c2cbc37290 100644 --- a/compiler/rustc_mir_build/src/check_tail_calls.rs +++ b/compiler/rustc_mir_build/src/check_tail_calls.rs @@ -3,6 +3,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::Applicability; use rustc_hir::LangItem; use rustc_hir::def::DefKind; +use rustc_hir::def_id::CRATE_DEF_ID; use rustc_middle::span_bug; use rustc_middle::thir::visit::{self, Visitor}; use rustc_middle::thir::{BodyTy, Expr, ExprId, ExprKind, Thir}; @@ -132,7 +133,15 @@ impl<'tcx> TailCallCkVisitor<'_, 'tcx> { if caller_sig.inputs_and_output != callee_sig.inputs_and_output { if caller_sig.inputs() != callee_sig.inputs() { - self.report_arguments_mismatch(expr.span, caller_sig, callee_sig); + 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. diff --git a/tests/ui/explicit-tail-calls/caller-lifetime-presence.rs b/tests/ui/explicit-tail-calls/caller-lifetime-presence.rs new file mode 100644 index 0000000000000..2382bc9dd1e05 --- /dev/null +++ b/tests/ui/explicit-tail-calls/caller-lifetime-presence.rs @@ -0,0 +1,51 @@ +//! Regression test for: https://github.com/rust-lang/rust/issues/144957 +//! +//! This test ensures that lifetime information is included in diagnostics. +//! +//! Specifically, it checks that the `become` call produces an error with lifetimes shown +//! in both caller and callee signatures. +//! +//! If the test fails: +//! - Lifetimes may be missing (fix the diagnostic), or +//! - The message format changed (update the test). + +#![feature(explicit_tail_calls)] +#![allow(incomplete_features)] + +fn foo<'a>(_: fn(&'a ())) { + become bar(dummy); + //~^ ERROR mismatched signatures + //~| NOTE `become` requires caller and callee to have matching signatures + //~| NOTE caller signature: `fn(fn(&'a ()))` + //~| NOTE callee signature: `fn(for<'a> fn(&'a ()))` +} + +fn bar(_: fn(&())) {} + +fn dummy(_: &()) {} + +fn foo_(_: fn(&())) { + become bar1(dummy2); + //~^ ERROR mismatched signatures + //~| NOTE `become` requires caller and callee to have matching signatures + //~| NOTE caller signature: `fn(for<'a> fn(&'a ()))` + //~| NOTE callee signature: `fn(fn(&'a ()))` +} + +fn bar1<'a>(_: fn(&'a ())) {} + +fn dummy2(_: &()) {} + +fn foo__(_: fn(&'static ())) { + become bar(dummy3); + //~^ ERROR mismatched signatures + //~| NOTE `become` requires caller and callee to have matching signatures + //~| NOTE caller signature: `fn(fn(&'static ()))` + //~| NOTE callee signature: `fn(for<'a> fn(&'a ()))` +} + +fn bar2(_: fn(&())) {} + +fn dummy3(_: &()) {} + +fn main() {} diff --git a/tests/ui/explicit-tail-calls/caller-lifetime-presence.stderr b/tests/ui/explicit-tail-calls/caller-lifetime-presence.stderr new file mode 100644 index 0000000000000..2fb981d968206 --- /dev/null +++ b/tests/ui/explicit-tail-calls/caller-lifetime-presence.stderr @@ -0,0 +1,32 @@ +error: mismatched signatures + --> $DIR/caller-lifetime-presence.rs:16:5 + | +LL | become bar(dummy); + | ^^^^^^^^^^^^^^^^^ + | + = note: `become` requires caller and callee to have matching signatures + = note: caller signature: `fn(fn(&'a ()))` + = note: callee signature: `fn(for<'a> fn(&'a ()))` + +error: mismatched signatures + --> $DIR/caller-lifetime-presence.rs:28:5 + | +LL | become bar1(dummy2); + | ^^^^^^^^^^^^^^^^^^^ + | + = note: `become` requires caller and callee to have matching signatures + = note: caller signature: `fn(for<'a> fn(&'a ()))` + = note: callee signature: `fn(fn(&'a ()))` + +error: mismatched signatures + --> $DIR/caller-lifetime-presence.rs:40:5 + | +LL | become bar(dummy3); + | ^^^^^^^^^^^^^^^^^^ + | + = note: `become` requires caller and callee to have matching signatures + = note: caller signature: `fn(fn(&'static ()))` + = note: callee signature: `fn(for<'a> fn(&'a ()))` + +error: aborting due to 3 previous errors +