Change:
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --(also reproduced in beta and nightly) <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<pNo backtrace generated </p</details
This is already fixed on nightly, I just tried it locally. Can you confirm?
Installed nightly last night but to double check:
Hmm... must be apple specific. Do you have a gdb handy that you could run on that last rustc invocation to obtain a stack trace?
Having problems getting it working, not normally a debugger person (been years since I've run gdb) and not much of a Mac person (work computer). I installed for nightly and I get Then when I run, I get
hmm... not sure what our gdb capabilities on mac are. I'll try to find someone who's building rustc on macs. Thanks for the attempt!
I'm looking into producing a build locally.
backtrace:
Looks like my CI saw a stack overflow on Windows as well
lol I recently (two days ago) looked at and went "oh this could stack overflow, why is this not a loop". I'll (try to) fix this without inserting more stacker invocations

Discussion:
use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; <ins> use smallvec::SmallVec; </ins> use std::borrow::Cow; pub struct SimplifyCfg {

} } <del> // Collapse a goto chain starting from `start` fn collapse_goto_chain(&mut self, start: &mut BasicBlock, changed: &mut bool) { let mut terminator = match self.basic_blocks[*start] { </del> <ins> /// This function will return `None` if /// * the block has statements /// * the block has a terminator other than `goto` /// * the block has no terminator (meaning some other part of the current optimization stole it) fn take_terminator_if_simple_goto(&mut self, bb: BasicBlock) -> Option<Terminator<'tcx>> { match self.basic_blocks[bb] { </ins> BasicBlockData { ref statements, terminator:

} if statements.is_empty() => terminator.take(), // if `terminator` is None, this means we are in a loop. In that // case, let all the loop collapse to its entry. <del> _ => return, }; let target = match terminator { Some(Terminator { kind: TerminatorKind::Goto { ref mut target }, .. }) => { self.collapse_goto_chain(target, changed); *target } _ => unreachable!(), }; self.basic_blocks[*start].terminator = terminator; debug!("collapsing goto chain from {:?} to {:?}", *start, target); *changed |= *start != target; </del> <ins> _ => None, } } </ins> <del> if self.pred_count[*start] == 1 { // This is the last reference to *start, so the pred-count to // to target is moved into the current block. self.pred_count[*start] = 0; } else { self.pred_count[target] += 1; self.pred_count[*start] -= 1; </del> <ins> /// Collapse a goto chain starting from `start` fn collapse_goto_chain(&mut self, start: &mut BasicBlock, changed: &mut bool) { // Using `SmallVec` here, because in some logs on libcore oli-obk saw many single-element // goto chains. We should probably benchmark different sizes. let mut terminators: SmallVec<[_; 1]> = Default::default(); let mut current = *start; while let Some(terminator) = self.take_terminator_if_simple_goto(current) { let target = match terminator { Terminator { kind: TerminatorKind::Goto { target }, .. } => target, _ => unreachable!(), }; terminators.push((current, terminator)); current = target; </ins> } <ins> let last = current; *start = last; while let Some((current, mut terminator)) = terminators.pop() { let target = match terminator { Terminator { kind: TerminatorKind::Goto { ref mut target }, .. } => target, _ => unreachable!(), }; *target = last; debug!("collapsing goto chain from {:?} to {:?}", current, target); </ins> <del> *start = target; </del> <ins> if self.pred_count[current] == 1 { // This is the last reference to current, so the pred-count to // to target is moved into the current block. self.pred_count[current] = 0; } else { self.pred_count[*target] += 1; self.pred_count[current] -= 1; } *changed = true; self.basic_blocks[current].terminator = Some(terminator); } </ins> } // merge a block with 1 `goto` predecessor to its parent