//@ test-mir-pass: GVN //@ compile-flags: --crate-type lib //! Regressions test for a mis-optimization where some functions //! (`type_id` / `type_name` / `needs_drop`) could be evaluated in //! a generic context, even though their value depends on some type //! parameter `T`. //! //! In particular, `type_name_of_val(&generic::)` was incorrectly //! evaluated to the string "crate_name::generic::", and //! `no_optimize` was incorrectly optimized to `false`. #![feature(const_type_name)] fn generic() {} const fn type_name_contains_i32(_: &T) -> bool { let pattern = b"i32"; let name = std::any::type_name::().as_bytes(); let mut i = 0; 'outer: while i < name.len() - pattern.len() + 1 { let mut j = 0; while j < pattern.len() { if name[i + j] != pattern[j] { i += 1; continue 'outer; } j += 1; } return true; } false } // EMIT_MIR gvn_const_eval_polymorphic.optimize_true.GVN.diff fn optimize_true() -> bool { // CHECK-LABEL: fn optimize_true( // CHECK: _0 = const true; // CHECK-NEXT: return; (const { type_name_contains_i32(&generic::) }) == const { true } } // EMIT_MIR gvn_const_eval_polymorphic.optimize_false.GVN.diff fn optimize_false() -> bool { // CHECK-LABEL: fn optimize_false( // CHECK: _0 = const false; // CHECK-NEXT: return; (const { type_name_contains_i32(&generic::) }) == const { true } } // EMIT_MIR gvn_const_eval_polymorphic.no_optimize.GVN.diff fn no_optimize() -> bool { // CHECK-LABEL: fn no_optimize( // CHECK: _0 = Eq(const no_optimize::::{constant#0}, const no_optimize::::{constant#1}); // CHECK-NEXT: return; (const { type_name_contains_i32(&generic::) }) == const { true } }