/src/test/codegen-units/polymorphization/unused_type_parameters.rs

https://gitlab.com/rust-lang/rust · Rust · 322 lines · 147 code · 69 blank · 106 comment · 6 complexity · bee44f0d3c6e4d28507d2ce807393f4d MD5 · raw file

  1. // compile-flags:-Zpolymorphize=on -Zprint-mono-items=lazy -Copt-level=1
  2. #![crate_type = "rlib"]
  3. // This test checks that the polymorphization analysis correctly reduces the
  4. // generated mono items.
  5. mod functions {
  6. // Function doesn't have any type parameters to be unused.
  7. pub fn no_parameters() {}
  8. //~ MONO_ITEM fn functions::no_parameters
  9. // Function has an unused type parameter.
  10. pub fn unused<T>() {
  11. }
  12. //~ MONO_ITEM fn functions::unused::<T>
  13. // Function uses type parameter in value of a binding.
  14. pub fn used_binding_value<T: Default>() {
  15. let _: T = Default::default();
  16. }
  17. //~ MONO_ITEM fn functions::used_binding_value::<u32>
  18. //~ MONO_ITEM fn functions::used_binding_value::<u64>
  19. // Function uses type parameter in type of a binding.
  20. pub fn used_binding_type<T>() {
  21. let _: Option<T> = None;
  22. }
  23. //~ MONO_ITEM fn functions::used_binding_type::<u32>
  24. //~ MONO_ITEM fn functions::used_binding_type::<u64>
  25. // Function uses type parameter in argument.
  26. pub fn used_argument<T>(_: T) {
  27. }
  28. //~ MONO_ITEM fn functions::used_argument::<u32>
  29. //~ MONO_ITEM fn functions::used_argument::<u64>
  30. //
  31. // Function uses type parameter in substitutions to another function.
  32. pub fn used_substs<T>() {
  33. unused::<T>()
  34. }
  35. //~ MONO_ITEM fn functions::used_substs::<u32>
  36. //~ MONO_ITEM fn functions::used_substs::<u64>
  37. }
  38. mod closures {
  39. // Function doesn't have any type parameters to be unused.
  40. pub fn no_parameters() {
  41. let _ = || {};
  42. }
  43. //~ MONO_ITEM fn closures::no_parameters
  44. // Function has an unused type parameter in parent and closure.
  45. pub fn unused<T>() -> u32 {
  46. let add_one = |x: u32| x + 1;
  47. add_one(3)
  48. }
  49. //~ MONO_ITEM fn closures::unused::<T>::{closure#0}
  50. //~ MONO_ITEM fn closures::unused::<T>
  51. // Function has an unused type parameter in closure, but not in parent.
  52. pub fn used_parent<T: Default>() -> u32 {
  53. let _: T = Default::default();
  54. let add_one = |x: u32| x + 1;
  55. add_one(3)
  56. }
  57. //~ MONO_ITEM fn closures::used_parent::<T>::{closure#0}
  58. //~ MONO_ITEM fn closures::used_parent::<u32>
  59. //~ MONO_ITEM fn closures::used_parent::<u64>
  60. // Function uses type parameter in value of a binding in closure.
  61. pub fn used_binding_value<T: Default>() -> T {
  62. let x = || {
  63. let y: T = Default::default();
  64. y
  65. };
  66. x()
  67. }
  68. //~ MONO_ITEM fn closures::used_binding_value::<u32>::{closure#0}
  69. //~ MONO_ITEM fn closures::used_binding_value::<u64>::{closure#0}
  70. //~ MONO_ITEM fn closures::used_binding_value::<u32>
  71. //~ MONO_ITEM fn closures::used_binding_value::<u64>
  72. // Function uses type parameter in type of a binding in closure.
  73. pub fn used_binding_type<T>() -> Option<T> {
  74. let x = || {
  75. let y: Option<T> = None;
  76. y
  77. };
  78. x()
  79. }
  80. //~ MONO_ITEM fn closures::used_binding_type::<u32>::{closure#0}
  81. //~ MONO_ITEM fn closures::used_binding_type::<u64>::{closure#0}
  82. //~ MONO_ITEM fn closures::used_binding_type::<u32>
  83. //~ MONO_ITEM fn closures::used_binding_type::<u64>
  84. // Function and closure uses type parameter in argument.
  85. pub fn used_argument<T>(t: T) -> u32 {
  86. let x = |_: T| 3;
  87. x(t)
  88. }
  89. //~ MONO_ITEM fn closures::used_argument::<u32>::{closure#0}
  90. //~ MONO_ITEM fn closures::used_argument::<u64>::{closure#0}
  91. //~ MONO_ITEM fn closures::used_argument::<u32>
  92. //~ MONO_ITEM fn closures::used_argument::<u64>
  93. // Closure uses type parameter in argument.
  94. pub fn used_argument_closure<T: Default>() -> u32 {
  95. let t: T = Default::default();
  96. let x = |_: T| 3;
  97. x(t)
  98. }
  99. //~ MONO_ITEM fn closures::used_argument_closure::<u32>::{closure#0}
  100. //~ MONO_ITEM fn closures::used_argument_closure::<u64>::{closure#0}
  101. //~ MONO_ITEM fn closures::used_argument_closure::<u32>
  102. //~ MONO_ITEM fn closures::used_argument_closure::<u64>
  103. // Closure uses type parameter as upvar.
  104. pub fn used_upvar<T: Default>() -> T {
  105. let x: T = Default::default();
  106. let y = || x;
  107. y()
  108. }
  109. //~ MONO_ITEM fn closures::used_upvar::<u32>::{closure#0}
  110. //~ MONO_ITEM fn closures::used_upvar::<u64>::{closure#0}
  111. //~ MONO_ITEM fn closures::used_upvar::<u32>
  112. //~ MONO_ITEM fn closures::used_upvar::<u64>
  113. // Closure uses type parameter in substitutions to another function.
  114. pub fn used_substs<T>() {
  115. let x = || super::functions::unused::<T>();
  116. x()
  117. }
  118. //~ MONO_ITEM fn closures::used_substs::<u32>::{closure#0}
  119. //~ MONO_ITEM fn closures::used_substs::<u64>::{closure#0}
  120. //~ MONO_ITEM fn closures::used_substs::<u32>
  121. //~ MONO_ITEM fn closures::used_substs::<u64>
  122. }
  123. mod methods {
  124. pub struct Foo<F>(F);
  125. impl<F: Default> Foo<F> {
  126. // Function has an unused type parameter from impl.
  127. pub fn unused_impl() {
  128. }
  129. //~ MONO_ITEM fn methods::Foo::<F>::unused_impl
  130. // Function has an unused type parameter from impl and fn.
  131. pub fn unused_both<G: Default>() {
  132. }
  133. //~ MONO_ITEM fn methods::Foo::<F>::unused_both::<G>
  134. // Function uses type parameter from impl.
  135. pub fn used_impl() {
  136. let _: F = Default::default();
  137. }
  138. //~ MONO_ITEM fn methods::Foo::<u32>::used_impl
  139. //~ MONO_ITEM fn methods::Foo::<u64>::used_impl
  140. // Function uses type parameter from impl.
  141. pub fn used_fn<G: Default>() {
  142. let _: G = Default::default();
  143. }
  144. //~ MONO_ITEM fn methods::Foo::<F>::used_fn::<u32>
  145. //~ MONO_ITEM fn methods::Foo::<F>::used_fn::<u64>
  146. // Function uses type parameter from impl.
  147. pub fn used_both<G: Default>() {
  148. let _: F = Default::default();
  149. let _: G = Default::default();
  150. }
  151. //~ MONO_ITEM fn methods::Foo::<u32>::used_both::<u32>
  152. //~ MONO_ITEM fn methods::Foo::<u64>::used_both::<u64>
  153. // Function uses type parameter in substitutions to another function.
  154. pub fn used_substs() {
  155. super::functions::unused::<F>()
  156. }
  157. //~ MONO_ITEM fn methods::Foo::<u32>::used_substs
  158. //~ MONO_ITEM fn methods::Foo::<u64>::used_substs
  159. // Function has an unused type parameter from impl and fn.
  160. pub fn closure_unused_all<G: Default>() -> u32 {
  161. let add_one = |x: u32| x + 1;
  162. add_one(3)
  163. }
  164. //~ MONO_ITEM fn methods::Foo::<F>::closure_unused_all::<G>::{closure#0}
  165. //~ MONO_ITEM fn methods::Foo::<F>::closure_unused_all::<G>
  166. // Function uses type parameter from impl and fn in closure.
  167. pub fn closure_used_both<G: Default>() -> u32 {
  168. let add_one = |x: u32| {
  169. let _: F = Default::default();
  170. let _: G = Default::default();
  171. x + 1
  172. };
  173. add_one(3)
  174. }
  175. //~ MONO_ITEM fn methods::Foo::<u32>::closure_used_both::<u32>::{closure#0}
  176. //~ MONO_ITEM fn methods::Foo::<u64>::closure_used_both::<u64>::{closure#0}
  177. //~ MONO_ITEM fn methods::Foo::<u32>::closure_used_both::<u32>
  178. //~ MONO_ITEM fn methods::Foo::<u64>::closure_used_both::<u64>
  179. // Function uses type parameter from fn in closure.
  180. pub fn closure_used_fn<G: Default>() -> u32 {
  181. let add_one = |x: u32| {
  182. let _: G = Default::default();
  183. x + 1
  184. };
  185. add_one(3)
  186. }
  187. //~ MONO_ITEM fn methods::Foo::<F>::closure_used_fn::<u32>::{closure#0}
  188. //~ MONO_ITEM fn methods::Foo::<F>::closure_used_fn::<u64>::{closure#0}
  189. //~ MONO_ITEM fn methods::Foo::<F>::closure_used_fn::<u32>
  190. //~ MONO_ITEM fn methods::Foo::<F>::closure_used_fn::<u64>
  191. // Function uses type parameter from impl in closure.
  192. pub fn closure_used_impl<G: Default>() -> u32 {
  193. let add_one = |x: u32| {
  194. let _: F = Default::default();
  195. x + 1
  196. };
  197. add_one(3)
  198. }
  199. //~ MONO_ITEM fn methods::Foo::<u32>::closure_used_impl::<G>::{closure#0}
  200. //~ MONO_ITEM fn methods::Foo::<u64>::closure_used_impl::<G>::{closure#0}
  201. //~ MONO_ITEM fn methods::Foo::<u32>::closure_used_impl::<G>
  202. //~ MONO_ITEM fn methods::Foo::<u64>::closure_used_impl::<G>
  203. // Closure uses type parameter in substitutions to another function.
  204. pub fn closure_used_substs() {
  205. let x = || super::functions::unused::<F>();
  206. x()
  207. }
  208. //~ MONO_ITEM fn methods::Foo::<u32>::closure_used_substs::{closure#0}
  209. //~ MONO_ITEM fn methods::Foo::<u64>::closure_used_substs::{closure#0}
  210. //~ MONO_ITEM fn methods::Foo::<u32>::closure_used_substs
  211. //~ MONO_ITEM fn methods::Foo::<u64>::closure_used_substs
  212. }
  213. }
  214. fn dispatch<T: Default>() {
  215. functions::no_parameters();
  216. functions::unused::<T>();
  217. functions::used_binding_value::<T>();
  218. functions::used_binding_type::<T>();
  219. functions::used_argument::<T>(Default::default());
  220. functions::used_substs::<T>();
  221. closures::no_parameters();
  222. let _ = closures::unused::<T>();
  223. let _ = closures::used_parent::<T>();
  224. let _ = closures::used_binding_value::<T>();
  225. let _ = closures::used_binding_type::<T>();
  226. let _ = closures::used_argument::<T>(Default::default());
  227. let _ = closures::used_argument_closure::<T>();
  228. let _ = closures::used_upvar::<T>();
  229. let _ = closures::used_substs::<T>();
  230. methods::Foo::<T>::unused_impl();
  231. methods::Foo::<T>::unused_both::<T>();
  232. methods::Foo::<T>::used_impl();
  233. methods::Foo::<T>::used_fn::<T>();
  234. methods::Foo::<T>::used_both::<T>();
  235. methods::Foo::<T>::used_substs();
  236. let _ = methods::Foo::<T>::closure_unused_all::<T>();
  237. let _ = methods::Foo::<T>::closure_used_both::<T>();
  238. let _ = methods::Foo::<T>::closure_used_impl::<T>();
  239. let _ = methods::Foo::<T>::closure_used_fn::<T>();
  240. let _ = methods::Foo::<T>::closure_used_substs();
  241. }
  242. //~ MONO_ITEM fn dispatch::<u32>
  243. //~ MONO_ITEM fn dispatch::<u64>
  244. pub fn foo() {
  245. // Generate two copies of each function to check that where the type parameter is unused,
  246. // there is only a single copy.
  247. dispatch::<u32>();
  248. dispatch::<u64>();
  249. }
  250. //~ MONO_ITEM fn foo @@ unused_type_parameters-cgu.0[External]
  251. // These are all the items that aren't relevant to the test.
  252. //~ MONO_ITEM fn <u32 as std::default::Default>::default
  253. //~ MONO_ITEM fn <u64 as std::default::Default>::default