Change:
I have some code which asynchronously computes an integer, and selects an item from a static slice in the same expression. This used to work (it does on stable), but after a nightly update the compiler ICEs when computing generator layout. The bug stops reproducing if I change the static to a local variable, or extract the index into a separate variable. rustc 1.41.0-nightly ( 2019-11-23) binary: rustc commit-hash: commit-date: 2019-11-23 host: x86_64-unknown-linux-gnu release: 1.41.0-nightly LLVM version: 9.0
De-nominating from compiler team as we have a fix pending.
triage: P-high.

Discussion:
self.static_mutability(def_id) == Some(hir::Mutability::Mutable) } <ins> /// Get the type of the pointer to the static that we use in MIR. pub fn static_ptr_ty(&self, def_id: DefId) -> Ty<'tcx> { // Make sure that any constants in the static's type are evaluated. let static_ty = self.normalize_erasing_regions( ty::ParamEnv::empty(), self.type_of(def_id), ); if self.is_mutable_static(def_id) { self.mk_mut_ptr(static_ty) } else if self.is_foreign_item(def_id) { self.mk_imm_ptr(static_ty) } else { self.mk_imm_ref(self.lifetimes.re_erased, static_ty) } } </ins> /// Expands the given impl trait type, stopping if the type is recursive. pub fn try_expand_impl_trait_type( self,

// We encode uses of statics as a `*&STATIC` where the `&STATIC` part is // a constant reference (or constant raw pointer for `static mut`) in MIR Res::Def(DefKind::Static, id) => { <del> let ty = cx.tcx.type_of(id); let ty = if cx.tcx.is_mutable_static(id) { cx.tcx.mk_mut_ptr(ty) } else if cx.tcx.is_foreign_item(id) { cx.tcx.mk_imm_ptr(ty) } else { cx.tcx.mk_imm_ref(cx.tcx.lifetimes.re_static, ty) }; </del> <ins> let ty = cx.tcx.static_ptr_ty(id); </ins> let ptr = cx.tcx.alloc_map.lock().create_static_alloc(id); let temp_lifetime = cx.region_scope_tree.temporary_scope(expr.hir_id.local_id); ExprKind::Deref { arg: Expr {

} fn visit_expr(&mut self, expr: &'tcx Expr) { <ins> let scope = self.region_scope_tree.temporary_scope(expr.hir_id.local_id); </ins> match &expr.kind { ExprKind::Call(callee, args) => match &callee.kind { ExprKind::Path(qpath) => {

} _ => intravisit::walk_expr(self, expr), } <ins> ExprKind::Path(qpath) => { let res = self.fcx.tables.borrow().qpath_res(qpath, expr.hir_id); if let Res::Def(DefKind::Static, def_id) = res { // Statics are lowered to temporary references or // pointers in MIR, so record that type. let ptr_ty = self.fcx.tcx.static_ptr_ty(def_id); self.record(ptr_ty, scope, Some(expr), expr.span); } } </ins> _ => intravisit::walk_expr(self, expr), } self.expr_count += 1; <del> let scope = self.region_scope_tree.temporary_scope(expr.hir_id.local_id); </del> // If there are adjustments, then record the final type -- // this is the actual value that is being produced. if let Some(adjusted_ty) = self.fcx.tables.borrow().expr_ty_adjusted_opt(expr) {

<ins> // build-pass // edition:2018 static A: [i32; 5] = [1, 2, 3, 4, 5]; async fn fun() { let u = A[async { 1 }.await]; match A { i if async { true }.await => (), _ => (), } } fn main() { async { let u = A[async { 1 }.await]; }; async { match A { i if async { true }.await => (), _ => (), } }; } </ins>

<ins> // build-pass #![feature(generators)] static A: [i32; 5] = [1, 2, 3, 4, 5]; fn main() { static || { let u = A[{yield; 1}]; }; static || { match A { i if { yield; true } => (), _ => (), } }; } </ins>