Change:
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.

Discussion:
) -> ConstPropagator<'mir, 'tcx> { let def_id = source.def_id(); let substs = &InternalSubsts::identity_for_item(tcx, def_id); <del> let mut param_env = tcx.param_env(def_id); // If we're evaluating inside a monomorphic function, then use `Reveal::All` because // we want to see the same instances that codegen will see. This allows us to `resolve()` // specializations. if !substs.needs_subst() { param_env = param_env.with_reveal_all(); } </del> <ins> let param_env = tcx.param_env(def_id).with_reveal_all(); </ins> let span = tcx.def_span(def_id); let mut ecx = InterpCx::new(tcx.at(span), param_env, ConstPropMachine, ());

use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc::mir::visit::*; use rustc::mir::*; <del> use rustc::ty::subst::{InternalSubsts, Subst, SubstsRef}; use rustc::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt, TypeFoldable}; </del> <ins> use rustc::ty::subst::{Subst, SubstsRef}; use rustc::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt}; </ins> use rustc_attr as attr; use rustc_hir::def_id::DefId; use rustc_index::bit_set::BitSet;

let mut callsites = VecDeque::new(); <del> let mut param_env = self.tcx.param_env(self.source.def_id()); let substs = &InternalSubsts::identity_for_item(self.tcx, self.source.def_id()); // For monomorphic functions, we can use `Reveal::All` to resolve specialized instances. if !substs.needs_subst() { param_env = param_env.with_reveal_all(); } </del> <ins> let param_env = self.tcx.param_env(self.source.def_id()).with_reveal_all(); </ins> // Only do inlining into fn bodies. let id = self.tcx.hir().as_local_hir_id(self.source.def_id()).unwrap();

<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>