Skip to content

Commit e0738ad

Browse files
committed
explicit tail call tests with indexing, indirect operands in LLVM
1 parent a448837 commit e0738ad

File tree

5 files changed

+222
-2
lines changed

5 files changed

+222
-2
lines changed

tests/ui/explicit-tail-calls/drop-order.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// FIXME(explicit_tail_calls): enable this test once rustc_codegen_ssa supports tail calls
2-
//@ ignore-test: tail calls are not implemented in rustc_codegen_ssa yet, so this causes 🧊
31
//@ run-pass
42
#![expect(incomplete_features)]
53
#![feature(explicit_tail_calls)]
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Indexing taken from
2+
// https://github.com/phi-go/rfcs/blob/guaranteed-tco/text%2F0000-explicit-tail-calls.md#tail-call-elimination
3+
// should probably come back to after some decision on verbiage
4+
#![expect(incomplete_features)]
5+
#![feature(explicit_tail_calls)]
6+
7+
fn f0(_: usize) {}
8+
fn f1(_: usize) {}
9+
fn f2(_: usize) {}
10+
11+
fn indexer(idx: usize) {
12+
let v: [&dyn Fn(usize); 3] = [&f0, &f1, &f2];
13+
become v[idx](idx) //~ error: mismatched function ABIs
14+
//~^ error: mismatched signatures
15+
}
16+
17+
fn main() {
18+
for idx in 0..3 {
19+
indexer(idx);
20+
}
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error: mismatched function ABIs
2+
--> $DIR/indexer.rs:13:5
3+
|
4+
LL | become v[idx](idx)
5+
| ^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: `become` requires caller and callee to have the same ABI
8+
= note: caller ABI is `"Rust"`, while callee ABI is `"rust-call"`
9+
10+
error: mismatched signatures
11+
--> $DIR/indexer.rs:13:5
12+
|
13+
LL | become v[idx](idx)
14+
| ^^^^^^^^^^^^^^^^^^
15+
|
16+
= note: `become` requires caller and callee to have matching signatures
17+
= note: caller signature: `fn(usize)`
18+
= note: callee signature: `extern "rust-call" fn(&dyn Fn(usize), (usize,))`
19+
20+
error: aborting due to 2 previous errors
21+
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//@build-fail
2+
//@normalize-stderr
3+
//@known-bug: #144293
4+
//@ failure-status: 101
5+
// Same as recursion-etc but eggs LLVM emission into giving indirect arguments.
6+
#![expect(incomplete_features)]
7+
#![feature(explicit_tail_calls)]
8+
9+
use std::hint::black_box;
10+
11+
struct U64Wrapper {
12+
pub x: u64,
13+
pub arbitrary: String,
14+
}
15+
16+
fn count(curr: U64Wrapper, top: U64Wrapper) -> U64Wrapper {
17+
if black_box(curr.x) >= top.x {
18+
curr
19+
} else {
20+
become count(
21+
U64Wrapper {
22+
x: curr.x + 1,
23+
arbitrary: curr.arbitrary,
24+
},
25+
top,
26+
)
27+
}
28+
}
29+
30+
fn main() {
31+
println!(
32+
"{}",
33+
count(
34+
U64Wrapper {
35+
x: 0,
36+
arbitrary: "hello!".into()
37+
},
38+
black_box(U64Wrapper {
39+
x: 1000000,
40+
arbitrary: "goodbye!".into()
41+
})
42+
)
43+
.x
44+
);
45+
}
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
error: internal compiler error: $COMPILER_DIR_REAL/rustc_codegen_ssa/src/mir/block.rs:1059:17: arguments using PassMode::Indirect are currently not supported for tail calls
2+
--> $DIR/recursion-etc-u64wrapper.rs:20:16
3+
|
4+
LL | become count(
5+
| ________________^
6+
LL | | U64Wrapper {
7+
LL | | x: curr.x + 1,
8+
LL | | arbitrary: curr.arbitrary,
9+
LL | | },
10+
LL | | top,
11+
LL | | )
12+
| |_________^
13+
14+
15+
thread 'rustc' panicked at $COMPILER_DIR_REAL/rustc_codegen_ssa/src/mir/block.rs:1059:17:
16+
Box<dyn Any>
17+
stack backtrace:
18+
0: std::panicking::begin_panic::<rustc_errors::ExplicitBug>
19+
at /rustc/390a0ab5dc4a895235a551e502c3893c3337731d/library/std/src/panicking.rs:769:5
20+
1: std::panic::panic_any::<rustc_errors::ExplicitBug>
21+
at /rustc/390a0ab5dc4a895235a551e502c3893c3337731d/library/std/src/panic.rs:260:5
22+
2: <rustc_errors::diagnostic::BugAbort as rustc_errors::diagnostic::EmissionGuarantee>::emit_producing_guarantee
23+
at ./compiler/rustc_errors/src/diagnostic.rs:83:9
24+
3: <rustc_errors::diagnostic::Diag<rustc_errors::diagnostic::BugAbort>>::emit
25+
at ./compiler/rustc_errors/src/diagnostic.rs:1416:9
26+
4: <rustc_errors::DiagCtxtHandle>::span_bug::<rustc_span::span_encoding::Span, alloc::string::String>
27+
at ./compiler/rustc_errors/src/lib.rs:1234:48
28+
5: {closure#0}<rustc_span::span_encoding::Span>
29+
at ./compiler/rustc_middle/src/util/bug.rs:38:54
30+
6: {closure#0}<rustc_middle::util::bug::opt_span_bug_fmt::{closure_env#0}<rustc_span::span_encoding::Span>, !>
31+
at ./compiler/rustc_middle/src/ty/context/tls.rs:136:23
32+
7: with_context_opt<rustc_middle::ty::context::tls::with_opt::{closure_env#0}<rustc_middle::util::bug::opt_span_bug_fmt::{closure_env#0}<rustc_span::span_encoding::Span>, !>, !>
33+
at ./compiler/rustc_middle/src/ty/context/tls.rs:79:18
34+
8: rustc_middle::ty::context::tls::with_opt::<rustc_middle::util::bug::opt_span_bug_fmt<rustc_span::span_encoding::Span>::{closure#0}, !>
35+
at ./compiler/rustc_middle/src/ty/context/tls.rs:134:5
36+
9: rustc_middle::util::bug::opt_span_bug_fmt::<rustc_span::span_encoding::Span>
37+
at ./compiler/rustc_middle/src/util/bug.rs:33:5
38+
10: rustc_middle::util::bug::span_bug_fmt::<rustc_span::span_encoding::Span>
39+
at ./compiler/rustc_middle/src/util/bug.rs:24:5
40+
11: codegen_call_terminator<rustc_codegen_llvm::builder::GenericBuilder<rustc_codegen_llvm::context::FullCx>>
41+
12: codegen_terminator<rustc_codegen_llvm::builder::GenericBuilder<rustc_codegen_llvm::context::FullCx>>
42+
13: codegen_block<rustc_codegen_llvm::builder::GenericBuilder<rustc_codegen_llvm::context::FullCx>>
43+
at ./compiler/rustc_codegen_ssa/src/mir/block.rs:1299:37
44+
14: codegen_mir<rustc_codegen_llvm::builder::GenericBuilder<rustc_codegen_llvm::context::FullCx>>
45+
at ./compiler/rustc_codegen_ssa/src/mir/mod.rs:310:12
46+
15: codegen_instance<rustc_codegen_llvm::builder::GenericBuilder<rustc_codegen_llvm::context::FullCx>>
47+
at ./compiler/rustc_codegen_ssa/src/base.rs:394:5
48+
16: define<rustc_codegen_llvm::builder::GenericBuilder<rustc_codegen_llvm::context::FullCx>>
49+
at ./compiler/rustc_codegen_ssa/src/mono_item.rs:48:21
50+
17: module_codegen
51+
at ./compiler/rustc_codegen_llvm/src/base.rs:99:27
52+
18: with_task<rustc_middle::dep_graph::DepsType, rustc_middle::ty::context::TyCtxt, rustc_span::symbol::Symbol, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>
53+
at ./compiler/rustc_query_system/src/dep_graph/graph.rs:274:22
54+
19: compile_codegen_unit
55+
at ./compiler/rustc_codegen_llvm/src/base.rs:63:37
56+
20: <rustc_codegen_llvm::LlvmCodegenBackend as rustc_codegen_ssa::traits::backend::ExtraBackendMethods>::compile_codegen_unit
57+
at ./compiler/rustc_codegen_llvm/src/lib.rs:128:9
58+
21: codegen_crate<rustc_codegen_llvm::LlvmCodegenBackend>
59+
at ./compiler/rustc_codegen_ssa/src/base.rs:794:42
60+
22: codegen_crate
61+
at ./compiler/rustc_codegen_llvm/src/lib.rs:344:18
62+
23: {closure#0}
63+
at ./compiler/rustc_interface/src/passes.rs:1219:74
64+
24: run<alloc::boxed::Box<dyn core::any::Any, alloc::alloc::Global>, rustc_interface::passes::start_codegen::{closure_env#0}>
65+
at ./compiler/rustc_data_structures/src/profiling.rs:839:9
66+
25: time<alloc::boxed::Box<dyn core::any::Any, alloc::alloc::Global>, rustc_interface::passes::start_codegen::{closure_env#0}>
67+
at ./compiler/rustc_session/src/utils.rs:16:50
68+
26: start_codegen
69+
at ./compiler/rustc_interface/src/passes.rs:1219:28
70+
27: codegen_and_build_linker
71+
at ./compiler/rustc_interface/src/queries.rs:32:43
72+
28: {closure#2}
73+
at ./compiler/rustc_driver_impl/src/lib.rs:386:18
74+
29: {closure#0}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>
75+
at ./compiler/rustc_interface/src/passes.rs:1002:27
76+
30: {closure#1}<rustc_interface::passes::create_and_enter_global_ctxt::{closure#2}::{closure_env#0}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>, core::option::Option<rustc_interface::queries::Linker>>
77+
at ./compiler/rustc_middle/src/ty/context.rs:1528:37
78+
31: {closure#0}<rustc_middle::ty::context::{impl#21}::enter::{closure_env#1}<rustc_interface::passes::create_and_enter_global_ctxt::{closure#2}::{closure_env#0}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>, core::option::Option<rustc_interface::queries::Linker>>, core::option::Option<rustc_interface::queries::Linker>>
79+
at ./compiler/rustc_middle/src/ty/context/tls.rs:60:9
80+
32: try_with<core::cell::Cell<*const ()>, rustc_middle::ty::context::tls::enter_context::{closure_env#0}<rustc_middle::ty::context::{impl#21}::enter::{closure_env#1}<rustc_interface::passes::create_and_enter_global_ctxt::{closure#2}::{closure_env#0}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>, core::option::Option<rustc_interface::queries::Linker>>, core::option::Option<rustc_interface::queries::Linker>>, core::option::Option<rustc_interface::queries::Linker>>
81+
at /rustc/390a0ab5dc4a895235a551e502c3893c3337731d/library/std/src/thread/local.rs:315:12
82+
33: with<core::cell::Cell<*const ()>, rustc_middle::ty::context::tls::enter_context::{closure_env#0}<rustc_middle::ty::context::{impl#21}::enter::{closure_env#1}<rustc_interface::passes::create_and_enter_global_ctxt::{closure#2}::{closure_env#0}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>, core::option::Option<rustc_interface::queries::Linker>>, core::option::Option<rustc_interface::queries::Linker>>, core::option::Option<rustc_interface::queries::Linker>>
83+
at /rustc/390a0ab5dc4a895235a551e502c3893c3337731d/library/std/src/thread/local.rs:279:20
84+
34: enter_context<rustc_middle::ty::context::{impl#21}::enter::{closure_env#1}<rustc_interface::passes::create_and_enter_global_ctxt::{closure#2}::{closure_env#0}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>, core::option::Option<rustc_interface::queries::Linker>>, core::option::Option<rustc_interface::queries::Linker>>
85+
at ./compiler/rustc_middle/src/ty/context/tls.rs:57:9
86+
35: enter<rustc_interface::passes::create_and_enter_global_ctxt::{closure#2}::{closure_env#0}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>, core::option::Option<rustc_interface::queries::Linker>>
87+
at ./compiler/rustc_middle/src/ty/context.rs:1528:9
88+
36: create_global_ctxt<core::option::Option<rustc_interface::queries::Linker>, rustc_interface::passes::create_and_enter_global_ctxt::{closure#2}::{closure_env#0}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>>
89+
at ./compiler/rustc_middle/src/ty/context.rs:1733:13
90+
37: {closure#2}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>
91+
at ./compiler/rustc_interface/src/passes.rs:969:9
92+
38: call_once<rustc_interface::passes::create_and_enter_global_ctxt::{closure_env#2}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>, (&rustc_session::session::Session, rustc_middle::ty::context::CurrentGcx, alloc::sync::Arc<rustc_data_structures::jobserver::Proxy, alloc::alloc::Global>, &std::sync::once_lock::OnceLock<rustc_middle::ty::context::GlobalCtxt>, &rustc_data_structures::sync::worker_local::WorkerLocal<rustc_middle::arena::Arena>, &rustc_data_structures::sync::worker_local::WorkerLocal<rustc_hir::Arena>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2})>
93+
at /rustc/390a0ab5dc4a895235a551e502c3893c3337731d/library/core/src/ops/function.rs:250:5
94+
39: call_once<(&rustc_session::session::Session, rustc_middle::ty::context::CurrentGcx, alloc::sync::Arc<rustc_data_structures::jobserver::Proxy, alloc::alloc::Global>, &std::sync::once_lock::OnceLock<rustc_middle::ty::context::GlobalCtxt>, &rustc_data_structures::sync::worker_local::WorkerLocal<rustc_middle::arena::Arena>, &rustc_data_structures::sync::worker_local::WorkerLocal<rustc_hir::Arena>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}), dyn core::ops::function::FnOnce<(&rustc_session::session::Session, rustc_middle::ty::context::CurrentGcx, alloc::sync::Arc<rustc_data_structures::jobserver::Proxy, alloc::alloc::Global>, &std::sync::once_lock::OnceLock<rustc_middle::ty::context::GlobalCtxt>, &rustc_data_structures::sync::worker_local::WorkerLocal<rustc_middle::arena::Arena>, &rustc_data_structures::sync::worker_local::WorkerLocal<rustc_hir::Arena>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}), Output=core::option::Option<rustc_interface::queries::Linker>>, alloc::alloc::Global>
95+
at /rustc/390a0ab5dc4a895235a551e502c3893c3337731d/library/alloc/src/boxed.rs:1966:9
96+
40: create_and_enter_global_ctxt<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>
97+
at ./compiler/rustc_interface/src/passes.rs:1010:5
98+
41: {closure#0}
99+
at ./compiler/rustc_driver_impl/src/lib.rs:343:22
100+
42: {closure#0}<(), rustc_driver_impl::run_compiler::{closure_env#0}>
101+
at ./compiler/rustc_interface/src/interface.rs:525:80
102+
43: call_once<(), rustc_interface::interface::run_compiler::{closure#1}::{closure_env#0}<(), rustc_driver_impl::run_compiler::{closure_env#0}>>
103+
at /rustc/390a0ab5dc4a895235a551e502c3893c3337731d/library/core/src/panic/unwind_safe.rs:272:9
104+
44: do_call<core::panic::unwind_safe::AssertUnwindSafe<rustc_interface::interface::run_compiler::{closure#1}::{closure_env#0}<(), rustc_driver_impl::run_compiler::{closure_env#0}>>, ()>
105+
at /rustc/390a0ab5dc4a895235a551e502c3893c3337731d/library/std/src/panicking.rs:589:40
106+
45: catch_unwind<(), core::panic::unwind_safe::AssertUnwindSafe<rustc_interface::interface::run_compiler::{closure#1}::{closure_env#0}<(), rustc_driver_impl::run_compiler::{closure_env#0}>>>
107+
at /rustc/390a0ab5dc4a895235a551e502c3893c3337731d/library/std/src/panicking.rs:552:19
108+
46: catch_unwind<core::panic::unwind_safe::AssertUnwindSafe<rustc_interface::interface::run_compiler::{closure#1}::{closure_env#0}<(), rustc_driver_impl::run_compiler::{closure_env#0}>>, ()>
109+
at /rustc/390a0ab5dc4a895235a551e502c3893c3337731d/library/std/src/panic.rs:359:14
110+
47: {closure#1}<(), rustc_driver_impl::run_compiler::{closure_env#0}>
111+
at ./compiler/rustc_interface/src/interface.rs:525:23
112+
48: {closure#0}<rustc_interface::interface::run_compiler::{closure_env#1}<(), rustc_driver_impl::run_compiler::{closure_env#0}>, ()>
113+
at ./compiler/rustc_interface/src/util.rs:199:17
114+
49: {closure#0}<rustc_interface::util::run_in_thread_pool_with_globals::{closure_env#0}<rustc_interface::interface::run_compiler::{closure_env#1}<(), rustc_driver_impl::run_compiler::{closure_env#0}>, ()>, ()>
115+
at ./compiler/rustc_interface/src/util.rs:153:24
116+
50: set<rustc_span::SessionGlobals, rustc_interface::util::run_in_thread_with_globals::{closure#0}::{closure#0}::{closure_env#0}<rustc_interface::util::run_in_thread_pool_with_globals::{closure_env#0}<rustc_interface::interface::run_compiler::{closure_env#1}<(), rustc_driver_impl::run_compiler::{closure_env#0}>, ()>, ()>, ()>
117+
at /home/ash/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/scoped-tls-1.0.1/src/lib.rs:137:9
118+
51: create_session_globals_then<(), rustc_interface::util::run_in_thread_with_globals::{closure#0}::{closure#0}::{closure_env#0}<rustc_interface::util::run_in_thread_pool_with_globals::{closure_env#0}<rustc_interface::interface::run_compiler::{closure_env#1}<(), rustc_driver_impl::run_compiler::{closure_env#0}>, ()>, ()>>
119+
at ./compiler/rustc_span/src/lib.rs:145:21
120+
52: {closure#0}<rustc_interface::util::run_in_thread_pool_with_globals::{closure_env#0}<rustc_interface::interface::run_compiler::{closure_env#1}<(), rustc_driver_impl::run_compiler::{closure_env#0}>, ()>, ()>
121+
at ./compiler/rustc_interface/src/util.rs:149:17
122+
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
123+
124+
note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md
125+
126+
note: please make sure that you have updated to the latest nightly
127+
128+
note: rustc 1.90.0-dev running on x86_64-unknown-linux-gnu
129+
130+
note: compiler flags: -Z threads=1 -Z simulate-remapped-rust-src-base=/rustc/FAKE_PREFIX -Z translate-remapped-path-to-local-path=no -Z ignore-directory-in-diagnostics-source-blocks=/home/ash/.cargo -Z ignore-directory-in-diagnostics-source-blocks=/home/ash/Projects/foss/rust/working/vendor -C codegen-units=1 -Z ui-testing -Z deduplicate-diagnostics=no -Z write-long-types-to-disk=no -C strip=debuginfo -C prefer-dynamic -C rpath -C debuginfo=0
131+
132+
query stack during panic:
133+
end of query stack
134+
error: aborting due to 1 previous error
135+

0 commit comments

Comments
 (0)