Change:
In the following example, and are allowed but isn't: The reason is that is lowered to in MIR, and that's not handled in const-checking as a and an assignment (which it functionally is). EDIT: nevermind, promotion works based on temporaries, so it shouldn't be affected. cc
I'm going to label this as a bug since it seems covered by from a T-Lang perspective.

Discussion:
#[derive(Copy, Clone, Debug)] enum ValueSource<'a, 'tcx> { Rvalue(&'a Rvalue<'tcx>), <ins> DropAndReplace(&'a Operand<'tcx>), </ins> Call { callee: &'a Operand<'tcx>, args: &'a [Operand<'tcx>],

fn in_value(cx: &ConstCx<'_, 'tcx>, source: ValueSource<'_, 'tcx>) -> bool { match source { ValueSource::Rvalue(rvalue) => Self::in_rvalue(cx, rvalue), <ins> ValueSource::DropAndReplace(source) => Self::in_operand(cx, source), </ins> ValueSource::Call { callee, args, return_ty } => { Self::in_call(cx, callee, args, return_ty) }

let target = match body[bb].terminator().kind { TerminatorKind::Goto { target } | TerminatorKind::Drop { target, .. } | <ins> TerminatorKind::DropAndReplace { target, .. } | </ins> TerminatorKind::Assert { target, .. } | TerminatorKind::Call { destination: Some((_, target)), .. } => { Some(target)

} TerminatorKind::SwitchInt {..} | <del> TerminatorKind::DropAndReplace { .. } | </del> TerminatorKind::Resume | TerminatorKind::Abort | TerminatorKind::GeneratorDrop |

for arg in args { self.visit_operand(arg, location); } <del> } else if let TerminatorKind::Drop { location: ref place, .. } = *kind { self.super_terminator_kind(kind, location); </del> <ins> } else if let TerminatorKind::Drop { location: ref place, .. } | TerminatorKind::DropAndReplace { location: ref place, .. } = *kind { match *kind { TerminatorKind::DropAndReplace { .. } => {} _ => self.super_terminator_kind(kind, location), } </ins> // Deny *any* live drops anywhere other than functions. if self.mode.requires_const_checking() {

} } } <ins> match *kind { TerminatorKind::DropAndReplace { ref value, .. } => { self.assign(place, ValueSource::DropAndReplace(value), location); self.visit_operand(value, location); } _ => {} } </ins> } else { // Qualify any operands inside other terminators. self.super_terminator_kind(kind, location);

// ok const X: FakeNeedsDrop = { let x = FakeNeedsDrop; x }; <ins> // ok (used to incorrectly error, see #62273) const X2: FakeNeedsDrop = { let x; x = FakeNeedsDrop; x }; </ins> // error const Y: FakeNeedsDrop = { let mut x = FakeNeedsDrop; x = FakeNeedsDrop; x }; <del> //~^ ERROR constant contains unimplemented expression type </del> <ins> //~^ ERROR destructors cannot be evaluated at compile-time // error const Y2: FakeNeedsDrop = { let mut x; x = FakeNeedsDrop; x = FakeNeedsDrop; x }; //~^ ERROR destructors cannot be evaluated at compile-time </ins> // error const Z: () = { let mut x = None; x = Some(FakeNeedsDrop); }; <del> //~^ ERROR constant contains unimplemented expression type </del> <ins> //~^ ERROR destructors cannot be evaluated at compile-time // error const Z2: () = { let mut x; x = None; x = Some(FakeNeedsDrop); }; //~^ ERROR destructors cannot be evaluated at compile-time </ins>

<del> error[E0019]: constant contains unimplemented expression type --> $DIR/const_let.rs:13:55 </del> <ins> error[E0493]: destructors cannot be evaluated at compile-time --> $DIR/const_let.rs:16:32 </ins> | LL | const Y: FakeNeedsDrop = { let mut x = FakeNeedsDrop; x = FakeNeedsDrop; x }; <del> |                                                       ^ </del> <ins> |                                ^^^^^ constants cannot evaluate destructors </ins> <del> error[E0019]: constant contains unimplemented expression type --> $DIR/const_let.rs:17:35 </del> <ins> error[E0493]: destructors cannot be evaluated at compile-time --> $DIR/const_let.rs:20:33 | LL | const Y2: FakeNeedsDrop = { let mut x; x = FakeNeedsDrop; x = FakeNeedsDrop; x }; |                                 ^^^^^ constants cannot evaluate destructors error[E0493]: destructors cannot be evaluated at compile-time --> $DIR/const_let.rs:24:21 </ins> | LL | const Z: () = { let mut x = None; x = Some(FakeNeedsDrop); }; <del> |                                   ^ </del> <ins> |                     ^^^^^ constants cannot evaluate destructors error[E0493]: destructors cannot be evaluated at compile-time --> $DIR/const_let.rs:28:22 | LL | const Z2: () = { let mut x; x = None; x = Some(FakeNeedsDrop); }; |                      ^^^^^ constants cannot evaluate destructors </ins> <del> error: aborting due to 2 previous errors </del> <ins> error: aborting due to 4 previous errors </ins> <del> For more information about this error, try `rustc --explain E0019`. </del>