Change:
Compiles in stable rust (1.64) as well as in beta. But in nightly, we get this compilation error: playground link: 64, and beta current nightly
searched nightlies: from nightly-2022-08-01 to nightly-2022-10-24 regressed nightly: nightly-2022-09-23 searched commit range: regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.4</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </details
Seems like closures pick the constness of their parent when they should always be notconst

Discussion:
cast_ty: Ty<'tcx>, cast_span: Span, span: Span, <ins> /// whether the cast is made in a const context or not. pub constness: hir::Constness, </ins> } /// The kind of pointer and associated metadata (thin, length or vtable) - we

cast_ty: Ty<'tcx>, cast_span: Span, span: Span, <ins> constness: hir::Constness, </ins> ) -> Result<CastCheck<'tcx>, ErrorGuaranteed> { let expr_span = expr.span.find_ancestor_inside(span).unwrap_or(expr.span); <del> let check = CastCheck { expr, expr_ty, expr_span, cast_ty, cast_span, span }; </del> <ins> let check = CastCheck { expr, expr_ty, expr_span, cast_ty, cast_span, span, constness }; </ins> // For better error messages, check for some obviously unsized // cases now. We do a more thorough check at the end, once

} else { // Defer other checks until we're done type checking. let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut(); <del> match cast::CastCheck::new(self, e, t_expr, t_cast, t.span, expr.span) { </del> <ins> match cast::CastCheck::new( self, e, t_expr, t_cast, t.span, expr.span, self.param_env.constness(), ) { </ins> Ok(cast_check) => { debug!( "check_expr_cast: deferring cast from {:?} to {:?}: {:?}",

use rustc_trait_selection::traits::{self, ObligationCauseCode, SelectionContext}; use std::iter; <ins> use std::mem; </ins> use std::ops::ControlFlow; use std::slice; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { <del> pub(in super::super) fn check_casts(&self) { let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut(); </del> <ins> pub(in super::super) fn check_casts(&mut self) { // don't hold the borrow to deferred_cast_checks while checking to avoid borrow checker errors // when writing to `self.param_env`. let mut deferred_cast_checks = mem::take(&mut *self.deferred_cast_checks.borrow_mut()); </ins> debug!("FnCtxt::check_casts: {} deferred checks", deferred_cast_checks.len()); for cast in deferred_cast_checks.drain(..) { <ins> let prev_env = self.param_env; self.param_env = self.param_env.with_constness(cast.constness); </ins> cast.check(self); <ins> self.param_env = prev_env; </ins> } <ins> *self.deferred_cast_checks.borrow_mut() = deferred_cast_checks; </ins> } pub(in super::super) fn check_transmutes(&self) {

<ins> // check-pass const _: fn(&String) = |s| { &*s as &str; }; fn main() {} </ins>

use rustc_lint::LateContext; use rustc_middle::ty::{cast::CastKind, Ty}; use rustc_span::DUMMY_SP; <ins> use rustc_hir as hir; </ins> // check if the component types of the transmuted collection and the result have different ABI, // size or alignment

if let Ok(check) = cast::CastCheck::new( &fn_ctxt, e, from_ty, to_ty, // We won't show any error to the user, so we don't care what the span is here. <del> DUMMY_SP, DUMMY_SP, </del> <ins> DUMMY_SP, DUMMY_SP, hir::Constness::NotConst, </ins> ) { let res = check.do_check(&fn_ctxt);