authorbors <bors@rust-lang.org> 2025-07-19 11:10:04 UTC
committerbors <bors@rust-lang.org> 2025-07-19 11:10:04 UTC
log12865ffd0dfb4ea969e2f16eb0140238bb9dd382
treecd1b60381a5d2c032182e3fdfcfffde159f04a93
parent83825dd277503edf5d7eda6be8b5fb9896f343f5
parentcc699e1edf1e0f4302e9c0feff2a004afcdb2e11

Auto merge of #144166 - matthiaskrgr:rollup-wccepuo, r=matthiaskrgr

Rollup of 10 pull requests Successful merges: - rust-lang/rust#141076 (fix Zip unsoundness (again)) - rust-lang/rust#142444 (adding run-make test to autodiff) - rust-lang/rust#143704 (Be a bit more careful around exotic cycles in in the inliner) - rust-lang/rust#144073 (Don't test panic=unwind in panic_main.rs on Fuchsia) - rust-lang/rust#144083 (miri sleep tests: increase slack) - rust-lang/rust#144092 (bootstrap: Detect musl hosts) - rust-lang/rust#144098 (Do not lint private-in-public for RPITIT) - rust-lang/rust#144103 (Rename `emit_unless` to `emit_unless_delay`) - rust-lang/rust#144108 (Ignore tests/run-make/link-eh-frame-terminator/rmake.rs when cross-compiling) - rust-lang/rust#144115 (fix outdated comment) r? `@ghost` `@rustbot` modify labels: rollup

95 files changed, 1785 insertions(+), 168 deletions(-)

compiler/rustc_errors/src/diagnostic.rs+1-1
...@@ -1421,7 +1421,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {...@@ -1421,7 +1421,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
1421 ///1421 ///
1422 /// See `emit` and `delay_as_bug` for details.1422 /// See `emit` and `delay_as_bug` for details.
1423 #[track_caller]1423 #[track_caller]
1424 pub fn emit_unless(mut self, delay: bool) -> G::EmitResult {1424 pub fn emit_unless_delay(mut self, delay: bool) -> G::EmitResult {
1425 if delay {1425 if delay {
1426 self.downgrade_to_delayed_bug();1426 self.downgrade_to_delayed_bug();
1427 }1427 }
compiler/rustc_hir_analysis/src/check/compare_impl_item.rs+7-7
...@@ -1173,7 +1173,7 @@ fn check_region_bounds_on_impl_item<'tcx>(...@@ -1173,7 +1173,7 @@ fn check_region_bounds_on_impl_item<'tcx>(
1173 bounds_span,1173 bounds_span,
1174 where_span,1174 where_span,
1175 })1175 })
1176 .emit_unless(delay);1176 .emit_unless_delay(delay);
11771177
1178 Err(reported)1178 Err(reported)
1179}1179}
...@@ -1481,7 +1481,7 @@ fn compare_self_type<'tcx>(...@@ -1481,7 +1481,7 @@ fn compare_self_type<'tcx>(
1481 } else {1481 } else {
1482 err.note_trait_signature(trait_m.name(), trait_m.signature(tcx));1482 err.note_trait_signature(trait_m.name(), trait_m.signature(tcx));
1483 }1483 }
1484 return Err(err.emit_unless(delay));1484 return Err(err.emit_unless_delay(delay));
1485 }1485 }
14861486
1487 (true, false) => {1487 (true, false) => {
...@@ -1502,7 +1502,7 @@ fn compare_self_type<'tcx>(...@@ -1502,7 +1502,7 @@ fn compare_self_type<'tcx>(
1502 err.note_trait_signature(trait_m.name(), trait_m.signature(tcx));1502 err.note_trait_signature(trait_m.name(), trait_m.signature(tcx));
1503 }1503 }
15041504
1505 return Err(err.emit_unless(delay));1505 return Err(err.emit_unless_delay(delay));
1506 }1506 }
1507 }1507 }
15081508
...@@ -1662,7 +1662,7 @@ fn compare_number_of_generics<'tcx>(...@@ -1662,7 +1662,7 @@ fn compare_number_of_generics<'tcx>(
1662 err.span_label(*span, "`impl Trait` introduces an implicit type parameter");1662 err.span_label(*span, "`impl Trait` introduces an implicit type parameter");
1663 }1663 }
16641664
1665 let reported = err.emit_unless(delay);1665 let reported = err.emit_unless_delay(delay);
1666 err_occurred = Some(reported);1666 err_occurred = Some(reported);
1667 }1667 }
1668 }1668 }
...@@ -1745,7 +1745,7 @@ fn compare_number_of_method_arguments<'tcx>(...@@ -1745,7 +1745,7 @@ fn compare_number_of_method_arguments<'tcx>(
1745 ),1745 ),
1746 );1746 );
17471747
1748 return Err(err.emit_unless(delay));1748 return Err(err.emit_unless_delay(delay));
1749 }1749 }
17501750
1751 Ok(())1751 Ok(())
...@@ -1872,7 +1872,7 @@ fn compare_synthetic_generics<'tcx>(...@@ -1872,7 +1872,7 @@ fn compare_synthetic_generics<'tcx>(
1872 );1872 );
1873 };1873 };
1874 }1874 }
1875 error_found = Some(err.emit_unless(delay));1875 error_found = Some(err.emit_unless_delay(delay));
1876 }1876 }
1877 }1877 }
1878 if let Some(reported) = error_found { Err(reported) } else { Ok(()) }1878 if let Some(reported) = error_found { Err(reported) } else { Ok(()) }
...@@ -1974,7 +1974,7 @@ fn compare_generic_param_kinds<'tcx>(...@@ -1974,7 +1974,7 @@ fn compare_generic_param_kinds<'tcx>(
1974 err.span_label(impl_header_span, "");1974 err.span_label(impl_header_span, "");
1975 err.span_label(param_impl_span, make_param_message("found", param_impl));1975 err.span_label(param_impl_span, make_param_message("found", param_impl));
19761976
1977 let reported = err.emit_unless(delay);1977 let reported = err.emit_unless_delay(delay);
1978 return Err(reported);1978 return Err(reported);
1979 }1979 }
1980 }1980 }
compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs+1-1
...@@ -2495,7 +2495,7 @@ fn deny_non_region_late_bound(...@@ -2495,7 +2495,7 @@ fn deny_non_region_late_bound(
2495 format!("late-bound {what} parameter not allowed on {where_}"),2495 format!("late-bound {what} parameter not allowed on {where_}"),
2496 );2496 );
24972497
2498 let guar = diag.emit_unless(!tcx.features().non_lifetime_binders() || !first);2498 let guar = diag.emit_unless_delay(!tcx.features().non_lifetime_binders() || !first);
24992499
2500 first = false;2500 first = false;
2501 *arg = ResolvedArg::Error(guar);2501 *arg = ResolvedArg::Error(guar);
compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs+1-1
...@@ -570,7 +570,7 @@ pub(crate) fn check_generic_arg_count(...@@ -570,7 +570,7 @@ pub(crate) fn check_generic_arg_count(
570 gen_args,570 gen_args,
571 def_id,571 def_id,
572 ))572 ))
573 .emit_unless(all_params_are_binded)573 .emit_unless_delay(all_params_are_binded)
574 });574 });
575575
576 Err(reported)576 Err(reported)
compiler/rustc_hir_typeck/src/coercion.rs+1-1
...@@ -1775,7 +1775,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {...@@ -1775,7 +1775,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
1775 );1775 );
1776 }1776 }
17771777
1778 let reported = err.emit_unless(unsized_return);1778 let reported = err.emit_unless_delay(unsized_return);
17791779
1780 self.final_ty = Some(Ty::new_error(fcx.tcx, reported));1780 self.final_ty = Some(Ty::new_error(fcx.tcx, reported));
1781 }1781 }
compiler/rustc_hir_typeck/src/expr.rs+3-3
...@@ -1549,7 +1549,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {...@@ -1549,7 +1549,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15491549
1550 // If the assignment expression itself is ill-formed, don't1550 // If the assignment expression itself is ill-formed, don't
1551 // bother emitting another error1551 // bother emitting another error
1552 err.emit_unless(lhs_ty.references_error() || rhs_ty.references_error())1552 err.emit_unless_delay(lhs_ty.references_error() || rhs_ty.references_error())
1553 }1553 }
15541554
1555 pub(super) fn check_expr_let(1555 pub(super) fn check_expr_let(
...@@ -3865,7 +3865,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {...@@ -3865,7 +3865,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3865 self.dcx()3865 self.dcx()
3866 .create_err(NoVariantNamed { span: ident.span, ident, ty: container })3866 .create_err(NoVariantNamed { span: ident.span, ident, ty: container })
3867 .with_span_label(field.span, "variant not found")3867 .with_span_label(field.span, "variant not found")
3868 .emit_unless(container.references_error());3868 .emit_unless_delay(container.references_error());
3869 break;3869 break;
3870 };3870 };
3871 let Some(&subfield) = fields.next() else {3871 let Some(&subfield) = fields.next() else {
...@@ -3897,7 +3897,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {...@@ -3897,7 +3897,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3897 enum_span: field.span,3897 enum_span: field.span,
3898 field_span: subident.span,3898 field_span: subident.span,
3899 })3899 })
3900 .emit_unless(container.references_error());3900 .emit_unless_delay(container.references_error());
3901 break;3901 break;
3902 };3902 };
39033903
compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp+13
...@@ -700,6 +700,10 @@ struct LLVMRustSanitizerOptions {...@@ -700,6 +700,10 @@ struct LLVMRustSanitizerOptions {
700#ifdef ENZYME700#ifdef ENZYME
701extern "C" void registerEnzymeAndPassPipeline(llvm::PassBuilder &PB,701extern "C" void registerEnzymeAndPassPipeline(llvm::PassBuilder &PB,
702 /* augmentPassBuilder */ bool);702 /* augmentPassBuilder */ bool);
703
704extern "C" {
705extern llvm::cl::opt<std::string> EnzymeFunctionToAnalyze;
706}
703#endif707#endif
704708
705extern "C" LLVMRustResult LLVMRustOptimize(709extern "C" LLVMRustResult LLVMRustOptimize(
...@@ -1069,6 +1073,15 @@ extern "C" LLVMRustResult LLVMRustOptimize(...@@ -1069,6 +1073,15 @@ extern "C" LLVMRustResult LLVMRustOptimize(
1069 return LLVMRustResult::Failure;1073 return LLVMRustResult::Failure;
1070 }1074 }
10711075
1076 // Check if PrintTAFn was used and add type analysis pass if needed
1077 if (!EnzymeFunctionToAnalyze.empty()) {
1078 if (auto Err = PB.parsePassPipeline(MPM, "print-type-analysis")) {
1079 std::string ErrMsg = toString(std::move(Err));
1080 LLVMRustSetLastError(ErrMsg.c_str());
1081 return LLVMRustResult::Failure;
1082 }
1083 }
1084
1072 if (PrintAfterEnzyme) {1085 if (PrintAfterEnzyme) {
1073 // Handle the Rust flag `-Zautodiff=PrintModAfter`.1086 // Handle the Rust flag `-Zautodiff=PrintModAfter`.
1074 std::string Banner = "Module after EnzymeNewPM";1087 std::string Banner = "Module after EnzymeNewPM";
compiler/rustc_mir_transform/src/inline/cycle.rs+28-16
...@@ -64,15 +64,15 @@ fn process<'tcx>(...@@ -64,15 +64,15 @@ fn process<'tcx>(
64 typing_env: ty::TypingEnv<'tcx>,64 typing_env: ty::TypingEnv<'tcx>,
65 caller: ty::Instance<'tcx>,65 caller: ty::Instance<'tcx>,
66 target: LocalDefId,66 target: LocalDefId,
67 seen: &mut FxHashSet<ty::Instance<'tcx>>,67 seen: &mut FxHashMap<ty::Instance<'tcx>, bool>,
68 involved: &mut FxHashSet<LocalDefId>,68 involved: &mut FxHashSet<LocalDefId>,
69 recursion_limiter: &mut FxHashMap<DefId, usize>,69 recursion_limiter: &mut FxHashMap<DefId, usize>,
70 recursion_limit: Limit,70 recursion_limit: Limit,
71) -> bool {71) -> bool {
72 trace!(%caller);72 trace!(%caller);
73 let mut cycle_found = false;73 let mut reaches_root = false;
7474
75 for &(callee, args) in tcx.mir_inliner_callees(caller.def) {75 for &(callee_def_id, args) in tcx.mir_inliner_callees(caller.def) {
76 let Ok(args) = caller.try_instantiate_mir_and_normalize_erasing_regions(76 let Ok(args) = caller.try_instantiate_mir_and_normalize_erasing_regions(
77 tcx,77 tcx,
78 typing_env,78 typing_env,
...@@ -81,14 +81,17 @@ fn process<'tcx>(...@@ -81,14 +81,17 @@ fn process<'tcx>(
81 trace!(?caller, ?typing_env, ?args, "cannot normalize, skipping");81 trace!(?caller, ?typing_env, ?args, "cannot normalize, skipping");
82 continue;82 continue;
83 };83 };
84 let Ok(Some(callee)) = ty::Instance::try_resolve(tcx, typing_env, callee, args) else {84 let Ok(Some(callee)) = ty::Instance::try_resolve(tcx, typing_env, callee_def_id, args)
85 trace!(?callee, "cannot resolve, skipping");85 else {
86 trace!(?callee_def_id, "cannot resolve, skipping");
86 continue;87 continue;
87 };88 };
8889
89 // Found a path.90 // Found a path.
90 if callee.def_id() == target.to_def_id() {91 if callee.def_id() == target.to_def_id() {
91 cycle_found = true;92 reaches_root = true;
93 seen.insert(callee, true);
94 continue;
92 }95 }
9396
94 if tcx.is_constructor(callee.def_id()) {97 if tcx.is_constructor(callee.def_id()) {
...@@ -101,10 +104,17 @@ fn process<'tcx>(...@@ -101,10 +104,17 @@ fn process<'tcx>(
101 continue;104 continue;
102 }105 }
103106
104 if seen.insert(callee) {107 let callee_reaches_root = if let Some(&c) = seen.get(&callee) {
108 // Even if we have seen this callee before, and thus don't need
109 // to recurse into it, we still need to propagate whether it reaches
110 // the root so that we can mark all the involved callers, in case we
111 // end up reaching that same recursive callee through some *other* cycle.
112 c
113 } else {
114 seen.insert(callee, false);
105 let recursion = recursion_limiter.entry(callee.def_id()).or_default();115 let recursion = recursion_limiter.entry(callee.def_id()).or_default();
106 trace!(?callee, recursion = *recursion);116 trace!(?callee, recursion = *recursion);
107 let found_recursion = if recursion_limit.value_within_limit(*recursion) {117 let callee_reaches_root = if recursion_limit.value_within_limit(*recursion) {
108 *recursion += 1;118 *recursion += 1;
109 ensure_sufficient_stack(|| {119 ensure_sufficient_stack(|| {
110 process(120 process(
...@@ -122,17 +132,19 @@ fn process<'tcx>(...@@ -122,17 +132,19 @@ fn process<'tcx>(
122 // Pessimistically assume that there could be recursion.132 // Pessimistically assume that there could be recursion.
123 true133 true
124 };134 };
125 if found_recursion {135 seen.insert(callee, callee_reaches_root);
126 if let Some(callee) = callee.def_id().as_local() {136 callee_reaches_root
127 // Calling `optimized_mir` of a non-local definition cannot cycle.137 };
128 involved.insert(callee);138 if callee_reaches_root {
129 }139 if let Some(callee_def_id) = callee.def_id().as_local() {
130 cycle_found = true;140 // Calling `optimized_mir` of a non-local definition cannot cycle.
141 involved.insert(callee_def_id);
131 }142 }
143 reaches_root = true;
132 }144 }
133 }145 }
134146
135 cycle_found147 reaches_root
136}148}
137149
138#[instrument(level = "debug", skip(tcx), ret)]150#[instrument(level = "debug", skip(tcx), ret)]
...@@ -166,7 +178,7 @@ pub(crate) fn mir_callgraph_cyclic<'tcx>(...@@ -166,7 +178,7 @@ pub(crate) fn mir_callgraph_cyclic<'tcx>(
166 typing_env,178 typing_env,
167 root_instance,179 root_instance,
168 root,180 root,
169 &mut FxHashSet::default(),181 &mut FxHashMap::default(),
170 &mut involved,182 &mut involved,
171 &mut FxHashMap::default(),183 &mut FxHashMap::default(),
172 recursion_limit,184 recursion_limit,
compiler/rustc_next_trait_solver/src/solve/trait_goals.rs+2-4
...@@ -1219,10 +1219,8 @@ where...@@ -1219,10 +1219,8 @@ where
1219 // the type (even if after unification and processing nested goals1219 // the type (even if after unification and processing nested goals
1220 // it does not hold) will disqualify the built-in auto impl.1220 // it does not hold) will disqualify the built-in auto impl.
1221 //1221 //
1222 // This differs from the current stable behavior and fixes #84857.1222 // We've originally had a more permissive check here which resulted
1223 // Due to breakage found via crater, we currently instead lint1223 // in unsoundness, see #84857.
1224 // patterns which can be used to exploit this unsoundness on stable,
1225 // see #93367 for more details.
1226 ty::Bool1224 ty::Bool
1227 | ty::Char1225 | ty::Char
1228 | ty::Int(_)1226 | ty::Int(_)
compiler/rustc_privacy/src/lib.rs+8
...@@ -1624,6 +1624,10 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {...@@ -1624,6 +1624,10 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
1624 self.check(def_id, item_visibility, effective_vis).generics().predicates();1624 self.check(def_id, item_visibility, effective_vis).generics().predicates();
16251625
1626 for assoc_item in tcx.associated_items(id.owner_id).in_definition_order() {1626 for assoc_item in tcx.associated_items(id.owner_id).in_definition_order() {
1627 if assoc_item.is_impl_trait_in_trait() {
1628 continue;
1629 }
1630
1627 self.check_assoc_item(assoc_item, item_visibility, effective_vis);1631 self.check_assoc_item(assoc_item, item_visibility, effective_vis);
16281632
1629 if assoc_item.is_type() {1633 if assoc_item.is_type() {
...@@ -1736,6 +1740,10 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {...@@ -1736,6 +1740,10 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
1736 check.ty().trait_ref();1740 check.ty().trait_ref();
17371741
1738 for assoc_item in tcx.associated_items(id.owner_id).in_definition_order() {1742 for assoc_item in tcx.associated_items(id.owner_id).in_definition_order() {
1743 if assoc_item.is_impl_trait_in_trait() {
1744 continue;
1745 }
1746
1739 let impl_item_vis = if !of_trait {1747 let impl_item_vis = if !of_trait {
1740 min(tcx.local_visibility(assoc_item.def_id.expect_local()), impl_vis, tcx)1748 min(tcx.local_visibility(assoc_item.def_id.expect_local()), impl_vis, tcx)
1741 } else {1749 } else {
compiler/rustc_resolve/src/late.rs+1-1
...@@ -2913,7 +2913,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {...@@ -2913,7 +2913,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
2913 self.r2913 self.r
2914 .dcx()2914 .dcx()
2915 .create_err(errors::UnderscoreLifetimeIsReserved { span: param.ident.span })2915 .create_err(errors::UnderscoreLifetimeIsReserved { span: param.ident.span })
2916 .emit_unless(is_raw_underscore_lifetime);2916 .emit_unless_delay(is_raw_underscore_lifetime);
2917 // Record lifetime res, so lowering knows there is something fishy.2917 // Record lifetime res, so lowering knows there is something fishy.
2918 self.record_lifetime_param(param.id, LifetimeRes::Error);2918 self.record_lifetime_param(param.id, LifetimeRes::Error);
2919 continue;2919 continue;
library/core/src/iter/adapters/zip.rs+33-41
...@@ -18,7 +18,6 @@ pub struct Zip<A, B> {...@@ -18,7 +18,6 @@ pub struct Zip<A, B> {
18 // index, len and a_len are only used by the specialized version of zip18 // index, len and a_len are only used by the specialized version of zip
19 index: usize,19 index: usize,
20 len: usize,20 len: usize,
21 a_len: usize,
22}21}
23impl<A: Iterator, B: Iterator> Zip<A, B> {22impl<A: Iterator, B: Iterator> Zip<A, B> {
24 pub(in crate::iter) fn new(a: A, b: B) -> Zip<A, B> {23 pub(in crate::iter) fn new(a: A, b: B) -> Zip<A, B> {
...@@ -158,7 +157,6 @@ macro_rules! zip_impl_general_defaults {...@@ -158,7 +157,6 @@ macro_rules! zip_impl_general_defaults {
158 b,157 b,
159 index: 0, // unused158 index: 0, // unused
160 len: 0, // unused159 len: 0, // unused
161 a_len: 0, // unused
162 }160 }
163 }161 }
164162
...@@ -299,9 +297,8 @@ where...@@ -299,9 +297,8 @@ where
299 B: TrustedRandomAccess + Iterator,297 B: TrustedRandomAccess + Iterator,
300{298{
301 fn new(a: A, b: B) -> Self {299 fn new(a: A, b: B) -> Self {
302 let a_len = a.size();300 let len = cmp::min(a.size(), b.size());
303 let len = cmp::min(a_len, b.size());301 Zip { a, b, index: 0, len }
304 Zip { a, b, index: 0, len, a_len }
305 }302 }
306303
307 #[inline]304 #[inline]
...@@ -315,17 +312,6 @@ where...@@ -315,17 +312,6 @@ where
315 unsafe {312 unsafe {
316 Some((self.a.__iterator_get_unchecked(i), self.b.__iterator_get_unchecked(i)))313 Some((self.a.__iterator_get_unchecked(i), self.b.__iterator_get_unchecked(i)))
317 }314 }
318 } else if A::MAY_HAVE_SIDE_EFFECT && self.index < self.a_len {
319 let i = self.index;
320 // as above, increment before executing code that may panic
321 self.index += 1;
322 self.len += 1;
323 // match the base implementation's potential side effects
324 // SAFETY: we just checked that `i` < `self.a.len()`
325 unsafe {
326 self.a.__iterator_get_unchecked(i);
327 }
328 None
329 } else {315 } else {
330 None316 None
331 }317 }
...@@ -371,36 +357,42 @@ where...@@ -371,36 +357,42 @@ where
371 A: DoubleEndedIterator + ExactSizeIterator,357 A: DoubleEndedIterator + ExactSizeIterator,
372 B: DoubleEndedIterator + ExactSizeIterator,358 B: DoubleEndedIterator + ExactSizeIterator,
373 {359 {
374 if A::MAY_HAVE_SIDE_EFFECT || B::MAY_HAVE_SIDE_EFFECT {360 // No effects when the iterator is exhausted, to reduce the number of
375 let sz_a = self.a.size();361 // cases the unsafe code has to handle.
376 let sz_b = self.b.size();362 // See #137255 for a case where where too many epicycles lead to unsoundness.
377 // Adjust a, b to equal length, make sure that only the first call363 if self.index < self.len {
378 // of `next_back` does this, otherwise we will break the restriction364 let old_len = self.len;
379 // on calls to `self.next_back()` after calling `get_unchecked()`.365
380 if sz_a != sz_b {366 // since get_unchecked and the side-effecting code can execute user code
367 // which can panic we decrement the counter beforehand
368 // so that the same index won't be accessed twice, as required by TrustedRandomAccess.
369 // Additionally this will ensure that the side-effects code won't run a second time.
370 self.len -= 1;
371
372 // Adjust a, b to equal length if we're iterating backwards.
373 if A::MAY_HAVE_SIDE_EFFECT || B::MAY_HAVE_SIDE_EFFECT {
374 // note if some forward-iteration already happened then these aren't the real
375 // remaining lengths of the inner iterators, so we have to relate them to
376 // Zip's internal length-tracking.
381 let sz_a = self.a.size();377 let sz_a = self.a.size();
382 if A::MAY_HAVE_SIDE_EFFECT && sz_a > self.len {
383 for _ in 0..sz_a - self.len {
384 // since next_back() may panic we increment the counters beforehand
385 // to keep Zip's state in sync with the underlying iterator source
386 self.a_len -= 1;
387 self.a.next_back();
388 }
389 debug_assert_eq!(self.a_len, self.len);
390 }
391 let sz_b = self.b.size();378 let sz_b = self.b.size();
392 if B::MAY_HAVE_SIDE_EFFECT && sz_b > self.len {379 // This condition can and must only be true on the first `next_back` call,
393 for _ in 0..sz_b - self.len {380 // otherwise we will break the restriction on calls to `self.next_back()`
394 self.b.next_back();381 // after calling `get_unchecked()`.
382 if sz_a != sz_b && (old_len == sz_a || old_len == sz_b) {
383 if A::MAY_HAVE_SIDE_EFFECT && sz_a > old_len {
384 for _ in 0..sz_a - old_len {
385 self.a.next_back();
386 }
395 }387 }
388 if B::MAY_HAVE_SIDE_EFFECT && sz_b > old_len {
389 for _ in 0..sz_b - old_len {
390 self.b.next_back();
391 }
392 }
393 debug_assert_eq!(self.a.size(), self.b.size());
396 }394 }
397 }395 }
398 }
399 if self.index < self.len {
400 // since get_unchecked executes code which can panic we increment the counters beforehand
401 // so that the same index won't be accessed twice, as required by TrustedRandomAccess
402 self.len -= 1;
403 self.a_len -= 1;
404 let i = self.len;396 let i = self.len;
405 // SAFETY: `i` is smaller than the previous value of `self.len`,397 // SAFETY: `i` is smaller than the previous value of `self.len`,
406 // which is also smaller than or equal to `self.a.len()` and `self.b.len()`398 // which is also smaller than or equal to `self.a.len()` and `self.b.len()`
library/coretests/tests/iter/adapters/cloned.rs+2-1
...@@ -31,7 +31,8 @@ fn test_cloned_side_effects() {...@@ -31,7 +31,8 @@ fn test_cloned_side_effects() {
31 .zip(&[1]);31 .zip(&[1]);
32 for _ in iter {}32 for _ in iter {}
33 }33 }
34 assert_eq!(count, 2);34 // Zip documentation provides some leeway about side-effects
35 assert!([1, 2].iter().any(|v| *v == count));
35}36}
3637
37#[test]38#[test]
library/coretests/tests/iter/adapters/zip.rs+86-33
...@@ -107,9 +107,19 @@ fn test_zip_next_back_side_effects_exhausted() {...@@ -107,9 +107,19 @@ fn test_zip_next_back_side_effects_exhausted() {
107 iter.next();107 iter.next();
108 iter.next();108 iter.next();
109 iter.next();109 iter.next();
110 iter.next();110 assert_eq!(iter.next(), None);
111 assert_eq!(iter.next_back(), None);111 assert_eq!(iter.next_back(), None);
112 assert_eq!(a, vec![1, 2, 3, 4, 6, 5]);112
113 assert!(a.starts_with(&[1, 2, 3]));
114 let a_len = a.len();
115 // Tail-side-effects of forward-iteration are "at most one" per next().
116 // And for reverse iteration we don't guarantee much either.
117 // But we can put some bounds on the possible behaviors.
118 assert!(a_len <= 6);
119 assert!(a_len >= 3);
120 a.sort();
121 assert_eq!(a, &[1, 2, 3, 4, 5, 6][..a.len()]);
122
113 assert_eq!(b, vec![200, 300, 400]);123 assert_eq!(b, vec![200, 300, 400]);
114}124}
115125
...@@ -120,7 +130,8 @@ fn test_zip_cloned_sideffectful() {...@@ -120,7 +130,8 @@ fn test_zip_cloned_sideffectful() {
120130
121 for _ in xs.iter().cloned().zip(ys.iter().cloned()) {}131 for _ in xs.iter().cloned().zip(ys.iter().cloned()) {}
122132
123 assert_eq!(&xs, &[1, 1, 1, 0][..]);133 // Zip documentation permits either case.
134 assert!([&[1, 1, 1, 0], &[1, 1, 0, 0]].iter().any(|v| &xs == *v));
124 assert_eq!(&ys, &[1, 1][..]);135 assert_eq!(&ys, &[1, 1][..]);
125136
126 let xs = [CountClone::new(), CountClone::new()];137 let xs = [CountClone::new(), CountClone::new()];
...@@ -139,7 +150,8 @@ fn test_zip_map_sideffectful() {...@@ -139,7 +150,8 @@ fn test_zip_map_sideffectful() {
139150
140 for _ in xs.iter_mut().map(|x| *x += 1).zip(ys.iter_mut().map(|y| *y += 1)) {}151 for _ in xs.iter_mut().map(|x| *x += 1).zip(ys.iter_mut().map(|y| *y += 1)) {}
141152
142 assert_eq!(&xs, &[1, 1, 1, 1, 1, 0]);153 // Zip documentation permits either case.
154 assert!([&[1, 1, 1, 1, 1, 0], &[1, 1, 1, 1, 0, 0]].iter().any(|v| &xs == *v));
143 assert_eq!(&ys, &[1, 1, 1, 1]);155 assert_eq!(&ys, &[1, 1, 1, 1]);
144156
145 let mut xs = [0; 4];157 let mut xs = [0; 4];
...@@ -168,7 +180,8 @@ fn test_zip_map_rev_sideffectful() {...@@ -168,7 +180,8 @@ fn test_zip_map_rev_sideffectful() {
168180
169 {181 {
170 let mut it = xs.iter_mut().map(|x| *x += 1).zip(ys.iter_mut().map(|y| *y += 1));182 let mut it = xs.iter_mut().map(|x| *x += 1).zip(ys.iter_mut().map(|y| *y += 1));
171 (&mut it).take(5).count();183 // the current impl only trims the tails if the iterator isn't exhausted
184 (&mut it).take(3).count();
172 it.next_back();185 it.next_back();
173 }186 }
174 assert_eq!(&xs, &[1, 1, 1, 1, 1, 1]);187 assert_eq!(&xs, &[1, 1, 1, 1, 1, 1]);
...@@ -211,9 +224,18 @@ fn test_zip_nth_back_side_effects_exhausted() {...@@ -211,9 +224,18 @@ fn test_zip_nth_back_side_effects_exhausted() {
211 iter.next();224 iter.next();
212 iter.next();225 iter.next();
213 iter.next();226 iter.next();
214 iter.next();227 assert_eq!(iter.next(), None);
215 assert_eq!(iter.nth_back(0), None);228 assert_eq!(iter.nth_back(0), None);
216 assert_eq!(a, vec![1, 2, 3, 4, 6, 5]);229 assert!(a.starts_with(&[1, 2, 3]));
230 let a_len = a.len();
231 // Tail-side-effects of forward-iteration are "at most one" per next().
232 // And for reverse iteration we don't guarantee much either.
233 // But we can put some bounds on the possible behaviors.
234 assert!(a_len <= 6);
235 assert!(a_len >= 3);
236 a.sort();
237 assert_eq!(a, &[1, 2, 3, 4, 5, 6][..a.len()]);
238
217 assert_eq!(b, vec![200, 300, 400]);239 assert_eq!(b, vec![200, 300, 400]);
218}240}
219241
...@@ -237,32 +259,6 @@ fn test_zip_trusted_random_access_composition() {...@@ -237,32 +259,6 @@ fn test_zip_trusted_random_access_composition() {
237 assert_eq!(z2.next().unwrap(), ((1, 1), 1));259 assert_eq!(z2.next().unwrap(), ((1, 1), 1));
238}260}
239261
240#[test]
241#[cfg(panic = "unwind")]
242fn test_zip_trusted_random_access_next_back_drop() {
243 use std::panic::{AssertUnwindSafe, catch_unwind};
244
245 let mut counter = 0;
246
247 let it = [42].iter().map(|e| {
248 let c = counter;
249 counter += 1;
250 if c == 0 {
251 panic!("bomb");
252 }
253
254 e
255 });
256 let it2 = [(); 0].iter();
257 let mut zip = it.zip(it2);
258 catch_unwind(AssertUnwindSafe(|| {
259 zip.next_back();
260 }))
261 .unwrap_err();
262 assert!(zip.next().is_none());
263 assert_eq!(counter, 1);
264}
265
266#[test]262#[test]
267fn test_double_ended_zip() {263fn test_double_ended_zip() {
268 let xs = [1, 2, 3, 4, 5, 6];264 let xs = [1, 2, 3, 4, 5, 6];
...@@ -275,6 +271,63 @@ fn test_double_ended_zip() {...@@ -275,6 +271,63 @@ fn test_double_ended_zip() {
275 assert_eq!(it.next(), None);271 assert_eq!(it.next(), None);
276}272}
277273
274#[test]
275#[cfg(panic = "unwind")]
276/// Regresion test for #137255
277/// A previous implementation of Zip TrustedRandomAccess specializations tried to do a lot of work
278/// to preserve side-effects of equalizing the iterator lengths during backwards iteration.
279/// This lead to several cases of unsoundness, twice due to being left in an inconsistent state
280/// after panics.
281/// The new implementation does not try as hard, but we still need panic-safety.
282fn test_nested_zip_panic_safety() {
283 use std::panic::{AssertUnwindSafe, catch_unwind, resume_unwind};
284 use std::sync::atomic::{AtomicUsize, Ordering};
285
286 let mut panic = true;
287 // keeps track of how often element get visited, must be at most once each
288 let witness = [8, 9, 10, 11, 12].map(|i| (i, AtomicUsize::new(0)));
289 let a = witness.as_slice().iter().map(|e| {
290 e.1.fetch_add(1, Ordering::Relaxed);
291 if panic {
292 panic = false;
293 resume_unwind(Box::new(()))
294 }
295 e.0
296 });
297 // shorter than `a`, so `a` will get trimmed
298 let b = [1, 2, 3, 4].as_slice().iter().copied();
299 // shorter still, so `ab` will get trimmed.`
300 let c = [5, 6, 7].as_slice().iter().copied();
301
302 // This will panic during backwards trimming.
303 let ab = zip(a, b);
304 // This being Zip + TrustedRandomAccess means it will only call `next_back``
305 // during trimming and otherwise do calls `__iterator_get_unchecked` on `ab`.
306 let mut abc = zip(ab, c);
307
308 assert_eq!(abc.len(), 3);
309 // This will first trigger backwards trimming before it would normally obtain the
310 // actual element if it weren't for the panic.
311 // This used to corrupt the internal state of `abc`, which then lead to
312 // TrustedRandomAccess safety contract violations in calls to `ab`,
313 // which ultimately lead to UB.
314 catch_unwind(AssertUnwindSafe(|| abc.next_back())).ok();
315 // check for sane outward behavior after the panic, which indicates a sane internal state.
316 // Technically these outcomes are not required because a panic frees us from correctness obligations.
317 assert_eq!(abc.len(), 2);
318 assert_eq!(abc.next(), Some(((8, 1), 5)));
319 assert_eq!(abc.next_back(), Some(((9, 2), 6)));
320 for (i, (_, w)) in witness.iter().enumerate() {
321 let v = w.load(Ordering::Relaxed);
322 // required by TRA contract
323 assert!(v <= 1, "expected idx {i} to be visited at most once, actual: {v}");
324 }
325 // Trimming panicked and should only run once, so this one won't be visited.
326 // Implementation detail, but not trying to run it again is what keeps
327 // things simple.
328 assert_eq!(witness[3].1.load(Ordering::Relaxed), 0);
329}
330
278#[test]331#[test]
279fn test_issue_82282() {332fn test_issue_82282() {
280 fn overflowed_zip(arr: &[i32]) -> impl Iterator<Item = (i32, &())> {333 fn overflowed_zip(arr: &[i32]) -> impl Iterator<Item = (i32, &())> {
src/bootstrap/bootstrap.py+6-1
...@@ -8,6 +8,7 @@ import re...@@ -8,6 +8,7 @@ import re
8import shutil8import shutil
9import subprocess9import subprocess
10import sys10import sys
11import sysconfig
11import tarfile12import tarfile
12import tempfile13import tempfile
1314
...@@ -333,7 +334,11 @@ def default_build_triple(verbose):...@@ -333,7 +334,11 @@ def default_build_triple(verbose):
333 if ostype == "Android":334 if ostype == "Android":
334 kernel = "linux-android"335 kernel = "linux-android"
335 else:336 else:
336 kernel = "unknown-linux-gnu"337 python_soabi = sysconfig.get_config_var("SOABI")
338 if python_soabi is not None and "musl" in python_soabi:
339 kernel = "unknown-linux-musl"
340 else:
341 kernel = "unknown-linux-gnu"
337 elif kernel == "SunOS":342 elif kernel == "SunOS":
338 kernel = "pc-solaris"343 kernel = "pc-solaris"
339 # On Solaris, uname -m will return a machine classification instead344 # On Solaris, uname -m will return a machine classification instead
src/tools/miri/tests/pass-dep/libc/libc-time.rs+3-3
...@@ -336,7 +336,7 @@ fn test_nanosleep() {...@@ -336,7 +336,7 @@ fn test_nanosleep() {
336 let remainder = ptr::null_mut::<libc::timespec>();336 let remainder = ptr::null_mut::<libc::timespec>();
337 let is_error = unsafe { libc::nanosleep(&duration_zero, remainder) };337 let is_error = unsafe { libc::nanosleep(&duration_zero, remainder) };
338 assert_eq!(is_error, 0);338 assert_eq!(is_error, 0);
339 assert!(start_test_sleep.elapsed() < Duration::from_millis(10));339 assert!(start_test_sleep.elapsed() < Duration::from_millis(100));
340340
341 let start_test_sleep = Instant::now();341 let start_test_sleep = Instant::now();
342 let duration_100_millis = libc::timespec { tv_sec: 0, tv_nsec: 1_000_000_000 / 10 };342 let duration_100_millis = libc::timespec { tv_sec: 0, tv_nsec: 1_000_000_000 / 10 };
...@@ -390,7 +390,7 @@ mod test_clock_nanosleep {...@@ -390,7 +390,7 @@ mod test_clock_nanosleep {
390 )390 )
391 };391 };
392 assert_eq!(error, 0);392 assert_eq!(error, 0);
393 assert!(start_test_sleep.elapsed() < Duration::from_millis(10));393 assert!(start_test_sleep.elapsed() < Duration::from_millis(100));
394394
395 let start_test_sleep = Instant::now();395 let start_test_sleep = Instant::now();
396 let hunderd_millis_after_start = add_100_millis(timespec_now(libc::CLOCK_MONOTONIC));396 let hunderd_millis_after_start = add_100_millis(timespec_now(libc::CLOCK_MONOTONIC));
...@@ -417,7 +417,7 @@ mod test_clock_nanosleep {...@@ -417,7 +417,7 @@ mod test_clock_nanosleep {
417 libc::clock_nanosleep(libc::CLOCK_MONOTONIC, NO_FLAGS, &duration_zero, remainder)417 libc::clock_nanosleep(libc::CLOCK_MONOTONIC, NO_FLAGS, &duration_zero, remainder)
418 };418 };
419 assert_eq!(error, 0);419 assert_eq!(error, 0);
420 assert!(start_test_sleep.elapsed() < Duration::from_millis(10));420 assert!(start_test_sleep.elapsed() < Duration::from_millis(100));
421421
422 let start_test_sleep = Instant::now();422 let start_test_sleep = Instant::now();
423 let duration_100_millis = libc::timespec { tv_sec: 0, tv_nsec: 1_000_000_000 / 10 };423 let duration_100_millis = libc::timespec { tv_sec: 0, tv_nsec: 1_000_000_000 / 10 };
tests/mir-opt/inline_double_cycle.a.Inline.panic-abort.diff created+48
...@@ -0,0 +1,48 @@
1- // MIR for `a` before Inline
2+ // MIR for `a` after Inline
3
4 fn a() -> () {
5 let mut _0: ();
6 let _1: ();
7 let mut _2: ();
8 let _3: ();
9 let mut _4: ();
10+ let mut _5: fn() {a};
11+ let mut _6: fn() {b};
12+ scope 1 (inlined <fn() {a} as FnOnce<()>>::call_once - shim(fn() {a})) {
13+ }
14+ scope 2 (inlined <fn() {b} as FnOnce<()>>::call_once - shim(fn() {b})) {
15+ }
16
17 bb0: {
18 StorageLive(_1);
19 StorageLive(_2);
20 _2 = ();
21- _1 = <fn() {a} as FnOnce<()>>::call_once(a, move _2) -> [return: bb1, unwind unreachable];
22+ StorageLive(_5);
23+ _5 = a;
24+ _1 = move _5() -> [return: bb1, unwind unreachable];
25 }
26
27 bb1: {
28+ StorageDead(_5);
29 StorageDead(_2);
30 StorageDead(_1);
31 StorageLive(_3);
32 StorageLive(_4);
33 _4 = ();
34- _3 = <fn() {b} as FnOnce<()>>::call_once(b, move _4) -> [return: bb2, unwind unreachable];
35+ StorageLive(_6);
36+ _6 = b;
37+ _3 = move _6() -> [return: bb2, unwind unreachable];
38 }
39
40 bb2: {
41+ StorageDead(_6);
42 StorageDead(_4);
43 StorageDead(_3);
44 _0 = const ();
45 return;
46 }
47 }
48
tests/mir-opt/inline_double_cycle.a.Inline.panic-unwind.diff created+48
...@@ -0,0 +1,48 @@
1- // MIR for `a` before Inline
2+ // MIR for `a` after Inline
3
4 fn a() -> () {
5 let mut _0: ();
6 let _1: ();
7 let mut _2: ();
8 let _3: ();
9 let mut _4: ();
10+ let mut _5: fn() {a};
11+ let mut _6: fn() {b};
12+ scope 1 (inlined <fn() {a} as FnOnce<()>>::call_once - shim(fn() {a})) {
13+ }
14+ scope 2 (inlined <fn() {b} as FnOnce<()>>::call_once - shim(fn() {b})) {
15+ }
16
17 bb0: {
18 StorageLive(_1);
19 StorageLive(_2);
20 _2 = ();
21- _1 = <fn() {a} as FnOnce<()>>::call_once(a, move _2) -> [return: bb1, unwind continue];
22+ StorageLive(_5);
23+ _5 = a;
24+ _1 = move _5() -> [return: bb1, unwind continue];
25 }
26
27 bb1: {
28+ StorageDead(_5);
29 StorageDead(_2);
30 StorageDead(_1);
31 StorageLive(_3);
32 StorageLive(_4);
33 _4 = ();
34- _3 = <fn() {b} as FnOnce<()>>::call_once(b, move _4) -> [return: bb2, unwind continue];
35+ StorageLive(_6);
36+ _6 = b;
37+ _3 = move _6() -> [return: bb2, unwind continue];
38 }
39
40 bb2: {
41+ StorageDead(_6);
42 StorageDead(_4);
43 StorageDead(_3);
44 _0 = const ();
45 return;
46 }
47 }
48
tests/mir-opt/inline_double_cycle.b.Inline.panic-abort.diff created+48
...@@ -0,0 +1,48 @@
1- // MIR for `b` before Inline
2+ // MIR for `b` after Inline
3
4 fn b() -> () {
5 let mut _0: ();
6 let _1: ();
7 let mut _2: ();
8 let _3: ();
9 let mut _4: ();
10+ let mut _5: fn() {b};
11+ let mut _6: fn() {a};
12+ scope 1 (inlined <fn() {b} as FnOnce<()>>::call_once - shim(fn() {b})) {
13+ }
14+ scope 2 (inlined <fn() {a} as FnOnce<()>>::call_once - shim(fn() {a})) {
15+ }
16
17 bb0: {
18 StorageLive(_1);
19 StorageLive(_2);
20 _2 = ();
21- _1 = <fn() {b} as FnOnce<()>>::call_once(b, move _2) -> [return: bb1, unwind unreachable];
22+ StorageLive(_5);
23+ _5 = b;
24+ _1 = move _5() -> [return: bb1, unwind unreachable];
25 }
26
27 bb1: {
28+ StorageDead(_5);
29 StorageDead(_2);
30 StorageDead(_1);
31 StorageLive(_3);
32 StorageLive(_4);
33 _4 = ();
34- _3 = <fn() {a} as FnOnce<()>>::call_once(a, move _4) -> [return: bb2, unwind unreachable];
35+ StorageLive(_6);
36+ _6 = a;
37+ _3 = move _6() -> [return: bb2, unwind unreachable];
38 }
39
40 bb2: {
41+ StorageDead(_6);
42 StorageDead(_4);
43 StorageDead(_3);
44 _0 = const ();
45 return;
46 }
47 }
48
tests/mir-opt/inline_double_cycle.b.Inline.panic-unwind.diff created+48
...@@ -0,0 +1,48 @@
1- // MIR for `b` before Inline
2+ // MIR for `b` after Inline
3
4 fn b() -> () {
5 let mut _0: ();
6 let _1: ();
7 let mut _2: ();
8 let _3: ();
9 let mut _4: ();
10+ let mut _5: fn() {b};
11+ let mut _6: fn() {a};
12+ scope 1 (inlined <fn() {b} as FnOnce<()>>::call_once - shim(fn() {b})) {
13+ }
14+ scope 2 (inlined <fn() {a} as FnOnce<()>>::call_once - shim(fn() {a})) {
15+ }
16
17 bb0: {
18 StorageLive(_1);
19 StorageLive(_2);
20 _2 = ();
21- _1 = <fn() {b} as FnOnce<()>>::call_once(b, move _2) -> [return: bb1, unwind continue];
22+ StorageLive(_5);
23+ _5 = b;
24+ _1 = move _5() -> [return: bb1, unwind continue];
25 }
26
27 bb1: {
28+ StorageDead(_5);
29 StorageDead(_2);
30 StorageDead(_1);
31 StorageLive(_3);
32 StorageLive(_4);
33 _4 = ();
34- _3 = <fn() {a} as FnOnce<()>>::call_once(a, move _4) -> [return: bb2, unwind continue];
35+ StorageLive(_6);
36+ _6 = a;
37+ _3 = move _6() -> [return: bb2, unwind continue];
38 }
39
40 bb2: {
41+ StorageDead(_6);
42 StorageDead(_4);
43 StorageDead(_3);
44 _0 = const ();
45 return;
46 }
47 }
48
tests/mir-opt/inline_double_cycle.rs created+22
...@@ -0,0 +1,22 @@
1// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
2// skip-filecheck
3//@ test-mir-pass: Inline
4//@ edition: 2021
5//@ compile-flags: -Zinline-mir --crate-type=lib
6
7// EMIT_MIR inline_double_cycle.a.Inline.diff
8// EMIT_MIR inline_double_cycle.b.Inline.diff
9
10#![feature(fn_traits)]
11
12#[inline]
13pub fn a() {
14 FnOnce::call_once(a, ());
15 FnOnce::call_once(b, ());
16}
17
18#[inline]
19pub fn b() {
20 FnOnce::call_once(b, ());
21 FnOnce::call_once(a, ());
22}
tests/run-make/autodiff/type-trees/type-analysis/README.md created+13
...@@ -0,0 +1,13 @@
1# Autodiff Type-Trees Type Analysis Tests
2
3This directory contains run-make tests for the autodiff type-trees type analysis functionality. These tests verify that the autodiff compiler correctly analyzes and tracks type information for different Rust types during automatic differentiation.
4
5## What These Tests Do
6
7Each test compiles a simple Rust function with the `#[autodiff_reverse]` attribute and verifies that the compiler:
8
91. **Correctly identifies type information** in the generated LLVM IR
102. **Tracks type annotations** for variables and operations
113. **Preserves type context** through the autodiff transformation process
12
13The tests capture the stdout from the autodiff compiler (which contains type analysis information) and verify it matches expected patterns using FileCheck.
tests/run-make/autodiff/type-trees/type-analysis/array/array.check created+26
...@@ -0,0 +1,26 @@
1// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{}
2// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float}
3// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
4// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
5// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw i8, ptr %{{[0-9]+}}, i64 4, !dbg !{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float}
6// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
7// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
8// CHECK-DAG: %{{[0-9]+}} = fadd float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
9// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw i8, ptr %{{[0-9]+}}, i64 8, !dbg !{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
10// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
11// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
12// CHECK-DAG: %{{[0-9]+}} = fadd float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
13// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
14// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float}:{}
15// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float, [-1,8]:Float@float}
16// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
17// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
18// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw i8, ptr %{{[0-9]+}}, i64 4, !dbg !{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float}
19// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
20// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
21// CHECK-DAG: %{{[0-9]+}} = fadd float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
22// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw i8, ptr %{{[0-9]+}}, i64 8, !dbg !{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
23// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
24// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
25// CHECK-DAG: %{{[0-9]+}} = fadd float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
26// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
\ No newline at end of file
tests/run-make/autodiff/type-trees/type-analysis/array/array.rs created+20
...@@ -0,0 +1,20 @@
1#![feature(autodiff)]
2
3use std::autodiff::autodiff_reverse;
4
5#[autodiff_reverse(d_square, Duplicated, Active)]
6#[no_mangle]
7fn callee(x: &[f32; 3]) -> f32 {
8 x[0] * x[0] + x[1] * x[1] + x[2] * x[2]
9}
10
11fn main() {
12 let x = [1.0f32, 2.0, 3.0];
13 let mut df_dx = [0.0f32; 3];
14 let out = callee(&x);
15 let out_ = d_square(&x, &mut df_dx, 1.0);
16 assert_eq!(out, out_);
17 assert_eq!(2.0, df_dx[0]);
18 assert_eq!(4.0, df_dx[1]);
19 assert_eq!(6.0, df_dx[2]);
20}
tests/run-make/autodiff/type-trees/type-analysis/array/rmake.rs created+28
...@@ -0,0 +1,28 @@
1//@ needs-enzyme
2//@ ignore-cross-compile
3
4use std::fs;
5
6use run_make_support::{llvm_filecheck, rfs, rustc};
7
8fn main() {
9 // Compile the Rust file with the required flags, capturing both stdout and stderr
10 let output = rustc()
11 .input("array.rs")
12 .arg("-Zautodiff=Enable,PrintTAFn=callee")
13 .arg("-Zautodiff=NoPostopt")
14 .opt_level("3")
15 .arg("-Clto=fat")
16 .arg("-g")
17 .run();
18
19 let stdout = output.stdout_utf8();
20 let stderr = output.stderr_utf8();
21
22 // Write the outputs to files
23 rfs::write("array.stdout", stdout);
24 rfs::write("array.stderr", stderr);
25
26 // Run FileCheck on the stdout using the check file
27 llvm_filecheck().patterns("array.check").stdin_buf(rfs::read("array.stdout")).run();
28}
tests/run-make/autodiff/type-trees/type-analysis/array3d/array3d.check created+54
...@@ -0,0 +1,54 @@
1// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{}
2// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
3// CHECK-DAG: br label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
4// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], !dbg !{{[0-9]+}}: {[-1]:Float@float}
5// CHECK-DAG: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
6// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], !dbg !{{[0-9]+}}: {[-1]:Float@float}
7// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
8// CHECK-DAG: %{{[0-9]+}} = phi float [ 0.000000e+00, %{{[0-9]+}} ], [ %{{[0-9]+}}, %{{[0-9]+}} ]: {[-1]:Float@float}
9// CHECK-DAG: %{{[0-9]+}} = phi i1 [ true, %{{[0-9]+}} ], [ false, %{{[0-9]+}} ]: {[-1]:Integer}
10// CHECK-DAG: %{{[0-9]+}} = phi i64 [ 0, %{{[0-9]+}} ], [ 1, %{{[0-9]+}} ]: {[-1]:Integer}
11// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw [2 x [2 x float]], ptr %{{[0-9]+}}, i64 %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
12// CHECK-DAG: br label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
13// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], !dbg !{{[0-9]+}}: {[-1]:Float@float}
14// CHECK-DAG: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
15// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], [ %{{[0-9]+}}, %{{[0-9]+}} ]: {[-1]:Float@float}
16// CHECK-DAG: %{{[0-9]+}} = phi i1 [ true, %{{[0-9]+}} ], [ false, %{{[0-9]+}} ]: {[-1]:Integer}
17// CHECK-DAG: %{{[0-9]+}} = phi i64 [ 0, %{{[0-9]+}} ], [ 1, %{{[0-9]+}} ]: {[-1]:Integer}
18// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw [2 x float], ptr %{{[0-9]+}}, i64 %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
19// CHECK-DAG: br label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
20// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], [ %{{[0-9]+}}, %{{[0-9]+}} ]: {[-1]:Float@float}
21// CHECK-DAG: %{{[0-9]+}} = phi i1 [ true, %{{[0-9]+}} ], [ false, %{{[0-9]+}} ]: {[-1]:Integer}
22// CHECK-DAG: %{{[0-9]+}} = phi i64 [ 0, %{{[0-9]+}} ], [ 1, %{{[0-9]+}} ]: {[-1]:Integer}
23// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw float, ptr %{{[0-9]+}}, i64 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
24// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
25// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
26// CHECK-DAG: %{{[0-9]+}} = fadd float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
27// CHECK-DAG: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
28// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{}
29// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
30// CHECK-DAG: br label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
31// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], !dbg !{{[0-9]+}}: {[-1]:Float@float}
32// CHECK-DAG: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
33// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], !dbg !{{[0-9]+}}: {[-1]:Float@float}
34// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
35// CHECK-DAG: %{{[0-9]+}} = phi float [ 0.000000e+00, %{{[0-9]+}} ], [ %{{[0-9]+}}, %{{[0-9]+}} ]: {[-1]:Float@float}
36// CHECK-DAG: %{{[0-9]+}} = phi i1 [ true, %{{[0-9]+}} ], [ false, %{{[0-9]+}} ]: {[-1]:Integer}
37// CHECK-DAG: %{{[0-9]+}} = phi i64 [ 0, %{{[0-9]+}} ], [ 1, %{{[0-9]+}} ]: {[-1]:Integer}
38// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw [2 x [2 x float]], ptr %{{[0-9]+}}, i64 %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
39// CHECK-DAG: br label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
40// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], !dbg !{{[0-9]+}}: {[-1]:Float@float}
41// CHECK-DAG: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
42// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], [ %{{[0-9]+}}, %{{[0-9]+}} ]: {[-1]:Float@float}
43// CHECK-DAG: %{{[0-9]+}} = phi i1 [ true, %{{[0-9]+}} ], [ false, %{{[0-9]+}} ]: {[-1]:Integer}
44// CHECK-DAG: %{{[0-9]+}} = phi i64 [ 0, %{{[0-9]+}} ], [ 1, %{{[0-9]+}} ]: {[-1]:Integer}
45// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw [2 x float], ptr %{{[0-9]+}}, i64 %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
46// CHECK-DAG: br label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
47// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], [ %{{[0-9]+}}, %{{[0-9]+}} ]: {[-1]:Float@float}
48// CHECK-DAG: %{{[0-9]+}} = phi i1 [ true, %{{[0-9]+}} ], [ false, %{{[0-9]+}} ]: {[-1]:Integer}
49// CHECK-DAG: %{{[0-9]+}} = phi i64 [ 0, %{{[0-9]+}} ], [ 1, %{{[0-9]+}} ]: {[-1]:Integer}
50// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw float, ptr %{{[0-9]+}}, i64 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
51// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
52// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
53// CHECK-DAG: %{{[0-9]+}} = fadd float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
54// CHECK-DAG: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
\ No newline at end of file
tests/run-make/autodiff/type-trees/type-analysis/array3d/array3d.rs created+32
...@@ -0,0 +1,32 @@
1#![feature(autodiff)]
2
3use std::autodiff::autodiff_reverse;
4
5#[autodiff_reverse(d_square, Duplicated, Active)]
6#[no_mangle]
7fn callee(x: &[[[f32; 2]; 2]; 2]) -> f32 {
8 let mut sum = 0.0;
9 for i in 0..2 {
10 for j in 0..2 {
11 for k in 0..2 {
12 sum += x[i][j][k] * x[i][j][k];
13 }
14 }
15 }
16 sum
17}
18
19fn main() {
20 let x = [[[1.0f32, 2.0], [3.0, 4.0]], [[5.0, 6.0], [7.0, 8.0]]];
21 let mut df_dx = [[[0.0f32; 2]; 2]; 2];
22 let out = callee(&x);
23 let out_ = d_square(&x, &mut df_dx, 1.0);
24 assert_eq!(out, out_);
25 for i in 0..2 {
26 for j in 0..2 {
27 for k in 0..2 {
28 assert_eq!(df_dx[i][j][k], 2.0 * x[i][j][k]);
29 }
30 }
31 }
32}
tests/run-make/autodiff/type-trees/type-analysis/array3d/rmake.rs created+28
...@@ -0,0 +1,28 @@
1//@ needs-enzyme
2//@ ignore-cross-compile
3
4use std::fs;
5
6use run_make_support::{llvm_filecheck, rfs, rustc};
7
8fn main() {
9 // Compile the Rust file with the required flags, capturing both stdout and stderr
10 let output = rustc()
11 .input("array3d.rs")
12 .arg("-Zautodiff=Enable,PrintTAFn=callee")
13 .arg("-Zautodiff=NoPostopt")
14 .opt_level("3")
15 .arg("-Clto=fat")
16 .arg("-g")
17 .run();
18
19 let stdout = output.stdout_utf8();
20 let stderr = output.stderr_utf8();
21
22 // Write the outputs to files
23 rfs::write("array3d.stdout", stdout);
24 rfs::write("array3d.stderr", stderr);
25
26 // Run FileCheck on the stdout using the check file
27 llvm_filecheck().patterns("array3d.check").stdin_buf(rfs::read("array3d.stdout")).run();
28}
tests/run-make/autodiff/type-trees/type-analysis/box/box.check created+12
...@@ -0,0 +1,12 @@
1// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{}
2// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Float@float}
3// CHECK-DAG: %{{[0-9]+}} = load ptr, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !nonnull !{{[0-9]+}}, !align !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
4// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
5// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
6// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
7// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Float@float}:{}
8// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Float@float}
9// CHECK-DAG: %{{[0-9]+}} = load ptr, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !nonnull !{{[0-9]+}}, !align !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
10// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
11// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
12// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
\ No newline at end of file
tests/run-make/autodiff/type-trees/type-analysis/box/box.rs created+18
...@@ -0,0 +1,18 @@
1#![feature(autodiff)]
2
3use std::autodiff::autodiff_reverse;
4
5#[autodiff_reverse(d_square, Duplicated, Active)]
6#[no_mangle]
7fn callee(x: &Box<f32>) -> f32 {
8 **x * **x
9}
10
11fn main() {
12 let x = Box::new(7.0f32);
13 let mut df_dx = Box::new(0.0f32);
14 let out = callee(&x);
15 let out_ = d_square(&x, &mut df_dx, 1.0);
16 assert_eq!(out, out_);
17 assert_eq!(14.0, *df_dx);
18}
tests/run-make/autodiff/type-trees/type-analysis/box/rmake.rs created+28
...@@ -0,0 +1,28 @@
1//@ needs-enzyme
2//@ ignore-cross-compile
3
4use std::fs;
5
6use run_make_support::{llvm_filecheck, rfs, rustc};
7
8fn main() {
9 // Compile the Rust file with the required flags, capturing both stdout and stderr
10 let output = rustc()
11 .input("box.rs")
12 .arg("-Zautodiff=Enable,PrintTAFn=callee")
13 .arg("-Zautodiff=NoPostopt")
14 .opt_level("3")
15 .arg("-Clto=fat")
16 .arg("-g")
17 .run();
18
19 let stdout = output.stdout_utf8();
20 let stderr = output.stderr_utf8();
21
22 // Write the outputs to files
23 rfs::write("box.stdout", stdout);
24 rfs::write("box.stderr", stderr);
25
26 // Run FileCheck on the stdout using the check file
27 llvm_filecheck().patterns("box.check").stdin_buf(rfs::read("box.stdout")).run();
28}
tests/run-make/autodiff/type-trees/type-analysis/const_pointer/const_pointer.check created+10
...@@ -0,0 +1,10 @@
1// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{}
2// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
3// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
4// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
5// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
6// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{}
7// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
8// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
9// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
10// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
\ No newline at end of file
tests/run-make/autodiff/type-trees/type-analysis/const_pointer/const_pointer.rs created+18
...@@ -0,0 +1,18 @@
1#![feature(autodiff)]
2
3use std::autodiff::autodiff_reverse;
4
5#[autodiff_reverse(d_square, Duplicated, Active)]
6#[no_mangle]
7fn callee(x: *const f32) -> f32 {
8 unsafe { *x * *x }
9}
10
11fn main() {
12 let x: f32 = 7.0;
13 let out = callee(&x as *const f32);
14 let mut df_dx: f32 = 0.0;
15 let out_ = d_square(&x as *const f32, &mut df_dx, 1.0);
16 assert_eq!(out, out_);
17 assert_eq!(14.0, df_dx);
18}
tests/run-make/autodiff/type-trees/type-analysis/const_pointer/rmake.rs created+31
...@@ -0,0 +1,31 @@
1//@ needs-enzyme
2//@ ignore-cross-compile
3
4use std::fs;
5
6use run_make_support::{llvm_filecheck, rfs, rustc};
7
8fn main() {
9 // Compile the Rust file with the required flags, capturing both stdout and stderr
10 let output = rustc()
11 .input("const_pointer.rs")
12 .arg("-Zautodiff=Enable,PrintTAFn=callee")
13 .arg("-Zautodiff=NoPostopt")
14 .opt_level("3")
15 .arg("-Clto=fat")
16 .arg("-g")
17 .run();
18
19 let stdout = output.stdout_utf8();
20 let stderr = output.stderr_utf8();
21
22 // Write the outputs to files
23 rfs::write("const_pointer.stdout", stdout);
24 rfs::write("const_pointer.stderr", stderr);
25
26 // Run FileCheck on the stdout using the check file
27 llvm_filecheck()
28 .patterns("const_pointer.check")
29 .stdin_buf(rfs::read("const_pointer.stdout"))
30 .run();
31}
tests/run-make/autodiff/type-trees/type-analysis/f32/f32.check created+12
...@@ -0,0 +1,12 @@
1// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{}
2// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
3
4// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
5// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
6// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
7// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{}
8// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
9
10// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
11// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
12// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
\ No newline at end of file
tests/run-make/autodiff/type-trees/type-analysis/f32/f32.rs created+19
...@@ -0,0 +1,19 @@
1#![feature(autodiff)]
2
3use std::autodiff::autodiff_reverse;
4
5#[autodiff_reverse(d_square, Duplicated, Active)]
6#[no_mangle]
7fn callee(x: &f32) -> f32 {
8 *x * *x
9}
10
11fn main() {
12 let x: f32 = 7.0;
13 let mut df_dx: f32 = 0.0;
14 let out = callee(&x);
15 let out_ = d_square(&x, &mut df_dx, 1.0);
16
17 assert_eq!(out, out_);
18 assert_eq!(14.0, df_dx);
19}
tests/run-make/autodiff/type-trees/type-analysis/f32/rmake.rs created+28
...@@ -0,0 +1,28 @@
1//@ needs-enzyme
2//@ ignore-cross-compile
3
4use std::fs;
5
6use run_make_support::{llvm_filecheck, rfs, rustc};
7
8fn main() {
9 // Compile the Rust file with the required flags, capturing both stdout and stderr
10 let output = rustc()
11 .input("f32.rs")
12 .arg("-Zautodiff=Enable,PrintTAFn=callee")
13 .arg("-Zautodiff=NoPostopt")
14 .opt_level("3")
15 .arg("-Clto=fat")
16 .arg("-g")
17 .run();
18
19 let stdout = output.stdout_utf8();
20 let stderr = output.stderr_utf8();
21
22 // Write the outputs to files
23 rfs::write("f32.stdout", stdout);
24 rfs::write("f32.stderr", stderr);
25
26 // Run FileCheck on the stdout using the check file
27 llvm_filecheck().patterns("f32.check").stdin_buf(rfs::read("f32.stdout")).run();
28}
tests/run-make/autodiff/type-trees/type-analysis/f64/f64.check created+10
...@@ -0,0 +1,10 @@
1// CHECK: callee - {[-1]:Float@double} |{[-1]:Pointer}:{}
2// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@double}
3// CHECK-DAG: %{{[0-9]+}} = load double, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@double}
4// CHECK-DAG: %{{[0-9]+}} = fmul double %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@double}
5// CHECK-DAG: ret double %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
6// CHECK: callee - {[-1]:Float@double} |{[-1]:Pointer, [-1,0]:Float@double}:{}
7// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@double}
8// CHECK-DAG: %{{[0-9]+}} = load double, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@double}
9// CHECK-DAG: %{{[0-9]+}} = fmul double %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@double}
10// CHECK-DAG: ret double %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
\ No newline at end of file
tests/run-make/autodiff/type-trees/type-analysis/f64/f64.rs created+20
...@@ -0,0 +1,20 @@
1#![feature(autodiff)]
2use std::autodiff::autodiff_reverse;
3
4#[autodiff_reverse(d_callee, Duplicated, Active)]
5#[no_mangle]
6fn callee(x: &f64) -> f64 {
7 x * x
8}
9
10fn main() {
11 let x = std::hint::black_box(3.0);
12
13 let output = callee(&x);
14 assert_eq!(9.0, output);
15
16 let mut df_dx = 0.0;
17 let output_ = d_callee(&x, &mut df_dx, 1.0);
18 assert_eq!(output, output_);
19 assert_eq!(6.0, df_dx);
20}
tests/run-make/autodiff/type-trees/type-analysis/f64/rmake.rs created+28
...@@ -0,0 +1,28 @@
1//@ needs-enzyme
2//@ ignore-cross-compile
3
4use std::fs;
5
6use run_make_support::{llvm_filecheck, rfs, rustc};
7
8fn main() {
9 // Compile the Rust file with the required flags, capturing both stdout and stderr
10 let output = rustc()
11 .input("f64.rs")
12 .arg("-Zautodiff=Enable,PrintTAFn=callee")
13 .arg("-Zautodiff=NoPostopt")
14 .opt_level("3")
15 .arg("-Clto=fat")
16 .arg("-g")
17 .run();
18
19 let stdout = output.stdout_utf8();
20 let stderr = output.stderr_utf8();
21
22 // Write the outputs to files
23 rfs::write("f64.stdout", stdout);
24 rfs::write("f64.stderr", stderr);
25
26 // Run FileCheck on the stdout using the check file
27 llvm_filecheck().patterns("f64.check").stdin_buf(rfs::read("f64.stdout")).run();
28}
tests/run-make/autodiff/type-trees/type-analysis/i128/i128.check created+10
...@@ -0,0 +1,10 @@
1// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{}
2// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer}
3// CHECK-DAG: %{{[0-9]+}} = load i128, ptr %{{[0-9]+}}, align 16, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
4// CHECK-DAG: %{{[0-9]+}} = mul i128 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
5// CHECK-DAG: ret i128 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
6// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer}:{}
7// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer}
8// CHECK-DAG: %{{[0-9]+}} = load i128, ptr %{{[0-9]+}}, align 16, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
9// CHECK-DAG: %{{[0-9]+}} = mul i128 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
10// CHECK-DAG: ret i128 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
\ No newline at end of file
tests/run-make/autodiff/type-trees/type-analysis/i128/i128.rs created+14
...@@ -0,0 +1,14 @@
1#![feature(autodiff)]
2
3use std::autodiff::autodiff_reverse;
4
5#[autodiff_reverse(d_square, Duplicated, Active)]
6#[no_mangle]
7fn callee(x: &i128) -> i128 {
8 *x * *x
9}
10
11fn main() {
12 let x: i128 = 7;
13 let _ = callee(&x);
14}
tests/run-make/autodiff/type-trees/type-analysis/i128/rmake.rs created+28
...@@ -0,0 +1,28 @@
1//@ needs-enzyme
2//@ ignore-cross-compile
3
4use std::fs;
5
6use run_make_support::{llvm_filecheck, rfs, rustc};
7
8fn main() {
9 // Compile the Rust file with the required flags, capturing both stdout and stderr
10 let output = rustc()
11 .input("i128.rs")
12 .arg("-Zautodiff=Enable,PrintTAFn=callee")
13 .arg("-Zautodiff=NoPostopt")
14 .opt_level("3")
15 .arg("-Clto=fat")
16 .arg("-g")
17 .run();
18
19 let stdout = output.stdout_utf8();
20 let stderr = output.stderr_utf8();
21
22 // Write the outputs to files
23 rfs::write("i128.stdout", stdout);
24 rfs::write("i128.stderr", stderr);
25
26 // Run FileCheck on the stdout using the check file
27 llvm_filecheck().patterns("i128.check").stdin_buf(rfs::read("i128.stdout")).run();
28}
tests/run-make/autodiff/type-trees/type-analysis/i16/i16.check created+10
...@@ -0,0 +1,10 @@
1// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{}
2// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer}
3// CHECK-DAG: %{{[0-9]+}} = load i16, ptr %{{[0-9]+}}, align 2, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
4// CHECK-DAG: %{{[0-9]+}} = mul i16 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
5// CHECK-DAG: ret i16 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
6// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer}:{}
7// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer}
8// CHECK-DAG: %{{[0-9]+}} = load i16, ptr %{{[0-9]+}}, align 2, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
9// CHECK-DAG: %{{[0-9]+}} = mul i16 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
10// CHECK-DAG: ret i16 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
\ No newline at end of file
tests/run-make/autodiff/type-trees/type-analysis/i16/i16.rs created+14
...@@ -0,0 +1,14 @@
1#![feature(autodiff)]
2
3use std::autodiff::autodiff_reverse;
4
5#[autodiff_reverse(d_square, Duplicated, Active)]
6#[no_mangle]
7fn callee(x: &i16) -> i16 {
8 *x * *x
9}
10
11fn main() {
12 let x: i16 = 7;
13 let _ = callee(&x);
14}
tests/run-make/autodiff/type-trees/type-analysis/i16/rmake.rs created+28
...@@ -0,0 +1,28 @@
1//@ needs-enzyme
2//@ ignore-cross-compile
3
4use std::fs;
5
6use run_make_support::{llvm_filecheck, rfs, rustc};
7
8fn main() {
9 // Compile the Rust file with the required flags, capturing both stdout and stderr
10 let output = rustc()
11 .input("i16.rs")
12 .arg("-Zautodiff=Enable,PrintTAFn=callee")
13 .arg("-Zautodiff=NoPostopt")
14 .opt_level("3")
15 .arg("-Clto=fat")
16 .arg("-g")
17 .run();
18
19 let stdout = output.stdout_utf8();
20 let stderr = output.stderr_utf8();
21
22 // Write the outputs to files
23 rfs::write("i16.stdout", stdout);
24 rfs::write("i16.stderr", stderr);
25
26 // Run FileCheck on the stdout using the check file
27 llvm_filecheck().patterns("i16.check").stdin_buf(rfs::read("i16.stdout")).run();
28}
tests/run-make/autodiff/type-trees/type-analysis/i32/i32.check created+10
...@@ -0,0 +1,10 @@
1// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{}
2// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer}
3// CHECK-DAG: %{{[0-9]+}} = load i32, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
4// CHECK-DAG: %{{[0-9]+}} = mul i32 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
5// CHECK-DAG: ret i32 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
6// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer}:{}
7// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer}
8// CHECK-DAG: %{{[0-9]+}} = load i32, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
9// CHECK-DAG: %{{[0-9]+}} = mul i32 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
10// CHECK-DAG: ret i32 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
\ No newline at end of file
tests/run-make/autodiff/type-trees/type-analysis/i32/i32.rs created+14
...@@ -0,0 +1,14 @@
1#![feature(autodiff)]
2
3use std::autodiff::autodiff_reverse;
4
5#[autodiff_reverse(d_square, Duplicated, Active)]
6#[no_mangle]
7fn callee(x: &i32) -> i32 {
8 *x * *x
9}
10
11fn main() {
12 let x: i32 = 7;
13 let _ = callee(&x);
14}
tests/run-make/autodiff/type-trees/type-analysis/i32/rmake.rs created+28
...@@ -0,0 +1,28 @@
1//@ needs-enzyme
2//@ ignore-cross-compile
3
4use std::fs;
5
6use run_make_support::{llvm_filecheck, rfs, rustc};
7
8fn main() {
9 // Compile the Rust file with the required flags, capturing both stdout and stderr
10 let output = rustc()
11 .input("i32.rs")
12 .arg("-Zautodiff=Enable,PrintTAFn=callee")
13 .arg("-Zautodiff=NoPostopt")
14 .opt_level("3")
15 .arg("-Clto=fat")
16 .arg("-g")
17 .run();
18
19 let stdout = output.stdout_utf8();
20 let stderr = output.stderr_utf8();
21
22 // Write the outputs to files
23 rfs::write("i32.stdout", stdout);
24 rfs::write("i32.stderr", stderr);
25
26 // Run FileCheck on the stdout using the check file
27 llvm_filecheck().patterns("i32.check").stdin_buf(rfs::read("i32.stdout")).run();
28}
tests/run-make/autodiff/type-trees/type-analysis/i8/i8.check created+10
...@@ -0,0 +1,10 @@
1// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{}
2// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer}
3// CHECK-DAG: %{{[0-9]+}} = load i8, ptr %{{[0-9]+}}, align 1, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
4// CHECK-DAG: %{{[0-9]+}} = mul i8 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
5// CHECK-DAG: ret i8 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
6// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer}:{}
7// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer}
8// CHECK-DAG: %{{[0-9]+}} = load i8, ptr %{{[0-9]+}}, align 1, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
9// CHECK-DAG: %{{[0-9]+}} = mul i8 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
10// CHECK-DAG: ret i8 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
\ No newline at end of file
tests/run-make/autodiff/type-trees/type-analysis/i8/i8.rs created+14
...@@ -0,0 +1,14 @@
1#![feature(autodiff)]
2
3use std::autodiff::autodiff_reverse;
4
5#[autodiff_reverse(d_square, Duplicated, Active)]
6#[no_mangle]
7fn callee(x: &i8) -> i8 {
8 *x * *x
9}
10
11fn main() {
12 let x: i8 = 7;
13 let _ = callee(&x);
14}
tests/run-make/autodiff/type-trees/type-analysis/i8/rmake.rs created+28
...@@ -0,0 +1,28 @@
1//@ needs-enzyme
2//@ ignore-cross-compile
3
4use std::fs;
5
6use run_make_support::{llvm_filecheck, rfs, rustc};
7
8fn main() {
9 // Compile the Rust file with the required flags, capturing both stdout and stderr
10 let output = rustc()
11 .input("i8.rs")
12 .arg("-Zautodiff=Enable,PrintTAFn=callee")
13 .arg("-Zautodiff=NoPostopt")
14 .opt_level("3")
15 .arg("-Clto=fat")
16 .arg("-g")
17 .run();
18
19 let stdout = output.stdout_utf8();
20 let stderr = output.stderr_utf8();
21
22 // Write the outputs to files
23 rfs::write("i8.stdout", stdout);
24 rfs::write("i8.stderr", stderr);
25
26 // Run FileCheck on the stdout using the check file
27 llvm_filecheck().patterns("i8.check").stdin_buf(rfs::read("i8.stdout")).run();
28}
tests/run-make/autodiff/type-trees/type-analysis/isize/isize.check created+10
...@@ -0,0 +1,10 @@
1// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{}
2// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer}
3// CHECK-DAG: %{{[0-9]+}} = load i64, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
4// CHECK-DAG: %{{[0-9]+}} = mul i64 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
5// CHECK-DAG: ret i64 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
6// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer}:{}
7// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer}
8// CHECK-DAG: %{{[0-9]+}} = load i64, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
9// CHECK-DAG: %{{[0-9]+}} = mul i64 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
10// CHECK-DAG: ret i64 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
\ No newline at end of file
tests/run-make/autodiff/type-trees/type-analysis/isize/isize.rs created+14
...@@ -0,0 +1,14 @@
1#![feature(autodiff)]
2
3use std::autodiff::autodiff_reverse;
4
5#[autodiff_reverse(d_square, Duplicated, Active)]
6#[no_mangle]
7fn callee(x: &isize) -> isize {
8 *x * *x
9}
10
11fn main() {
12 let x: isize = 7;
13 let _ = callee(&x);
14}
tests/run-make/autodiff/type-trees/type-analysis/isize/rmake.rs created+28
...@@ -0,0 +1,28 @@
1//@ needs-enzyme
2//@ ignore-cross-compile
3
4use std::fs;
5
6use run_make_support::{llvm_filecheck, rfs, rustc};
7
8fn main() {
9 // Compile the Rust file with the required flags, capturing both stdout and stderr
10 let output = rustc()
11 .input("isize.rs")
12 .arg("-Zautodiff=Enable,PrintTAFn=callee")
13 .arg("-Zautodiff=NoPostopt")
14 .opt_level("3")
15 .arg("-Clto=fat")
16 .arg("-g")
17 .run();
18
19 let stdout = output.stdout_utf8();
20 let stderr = output.stderr_utf8();
21
22 // Write the outputs to files
23 rfs::write("isize.stdout", stdout);
24 rfs::write("isize.stderr", stderr);
25
26 // Run FileCheck on the stdout using the check file
27 llvm_filecheck().patterns("isize.check").stdin_buf(rfs::read("isize.stdout")).run();
28}
tests/run-make/autodiff/type-trees/type-analysis/mut_pointer/mut_pointer.check created+10
...@@ -0,0 +1,10 @@
1// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{}
2// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
3// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
4// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
5// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
6// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{}
7// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
8// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
9// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
10// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
\ No newline at end of file
tests/run-make/autodiff/type-trees/type-analysis/mut_pointer/mut_pointer.rs created+18
...@@ -0,0 +1,18 @@
1#![feature(autodiff)]
2
3use std::autodiff::autodiff_reverse;
4
5#[autodiff_reverse(d_square, Duplicated, Active)]
6#[no_mangle]
7fn callee(x: *mut f32) -> f32 {
8 unsafe { *x * *x }
9}
10
11fn main() {
12 let mut x: f32 = 7.0;
13 let out = callee(&mut x as *mut f32);
14 let mut df_dx: f32 = 0.0;
15 let out_ = d_square(&mut x as *mut f32, &mut df_dx, 1.0);
16 assert_eq!(out, out_);
17 assert_eq!(14.0, df_dx);
18}
tests/run-make/autodiff/type-trees/type-analysis/mut_pointer/rmake.rs created+28
...@@ -0,0 +1,28 @@
1//@ needs-enzyme
2//@ ignore-cross-compile
3
4use std::fs;
5
6use run_make_support::{llvm_filecheck, rfs, rustc};
7
8fn main() {
9 // Compile the Rust file with the required flags, capturing both stdout and stderr
10 let output = rustc()
11 .input("mut_pointer.rs")
12 .arg("-Zautodiff=Enable,PrintTAFn=callee")
13 .arg("-Zautodiff=NoPostopt")
14 .opt_level("3")
15 .arg("-Clto=fat")
16 .arg("-g")
17 .run();
18
19 let stdout = output.stdout_utf8();
20 let stderr = output.stderr_utf8();
21
22 // Write the outputs to files
23 rfs::write("mut_pointer.stdout", stdout);
24 rfs::write("mut_pointer.stderr", stderr);
25
26 // Run FileCheck on the stdout using the check file
27 llvm_filecheck().patterns("mut_pointer.check").stdin_buf(rfs::read("mut_pointer.stdout")).run();
28}
tests/run-make/autodiff/type-trees/type-analysis/mut_ref/mut_ref.check created+10
...@@ -0,0 +1,10 @@
1// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{}
2// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
3// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
4// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
5// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
6// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{}
7// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
8// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
9// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
10// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
\ No newline at end of file
tests/run-make/autodiff/type-trees/type-analysis/mut_ref/mut_ref.rs created+18
...@@ -0,0 +1,18 @@
1#![feature(autodiff)]
2
3use std::autodiff::autodiff_reverse;
4
5#[autodiff_reverse(d_square, Duplicated, Active)]
6#[no_mangle]
7fn callee(x: &mut f32) -> f32 {
8 *x * *x
9}
10
11fn main() {
12 let mut x: f32 = 7.0;
13 let mut df_dx: f32 = 0.0;
14 let out = callee(&mut x);
15 let out_ = d_square(&mut x, &mut df_dx, 1.0);
16 assert_eq!(out, out_);
17 assert_eq!(14.0, df_dx);
18}
tests/run-make/autodiff/type-trees/type-analysis/mut_ref/rmake.rs created+28
...@@ -0,0 +1,28 @@
1//@ needs-enzyme
2//@ ignore-cross-compile
3
4use std::fs;
5
6use run_make_support::{llvm_filecheck, rfs, rustc};
7
8fn main() {
9 // Compile the Rust file with the required flags, capturing both stdout and stderr
10 let output = rustc()
11 .input("mut_ref.rs")
12 .arg("-Zautodiff=Enable,PrintTAFn=callee")
13 .arg("-Zautodiff=NoPostopt")
14 .opt_level("3")
15 .arg("-Clto=fat")
16 .arg("-g")
17 .run();
18
19 let stdout = output.stdout_utf8();
20 let stderr = output.stderr_utf8();
21
22 // Write the outputs to files
23 rfs::write("mut_ref.stdout", stdout);
24 rfs::write("mut_ref.stderr", stderr);
25
26 // Run FileCheck on the stdout using the check file
27 llvm_filecheck().patterns("mut_ref.check").stdin_buf(rfs::read("mut_ref.stdout")).run();
28}
tests/run-make/autodiff/type-trees/type-analysis/ref/ref.check created+10
...@@ -0,0 +1,10 @@
1// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{}
2// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
3// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
4// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
5// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
6// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{}
7// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
8// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
9// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
10// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
\ No newline at end of file
tests/run-make/autodiff/type-trees/type-analysis/ref/ref.rs created+18
...@@ -0,0 +1,18 @@
1#![feature(autodiff)]
2
3use std::autodiff::autodiff_reverse;
4
5#[autodiff_reverse(d_square, Duplicated, Active)]
6#[no_mangle]
7fn callee(x: &f32) -> f32 {
8 *x * *x
9}
10
11fn main() {
12 let x: f32 = 7.0;
13 let mut df_dx: f32 = 0.0;
14 let out = callee(&x);
15 let out_ = d_square(&x, &mut df_dx, 1.0);
16 assert_eq!(out, out_);
17 assert_eq!(14.0, df_dx);
18}
tests/run-make/autodiff/type-trees/type-analysis/ref/rmake.rs created+28
...@@ -0,0 +1,28 @@
1//@ needs-enzyme
2//@ ignore-cross-compile
3
4use std::fs;
5
6use run_make_support::{llvm_filecheck, rfs, rustc};
7
8fn main() {
9 // Compile the Rust file with the required flags, capturing both stdout and stderr
10 let output = rustc()
11 .input("ref.rs")
12 .arg("-Zautodiff=Enable,PrintTAFn=callee")
13 .arg("-Zautodiff=NoPostopt")
14 .opt_level("3")
15 .arg("-Clto=fat")
16 .arg("-g")
17 .run();
18
19 let stdout = output.stdout_utf8();
20 let stderr = output.stderr_utf8();
21
22 // Write the outputs to files
23 rfs::write("ref.stdout", stdout);
24 rfs::write("ref.stderr", stderr);
25
26 // Run FileCheck on the stdout using the check file
27 llvm_filecheck().patterns("ref.check").stdin_buf(rfs::read("ref.stdout")).run();
28}
tests/run-make/autodiff/type-trees/type-analysis/struct/rmake.rs created+28
...@@ -0,0 +1,28 @@
1//@ needs-enzyme
2//@ ignore-cross-compile
3
4use std::fs;
5
6use run_make_support::{llvm_filecheck, rfs, rustc};
7
8fn main() {
9 // Compile the Rust file with the required flags, capturing both stdout and stderr
10 let output = rustc()
11 .input("struct.rs")
12 .arg("-Zautodiff=Enable,PrintTAFn=callee")
13 .arg("-Zautodiff=NoPostopt")
14 .opt_level("3")
15 .arg("-Clto=fat")
16 .arg("-g")
17 .run();
18
19 let stdout = output.stdout_utf8();
20 let stderr = output.stderr_utf8();
21
22 // Write the outputs to files
23 rfs::write("struct.stdout", stdout);
24 rfs::write("struct.stderr", stderr);
25
26 // Run FileCheck on the stdout using the check file
27 llvm_filecheck().patterns("struct.check").stdin_buf(rfs::read("struct.stdout")).run();
28}
tests/run-make/autodiff/type-trees/type-analysis/struct/struct.check created+10
...@@ -0,0 +1,10 @@
1// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{}
2// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
3// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
4// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
5// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
6// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{}
7// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
8// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
9// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
10// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
\ No newline at end of file
tests/run-make/autodiff/type-trees/type-analysis/struct/struct.rs created+23
...@@ -0,0 +1,23 @@
1#![feature(autodiff)]
2
3use std::autodiff::autodiff_reverse;
4
5#[derive(Copy, Clone)]
6struct MyStruct {
7 f: f32,
8}
9
10#[autodiff_reverse(d_square, Duplicated, Active)]
11#[no_mangle]
12fn callee(x: &MyStruct) -> f32 {
13 x.f * x.f
14}
15
16fn main() {
17 let x = MyStruct { f: 7.0 };
18 let mut df_dx = MyStruct { f: 0.0 };
19 let out = callee(&x);
20 let out_ = d_square(&x, &mut df_dx, 1.0);
21 assert_eq!(out, out_);
22 assert_eq!(14.0, df_dx.f);
23}
tests/run-make/autodiff/type-trees/type-analysis/u128/rmake.rs created+28
...@@ -0,0 +1,28 @@
1//@ needs-enzyme
2//@ ignore-cross-compile
3
4use std::fs;
5
6use run_make_support::{llvm_filecheck, rfs, rustc};
7
8fn main() {
9 // Compile the Rust file with the required flags, capturing both stdout and stderr
10 let output = rustc()
11 .input("u128.rs")
12 .arg("-Zautodiff=Enable,PrintTAFn=callee")
13 .arg("-Zautodiff=NoPostopt")
14 .opt_level("3")
15 .arg("-Clto=fat")
16 .arg("-g")
17 .run();
18
19 let stdout = output.stdout_utf8();
20 let stderr = output.stderr_utf8();
21
22 // Write the outputs to files
23 rfs::write("u128.stdout", stdout);
24 rfs::write("u128.stderr", stderr);
25
26 // Run FileCheck on the stdout using the check file
27 llvm_filecheck().patterns("u128.check").stdin_buf(rfs::read("u128.stdout")).run();
28}
tests/run-make/autodiff/type-trees/type-analysis/u128/u128.check created+10
...@@ -0,0 +1,10 @@
1// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{}
2// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer}
3// CHECK-DAG: %{{[0-9]+}} = load i128, ptr %{{[0-9]+}}, align 16, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
4// CHECK-DAG: %{{[0-9]+}} = mul i128 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
5// CHECK-DAG: ret i128 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
6// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer}:{}
7// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer, [-1,8]:Integer, [-1,9]:Integer, [-1,10]:Integer, [-1,11]:Integer, [-1,12]:Integer, [-1,13]:Integer, [-1,14]:Integer, [-1,15]:Integer}
8// CHECK-DAG: %{{[0-9]+}} = load i128, ptr %{{[0-9]+}}, align 16, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
9// CHECK-DAG: %{{[0-9]+}} = mul i128 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
10// CHECK-DAG: ret i128 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
\ No newline at end of file
tests/run-make/autodiff/type-trees/type-analysis/u128/u128.rs created+14
...@@ -0,0 +1,14 @@
1#![feature(autodiff)]
2
3use std::autodiff::autodiff_reverse;
4
5#[autodiff_reverse(d_square, Duplicated, Active)]
6#[no_mangle]
7fn callee(x: &u128) -> u128 {
8 *x * *x
9}
10
11fn main() {
12 let x: u128 = 7;
13 let _ = callee(&x);
14}
tests/run-make/autodiff/type-trees/type-analysis/u16/rmake.rs created+28
...@@ -0,0 +1,28 @@
1//@ needs-enzyme
2//@ ignore-cross-compile
3
4use std::fs;
5
6use run_make_support::{llvm_filecheck, rfs, rustc};
7
8fn main() {
9 // Compile the Rust file with the required flags, capturing both stdout and stderr
10 let output = rustc()
11 .input("u16.rs")
12 .arg("-Zautodiff=Enable,PrintTAFn=callee")
13 .arg("-Zautodiff=NoPostopt")
14 .opt_level("3")
15 .arg("-Clto=fat")
16 .arg("-g")
17 .run();
18
19 let stdout = output.stdout_utf8();
20 let stderr = output.stderr_utf8();
21
22 // Write the outputs to files
23 rfs::write("u16.stdout", stdout);
24 rfs::write("u16.stderr", stderr);
25
26 // Run FileCheck on the stdout using the check file
27 llvm_filecheck().patterns("u16.check").stdin_buf(rfs::read("u16.stdout")).run();
28}
tests/run-make/autodiff/type-trees/type-analysis/u16/u16.check created+10
...@@ -0,0 +1,10 @@
1// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{}
2// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer}
3// CHECK-DAG: %{{[0-9]+}} = load i16, ptr %{{[0-9]+}}, align 2, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
4// CHECK-DAG: %{{[0-9]+}} = mul i16 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
5// CHECK-DAG: ret i16 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
6// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer}:{}
7// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer}
8// CHECK-DAG: %{{[0-9]+}} = load i16, ptr %{{[0-9]+}}, align 2, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
9// CHECK-DAG: %{{[0-9]+}} = mul i16 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
10// CHECK-DAG: ret i16 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
\ No newline at end of file
tests/run-make/autodiff/type-trees/type-analysis/u16/u16.rs created+14
...@@ -0,0 +1,14 @@
1#![feature(autodiff)]
2
3use std::autodiff::autodiff_reverse;
4
5#[autodiff_reverse(d_square, Duplicated, Active)]
6#[no_mangle]
7fn callee(x: &u16) -> u16 {
8 *x * *x
9}
10
11fn main() {
12 let x: u16 = 7;
13 let _ = callee(&x);
14}
tests/run-make/autodiff/type-trees/type-analysis/u32/rmake.rs created+28
...@@ -0,0 +1,28 @@
1//@ needs-enzyme
2//@ ignore-cross-compile
3
4use std::fs;
5
6use run_make_support::{llvm_filecheck, rfs, rustc};
7
8fn main() {
9 // Compile the Rust file with the required flags, capturing both stdout and stderr
10 let output = rustc()
11 .input("u32.rs")
12 .arg("-Zautodiff=Enable,PrintTAFn=callee")
13 .arg("-Zautodiff=NoPostopt")
14 .opt_level("3")
15 .arg("-Clto=fat")
16 .arg("-g")
17 .run();
18
19 let stdout = output.stdout_utf8();
20 let stderr = output.stderr_utf8();
21
22 // Write the outputs to files
23 rfs::write("u32.stdout", stdout);
24 rfs::write("u32.stderr", stderr);
25
26 // Run FileCheck on the stdout using the check file
27 llvm_filecheck().patterns("u32.check").stdin_buf(rfs::read("u32.stdout")).run();
28}
tests/run-make/autodiff/type-trees/type-analysis/u32/u32.check created+10
...@@ -0,0 +1,10 @@
1// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{}
2// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer}
3// CHECK-DAG: %{{[0-9]+}} = load i32, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
4// CHECK-DAG: %{{[0-9]+}} = mul i32 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
5// CHECK-DAG: ret i32 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
6// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer}:{}
7// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer}
8// CHECK-DAG: %{{[0-9]+}} = load i32, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
9// CHECK-DAG: %{{[0-9]+}} = mul i32 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
10// CHECK-DAG: ret i32 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
\ No newline at end of file
tests/run-make/autodiff/type-trees/type-analysis/u32/u32.rs created+14
...@@ -0,0 +1,14 @@
1#![feature(autodiff)]
2
3use std::autodiff::autodiff_reverse;
4
5#[autodiff_reverse(d_square, Duplicated, Active)]
6#[no_mangle]
7fn callee(x: &u32) -> u32 {
8 *x * *x
9}
10
11fn main() {
12 let x: u32 = 7;
13 let _ = callee(&x);
14}
tests/run-make/autodiff/type-trees/type-analysis/u8/rmake.rs created+28
...@@ -0,0 +1,28 @@
1//@ needs-enzyme
2//@ ignore-cross-compile
3
4use std::fs;
5
6use run_make_support::{llvm_filecheck, rfs, rustc};
7
8fn main() {
9 // Compile the Rust file with the required flags, capturing both stdout and stderr
10 let output = rustc()
11 .input("u8.rs")
12 .arg("-Zautodiff=Enable,PrintTAFn=callee")
13 .arg("-Zautodiff=NoPostopt")
14 .opt_level("3")
15 .arg("-Clto=fat")
16 .arg("-g")
17 .run();
18
19 let stdout = output.stdout_utf8();
20 let stderr = output.stderr_utf8();
21
22 // Write the outputs to files
23 rfs::write("u8.stdout", stdout);
24 rfs::write("u8.stderr", stderr);
25
26 // Run FileCheck on the stdout using the check file
27 llvm_filecheck().patterns("u8.check").stdin_buf(rfs::read("u8.stdout")).run();
28}
tests/run-make/autodiff/type-trees/type-analysis/u8/u8.check created+10
...@@ -0,0 +1,10 @@
1// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{}
2// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer}
3// CHECK-DAG: %{{[0-9]+}} = load i8, ptr %{{[0-9]+}}, align 1, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
4// CHECK-DAG: %{{[0-9]+}} = mul i8 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
5// CHECK-DAG: ret i8 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
6// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer}:{}
7// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer}
8// CHECK-DAG: %{{[0-9]+}} = load i8, ptr %{{[0-9]+}}, align 1, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
9// CHECK-DAG: %{{[0-9]+}} = mul i8 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
10// CHECK-DAG: ret i8 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
\ No newline at end of file
tests/run-make/autodiff/type-trees/type-analysis/u8/u8.rs created+14
...@@ -0,0 +1,14 @@
1#![feature(autodiff)]
2
3use std::autodiff::autodiff_reverse;
4
5#[autodiff_reverse(d_square, Duplicated, Active)]
6#[no_mangle]
7fn callee(x: &u8) -> u8 {
8 *x * *x
9}
10
11fn main() {
12 let x: u8 = 7;
13 let _ = callee(&x);
14}
tests/run-make/autodiff/type-trees/type-analysis/union/rmake.rs created+28
...@@ -0,0 +1,28 @@
1//@ needs-enzyme
2//@ ignore-cross-compile
3
4use std::fs;
5
6use run_make_support::{llvm_filecheck, rfs, rustc};
7
8fn main() {
9 // Compile the Rust file with the required flags, capturing both stdout and stderr
10 let output = rustc()
11 .input("union.rs")
12 .arg("-Zautodiff=Enable,PrintTAFn=callee")
13 .arg("-Zautodiff=NoPostopt")
14 .opt_level("3")
15 .arg("-Clto=fat")
16 .arg("-g")
17 .run();
18
19 let stdout = output.stdout_utf8();
20 let stderr = output.stderr_utf8();
21
22 // Write the outputs to files
23 rfs::write("union.stdout", stdout);
24 rfs::write("union.stderr", stderr);
25
26 // Run FileCheck on the stdout using the check file
27 llvm_filecheck().patterns("union.check").stdin_buf(rfs::read("union.stdout")).run();
28}
tests/run-make/autodiff/type-trees/type-analysis/union/union.check created+10
...@@ -0,0 +1,10 @@
1// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{}
2// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
3// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
4// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
5// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
6// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer, [-1,0]:Float@float}:{}
7// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
8// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
9// CHECK-DAG: %{{[0-9]+}} = fmul float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
10// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
\ No newline at end of file
tests/run-make/autodiff/type-trees/type-analysis/union/union.rs created+20
...@@ -0,0 +1,20 @@
1#![feature(autodiff)]
2
3use std::autodiff::autodiff_reverse;
4
5#[allow(dead_code)]
6union MyUnion {
7 f: f32,
8 i: i32,
9}
10
11#[autodiff_reverse(d_square, Duplicated, Active)]
12#[no_mangle]
13fn callee(x: &MyUnion) -> f32 {
14 unsafe { x.f * x.f }
15}
16
17fn main() {
18 let x = MyUnion { f: 7.0 };
19 let _ = callee(&x);
20}
tests/run-make/autodiff/type-trees/type-analysis/usize/rmake.rs created+28
...@@ -0,0 +1,28 @@
1//@ needs-enzyme
2//@ ignore-cross-compile
3
4use std::fs;
5
6use run_make_support::{llvm_filecheck, rfs, rustc};
7
8fn main() {
9 // Compile the Rust file with the required flags, capturing both stdout and stderr
10 let output = rustc()
11 .input("usize.rs")
12 .arg("-Zautodiff=Enable,PrintTAFn=callee")
13 .arg("-Zautodiff=NoPostopt")
14 .opt_level("3")
15 .arg("-Clto=fat")
16 .arg("-g")
17 .run();
18
19 let stdout = output.stdout_utf8();
20 let stderr = output.stderr_utf8();
21
22 // Write the outputs to files
23 rfs::write("usize.stdout", stdout);
24 rfs::write("usize.stderr", stderr);
25
26 // Run FileCheck on the stdout using the check file
27 llvm_filecheck().patterns("usize.check").stdin_buf(rfs::read("usize.stdout")).run();
28}
tests/run-make/autodiff/type-trees/type-analysis/usize/usize.check created+10
...@@ -0,0 +1,10 @@
1// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer}:{}
2// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer}
3// CHECK-DAG: %{{[0-9]+}} = load i64, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
4// CHECK-DAG: %{{[0-9]+}} = mul i64 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
5// CHECK-DAG: ret i64 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
6// CHECK: callee - {[-1]:Integer} |{[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer}:{}
7// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Integer, [-1,1]:Integer, [-1,2]:Integer, [-1,3]:Integer, [-1,4]:Integer, [-1,5]:Integer, [-1,6]:Integer, [-1,7]:Integer}
8// CHECK-DAG: %{{[0-9]+}} = load i64, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Integer}
9// CHECK-DAG: %{{[0-9]+}} = mul i64 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
10// CHECK-DAG: ret i64 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
\ No newline at end of file
tests/run-make/autodiff/type-trees/type-analysis/usize/usize.rs created+14
...@@ -0,0 +1,14 @@
1#![feature(autodiff)]
2
3use std::autodiff::autodiff_reverse;
4
5#[autodiff_reverse(d_square, Duplicated, Active)]
6#[no_mangle]
7fn callee(x: &usize) -> usize {
8 *x * *x
9}
10
11fn main() {
12 let x: usize = 7;
13 let _ = callee(&x);
14}
tests/run-make/autodiff/type-trees/type-analysis/vec/rmake.rs created+28
...@@ -0,0 +1,28 @@
1//@ needs-enzyme
2//@ ignore-cross-compile
3
4use std::fs;
5
6use run_make_support::{llvm_filecheck, rfs, rustc};
7
8fn main() {
9 // Compile the Rust file with the required flags, capturing both stdout and stderr
10 let output = rustc()
11 .input("vec.rs")
12 .arg("-Zautodiff=Enable,PrintTAFn=callee")
13 .arg("-Zautodiff=NoPostopt")
14 .opt_level("3")
15 .arg("-Clto=fat")
16 .arg("-g")
17 .run();
18
19 let stdout = output.stdout_utf8();
20 let stderr = output.stderr_utf8();
21
22 // Write the outputs to files
23 rfs::write("vec.stdout", stdout);
24 rfs::write("vec.stderr", stderr);
25
26 // Run FileCheck on the stdout using the check file
27 llvm_filecheck().patterns("vec.check").stdin_buf(rfs::read("vec.stdout")).run();
28}
tests/run-make/autodiff/type-trees/type-analysis/vec/vec.check created+18
...@@ -0,0 +1,18 @@
1// CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{}
2// CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer}
3// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw i8, ptr %{{[0-9]+}}, i64 8, !dbg !{{[0-9]+}}: {[-1]:Pointer}
4// CHECK-DAG: %{{[0-9]+}} = load ptr, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !nonnull !102, !noundef !{{[0-9]+}}: {}
5// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw i8, ptr %{{[0-9]+}}, i64 16, !dbg !{{[0-9]+}}: {[-1]:Pointer}
6// CHECK-DAG: %{{[0-9]+}} = load i64, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {}
7// CHECK-DAG: %{{[0-9]+}} = icmp eq i64 %{{[0-9]+}}, 0, !dbg !{{[0-9]+}}: {[-1]:Integer}
8// CHECK-DAG: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
9// CHECK-DAG: %{{[0-9]+}} = phi i64 [ %{{[0-9]+}}, %{{[0-9]+}} ], [ 0, %{{[0-9]+}} ], !dbg !{{[0-9]+}}: {[-1]:Integer}
10// CHECK-DAG: %{{[0-9]+}} = phi float [ %{{[0-9]+}}, %{{[0-9]+}} ], [ -0.000000e+00, %{{[0-9]+}} ], !dbg !{{[0-9]+}}: {[-1]:Float@float}
11// CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw float, ptr %{{[0-9]+}}, i64 %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@float}
12// CHECK-DAG: %{{[0-9]+}} = load float, ptr %{{[0-9]+}}, align 4, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {[-1]:Float@float}
13// CHECK-DAG: %{{[0-9]+}} = fadd float %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Float@float}
14// CHECK-DAG: %{{[0-9]+}} = add nuw i64 %{{[0-9]+}}, 1, !dbg !{{[0-9]+}}: {[-1]:Integer}
15// CHECK-DAG: %{{[0-9]+}} = icmp eq i64 %{{[0-9]+}}, %{{[0-9]+}}, !dbg !{{[0-9]+}}: {[-1]:Integer}
16// CHECK-DAG: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
17// CHECK-DAG: %{{[0-9]+}} = phi float [ -0.000000e+00, %{{[0-9]+}} ], [ %{{[0-9]+}}, %{{[0-9]+}} ], !dbg !{{[0-9]+}}: {[-1]:Float@float}
18// CHECK-DAG: ret float %{{[0-9]+}}, !dbg !{{[0-9]+}}: {}
\ No newline at end of file
tests/run-make/autodiff/type-trees/type-analysis/vec/vec.rs created+14
...@@ -0,0 +1,14 @@
1#![feature(autodiff)]
2
3use std::autodiff::autodiff_reverse;
4
5#[autodiff_reverse(d_square, Duplicated, Active)]
6#[no_mangle]
7fn callee(arg: &std::vec::Vec<f32>) -> f32 {
8 arg.iter().sum()
9}
10
11fn main() {
12 let v = vec![1.0f32, 2.0, 3.0];
13 let _ = callee(&v);
14}
tests/run-make/link-eh-frame-terminator/rmake.rs+1
...@@ -9,6 +9,7 @@...@@ -9,6 +9,7 @@
9//@ ignore-32bit9//@ ignore-32bit
10// Reason: the usage of a large array in the test causes an out-of-memory10// Reason: the usage of a large array in the test causes an out-of-memory
11// error on 32 bit systems.11// error on 32 bit systems.
12//@ ignore-cross-compile
1213
13use run_make_support::{bin_name, llvm_objdump, run, rustc};14use run_make_support::{bin_name, llvm_objdump, run, rustc};
1415
tests/ui/panics/panic-main.rs+3
...@@ -14,12 +14,15 @@...@@ -14,12 +14,15 @@
1414
15//@[unwind-zero] compile-flags: -Cpanic=unwind15//@[unwind-zero] compile-flags: -Cpanic=unwind
16//@[unwind-zero] exec-env:RUST_BACKTRACE=016//@[unwind-zero] exec-env:RUST_BACKTRACE=0
17//@[unwind-zero] needs-unwind
1718
18//@[unwind-one] compile-flags: -Cpanic=unwind19//@[unwind-one] compile-flags: -Cpanic=unwind
19//@[unwind-one] exec-env:RUST_BACKTRACE=120//@[unwind-one] exec-env:RUST_BACKTRACE=1
21//@[unwind-one] needs-unwind
2022
21//@[unwind-full] compile-flags: -Cpanic=unwind23//@[unwind-full] compile-flags: -Cpanic=unwind
22//@[unwind-full] exec-env:RUST_BACKTRACE=full24//@[unwind-full] exec-env:RUST_BACKTRACE=full
25//@[unwind-full] needs-unwind
2326
24//@ run-fail27//@ run-fail
25//@ error-pattern:moop28//@ error-pattern:moop
tests/ui/privacy/private-in-public-warn.rs+11-1
...@@ -35,6 +35,7 @@ mod types {...@@ -35,6 +35,7 @@ mod types {
3535
36mod traits {36mod traits {
37 trait PrivTr {}37 trait PrivTr {}
38 impl PrivTr for () {}
38 pub struct Pub<T>(T);39 pub struct Pub<T>(T);
39 pub trait PubTr {}40 pub trait PubTr {}
4041
...@@ -45,7 +46,10 @@ mod traits {...@@ -45,7 +46,10 @@ mod traits {
45 pub trait Tr3 {46 pub trait Tr3 {
46 type Alias: PrivTr;47 type Alias: PrivTr;
47 //~^ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::Alias`48 //~^ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::Alias`
48 fn f<T: PrivTr>(arg: T) {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::f`49 fn f<T: PrivTr>(arg: T) {}
50 //~^ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::f`
51 fn g() -> impl PrivTr;
52 fn h() -> impl PrivTr {}
49 }53 }
50 impl<T: PrivTr> Pub<T> {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Pub<T>`54 impl<T: PrivTr> Pub<T> {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Pub<T>`
51 impl<T: PrivTr> PubTr for Pub<T> {} // OK, trait impl predicates55 impl<T: PrivTr> PubTr for Pub<T> {} // OK, trait impl predicates
...@@ -75,12 +79,18 @@ mod generics {...@@ -75,12 +79,18 @@ mod generics {
75 pub struct Pub<T = u8>(T);79 pub struct Pub<T = u8>(T);
76 trait PrivTr<T> {}80 trait PrivTr<T> {}
77 pub trait PubTr<T> {}81 pub trait PubTr<T> {}
82 impl PrivTr<Priv<()>> for () {}
7883
79 pub trait Tr1: PrivTr<Pub> {}84 pub trait Tr1: PrivTr<Pub> {}
80 //~^ ERROR trait `generics::PrivTr<generics::Pub>` is more private than the item `generics::Tr1`85 //~^ ERROR trait `generics::PrivTr<generics::Pub>` is more private than the item `generics::Tr1`
81 pub trait Tr2: PubTr<Priv> {} //~ ERROR type `generics::Priv` is more private than the item `generics::Tr2`86 pub trait Tr2: PubTr<Priv> {} //~ ERROR type `generics::Priv` is more private than the item `generics::Tr2`
82 pub trait Tr3: PubTr<[Priv; 1]> {} //~ ERROR type `generics::Priv` is more private than the item `generics::Tr3`87 pub trait Tr3: PubTr<[Priv; 1]> {} //~ ERROR type `generics::Priv` is more private than the item `generics::Tr3`
83 pub trait Tr4: PubTr<Pub<Priv>> {} //~ ERROR type `generics::Priv` is more private than the item `Tr4`88 pub trait Tr4: PubTr<Pub<Priv>> {} //~ ERROR type `generics::Priv` is more private than the item `Tr4`
89
90 pub trait Tr5 {
91 fn required() -> impl PrivTr<Priv<()>>;
92 fn provided() -> impl PrivTr<Priv<()>> {}
93 }
84}94}
8595
86mod impls {96mod impls {
tests/ui/privacy/private-in-public-warn.stderr+37-37
...@@ -130,7 +130,7 @@ LL | type Alias = Priv;...@@ -130,7 +130,7 @@ LL | type Alias = Priv;
130 | ^^^^^^^^^^ can't leak private type130 | ^^^^^^^^^^ can't leak private type
131131
132error: trait `traits::PrivTr` is more private than the item `traits::Alias`132error: trait `traits::PrivTr` is more private than the item `traits::Alias`
133 --> $DIR/private-in-public-warn.rs:41:5133 --> $DIR/private-in-public-warn.rs:42:5
134 |134 |
135LL | pub type Alias<T: PrivTr> = T;135LL | pub type Alias<T: PrivTr> = T;
136 | ^^^^^^^^^^^^^^^^^^^^^^^^^ type alias `traits::Alias` is reachable at visibility `pub(crate)`136 | ^^^^^^^^^^^^^^^^^^^^^^^^^ type alias `traits::Alias` is reachable at visibility `pub(crate)`
...@@ -147,7 +147,7 @@ LL | #![deny(private_interfaces, private_bounds)]...@@ -147,7 +147,7 @@ LL | #![deny(private_interfaces, private_bounds)]
147 | ^^^^^^^^^^^^^^147 | ^^^^^^^^^^^^^^
148148
149error: trait `traits::PrivTr` is more private than the item `traits::Tr1`149error: trait `traits::PrivTr` is more private than the item `traits::Tr1`
150 --> $DIR/private-in-public-warn.rs:43:5150 --> $DIR/private-in-public-warn.rs:44:5
151 |151 |
152LL | pub trait Tr1: PrivTr {}152LL | pub trait Tr1: PrivTr {}
153 | ^^^^^^^^^^^^^^^^^^^^^ trait `traits::Tr1` is reachable at visibility `pub(crate)`153 | ^^^^^^^^^^^^^^^^^^^^^ trait `traits::Tr1` is reachable at visibility `pub(crate)`
...@@ -159,7 +159,7 @@ LL | trait PrivTr {}...@@ -159,7 +159,7 @@ LL | trait PrivTr {}
159 | ^^^^^^^^^^^^159 | ^^^^^^^^^^^^
160160
161error: trait `traits::PrivTr` is more private than the item `traits::Tr2`161error: trait `traits::PrivTr` is more private than the item `traits::Tr2`
162 --> $DIR/private-in-public-warn.rs:44:5162 --> $DIR/private-in-public-warn.rs:45:5
163 |163 |
164LL | pub trait Tr2<T: PrivTr> {}164LL | pub trait Tr2<T: PrivTr> {}
165 | ^^^^^^^^^^^^^^^^^^^^^^^^ trait `traits::Tr2` is reachable at visibility `pub(crate)`165 | ^^^^^^^^^^^^^^^^^^^^^^^^ trait `traits::Tr2` is reachable at visibility `pub(crate)`
...@@ -171,7 +171,7 @@ LL | trait PrivTr {}...@@ -171,7 +171,7 @@ LL | trait PrivTr {}
171 | ^^^^^^^^^^^^171 | ^^^^^^^^^^^^
172172
173error: trait `traits::PrivTr` is more private than the item `traits::Tr3::Alias`173error: trait `traits::PrivTr` is more private than the item `traits::Tr3::Alias`
174 --> $DIR/private-in-public-warn.rs:46:9174 --> $DIR/private-in-public-warn.rs:47:9
175 |175 |
176LL | type Alias: PrivTr;176LL | type Alias: PrivTr;
177 | ^^^^^^^^^^^^^^^^^^ associated type `traits::Tr3::Alias` is reachable at visibility `pub(crate)`177 | ^^^^^^^^^^^^^^^^^^ associated type `traits::Tr3::Alias` is reachable at visibility `pub(crate)`
...@@ -183,7 +183,7 @@ LL | trait PrivTr {}...@@ -183,7 +183,7 @@ LL | trait PrivTr {}
183 | ^^^^^^^^^^^^183 | ^^^^^^^^^^^^
184184
185error: trait `traits::PrivTr` is more private than the item `traits::Tr3::f`185error: trait `traits::PrivTr` is more private than the item `traits::Tr3::f`
186 --> $DIR/private-in-public-warn.rs:48:9186 --> $DIR/private-in-public-warn.rs:49:9
187 |187 |
188LL | fn f<T: PrivTr>(arg: T) {}188LL | fn f<T: PrivTr>(arg: T) {}
189 | ^^^^^^^^^^^^^^^^^^^^^^^ associated function `traits::Tr3::f` is reachable at visibility `pub(crate)`189 | ^^^^^^^^^^^^^^^^^^^^^^^ associated function `traits::Tr3::f` is reachable at visibility `pub(crate)`
...@@ -195,7 +195,7 @@ LL | trait PrivTr {}...@@ -195,7 +195,7 @@ LL | trait PrivTr {}
195 | ^^^^^^^^^^^^195 | ^^^^^^^^^^^^
196196
197error: trait `traits::PrivTr` is more private than the item `traits::Pub<T>`197error: trait `traits::PrivTr` is more private than the item `traits::Pub<T>`
198 --> $DIR/private-in-public-warn.rs:50:5198 --> $DIR/private-in-public-warn.rs:54:5
199 |199 |
200LL | impl<T: PrivTr> Pub<T> {}200LL | impl<T: PrivTr> Pub<T> {}
201 | ^^^^^^^^^^^^^^^^^^^^^^ implementation `traits::Pub<T>` is reachable at visibility `pub(crate)`201 | ^^^^^^^^^^^^^^^^^^^^^^ implementation `traits::Pub<T>` is reachable at visibility `pub(crate)`
...@@ -207,103 +207,103 @@ LL | trait PrivTr {}...@@ -207,103 +207,103 @@ LL | trait PrivTr {}
207 | ^^^^^^^^^^^^207 | ^^^^^^^^^^^^
208208
209error: trait `traits_where::PrivTr` is more private than the item `traits_where::Alias`209error: trait `traits_where::PrivTr` is more private than the item `traits_where::Alias`
210 --> $DIR/private-in-public-warn.rs:59:5210 --> $DIR/private-in-public-warn.rs:63:5
211 |211 |
212LL | pub type Alias<T> where T: PrivTr = T;212LL | pub type Alias<T> where T: PrivTr = T;
213 | ^^^^^^^^^^^^^^^^^ type alias `traits_where::Alias` is reachable at visibility `pub(crate)`213 | ^^^^^^^^^^^^^^^^^ type alias `traits_where::Alias` is reachable at visibility `pub(crate)`
214 |214 |
215note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)`215note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)`
216 --> $DIR/private-in-public-warn.rs:55:5216 --> $DIR/private-in-public-warn.rs:59:5
217 |217 |
218LL | trait PrivTr {}218LL | trait PrivTr {}
219 | ^^^^^^^^^^^^219 | ^^^^^^^^^^^^
220220
221error: trait `traits_where::PrivTr` is more private than the item `traits_where::Tr2`221error: trait `traits_where::PrivTr` is more private than the item `traits_where::Tr2`
222 --> $DIR/private-in-public-warn.rs:62:5222 --> $DIR/private-in-public-warn.rs:66:5
223 |223 |
224LL | pub trait Tr2<T> where T: PrivTr {}224LL | pub trait Tr2<T> where T: PrivTr {}
225 | ^^^^^^^^^^^^^^^^ trait `traits_where::Tr2` is reachable at visibility `pub(crate)`225 | ^^^^^^^^^^^^^^^^ trait `traits_where::Tr2` is reachable at visibility `pub(crate)`
226 |226 |
227note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)`227note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)`
228 --> $DIR/private-in-public-warn.rs:55:5228 --> $DIR/private-in-public-warn.rs:59:5
229 |229 |
230LL | trait PrivTr {}230LL | trait PrivTr {}
231 | ^^^^^^^^^^^^231 | ^^^^^^^^^^^^
232232
233error: trait `traits_where::PrivTr` is more private than the item `traits_where::Tr3::f`233error: trait `traits_where::PrivTr` is more private than the item `traits_where::Tr3::f`
234 --> $DIR/private-in-public-warn.rs:65:9234 --> $DIR/private-in-public-warn.rs:69:9
235 |235 |
236LL | fn f<T>(arg: T) where T: PrivTr {}236LL | fn f<T>(arg: T) where T: PrivTr {}
237 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated function `traits_where::Tr3::f` is reachable at visibility `pub(crate)`237 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated function `traits_where::Tr3::f` is reachable at visibility `pub(crate)`
238 |238 |
239note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)`239note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)`
240 --> $DIR/private-in-public-warn.rs:55:5240 --> $DIR/private-in-public-warn.rs:59:5
241 |241 |
242LL | trait PrivTr {}242LL | trait PrivTr {}
243 | ^^^^^^^^^^^^243 | ^^^^^^^^^^^^
244244
245error: trait `traits_where::PrivTr` is more private than the item `traits_where::Pub<T>`245error: trait `traits_where::PrivTr` is more private than the item `traits_where::Pub<T>`
246 --> $DIR/private-in-public-warn.rs:68:5246 --> $DIR/private-in-public-warn.rs:72:5
247 |247 |
248LL | impl<T> Pub<T> where T: PrivTr {}248LL | impl<T> Pub<T> where T: PrivTr {}
249 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation `traits_where::Pub<T>` is reachable at visibility `pub(crate)`249 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation `traits_where::Pub<T>` is reachable at visibility `pub(crate)`
250 |250 |
251note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)`251note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)`
252 --> $DIR/private-in-public-warn.rs:55:5252 --> $DIR/private-in-public-warn.rs:59:5
253 |253 |
254LL | trait PrivTr {}254LL | trait PrivTr {}
255 | ^^^^^^^^^^^^255 | ^^^^^^^^^^^^
256256
257error: trait `generics::PrivTr<generics::Pub>` is more private than the item `generics::Tr1`257error: trait `generics::PrivTr<generics::Pub>` is more private than the item `generics::Tr1`
258 --> $DIR/private-in-public-warn.rs:79:5258 --> $DIR/private-in-public-warn.rs:84:5
259 |259 |
260LL | pub trait Tr1: PrivTr<Pub> {}260LL | pub trait Tr1: PrivTr<Pub> {}
261 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `generics::Tr1` is reachable at visibility `pub(crate)`261 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `generics::Tr1` is reachable at visibility `pub(crate)`
262 |262 |
263note: but trait `generics::PrivTr<generics::Pub>` is only usable at visibility `pub(self)`263note: but trait `generics::PrivTr<generics::Pub>` is only usable at visibility `pub(self)`
264 --> $DIR/private-in-public-warn.rs:76:5264 --> $DIR/private-in-public-warn.rs:80:5
265 |265 |
266LL | trait PrivTr<T> {}266LL | trait PrivTr<T> {}
267 | ^^^^^^^^^^^^^^^267 | ^^^^^^^^^^^^^^^
268268
269error: type `generics::Priv` is more private than the item `generics::Tr2`269error: type `generics::Priv` is more private than the item `generics::Tr2`
270 --> $DIR/private-in-public-warn.rs:81:5270 --> $DIR/private-in-public-warn.rs:86:5
271 |271 |
272LL | pub trait Tr2: PubTr<Priv> {}272LL | pub trait Tr2: PubTr<Priv> {}
273 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `generics::Tr2` is reachable at visibility `pub(crate)`273 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `generics::Tr2` is reachable at visibility `pub(crate)`
274 |274 |
275note: but type `generics::Priv` is only usable at visibility `pub(self)`275note: but type `generics::Priv` is only usable at visibility `pub(self)`
276 --> $DIR/private-in-public-warn.rs:74:5276 --> $DIR/private-in-public-warn.rs:78:5
277 |277 |
278LL | struct Priv<T = u8>(T);278LL | struct Priv<T = u8>(T);
279 | ^^^^^^^^^^^^^^^^^^^279 | ^^^^^^^^^^^^^^^^^^^
280280
281error: type `generics::Priv` is more private than the item `generics::Tr3`281error: type `generics::Priv` is more private than the item `generics::Tr3`
282 --> $DIR/private-in-public-warn.rs:82:5282 --> $DIR/private-in-public-warn.rs:87:5
283 |283 |
284LL | pub trait Tr3: PubTr<[Priv; 1]> {}284LL | pub trait Tr3: PubTr<[Priv; 1]> {}
285 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `generics::Tr3` is reachable at visibility `pub(crate)`285 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `generics::Tr3` is reachable at visibility `pub(crate)`
286 |286 |
287note: but type `generics::Priv` is only usable at visibility `pub(self)`287note: but type `generics::Priv` is only usable at visibility `pub(self)`
288 --> $DIR/private-in-public-warn.rs:74:5288 --> $DIR/private-in-public-warn.rs:78:5
289 |289 |
290LL | struct Priv<T = u8>(T);290LL | struct Priv<T = u8>(T);
291 | ^^^^^^^^^^^^^^^^^^^291 | ^^^^^^^^^^^^^^^^^^^
292292
293error: type `generics::Priv` is more private than the item `Tr4`293error: type `generics::Priv` is more private than the item `Tr4`
294 --> $DIR/private-in-public-warn.rs:83:5294 --> $DIR/private-in-public-warn.rs:88:5
295 |295 |
296LL | pub trait Tr4: PubTr<Pub<Priv>> {}296LL | pub trait Tr4: PubTr<Pub<Priv>> {}
297 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `Tr4` is reachable at visibility `pub(crate)`297 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `Tr4` is reachable at visibility `pub(crate)`
298 |298 |
299note: but type `generics::Priv` is only usable at visibility `pub(self)`299note: but type `generics::Priv` is only usable at visibility `pub(self)`
300 --> $DIR/private-in-public-warn.rs:74:5300 --> $DIR/private-in-public-warn.rs:78:5
301 |301 |
302LL | struct Priv<T = u8>(T);302LL | struct Priv<T = u8>(T);
303 | ^^^^^^^^^^^^^^^^^^^303 | ^^^^^^^^^^^^^^^^^^^
304304
305error[E0446]: private type `impls::Priv` in public interface305error[E0446]: private type `impls::Priv` in public interface
306 --> $DIR/private-in-public-warn.rs:109:9306 --> $DIR/private-in-public-warn.rs:119:9
307 |307 |
308LL | struct Priv;308LL | struct Priv;
309 | ----------- `impls::Priv` declared as private309 | ----------- `impls::Priv` declared as private
...@@ -312,19 +312,19 @@ LL | type Alias = Priv;...@@ -312,19 +312,19 @@ LL | type Alias = Priv;
312 | ^^^^^^^^^^ can't leak private type312 | ^^^^^^^^^^ can't leak private type
313313
314error: type `aliases_pub::Priv` is more private than the item `aliases_pub::<impl Pub2>::f`314error: type `aliases_pub::Priv` is more private than the item `aliases_pub::<impl Pub2>::f`
315 --> $DIR/private-in-public-warn.rs:180:9315 --> $DIR/private-in-public-warn.rs:190:9
316 |316 |
317LL | pub fn f(arg: Priv) {}317LL | pub fn f(arg: Priv) {}
318 | ^^^^^^^^^^^^^^^^^^^ associated function `aliases_pub::<impl Pub2>::f` is reachable at visibility `pub(crate)`318 | ^^^^^^^^^^^^^^^^^^^ associated function `aliases_pub::<impl Pub2>::f` is reachable at visibility `pub(crate)`
319 |319 |
320note: but type `aliases_pub::Priv` is only usable at visibility `pub(self)`320note: but type `aliases_pub::Priv` is only usable at visibility `pub(self)`
321 --> $DIR/private-in-public-warn.rs:153:5321 --> $DIR/private-in-public-warn.rs:163:5
322 |322 |
323LL | struct Priv;323LL | struct Priv;
324 | ^^^^^^^^^^^324 | ^^^^^^^^^^^
325325
326error[E0446]: private type `aliases_pub::Priv` in public interface326error[E0446]: private type `aliases_pub::Priv` in public interface
327 --> $DIR/private-in-public-warn.rs:183:9327 --> $DIR/private-in-public-warn.rs:193:9
328 |328 |
329LL | struct Priv;329LL | struct Priv;
330 | ----------- `aliases_pub::Priv` declared as private330 | ----------- `aliases_pub::Priv` declared as private
...@@ -333,7 +333,7 @@ LL | type Check = Priv;...@@ -333,7 +333,7 @@ LL | type Check = Priv;
333 | ^^^^^^^^^^ can't leak private type333 | ^^^^^^^^^^ can't leak private type
334334
335error[E0446]: private type `aliases_pub::Priv` in public interface335error[E0446]: private type `aliases_pub::Priv` in public interface
336 --> $DIR/private-in-public-warn.rs:186:9336 --> $DIR/private-in-public-warn.rs:196:9
337 |337 |
338LL | struct Priv;338LL | struct Priv;
339 | ----------- `aliases_pub::Priv` declared as private339 | ----------- `aliases_pub::Priv` declared as private
...@@ -342,7 +342,7 @@ LL | type Check = Priv;...@@ -342,7 +342,7 @@ LL | type Check = Priv;
342 | ^^^^^^^^^^ can't leak private type342 | ^^^^^^^^^^ can't leak private type
343343
344error[E0446]: private type `aliases_pub::Priv` in public interface344error[E0446]: private type `aliases_pub::Priv` in public interface
345 --> $DIR/private-in-public-warn.rs:189:9345 --> $DIR/private-in-public-warn.rs:199:9
346 |346 |
347LL | struct Priv;347LL | struct Priv;
348 | ----------- `aliases_pub::Priv` declared as private348 | ----------- `aliases_pub::Priv` declared as private
...@@ -351,7 +351,7 @@ LL | type Check = Priv;...@@ -351,7 +351,7 @@ LL | type Check = Priv;
351 | ^^^^^^^^^^ can't leak private type351 | ^^^^^^^^^^ can't leak private type
352352
353error[E0446]: private type `aliases_pub::Priv` in public interface353error[E0446]: private type `aliases_pub::Priv` in public interface
354 --> $DIR/private-in-public-warn.rs:192:9354 --> $DIR/private-in-public-warn.rs:202:9
355 |355 |
356LL | struct Priv;356LL | struct Priv;
357 | ----------- `aliases_pub::Priv` declared as private357 | ----------- `aliases_pub::Priv` declared as private
...@@ -360,43 +360,43 @@ LL | type Check = Priv;...@@ -360,43 +360,43 @@ LL | type Check = Priv;
360 | ^^^^^^^^^^ can't leak private type360 | ^^^^^^^^^^ can't leak private type
361361
362error: trait `PrivTr1` is more private than the item `aliases_priv::Tr1`362error: trait `PrivTr1` is more private than the item `aliases_priv::Tr1`
363 --> $DIR/private-in-public-warn.rs:222:5363 --> $DIR/private-in-public-warn.rs:232:5
364 |364 |
365LL | pub trait Tr1: PrivUseAliasTr {}365LL | pub trait Tr1: PrivUseAliasTr {}
366 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `aliases_priv::Tr1` is reachable at visibility `pub(crate)`366 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `aliases_priv::Tr1` is reachable at visibility `pub(crate)`
367 |367 |
368note: but trait `PrivTr1` is only usable at visibility `pub(self)`368note: but trait `PrivTr1` is only usable at visibility `pub(self)`
369 --> $DIR/private-in-public-warn.rs:208:5369 --> $DIR/private-in-public-warn.rs:218:5
370 |370 |
371LL | trait PrivTr1<T = u8> {371LL | trait PrivTr1<T = u8> {
372 | ^^^^^^^^^^^^^^^^^^^^^372 | ^^^^^^^^^^^^^^^^^^^^^
373373
374error: trait `PrivTr1<Priv2>` is more private than the item `aliases_priv::Tr2`374error: trait `PrivTr1<Priv2>` is more private than the item `aliases_priv::Tr2`
375 --> $DIR/private-in-public-warn.rs:224:5375 --> $DIR/private-in-public-warn.rs:234:5
376 |376 |
377LL | pub trait Tr2: PrivUseAliasTr<PrivAlias> {}377LL | pub trait Tr2: PrivUseAliasTr<PrivAlias> {}
378 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `aliases_priv::Tr2` is reachable at visibility `pub(crate)`378 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `aliases_priv::Tr2` is reachable at visibility `pub(crate)`
379 |379 |
380note: but trait `PrivTr1<Priv2>` is only usable at visibility `pub(self)`380note: but trait `PrivTr1<Priv2>` is only usable at visibility `pub(self)`
381 --> $DIR/private-in-public-warn.rs:208:5381 --> $DIR/private-in-public-warn.rs:218:5
382 |382 |
383LL | trait PrivTr1<T = u8> {383LL | trait PrivTr1<T = u8> {
384 | ^^^^^^^^^^^^^^^^^^^^^384 | ^^^^^^^^^^^^^^^^^^^^^
385385
386error: type `Priv2` is more private than the item `aliases_priv::Tr2`386error: type `Priv2` is more private than the item `aliases_priv::Tr2`
387 --> $DIR/private-in-public-warn.rs:224:5387 --> $DIR/private-in-public-warn.rs:234:5
388 |388 |
389LL | pub trait Tr2: PrivUseAliasTr<PrivAlias> {}389LL | pub trait Tr2: PrivUseAliasTr<PrivAlias> {}
390 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `aliases_priv::Tr2` is reachable at visibility `pub(crate)`390 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `aliases_priv::Tr2` is reachable at visibility `pub(crate)`
391 |391 |
392note: but type `Priv2` is only usable at visibility `pub(self)`392note: but type `Priv2` is only usable at visibility `pub(self)`
393 --> $DIR/private-in-public-warn.rs:206:5393 --> $DIR/private-in-public-warn.rs:216:5
394 |394 |
395LL | struct Priv2;395LL | struct Priv2;
396 | ^^^^^^^^^^^^396 | ^^^^^^^^^^^^
397397
398warning: bounds on generic parameters in type aliases are not enforced398warning: bounds on generic parameters in type aliases are not enforced
399 --> $DIR/private-in-public-warn.rs:41:23399 --> $DIR/private-in-public-warn.rs:42:23
400 |400 |
401LL | pub type Alias<T: PrivTr> = T;401LL | pub type Alias<T: PrivTr> = T;
402 | --^^^^^^402 | --^^^^^^
...@@ -410,7 +410,7 @@ LL | pub type Alias<T: PrivTr> = T;...@@ -410,7 +410,7 @@ LL | pub type Alias<T: PrivTr> = T;
410 = note: `#[warn(type_alias_bounds)]` on by default410 = note: `#[warn(type_alias_bounds)]` on by default
411411
412warning: where clauses on type aliases are not enforced412warning: where clauses on type aliases are not enforced
413 --> $DIR/private-in-public-warn.rs:59:29413 --> $DIR/private-in-public-warn.rs:63:29
414 |414 |
415LL | pub type Alias<T> where T: PrivTr = T;415LL | pub type Alias<T> where T: PrivTr = T;
416 | ------^^^^^^^^^416 | ------^^^^^^^^^
tests/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs+1
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1pub struct OtherType;1pub struct OtherType;
2pub trait OtherTrait {}2pub trait OtherTrait {}
3impl OtherTrait for OtherType {}
34
4#[macro_export]5#[macro_export]
5macro_rules! m {6macro_rules! m {
tests/ui/privacy/pub-priv-dep/pub-priv1.rs+5-1
...@@ -44,8 +44,12 @@ impl PublicType {...@@ -44,8 +44,12 @@ impl PublicType {
4444
45pub trait MyPubTrait {45pub trait MyPubTrait {
46 type Foo: OtherTrait;46 type Foo: OtherTrait;
47 //~^ ERROR trait `OtherTrait` from private dependency 'priv_dep' in public interface
48
49 fn required() -> impl OtherTrait;
50
51 fn provided() -> impl OtherTrait { OtherType }
47}52}
48//~^^ ERROR trait `OtherTrait` from private dependency 'priv_dep' in public interface
4953
50pub trait WithSuperTrait: OtherTrait {}54pub trait WithSuperTrait: OtherTrait {}
51//~^ ERROR trait `OtherTrait` from private dependency 'priv_dep' in public interface55//~^ ERROR trait `OtherTrait` from private dependency 'priv_dep' in public interface
tests/ui/privacy/pub-priv-dep/pub-priv1.stderr+15-15
...@@ -11,31 +11,31 @@ LL | #![deny(exported_private_dependencies)]...@@ -11,31 +11,31 @@ LL | #![deny(exported_private_dependencies)]
11 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^11 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1212
13error: macro `m` from private dependency 'priv_dep' is re-exported13error: macro `m` from private dependency 'priv_dep' is re-exported
14 --> $DIR/pub-priv1.rs:94:914 --> $DIR/pub-priv1.rs:98:9
15 |15 |
16LL | pub use priv_dep::m;16LL | pub use priv_dep::m;
17 | ^^^^^^^^^^^17 | ^^^^^^^^^^^
1818
19error: macro `fn_like` from private dependency 'pm' is re-exported19error: macro `fn_like` from private dependency 'pm' is re-exported
20 --> $DIR/pub-priv1.rs:96:920 --> $DIR/pub-priv1.rs:100:9
21 |21 |
22LL | pub use pm::fn_like;22LL | pub use pm::fn_like;
23 | ^^^^^^^^^^^23 | ^^^^^^^^^^^
2424
25error: derive macro `PmDerive` from private dependency 'pm' is re-exported25error: derive macro `PmDerive` from private dependency 'pm' is re-exported
26 --> $DIR/pub-priv1.rs:98:926 --> $DIR/pub-priv1.rs:102:9
27 |27 |
28LL | pub use pm::PmDerive;28LL | pub use pm::PmDerive;
29 | ^^^^^^^^^^^^29 | ^^^^^^^^^^^^
3030
31error: attribute macro `pm_attr` from private dependency 'pm' is re-exported31error: attribute macro `pm_attr` from private dependency 'pm' is re-exported
32 --> $DIR/pub-priv1.rs:100:932 --> $DIR/pub-priv1.rs:104:9
33 |33 |
34LL | pub use pm::pm_attr;34LL | pub use pm::pm_attr;
35 | ^^^^^^^^^^^35 | ^^^^^^^^^^^
3636
37error: variant `V1` from private dependency 'priv_dep' is re-exported37error: variant `V1` from private dependency 'priv_dep' is re-exported
38 --> $DIR/pub-priv1.rs:103:938 --> $DIR/pub-priv1.rs:107:9
39 |39 |
40LL | pub use priv_dep::E::V1;40LL | pub use priv_dep::E::V1;
41 | ^^^^^^^^^^^^^^^41 | ^^^^^^^^^^^^^^^
...@@ -65,61 +65,61 @@ LL | type Foo: OtherTrait;...@@ -65,61 +65,61 @@ LL | type Foo: OtherTrait;
65 | ^^^^^^^^^^^^^^^^^^^^65 | ^^^^^^^^^^^^^^^^^^^^
6666
67error: trait `OtherTrait` from private dependency 'priv_dep' in public interface67error: trait `OtherTrait` from private dependency 'priv_dep' in public interface
68 --> $DIR/pub-priv1.rs:50:168 --> $DIR/pub-priv1.rs:54:1
69 |69 |
70LL | pub trait WithSuperTrait: OtherTrait {}70LL | pub trait WithSuperTrait: OtherTrait {}
71 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^71 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7272
73error: type `OtherType` from private dependency 'priv_dep' in public interface73error: type `OtherType` from private dependency 'priv_dep' in public interface
74 --> $DIR/pub-priv1.rs:59:574 --> $DIR/pub-priv1.rs:63:5
75 |75 |
76LL | type X = OtherType;76LL | type X = OtherType;
77 | ^^^^^^77 | ^^^^^^
7878
79error: trait `OtherTrait` from private dependency 'priv_dep' in public interface79error: trait `OtherTrait` from private dependency 'priv_dep' in public interface
80 --> $DIR/pub-priv1.rs:63:180 --> $DIR/pub-priv1.rs:67:1
81 |81 |
82LL | pub fn in_bounds<T: OtherTrait>(x: T) { unimplemented!() }82LL | pub fn in_bounds<T: OtherTrait>(x: T) { unimplemented!() }
83 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^83 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8484
85error: type `OtherType` from private dependency 'priv_dep' in public interface85error: type `OtherType` from private dependency 'priv_dep' in public interface
86 --> $DIR/pub-priv1.rs:66:186 --> $DIR/pub-priv1.rs:70:1
87 |87 |
88LL | pub fn private_in_generic() -> std::num::Saturating<OtherType> { unimplemented!() }88LL | pub fn private_in_generic() -> std::num::Saturating<OtherType> { unimplemented!() }
89 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^89 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9090
91error: type `OtherType` from private dependency 'priv_dep' in public interface91error: type `OtherType` from private dependency 'priv_dep' in public interface
92 --> $DIR/pub-priv1.rs:69:192 --> $DIR/pub-priv1.rs:73:1
93 |93 |
94LL | pub static STATIC: OtherType = OtherType;94LL | pub static STATIC: OtherType = OtherType;
95 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^95 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9696
97error: type `OtherType` from private dependency 'priv_dep' in public interface97error: type `OtherType` from private dependency 'priv_dep' in public interface
98 --> $DIR/pub-priv1.rs:72:198 --> $DIR/pub-priv1.rs:76:1
99 |99 |
100LL | pub const CONST: OtherType = OtherType;100LL | pub const CONST: OtherType = OtherType;
101 | ^^^^^^^^^^^^^^^^^^^^^^^^^^101 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
102102
103error: type `OtherType` from private dependency 'priv_dep' in public interface103error: type `OtherType` from private dependency 'priv_dep' in public interface
104 --> $DIR/pub-priv1.rs:75:1104 --> $DIR/pub-priv1.rs:79:1
105 |105 |
106LL | pub type Alias = OtherType;106LL | pub type Alias = OtherType;
107 | ^^^^^^^^^^^^^^107 | ^^^^^^^^^^^^^^
108108
109error: trait `OtherTrait` from private dependency 'priv_dep' in public interface109error: trait `OtherTrait` from private dependency 'priv_dep' in public interface
110 --> $DIR/pub-priv1.rs:80:1110 --> $DIR/pub-priv1.rs:84:1
111 |111 |
112LL | impl OtherTrait for PublicWithPrivateImpl {}112LL | impl OtherTrait for PublicWithPrivateImpl {}
113 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^113 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
114114
115error: type `OtherType` from private dependency 'priv_dep' in public interface115error: type `OtherType` from private dependency 'priv_dep' in public interface
116 --> $DIR/pub-priv1.rs:85:1116 --> $DIR/pub-priv1.rs:89:1
117 |117 |
118LL | impl PubTraitOnPrivate for OtherType {}118LL | impl PubTraitOnPrivate for OtherType {}
119 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^119 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
120120
121error: type `OtherType` from private dependency 'priv_dep' in public interface121error: type `OtherType` from private dependency 'priv_dep' in public interface
122 --> $DIR/pub-priv1.rs:85:1122 --> $DIR/pub-priv1.rs:89:1
123 |123 |
124LL | impl PubTraitOnPrivate for OtherType {}124LL | impl PubTraitOnPrivate for OtherType {}
125 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^125 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^