ICE: `OpaqueCast unexpected because it isn't captured` in `rustc_middle/src/ty/closure.rs`
Open
Nobody has claimed this yet.
C-bug
I-ICE
S-bug-has-test
T-compiler
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
Code
(hand-reduced)
#![warn(rust_2021_compatibility)]
trait Static<'a> {}
struct Foo((u32, u32));
fn main() {
type T = impl Static;
let foo: T = Foo((1u32, 2u32));
let x = move || {
let Foo((a, b)) = foo;
};
}
I'm not sure whether it is okay to report ICE which requires #![warn(rust_2021_compatibility)] attribute.
(original, ~100 lines)
//@ edition:2018
//@ revisions: rpass1
// Regression test for #86753. The `type_implements_trait` query (since moved to a method)
// was encountering an ICE during incremental testing when hashing its arguments.
#![warn(rust_2021_compatibility)]
use std::future::Future;
use std::pin::Pin;
use std::task::{Poll, Context};
struct LocalSet {}
struct RunUntil<'a, F> {
_local_set: &'a LocalSet,
_future: F,
}
impl<'a, F> RunUntil<'a, F> {
fn project<'pin>(self: Pin<&'pin mut Self>) -> Projection<'pin, 'a, F> {
unimplemented!()
}
}
struct Projection<'pin, 'a, F>
where
RunUntil<'a, F>: 'pin,
{
pub local_set: &'pin mut &'a LocalSet,
pub future: Pin<&'pin mut F>,
}
impl LocalSet {
fn with<T>(&self, _f: impl FnOnce() -> T) -> T {
unimplemented!()
}
}
impl<T: Future> Future for RunUntil<'_, T> {
type Output = T::Output;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let me = self.project();
me.local_set.with(|| {
let _ = cx.waker();
let f = me.future;
let _ = f.poll(cx);
Poll::Pending
})
}
}
fn main() {}
#![feature(arbitrary_self_types)]
trait Static<'a> {
fn proof(self: *const Self, s: &'a str) -> &'static str;
}
fn bad_cast<'a>(x: Self::Output) -> *const dyn Static<'a> {
x as _
}
impl Static<'static> for () {
fn proof(self: *const Self, s: &'static str) -> &'static str {
s
}
}
fn extend_lifetime(s: &str) -> &'static str {
bad_cast(&()).proof(s)
}
fn main() {
let s = String::from("Hello World");
let slice = extend_lifetime(&s);
println!("Now it exists: {slice}");
drop(s);
println!("Now it’s gone: {slice}");
}
#![feature(type_alias_impl_trait)]
#[derive(Copy, Clone)]
struct Foo((u32, u32));
fn main() {
type T = impl Static;
let foo: T = Foo((1u32, 2u32));
let x = move || {
let Foo((a, b)) = foo;
};
}
Meta
rustc --version --verbose:
rustc 1.81.0-nightly (8fcd4dd08 2024-06-18)
binary: rustc
commit-hash: 8fcd4dd08e2ba3e922d917d819ba0be066bdb005
commit-date: 2024-06-18
host: x86_64-apple-darwin
release: 1.81.0-nightly
LLVM version: 18.1.7
Error output
Command: rustc
error[E0106]: missing lifetime specifier
--> r_closure331_419FDD4D.rs:8:19
|
8 | type T = impl Static;
| ^^^^^^ expected named lifetime parameter
|
= note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
help: consider making the bound lifetime-generic with a new `'a` lifetime
|
8 | type T = impl for<'a> Static<'a>;
| +++++++ ++++
help: consider introducing a named lifetime parameter
|
8 | type T<'a> = impl Static<'a>;
| ++++ ++++
error[E0658]: `impl Trait` in type aliases is unstable
--> r_closure331_419FDD4D.rs:8:14
|
8 | type T = impl Static;
| ^^^^^^^^^^^
|
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
= help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
= note: this compiler was built on 2024-06-18; consider upgrading it if it is out of date
Backtrace
error: internal compiler error: compiler/rustc_middle/src/ty/closure.rs:331:21: OpaqueCast unexpected because it isn't captured
thread 'rustc' panicked at compiler/rustc_middle/src/ty/closure.rs:331:21:
Box<dyn Any>
stack backtrace:
0: std::panicking::begin_panic::<rustc_errors::ExplicitBug>
1: <rustc_errors::diagnostic::BugAbort as rustc_errors::diagnostic::EmissionGuarantee>::emit_producing_guarantee
2: rustc_middle::util::bug::opt_span_bug_fmt::<rustc_span::span_encoding::Span>::{closure#0}
3: rustc_middle::ty::context::tls::with_opt::<rustc_middle::util::bug::opt_span_bug_fmt<rustc_span::span_encoding::Span>::{closure#0}, !>::{closure#0}
4: rustc_middle::ty::context::tls::with_context_opt::<rustc_middle::ty::context::tls::with_opt<rustc_middle::util::bug::opt_span_bug_fmt<rustc_span::span_encoding::Span>::{closure#0}, !>::{closure#0}, !>
5: rustc_middle::util::bug::bug_fmt
6: rustc_middle::ty::closure::place_to_string_for_capture
7: <rustc_hir_typeck::fn_ctxt::FnCtxt>::compute_2229_migrations
8: <rustc_hir_typeck::fn_ctxt::FnCtxt>::analyze_closure
9: <rustc_hir_typeck::upvar::InferBorrowKindVisitor as rustc_hir::intravisit::Visitor>::visit_expr
10: <rustc_hir_typeck::upvar::InferBorrowKindVisitor as rustc_hir::intravisit::Visitor>::visit_block
11: rustc_hir_typeck::typeck
[... omitted 1 frame ...]
12: rustc_middle::query::plumbing::query_get_at::<rustc_query_system::query::caches::VecCache<rustc_span::def_id::LocalDefId, rustc_middle::query::erase::Erased<[u8; 8]>>>
13: <rustc_hir_analysis::collect::type_of::opaque::TaitConstraintLocator>::check
14: rustc_hir_analysis::collect::type_of::type_of_opaque
[... omitted 1 frame ...]
15: rustc_middle::query::plumbing::query_get_at::<rustc_query_system::query::caches::DefIdCache<rustc_middle::query::erase::Erased<[u8; 8]>>>
16: rustc_hir_analysis::collect::type_of::type_of
[... omitted 1 frame ...]
17: rustc_middle::query::plumbing::query_get_at::<rustc_query_system::query::caches::DefIdCache<rustc_middle::query::erase::Erased<[u8; 8]>>>
18: rustc_hir_analysis::check::check::check_item_type
19: rustc_hir_analysis::check::wfcheck::check_well_formed
[... omitted 1 frame ...]
20: rustc_middle::query::plumbing::query_ensure_error_guaranteed::<rustc_query_system::query::caches::VecCache<rustc_hir::hir_id::OwnerId, rustc_middle::query::erase::Erased<[u8; 1]>>, ()>
21: rustc_hir_analysis::check::wfcheck::check_mod_type_wf
[... omitted 1 frame ...]
22: rustc_hir_analysis::check_crate
23: rustc_interface::passes::run_required_analyses
24: rustc_interface::passes::analysis
[... omitted 1 frame ...]
25: <rustc_interface::queries::QueryResult<&rustc_middle::ty::context::GlobalCtxt>>::enter::<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure#0}::{closure#1}::{closure#3}>
26: rustc_interface::interface::run_compiler::<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure#0}>::{closure#1}
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
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
note: please make sure that you have updated to the latest nightly
note: please attach the file at `/Volumes/T7/workspace/240615_100chaos_tree_combine_typ/icefiles/rustc-ice-2024-06-19T06_47_34-44593.txt` to your bug report
query stack during panic:
#0 [typeck] type-checking `main`
#1 [type_of_opaque] computing type of opaque `main::T::{opaque#0}`
#2 [type_of] computing type of `main::T::{opaque#0}`
#3 [check_well_formed] checking that `main::T::{opaque#0}` is well-formed
#4 [check_mod_type_wf] checking that types are well-formed in top-level module
#5 [analysis] running analysis passes on this crate
end of query stack
error[E0391]: cycle detected when computing type of opaque `main::T::{opaque#0}`
--> r_closure331_419FDD4D.rs:8:14
|
8 | type T = impl Static;
| ^^^^^^^^^^^
|
note: ...which requires type-checking `main`...
--> r_closure331_419FDD4D.rs:7:1
|
7 | fn main() {
| ^^^^^^^^^
= note: ...which requires evaluating trait selection obligation `main::T: core::panic::unwind_safe::RefUnwindSafe`...
= note: ...which again requires computing type of opaque `main::T::{opaque#0}`, completing the cycle
note: cycle used when computing type of `main::T::{opaque#0}`
--> r_closure331_419FDD4D.rs:8:14
|
8 | type T = impl Static;
| ^^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0106, E0391, E0658.
For more information about an error, try `rustc --explain E0106`.
Note
- ICE location:
compiler/rustc_middle/src/ty/closure.rs#L331
https://github.com/rust-lang/rust/blob/8fcd4dd08e2ba3e922d917d819ba0be066bdb005/compiler/rustc_middle/src/ty/closure.rs#L309-L332 - Might be related to Issue-109298, which points to identical ICE location.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with compiler/rustc_middle/src/ty/closure.rs around the cited line 331 and compare the behavior with issue #109298, which may involve the same ICE location. Run the hand-reduced example with the reported nightly compiler and trace the closure capture path shown in the backtrace. Done means the example no longer triggers an internal compiler error and has coverage for the regression.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100