Closed
Description
This bug popped up in CI on a project of ours. This does not reproduce on stable, but does reproduce on nightly and the latest beta (1.56.0-beta.4
). Bisection shows that nightly-2021-09-26
was the first build with the regression. Further bisection points to 6867dd2 being the commit that introduced the regression. If I had to guess from the PRs in the rollup I'd say #89208 seems the most likely, since it touched the code around the error source.
Code
use std::borrow::Cow;
pub type Block = [u8];
pub type BlockAncestorBlock<'a> = Cow<'a, [u8]>;
enum Fork {
Local,
Foreign,
}
pub struct BlockHeader<'a> {
pub block: Cow<'a, Block>,
}
pub struct PairedFork<'a>
{
local_head_block: Option<BlockAncestorBlock<'a>>,
foreign_head_block: Option<BlockAncestorBlock<'a>>,
}
impl<'a> Iterator for PairedFork<'a>
{
type Item = (BlockHeader<'a>, BlockHeader<'a>);
fn next(&mut self) -> Option<Self::Item> {
let tuplify = |prev_header: Option<BlockHeader<'a>>| match prev_header {
Some(block_header) => (
Some(Cow::Owned(Vec::from(block_header.block))),
Some(block_header),
),
None => (None, None),
};
let mut advance = |fork: Fork| {
let PairedFork {
local_head_block,
foreign_head_block,
} = self;
let (next_block, header) = tuplify(None);
match fork {
Fork::Local => self.local_head_block = next_block,
Fork::Foreign => self.foreign_head_block = next_block,
};
header
};
None
}
}
Meta
rustc --version --verbose
:
rustc 1.57.0-nightly (25ec82738 2021-10-05)
binary: rustc
commit-hash: 25ec8273855fde2d72ae877b397e054de5300e10
commit-date: 2021-10-05
host: x86_64-unknown-linux-gnu
release: 1.57.0-nightly
LLVM version: 13.0.0
Error output
thread 'rustc' panicked at 'internal error: entered unreachable code: we captured two identical projections: capture1 = CapturedPlace { place: Place { base_ty: &mut PairedFork<'a>, base: Upvar(UpvarId(HirId { owner: DefId(0:24 ~ regression[aef9]::{impl#0}::next), local_id: 2 };`self`;DefId(0:26 ~ regression[aef9]::{impl#0}::next::{closure#1}))), projections: [Projection { ty: PairedFork<'a>, kind: Deref }, Projection { ty: std::option::Option<std::borrow::Cow<'a, [u8]>>, kind: Field(1, 0) }] }, info: CaptureInfo { capture_kind_expr_id: Some(HirId { owner: DefId(0:24 ~ regression[aef9]::{impl#0}::next), local_id: 91 }), path_expr_id: Some(HirId { owner: DefId(0:24 ~ regression[aef9]::{impl#0}::next), local_id: 91 }), capture_kind: ByRef(UpvarBorrow(MutBorrow, '_#30r)) }, mutability: Mut }, capture2 = CapturedPlace { place: Place { base_ty: &mut PairedFork<'a>, base: Upvar(UpvarId(HirId { owner: DefId(0:24 ~ regression[aef9]::{impl#0}::next), local_id: 2 };`self`;DefId(0:26 ~ regression[aef9]::{impl#0}::next::{closure#1}))), projections: [Projection { ty: PairedFork<'a>, kind: Deref }, Projection { ty: std::option::Option<std::borrow::Cow<'_, [u8]>>, kind: Field(1, 0) }] }, info: CaptureInfo { capture_kind_expr_id: Some(HirId { owner: DefId(0:24 ~ regression[aef9]::{impl#0}::next), local_id: 54 }), path_expr_id: Some(HirId { owner: DefId(0:24 ~ regression[aef9]::{impl#0}::next), local_id: 54 }), capture_kind: ByRef(UpvarBorrow(MutBorrow, '_#27r)) }, mutability: Mut }', compiler/rustc_typeck/src/check/upvar.rs:665:17
Backtrace
stack backtrace:
0: rust_begin_unwind
at /rustc/25ec8273855fde2d72ae877b397e054de5300e10/library/std/src/panicking.rs:517:5
1: core::panicking::panic_fmt
at /rustc/25ec8273855fde2d72ae877b397e054de5300e10/library/core/src/panicking.rs:100:14
2: alloc::slice::<impl [T]>::sort_by::{{closure}}
3: alloc::slice::merge_sort
4: rustc_typeck::check::upvar::<impl rustc_typeck::check::fn_ctxt::FnCtxt>::compute_min_captures
5: rustc_typeck::check::upvar::<impl rustc_typeck::check::fn_ctxt::FnCtxt>::analyze_closure
6: rustc_hir::intravisit::walk_stmt
7: rustc_hir::intravisit::walk_block
8: rustc_hir::intravisit::walk_body
9: rustc_infer::infer::InferCtxtBuilder::enter
10: rustc_typeck::check::typeck
11: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task
12: rustc_data_structures::stack::ensure_sufficient_stack
13: rustc_query_system::query::plumbing::try_execute_query
14: <rustc_query_impl::Queries as rustc_middle::ty::query::QueryEngine>::typeck
15: rustc_typeck::check::typeck
16: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task
17: rustc_data_structures::stack::ensure_sufficient_stack
18: rustc_query_system::query::plumbing::try_execute_query
19: <rustc_query_impl::Queries as rustc_middle::ty::query::QueryEngine>::typeck
20: rustc_data_structures::sync::par_for_each_in
21: rustc_typeck::check::typeck_item_bodies
22: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task
23: rustc_data_structures::stack::ensure_sufficient_stack
24: rustc_query_system::query::plumbing::try_execute_query
25: <rustc_query_impl::Queries as rustc_middle::ty::query::QueryEngine>::typeck_item_bodies
26: rustc_session::utils::<impl rustc_session::session::Session>::time
27: rustc_typeck::check_crate
28: rustc_interface::passes::analysis
29: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task
30: rustc_data_structures::stack::ensure_sufficient_stack
31: rustc_query_system::query::plumbing::try_execute_query
32: <rustc_query_impl::Queries as rustc_middle::ty::query::QueryEngine>::analysis
33: rustc_interface::queries::<impl rustc_interface::interface::Compiler>::enter
34: rustc_span::with_source_map
35: scoped_tls::ScopedKey<T>::set
query stack during panic:
#0 [typeck] type-checking `<impl at src/main.rs:21:1: 47:2>::next`
#1 [typeck] type-checking `<impl at src/main.rs:21:1: 47:2>::next::{closure#0}`
end of query stack