Change:
<ins> // compile-flags: -Zmir-opt-level=1 trait NeedsDrop:Sized{ const NEEDS:bool=std::mem::needs_drop::<Self>(); } impl<This> NeedsDrop for This{} fn hello<T>(){ if <bool>::NEEDS { panic!() } } pub fn main() { hello::<()>(); hello::<Vec<()>>(); } // END RUST SOURCE // START rustc.hello.ConstProp.before.mir // let mut _0: (); // let mut _1: bool; // let mut _2: !; // bb0: { //   StorageLive(_1); //   _1 = const <bool as NeedsDrop>::NEEDS; //   switchInt(_1) -> [false: bb1, otherwise: bb2]; // } // bb1: { //   _0 = (); //   StorageDead(_1); //   return; // } // bb2: { //   StorageLive(_2); //   const std::rt::begin_panic::<&str>(const "explicit panic"); // } // END rustc.hello.ConstProp.before.mir // START rustc.hello.ConstProp.after.mir // let mut _0: (); // let mut _1: bool; // let mut _2: !; // bb0: { //   StorageLive(_1); //   _1 = const false; //   switchInt(const false) -> [false: bb1, otherwise: bb2]; // } // bb1: { //   _0 = (); //   StorageDead(_1); //   return; // } // bb2: { //   StorageLive(_2); //   const std::rt::begin_panic::<&str>(const "explicit panic"); // } // END rustc.hello.ConstProp.after.mir // START rustc.hello.PreCodegen.before.mir // let mut _0: (); // bb0: { //   return; // } // END rustc.hello.PreCodegen.before.mir </ins>

Discussion:
The assembly generated in debug builds (-C opt-level=0) worsened for this code that uses an associated constant from a trait.This seems to be caused by the fact that the function is generic,even though the associated constant doesn't depend on the generic parameters of the function. The code: The entirety of the generated assembly for stable 1.41.0 in a debug build: The assembly generated for the same functions by rustc 1.42.0-beta.2 (2020-02-04 ) in a debug build:
out of curiosity, what prompted you to investigate this specific code sequence? (I'm trying to evaluate the severity of this code-quality regression, and it might help for me to get some idea of how wide-spread the problem might be. There are obviously a couple different features interacting in the example you have provided...)
triage: leaving unprioritized. Nominating for discussion at today's T-compiler triage meeting.
I was experimenting to figure out the best design for a feature I want to add to eventually,being efficient in debug builds is a plus(but not a hard requirement for me). The reason I reported this is that if it optimizes fine in non-generic functions,it should also do the same optimization in generic functions(so long as the constant doesn't depend on generic parameters).
How does LLVM even generate such a code sequence? Well...: Okay so I guess LLVM doesn't even simplify the CFG when optimizations are off? <hr/Anyway, the MIR differs. This is a constant folding regression. cc
I'm guessing this is caused by We're in a generic context and resolve has to be conservative so it doesn't accidentally try to inline a default value if it could get a different value in an impl. In this situation that can't happen, but I don't know how to coax resolve to know this.
The fix was already implemented though! already returns in the problematic cases. Users of don't need to special-case anything anymore. Nor do we ever need to use just because something might be polymorphic, because the fix is in already, as it has been in for associated types. I left comments here:
T-compiler triage: P-medium. Leaving nomination tag on until we actually assign this to someone.