| author | bors <bors@rust-lang.org> 2025-07-19 11:10:04 UTC |
| committer | bors <bors@rust-lang.org> 2025-07-19 11:10:04 UTC |
| log | 12865ffd0dfb4ea969e2f16eb0140238bb9dd382 |
| tree | cd1b60381a5d2c032182e3fdfcfffde159f04a93 |
| parent | 83825dd277503edf5d7eda6be8b5fb9896f343f5 |
| parent | cc699e1edf1e0f4302e9c0feff2a004afcdb2e11 |
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: rollup95 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); |
| 1177 | 1177 | ||
| 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 | } |
| 1486 | 1486 | ||
| 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 | } |
| 1504 | 1504 | ||
| 1505 | return Err(err.emit_unless(delay)); | 1505 | return Err(err.emit_unless_delay(delay)); |
| 1506 | } | 1506 | } |
| 1507 | } | 1507 | } |
| 1508 | 1508 | ||
| ... | @@ -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 | } |
| 1664 | 1664 | ||
| 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 | ); |
| 1747 | 1747 | ||
| 1748 | return Err(err.emit_unless(delay)); | 1748 | return Err(err.emit_unless_delay(delay)); |
| 1749 | } | 1749 | } |
| 1750 | 1750 | ||
| 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)); |
| 1976 | 1976 | ||
| 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 | ); |
| 2497 | 2497 | ||
| 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); |
| 2499 | 2499 | ||
| 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 | }); |
| 575 | 575 | ||
| 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 | } |
| 1777 | 1777 | ||
| 1778 | let reported = err.emit_unless(unsized_return); | 1778 | let reported = err.emit_unless_delay(unsized_return); |
| 1779 | 1779 | ||
| 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> { |
| 1549 | 1549 | ||
| 1550 | // If the assignment expression itself is ill-formed, don't | 1550 | // If the assignment expression itself is ill-formed, don't |
| 1551 | // bother emitting another error | 1551 | // 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 | } |
| 1554 | 1554 | ||
| 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 | }; |
| 3903 | 3903 |
compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp+13| ... | @@ -700,6 +700,10 @@ struct LLVMRustSanitizerOptions { | ... | @@ -700,6 +700,10 @@ struct LLVMRustSanitizerOptions { |
| 700 | #ifdef ENZYME | 700 | #ifdef ENZYME |
| 701 | extern "C" void registerEnzymeAndPassPipeline(llvm::PassBuilder &PB, | 701 | extern "C" void registerEnzymeAndPassPipeline(llvm::PassBuilder &PB, |
| 702 | /* augmentPassBuilder */ bool); | 702 | /* augmentPassBuilder */ bool); |
| 703 | |||
| 704 | extern "C" { | ||
| 705 | extern llvm::cl::opt<std::string> EnzymeFunctionToAnalyze; | ||
| 706 | } | ||
| 703 | #endif | 707 | #endif |
| 704 | 708 | ||
| 705 | extern "C" LLVMRustResult LLVMRustOptimize( | 709 | extern "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 | } |
| 1071 | 1075 | ||
| 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; |
| 74 | 74 | ||
| 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 | }; |
| 88 | 89 | ||
| 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 | } |
| 93 | 96 | ||
| 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 | } |
| 103 | 106 | ||
| 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 | true | 133 | 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 | } |
| 134 | 146 | ||
| 135 | cycle_found | 147 | reaches_root |
| 136 | } | 148 | } |
| 137 | 149 | ||
| 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 goals | 1219 | // 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 lint | 1223 | // in unsoundness, see #84857. |
| 1224 | // patterns which can be used to exploit this unsoundness on stable, | ||
| 1225 | // see #93367 for more details. | ||
| 1226 | ty::Bool | 1224 | ty::Bool |
| 1227 | | ty::Char | 1225 | | 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(); |
| 1625 | 1625 | ||
| 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); |
| 1628 | 1632 | ||
| 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(); |
| 1737 | 1741 | ||
| 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.r | 2913 | 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 zip | 18 | // 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 | } |
| 23 | impl<A: Iterator, B: Iterator> Zip<A, B> { | 22 | impl<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, // unused | 158 | index: 0, // unused |
| 160 | len: 0, // unused | 159 | len: 0, // unused |
| 161 | a_len: 0, // unused | ||
| 162 | } | 160 | } |
| 163 | } | 161 | } |
| 164 | 162 | ||
| ... | @@ -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 | } |
| 306 | 303 | ||
| 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 | None | 316 | 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 call | 363 | if self.index < self.len { |
| 378 | // of `next_back` does this, otherwise we will break the restriction | 364 | 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 | } |
| 36 | 37 | ||
| 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 | } |
| 115 | 125 | ||
| ... | @@ -120,7 +130,8 @@ fn test_zip_cloned_sideffectful() { | ... | @@ -120,7 +130,8 @@ fn test_zip_cloned_sideffectful() { |
| 120 | 130 | ||
| 121 | for _ in xs.iter().cloned().zip(ys.iter().cloned()) {} | 131 | for _ in xs.iter().cloned().zip(ys.iter().cloned()) {} |
| 122 | 132 | ||
| 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][..]); |
| 125 | 136 | ||
| 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() { |
| 139 | 150 | ||
| 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)) {} |
| 141 | 152 | ||
| 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]); |
| 144 | 156 | ||
| 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() { |
| 168 | 180 | ||
| 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 | } |
| 219 | 241 | ||
| ... | @@ -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 | } |
| 239 | 261 | ||
| 240 | #[test] | ||
| 241 | #[cfg(panic = "unwind")] | ||
| 242 | fn 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] |
| 267 | fn test_double_ended_zip() { | 263 | fn 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 | } |
| 277 | 273 | ||
| 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. | ||
| 282 | fn 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] |
| 279 | fn test_issue_82282() { | 332 | fn 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 |
| 8 | import shutil | 8 | import shutil |
| 9 | import subprocess | 9 | import subprocess |
| 10 | import sys | 10 | import sys |
| 11 | import sysconfig | ||
| 11 | import tarfile | 12 | import tarfile |
| 12 | import tempfile | 13 | import tempfile |
| 13 | 14 | ||
| ... | @@ -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 instead | 344 | # 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)); |
| 340 | 340 | ||
| 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)); |
| 394 | 394 | ||
| 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)); |
| 421 | 421 | ||
| 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] | ||
| 13 | pub fn a() { | ||
| 14 | FnOnce::call_once(a, ()); | ||
| 15 | FnOnce::call_once(b, ()); | ||
| 16 | } | ||
| 17 | |||
| 18 | #[inline] | ||
| 19 | pub 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 | |||
| 3 | This 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 | |||
| 7 | Each test compiles a simple Rust function with the `#[autodiff_reverse]` attribute and verifies that the compiler: | ||
| 8 | |||
| 9 | 1. **Correctly identifies type information** in the generated LLVM IR | ||
| 10 | 2. **Tracks type annotations** for variables and operations | ||
| 11 | 3. **Preserves type context** through the autodiff transformation process | ||
| 12 | |||
| 13 | The 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 | |||
| 3 | use std::autodiff::autodiff_reverse; | ||
| 4 | |||
| 5 | #[autodiff_reverse(d_square, Duplicated, Active)] | ||
| 6 | #[no_mangle] | ||
| 7 | fn callee(x: &[f32; 3]) -> f32 { | ||
| 8 | x[0] * x[0] + x[1] * x[1] + x[2] * x[2] | ||
| 9 | } | ||
| 10 | |||
| 11 | fn 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 | |||
| 4 | use std::fs; | ||
| 5 | |||
| 6 | use run_make_support::{llvm_filecheck, rfs, rustc}; | ||
| 7 | |||
| 8 | fn 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 | |||
| 3 | use std::autodiff::autodiff_reverse; | ||
| 4 | |||
| 5 | #[autodiff_reverse(d_square, Duplicated, Active)] | ||
| 6 | #[no_mangle] | ||
| 7 | fn 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 | |||
| 19 | fn 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 | |||
| 4 | use std::fs; | ||
| 5 | |||
| 6 | use run_make_support::{llvm_filecheck, rfs, rustc}; | ||
| 7 | |||
| 8 | fn 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 | |||
| 3 | use std::autodiff::autodiff_reverse; | ||
| 4 | |||
| 5 | #[autodiff_reverse(d_square, Duplicated, Active)] | ||
| 6 | #[no_mangle] | ||
| 7 | fn callee(x: &Box<f32>) -> f32 { | ||
| 8 | **x * **x | ||
| 9 | } | ||
| 10 | |||
| 11 | fn 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 | |||
| 4 | use std::fs; | ||
| 5 | |||
| 6 | use run_make_support::{llvm_filecheck, rfs, rustc}; | ||
| 7 | |||
| 8 | fn 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 | |||
| 3 | use std::autodiff::autodiff_reverse; | ||
| 4 | |||
| 5 | #[autodiff_reverse(d_square, Duplicated, Active)] | ||
| 6 | #[no_mangle] | ||
| 7 | fn callee(x: *const f32) -> f32 { | ||
| 8 | unsafe { *x * *x } | ||
| 9 | } | ||
| 10 | |||
| 11 | fn 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 | |||
| 4 | use std::fs; | ||
| 5 | |||
| 6 | use run_make_support::{llvm_filecheck, rfs, rustc}; | ||
| 7 | |||
| 8 | fn 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 | |||
| 3 | use std::autodiff::autodiff_reverse; | ||
| 4 | |||
| 5 | #[autodiff_reverse(d_square, Duplicated, Active)] | ||
| 6 | #[no_mangle] | ||
| 7 | fn callee(x: &f32) -> f32 { | ||
| 8 | *x * *x | ||
| 9 | } | ||
| 10 | |||
| 11 | fn 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 | |||
| 4 | use std::fs; | ||
| 5 | |||
| 6 | use run_make_support::{llvm_filecheck, rfs, rustc}; | ||
| 7 | |||
| 8 | fn 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)] | ||
| 2 | use std::autodiff::autodiff_reverse; | ||
| 3 | |||
| 4 | #[autodiff_reverse(d_callee, Duplicated, Active)] | ||
| 5 | #[no_mangle] | ||
| 6 | fn callee(x: &f64) -> f64 { | ||
| 7 | x * x | ||
| 8 | } | ||
| 9 | |||
| 10 | fn 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 | |||
| 4 | use std::fs; | ||
| 5 | |||
| 6 | use run_make_support::{llvm_filecheck, rfs, rustc}; | ||
| 7 | |||
| 8 | fn 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 | |||
| 3 | use std::autodiff::autodiff_reverse; | ||
| 4 | |||
| 5 | #[autodiff_reverse(d_square, Duplicated, Active)] | ||
| 6 | #[no_mangle] | ||
| 7 | fn callee(x: &i128) -> i128 { | ||
| 8 | *x * *x | ||
| 9 | } | ||
| 10 | |||
| 11 | fn 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 | |||
| 4 | use std::fs; | ||
| 5 | |||
| 6 | use run_make_support::{llvm_filecheck, rfs, rustc}; | ||
| 7 | |||
| 8 | fn 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 | |||
| 3 | use std::autodiff::autodiff_reverse; | ||
| 4 | |||
| 5 | #[autodiff_reverse(d_square, Duplicated, Active)] | ||
| 6 | #[no_mangle] | ||
| 7 | fn callee(x: &i16) -> i16 { | ||
| 8 | *x * *x | ||
| 9 | } | ||
| 10 | |||
| 11 | fn 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 | |||
| 4 | use std::fs; | ||
| 5 | |||
| 6 | use run_make_support::{llvm_filecheck, rfs, rustc}; | ||
| 7 | |||
| 8 | fn 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 | |||
| 3 | use std::autodiff::autodiff_reverse; | ||
| 4 | |||
| 5 | #[autodiff_reverse(d_square, Duplicated, Active)] | ||
| 6 | #[no_mangle] | ||
| 7 | fn callee(x: &i32) -> i32 { | ||
| 8 | *x * *x | ||
| 9 | } | ||
| 10 | |||
| 11 | fn 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 | |||
| 4 | use std::fs; | ||
| 5 | |||
| 6 | use run_make_support::{llvm_filecheck, rfs, rustc}; | ||
| 7 | |||
| 8 | fn 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 | |||
| 3 | use std::autodiff::autodiff_reverse; | ||
| 4 | |||
| 5 | #[autodiff_reverse(d_square, Duplicated, Active)] | ||
| 6 | #[no_mangle] | ||
| 7 | fn callee(x: &i8) -> i8 { | ||
| 8 | *x * *x | ||
| 9 | } | ||
| 10 | |||
| 11 | fn 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 | |||
| 4 | use std::fs; | ||
| 5 | |||
| 6 | use run_make_support::{llvm_filecheck, rfs, rustc}; | ||
| 7 | |||
| 8 | fn 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 | |||
| 3 | use std::autodiff::autodiff_reverse; | ||
| 4 | |||
| 5 | #[autodiff_reverse(d_square, Duplicated, Active)] | ||
| 6 | #[no_mangle] | ||
| 7 | fn callee(x: &isize) -> isize { | ||
| 8 | *x * *x | ||
| 9 | } | ||
| 10 | |||
| 11 | fn 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 | |||
| 4 | use std::fs; | ||
| 5 | |||
| 6 | use run_make_support::{llvm_filecheck, rfs, rustc}; | ||
| 7 | |||
| 8 | fn 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 | |||
| 3 | use std::autodiff::autodiff_reverse; | ||
| 4 | |||
| 5 | #[autodiff_reverse(d_square, Duplicated, Active)] | ||
| 6 | #[no_mangle] | ||
| 7 | fn callee(x: *mut f32) -> f32 { | ||
| 8 | unsafe { *x * *x } | ||
| 9 | } | ||
| 10 | |||
| 11 | fn 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 | |||
| 4 | use std::fs; | ||
| 5 | |||
| 6 | use run_make_support::{llvm_filecheck, rfs, rustc}; | ||
| 7 | |||
| 8 | fn 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 | |||
| 3 | use std::autodiff::autodiff_reverse; | ||
| 4 | |||
| 5 | #[autodiff_reverse(d_square, Duplicated, Active)] | ||
| 6 | #[no_mangle] | ||
| 7 | fn callee(x: &mut f32) -> f32 { | ||
| 8 | *x * *x | ||
| 9 | } | ||
| 10 | |||
| 11 | fn 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 | |||
| 4 | use std::fs; | ||
| 5 | |||
| 6 | use run_make_support::{llvm_filecheck, rfs, rustc}; | ||
| 7 | |||
| 8 | fn 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 | |||
| 3 | use std::autodiff::autodiff_reverse; | ||
| 4 | |||
| 5 | #[autodiff_reverse(d_square, Duplicated, Active)] | ||
| 6 | #[no_mangle] | ||
| 7 | fn callee(x: &f32) -> f32 { | ||
| 8 | *x * *x | ||
| 9 | } | ||
| 10 | |||
| 11 | fn 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 | |||
| 4 | use std::fs; | ||
| 5 | |||
| 6 | use run_make_support::{llvm_filecheck, rfs, rustc}; | ||
| 7 | |||
| 8 | fn 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 | |||
| 4 | use std::fs; | ||
| 5 | |||
| 6 | use run_make_support::{llvm_filecheck, rfs, rustc}; | ||
| 7 | |||
| 8 | fn 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 | |||
| 3 | use std::autodiff::autodiff_reverse; | ||
| 4 | |||
| 5 | #[derive(Copy, Clone)] | ||
| 6 | struct MyStruct { | ||
| 7 | f: f32, | ||
| 8 | } | ||
| 9 | |||
| 10 | #[autodiff_reverse(d_square, Duplicated, Active)] | ||
| 11 | #[no_mangle] | ||
| 12 | fn callee(x: &MyStruct) -> f32 { | ||
| 13 | x.f * x.f | ||
| 14 | } | ||
| 15 | |||
| 16 | fn 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 | |||
| 4 | use std::fs; | ||
| 5 | |||
| 6 | use run_make_support::{llvm_filecheck, rfs, rustc}; | ||
| 7 | |||
| 8 | fn 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 | |||
| 3 | use std::autodiff::autodiff_reverse; | ||
| 4 | |||
| 5 | #[autodiff_reverse(d_square, Duplicated, Active)] | ||
| 6 | #[no_mangle] | ||
| 7 | fn callee(x: &u128) -> u128 { | ||
| 8 | *x * *x | ||
| 9 | } | ||
| 10 | |||
| 11 | fn 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 | |||
| 4 | use std::fs; | ||
| 5 | |||
| 6 | use run_make_support::{llvm_filecheck, rfs, rustc}; | ||
| 7 | |||
| 8 | fn 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 | |||
| 3 | use std::autodiff::autodiff_reverse; | ||
| 4 | |||
| 5 | #[autodiff_reverse(d_square, Duplicated, Active)] | ||
| 6 | #[no_mangle] | ||
| 7 | fn callee(x: &u16) -> u16 { | ||
| 8 | *x * *x | ||
| 9 | } | ||
| 10 | |||
| 11 | fn 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 | |||
| 4 | use std::fs; | ||
| 5 | |||
| 6 | use run_make_support::{llvm_filecheck, rfs, rustc}; | ||
| 7 | |||
| 8 | fn 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 | |||
| 3 | use std::autodiff::autodiff_reverse; | ||
| 4 | |||
| 5 | #[autodiff_reverse(d_square, Duplicated, Active)] | ||
| 6 | #[no_mangle] | ||
| 7 | fn callee(x: &u32) -> u32 { | ||
| 8 | *x * *x | ||
| 9 | } | ||
| 10 | |||
| 11 | fn 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 | |||
| 4 | use std::fs; | ||
| 5 | |||
| 6 | use run_make_support::{llvm_filecheck, rfs, rustc}; | ||
| 7 | |||
| 8 | fn 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 | |||
| 3 | use std::autodiff::autodiff_reverse; | ||
| 4 | |||
| 5 | #[autodiff_reverse(d_square, Duplicated, Active)] | ||
| 6 | #[no_mangle] | ||
| 7 | fn callee(x: &u8) -> u8 { | ||
| 8 | *x * *x | ||
| 9 | } | ||
| 10 | |||
| 11 | fn 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 | |||
| 4 | use std::fs; | ||
| 5 | |||
| 6 | use run_make_support::{llvm_filecheck, rfs, rustc}; | ||
| 7 | |||
| 8 | fn 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 | |||
| 3 | use std::autodiff::autodiff_reverse; | ||
| 4 | |||
| 5 | #[allow(dead_code)] | ||
| 6 | union MyUnion { | ||
| 7 | f: f32, | ||
| 8 | i: i32, | ||
| 9 | } | ||
| 10 | |||
| 11 | #[autodiff_reverse(d_square, Duplicated, Active)] | ||
| 12 | #[no_mangle] | ||
| 13 | fn callee(x: &MyUnion) -> f32 { | ||
| 14 | unsafe { x.f * x.f } | ||
| 15 | } | ||
| 16 | |||
| 17 | fn 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 | |||
| 4 | use std::fs; | ||
| 5 | |||
| 6 | use run_make_support::{llvm_filecheck, rfs, rustc}; | ||
| 7 | |||
| 8 | fn 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 | |||
| 3 | use std::autodiff::autodiff_reverse; | ||
| 4 | |||
| 5 | #[autodiff_reverse(d_square, Duplicated, Active)] | ||
| 6 | #[no_mangle] | ||
| 7 | fn callee(x: &usize) -> usize { | ||
| 8 | *x * *x | ||
| 9 | } | ||
| 10 | |||
| 11 | fn 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 | |||
| 4 | use std::fs; | ||
| 5 | |||
| 6 | use run_make_support::{llvm_filecheck, rfs, rustc}; | ||
| 7 | |||
| 8 | fn 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 | |||
| 3 | use std::autodiff::autodiff_reverse; | ||
| 4 | |||
| 5 | #[autodiff_reverse(d_square, Duplicated, Active)] | ||
| 6 | #[no_mangle] | ||
| 7 | fn callee(arg: &std::vec::Vec<f32>) -> f32 { | ||
| 8 | arg.iter().sum() | ||
| 9 | } | ||
| 10 | |||
| 11 | fn 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-32bit | 9 | //@ ignore-32bit |
| 10 | // Reason: the usage of a large array in the test causes an out-of-memory | 10 | // 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 | ||
| 12 | 13 | ||
| 13 | use run_make_support::{bin_name, llvm_objdump, run, rustc}; | 14 | use run_make_support::{bin_name, llvm_objdump, run, rustc}; |
| 14 | 15 |
tests/ui/panics/panic-main.rs+3| ... | @@ -14,12 +14,15 @@ | ... | @@ -14,12 +14,15 @@ |
| 14 | 14 | ||
| 15 | //@[unwind-zero] compile-flags: -Cpanic=unwind | 15 | //@[unwind-zero] compile-flags: -Cpanic=unwind |
| 16 | //@[unwind-zero] exec-env:RUST_BACKTRACE=0 | 16 | //@[unwind-zero] exec-env:RUST_BACKTRACE=0 |
| 17 | //@[unwind-zero] needs-unwind | ||
| 17 | 18 | ||
| 18 | //@[unwind-one] compile-flags: -Cpanic=unwind | 19 | //@[unwind-one] compile-flags: -Cpanic=unwind |
| 19 | //@[unwind-one] exec-env:RUST_BACKTRACE=1 | 20 | //@[unwind-one] exec-env:RUST_BACKTRACE=1 |
| 21 | //@[unwind-one] needs-unwind | ||
| 20 | 22 | ||
| 21 | //@[unwind-full] compile-flags: -Cpanic=unwind | 23 | //@[unwind-full] compile-flags: -Cpanic=unwind |
| 22 | //@[unwind-full] exec-env:RUST_BACKTRACE=full | 24 | //@[unwind-full] exec-env:RUST_BACKTRACE=full |
| 25 | //@[unwind-full] needs-unwind | ||
| 23 | 26 | ||
| 24 | //@ run-fail | 27 | //@ run-fail |
| 25 | //@ error-pattern:moop | 28 | //@ 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 { |
| 35 | 35 | ||
| 36 | mod traits { | 36 | mod 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 {} |
| 40 | 41 | ||
| ... | @@ -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 predicates | 55 | 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 () {} | ||
| 78 | 83 | ||
| 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 | } |
| 85 | 95 | ||
| 86 | mod impls { | 96 | mod 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 type | 130 | | ^^^^^^^^^^ can't leak private type |
| 131 | 131 | ||
| 132 | error: trait `traits::PrivTr` is more private than the item `traits::Alias` | 132 | error: trait `traits::PrivTr` is more private than the item `traits::Alias` |
| 133 | --> $DIR/private-in-public-warn.rs:41:5 | 133 | --> $DIR/private-in-public-warn.rs:42:5 |
| 134 | | | 134 | | |
| 135 | LL | pub type Alias<T: PrivTr> = T; | 135 | LL | 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 | | ^^^^^^^^^^^^^^ |
| 148 | 148 | ||
| 149 | error: trait `traits::PrivTr` is more private than the item `traits::Tr1` | 149 | error: trait `traits::PrivTr` is more private than the item `traits::Tr1` |
| 150 | --> $DIR/private-in-public-warn.rs:43:5 | 150 | --> $DIR/private-in-public-warn.rs:44:5 |
| 151 | | | 151 | | |
| 152 | LL | pub trait Tr1: PrivTr {} | 152 | LL | 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 | | ^^^^^^^^^^^^ |
| 160 | 160 | ||
| 161 | error: trait `traits::PrivTr` is more private than the item `traits::Tr2` | 161 | error: trait `traits::PrivTr` is more private than the item `traits::Tr2` |
| 162 | --> $DIR/private-in-public-warn.rs:44:5 | 162 | --> $DIR/private-in-public-warn.rs:45:5 |
| 163 | | | 163 | | |
| 164 | LL | pub trait Tr2<T: PrivTr> {} | 164 | LL | 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 | | ^^^^^^^^^^^^ |
| 172 | 172 | ||
| 173 | error: trait `traits::PrivTr` is more private than the item `traits::Tr3::Alias` | 173 | error: trait `traits::PrivTr` is more private than the item `traits::Tr3::Alias` |
| 174 | --> $DIR/private-in-public-warn.rs:46:9 | 174 | --> $DIR/private-in-public-warn.rs:47:9 |
| 175 | | | 175 | | |
| 176 | LL | type Alias: PrivTr; | 176 | LL | 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 | | ^^^^^^^^^^^^ |
| 184 | 184 | ||
| 185 | error: trait `traits::PrivTr` is more private than the item `traits::Tr3::f` | 185 | error: trait `traits::PrivTr` is more private than the item `traits::Tr3::f` |
| 186 | --> $DIR/private-in-public-warn.rs:48:9 | 186 | --> $DIR/private-in-public-warn.rs:49:9 |
| 187 | | | 187 | | |
| 188 | LL | fn f<T: PrivTr>(arg: T) {} | 188 | LL | 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 | | ^^^^^^^^^^^^ |
| 196 | 196 | ||
| 197 | error: trait `traits::PrivTr` is more private than the item `traits::Pub<T>` | 197 | error: trait `traits::PrivTr` is more private than the item `traits::Pub<T>` |
| 198 | --> $DIR/private-in-public-warn.rs:50:5 | 198 | --> $DIR/private-in-public-warn.rs:54:5 |
| 199 | | | 199 | | |
| 200 | LL | impl<T: PrivTr> Pub<T> {} | 200 | LL | 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 | | ^^^^^^^^^^^^ |
| 208 | 208 | ||
| 209 | error: trait `traits_where::PrivTr` is more private than the item `traits_where::Alias` | 209 | error: trait `traits_where::PrivTr` is more private than the item `traits_where::Alias` |
| 210 | --> $DIR/private-in-public-warn.rs:59:5 | 210 | --> $DIR/private-in-public-warn.rs:63:5 |
| 211 | | | 211 | | |
| 212 | LL | pub type Alias<T> where T: PrivTr = T; | 212 | LL | 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 | | |
| 215 | note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)` | 215 | note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)` |
| 216 | --> $DIR/private-in-public-warn.rs:55:5 | 216 | --> $DIR/private-in-public-warn.rs:59:5 |
| 217 | | | 217 | | |
| 218 | LL | trait PrivTr {} | 218 | LL | trait PrivTr {} |
| 219 | | ^^^^^^^^^^^^ | 219 | | ^^^^^^^^^^^^ |
| 220 | 220 | ||
| 221 | error: trait `traits_where::PrivTr` is more private than the item `traits_where::Tr2` | 221 | error: trait `traits_where::PrivTr` is more private than the item `traits_where::Tr2` |
| 222 | --> $DIR/private-in-public-warn.rs:62:5 | 222 | --> $DIR/private-in-public-warn.rs:66:5 |
| 223 | | | 223 | | |
| 224 | LL | pub trait Tr2<T> where T: PrivTr {} | 224 | LL | 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 | | |
| 227 | note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)` | 227 | note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)` |
| 228 | --> $DIR/private-in-public-warn.rs:55:5 | 228 | --> $DIR/private-in-public-warn.rs:59:5 |
| 229 | | | 229 | | |
| 230 | LL | trait PrivTr {} | 230 | LL | trait PrivTr {} |
| 231 | | ^^^^^^^^^^^^ | 231 | | ^^^^^^^^^^^^ |
| 232 | 232 | ||
| 233 | error: trait `traits_where::PrivTr` is more private than the item `traits_where::Tr3::f` | 233 | error: trait `traits_where::PrivTr` is more private than the item `traits_where::Tr3::f` |
| 234 | --> $DIR/private-in-public-warn.rs:65:9 | 234 | --> $DIR/private-in-public-warn.rs:69:9 |
| 235 | | | 235 | | |
| 236 | LL | fn f<T>(arg: T) where T: PrivTr {} | 236 | LL | 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 | | |
| 239 | note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)` | 239 | note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)` |
| 240 | --> $DIR/private-in-public-warn.rs:55:5 | 240 | --> $DIR/private-in-public-warn.rs:59:5 |
| 241 | | | 241 | | |
| 242 | LL | trait PrivTr {} | 242 | LL | trait PrivTr {} |
| 243 | | ^^^^^^^^^^^^ | 243 | | ^^^^^^^^^^^^ |
| 244 | 244 | ||
| 245 | error: trait `traits_where::PrivTr` is more private than the item `traits_where::Pub<T>` | 245 | error: trait `traits_where::PrivTr` is more private than the item `traits_where::Pub<T>` |
| 246 | --> $DIR/private-in-public-warn.rs:68:5 | 246 | --> $DIR/private-in-public-warn.rs:72:5 |
| 247 | | | 247 | | |
| 248 | LL | impl<T> Pub<T> where T: PrivTr {} | 248 | LL | 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 | | |
| 251 | note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)` | 251 | note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)` |
| 252 | --> $DIR/private-in-public-warn.rs:55:5 | 252 | --> $DIR/private-in-public-warn.rs:59:5 |
| 253 | | | 253 | | |
| 254 | LL | trait PrivTr {} | 254 | LL | trait PrivTr {} |
| 255 | | ^^^^^^^^^^^^ | 255 | | ^^^^^^^^^^^^ |
| 256 | 256 | ||
| 257 | error: trait `generics::PrivTr<generics::Pub>` is more private than the item `generics::Tr1` | 257 | error: trait `generics::PrivTr<generics::Pub>` is more private than the item `generics::Tr1` |
| 258 | --> $DIR/private-in-public-warn.rs:79:5 | 258 | --> $DIR/private-in-public-warn.rs:84:5 |
| 259 | | | 259 | | |
| 260 | LL | pub trait Tr1: PrivTr<Pub> {} | 260 | LL | 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 | | |
| 263 | note: but trait `generics::PrivTr<generics::Pub>` is only usable at visibility `pub(self)` | 263 | note: but trait `generics::PrivTr<generics::Pub>` is only usable at visibility `pub(self)` |
| 264 | --> $DIR/private-in-public-warn.rs:76:5 | 264 | --> $DIR/private-in-public-warn.rs:80:5 |
| 265 | | | 265 | | |
| 266 | LL | trait PrivTr<T> {} | 266 | LL | trait PrivTr<T> {} |
| 267 | | ^^^^^^^^^^^^^^^ | 267 | | ^^^^^^^^^^^^^^^ |
| 268 | 268 | ||
| 269 | error: type `generics::Priv` is more private than the item `generics::Tr2` | 269 | error: type `generics::Priv` is more private than the item `generics::Tr2` |
| 270 | --> $DIR/private-in-public-warn.rs:81:5 | 270 | --> $DIR/private-in-public-warn.rs:86:5 |
| 271 | | | 271 | | |
| 272 | LL | pub trait Tr2: PubTr<Priv> {} | 272 | LL | 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 | | |
| 275 | note: but type `generics::Priv` is only usable at visibility `pub(self)` | 275 | note: but type `generics::Priv` is only usable at visibility `pub(self)` |
| 276 | --> $DIR/private-in-public-warn.rs:74:5 | 276 | --> $DIR/private-in-public-warn.rs:78:5 |
| 277 | | | 277 | | |
| 278 | LL | struct Priv<T = u8>(T); | 278 | LL | struct Priv<T = u8>(T); |
| 279 | | ^^^^^^^^^^^^^^^^^^^ | 279 | | ^^^^^^^^^^^^^^^^^^^ |
| 280 | 280 | ||
| 281 | error: type `generics::Priv` is more private than the item `generics::Tr3` | 281 | error: type `generics::Priv` is more private than the item `generics::Tr3` |
| 282 | --> $DIR/private-in-public-warn.rs:82:5 | 282 | --> $DIR/private-in-public-warn.rs:87:5 |
| 283 | | | 283 | | |
| 284 | LL | pub trait Tr3: PubTr<[Priv; 1]> {} | 284 | LL | 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 | | |
| 287 | note: but type `generics::Priv` is only usable at visibility `pub(self)` | 287 | note: but type `generics::Priv` is only usable at visibility `pub(self)` |
| 288 | --> $DIR/private-in-public-warn.rs:74:5 | 288 | --> $DIR/private-in-public-warn.rs:78:5 |
| 289 | | | 289 | | |
| 290 | LL | struct Priv<T = u8>(T); | 290 | LL | struct Priv<T = u8>(T); |
| 291 | | ^^^^^^^^^^^^^^^^^^^ | 291 | | ^^^^^^^^^^^^^^^^^^^ |
| 292 | 292 | ||
| 293 | error: type `generics::Priv` is more private than the item `Tr4` | 293 | error: type `generics::Priv` is more private than the item `Tr4` |
| 294 | --> $DIR/private-in-public-warn.rs:83:5 | 294 | --> $DIR/private-in-public-warn.rs:88:5 |
| 295 | | | 295 | | |
| 296 | LL | pub trait Tr4: PubTr<Pub<Priv>> {} | 296 | LL | 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 | | |
| 299 | note: but type `generics::Priv` is only usable at visibility `pub(self)` | 299 | note: but type `generics::Priv` is only usable at visibility `pub(self)` |
| 300 | --> $DIR/private-in-public-warn.rs:74:5 | 300 | --> $DIR/private-in-public-warn.rs:78:5 |
| 301 | | | 301 | | |
| 302 | LL | struct Priv<T = u8>(T); | 302 | LL | struct Priv<T = u8>(T); |
| 303 | | ^^^^^^^^^^^^^^^^^^^ | 303 | | ^^^^^^^^^^^^^^^^^^^ |
| 304 | 304 | ||
| 305 | error[E0446]: private type `impls::Priv` in public interface | 305 | error[E0446]: private type `impls::Priv` in public interface |
| 306 | --> $DIR/private-in-public-warn.rs:109:9 | 306 | --> $DIR/private-in-public-warn.rs:119:9 |
| 307 | | | 307 | | |
| 308 | LL | struct Priv; | 308 | LL | struct Priv; |
| 309 | | ----------- `impls::Priv` declared as private | 309 | | ----------- `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 type | 312 | | ^^^^^^^^^^ can't leak private type |
| 313 | 313 | ||
| 314 | error: type `aliases_pub::Priv` is more private than the item `aliases_pub::<impl Pub2>::f` | 314 | error: type `aliases_pub::Priv` is more private than the item `aliases_pub::<impl Pub2>::f` |
| 315 | --> $DIR/private-in-public-warn.rs:180:9 | 315 | --> $DIR/private-in-public-warn.rs:190:9 |
| 316 | | | 316 | | |
| 317 | LL | pub fn f(arg: Priv) {} | 317 | LL | 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 | | |
| 320 | note: but type `aliases_pub::Priv` is only usable at visibility `pub(self)` | 320 | note: but type `aliases_pub::Priv` is only usable at visibility `pub(self)` |
| 321 | --> $DIR/private-in-public-warn.rs:153:5 | 321 | --> $DIR/private-in-public-warn.rs:163:5 |
| 322 | | | 322 | | |
| 323 | LL | struct Priv; | 323 | LL | struct Priv; |
| 324 | | ^^^^^^^^^^^ | 324 | | ^^^^^^^^^^^ |
| 325 | 325 | ||
| 326 | error[E0446]: private type `aliases_pub::Priv` in public interface | 326 | error[E0446]: private type `aliases_pub::Priv` in public interface |
| 327 | --> $DIR/private-in-public-warn.rs:183:9 | 327 | --> $DIR/private-in-public-warn.rs:193:9 |
| 328 | | | 328 | | |
| 329 | LL | struct Priv; | 329 | LL | struct Priv; |
| 330 | | ----------- `aliases_pub::Priv` declared as private | 330 | | ----------- `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 type | 333 | | ^^^^^^^^^^ can't leak private type |
| 334 | 334 | ||
| 335 | error[E0446]: private type `aliases_pub::Priv` in public interface | 335 | error[E0446]: private type `aliases_pub::Priv` in public interface |
| 336 | --> $DIR/private-in-public-warn.rs:186:9 | 336 | --> $DIR/private-in-public-warn.rs:196:9 |
| 337 | | | 337 | | |
| 338 | LL | struct Priv; | 338 | LL | struct Priv; |
| 339 | | ----------- `aliases_pub::Priv` declared as private | 339 | | ----------- `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 type | 342 | | ^^^^^^^^^^ can't leak private type |
| 343 | 343 | ||
| 344 | error[E0446]: private type `aliases_pub::Priv` in public interface | 344 | error[E0446]: private type `aliases_pub::Priv` in public interface |
| 345 | --> $DIR/private-in-public-warn.rs:189:9 | 345 | --> $DIR/private-in-public-warn.rs:199:9 |
| 346 | | | 346 | | |
| 347 | LL | struct Priv; | 347 | LL | struct Priv; |
| 348 | | ----------- `aliases_pub::Priv` declared as private | 348 | | ----------- `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 type | 351 | | ^^^^^^^^^^ can't leak private type |
| 352 | 352 | ||
| 353 | error[E0446]: private type `aliases_pub::Priv` in public interface | 353 | error[E0446]: private type `aliases_pub::Priv` in public interface |
| 354 | --> $DIR/private-in-public-warn.rs:192:9 | 354 | --> $DIR/private-in-public-warn.rs:202:9 |
| 355 | | | 355 | | |
| 356 | LL | struct Priv; | 356 | LL | struct Priv; |
| 357 | | ----------- `aliases_pub::Priv` declared as private | 357 | | ----------- `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 type | 360 | | ^^^^^^^^^^ can't leak private type |
| 361 | 361 | ||
| 362 | error: trait `PrivTr1` is more private than the item `aliases_priv::Tr1` | 362 | error: trait `PrivTr1` is more private than the item `aliases_priv::Tr1` |
| 363 | --> $DIR/private-in-public-warn.rs:222:5 | 363 | --> $DIR/private-in-public-warn.rs:232:5 |
| 364 | | | 364 | | |
| 365 | LL | pub trait Tr1: PrivUseAliasTr {} | 365 | LL | 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 | | |
| 368 | note: but trait `PrivTr1` is only usable at visibility `pub(self)` | 368 | note: but trait `PrivTr1` is only usable at visibility `pub(self)` |
| 369 | --> $DIR/private-in-public-warn.rs:208:5 | 369 | --> $DIR/private-in-public-warn.rs:218:5 |
| 370 | | | 370 | | |
| 371 | LL | trait PrivTr1<T = u8> { | 371 | LL | trait PrivTr1<T = u8> { |
| 372 | | ^^^^^^^^^^^^^^^^^^^^^ | 372 | | ^^^^^^^^^^^^^^^^^^^^^ |
| 373 | 373 | ||
| 374 | error: trait `PrivTr1<Priv2>` is more private than the item `aliases_priv::Tr2` | 374 | error: trait `PrivTr1<Priv2>` is more private than the item `aliases_priv::Tr2` |
| 375 | --> $DIR/private-in-public-warn.rs:224:5 | 375 | --> $DIR/private-in-public-warn.rs:234:5 |
| 376 | | | 376 | | |
| 377 | LL | pub trait Tr2: PrivUseAliasTr<PrivAlias> {} | 377 | LL | 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 | | |
| 380 | note: but trait `PrivTr1<Priv2>` is only usable at visibility `pub(self)` | 380 | note: but trait `PrivTr1<Priv2>` is only usable at visibility `pub(self)` |
| 381 | --> $DIR/private-in-public-warn.rs:208:5 | 381 | --> $DIR/private-in-public-warn.rs:218:5 |
| 382 | | | 382 | | |
| 383 | LL | trait PrivTr1<T = u8> { | 383 | LL | trait PrivTr1<T = u8> { |
| 384 | | ^^^^^^^^^^^^^^^^^^^^^ | 384 | | ^^^^^^^^^^^^^^^^^^^^^ |
| 385 | 385 | ||
| 386 | error: type `Priv2` is more private than the item `aliases_priv::Tr2` | 386 | error: type `Priv2` is more private than the item `aliases_priv::Tr2` |
| 387 | --> $DIR/private-in-public-warn.rs:224:5 | 387 | --> $DIR/private-in-public-warn.rs:234:5 |
| 388 | | | 388 | | |
| 389 | LL | pub trait Tr2: PrivUseAliasTr<PrivAlias> {} | 389 | LL | 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 | | |
| 392 | note: but type `Priv2` is only usable at visibility `pub(self)` | 392 | note: but type `Priv2` is only usable at visibility `pub(self)` |
| 393 | --> $DIR/private-in-public-warn.rs:206:5 | 393 | --> $DIR/private-in-public-warn.rs:216:5 |
| 394 | | | 394 | | |
| 395 | LL | struct Priv2; | 395 | LL | struct Priv2; |
| 396 | | ^^^^^^^^^^^^ | 396 | | ^^^^^^^^^^^^ |
| 397 | 397 | ||
| 398 | warning: bounds on generic parameters in type aliases are not enforced | 398 | warning: bounds on generic parameters in type aliases are not enforced |
| 399 | --> $DIR/private-in-public-warn.rs:41:23 | 399 | --> $DIR/private-in-public-warn.rs:42:23 |
| 400 | | | 400 | | |
| 401 | LL | pub type Alias<T: PrivTr> = T; | 401 | LL | 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 default | 410 | = note: `#[warn(type_alias_bounds)]` on by default |
| 411 | 411 | ||
| 412 | warning: where clauses on type aliases are not enforced | 412 | warning: where clauses on type aliases are not enforced |
| 413 | --> $DIR/private-in-public-warn.rs:59:29 | 413 | --> $DIR/private-in-public-warn.rs:63:29 |
| 414 | | | 414 | | |
| 415 | LL | pub type Alias<T> where T: PrivTr = T; | 415 | LL | 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 @@ |
| 1 | pub struct OtherType; | 1 | pub struct OtherType; |
| 2 | pub trait OtherTrait {} | 2 | pub trait OtherTrait {} |
| 3 | impl OtherTrait for OtherType {} | ||
| 3 | 4 | ||
| 4 | #[macro_export] | 5 | #[macro_export] |
| 5 | macro_rules! m { | 6 | macro_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 { |
| 44 | 44 | ||
| 45 | pub trait MyPubTrait { | 45 | pub 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 | ||
| 49 | 53 | ||
| 50 | pub trait WithSuperTrait: OtherTrait {} | 54 | pub trait WithSuperTrait: OtherTrait {} |
| 51 | //~^ ERROR trait `OtherTrait` from private dependency 'priv_dep' in public interface | 55 | //~^ 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 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 12 | 12 | ||
| 13 | error: macro `m` from private dependency 'priv_dep' is re-exported | 13 | error: macro `m` from private dependency 'priv_dep' is re-exported |
| 14 | --> $DIR/pub-priv1.rs:94:9 | 14 | --> $DIR/pub-priv1.rs:98:9 |
| 15 | | | 15 | | |
| 16 | LL | pub use priv_dep::m; | 16 | LL | pub use priv_dep::m; |
| 17 | | ^^^^^^^^^^^ | 17 | | ^^^^^^^^^^^ |
| 18 | 18 | ||
| 19 | error: macro `fn_like` from private dependency 'pm' is re-exported | 19 | error: macro `fn_like` from private dependency 'pm' is re-exported |
| 20 | --> $DIR/pub-priv1.rs:96:9 | 20 | --> $DIR/pub-priv1.rs:100:9 |
| 21 | | | 21 | | |
| 22 | LL | pub use pm::fn_like; | 22 | LL | pub use pm::fn_like; |
| 23 | | ^^^^^^^^^^^ | 23 | | ^^^^^^^^^^^ |
| 24 | 24 | ||
| 25 | error: derive macro `PmDerive` from private dependency 'pm' is re-exported | 25 | error: derive macro `PmDerive` from private dependency 'pm' is re-exported |
| 26 | --> $DIR/pub-priv1.rs:98:9 | 26 | --> $DIR/pub-priv1.rs:102:9 |
| 27 | | | 27 | | |
| 28 | LL | pub use pm::PmDerive; | 28 | LL | pub use pm::PmDerive; |
| 29 | | ^^^^^^^^^^^^ | 29 | | ^^^^^^^^^^^^ |
| 30 | 30 | ||
| 31 | error: attribute macro `pm_attr` from private dependency 'pm' is re-exported | 31 | error: attribute macro `pm_attr` from private dependency 'pm' is re-exported |
| 32 | --> $DIR/pub-priv1.rs:100:9 | 32 | --> $DIR/pub-priv1.rs:104:9 |
| 33 | | | 33 | | |
| 34 | LL | pub use pm::pm_attr; | 34 | LL | pub use pm::pm_attr; |
| 35 | | ^^^^^^^^^^^ | 35 | | ^^^^^^^^^^^ |
| 36 | 36 | ||
| 37 | error: variant `V1` from private dependency 'priv_dep' is re-exported | 37 | error: variant `V1` from private dependency 'priv_dep' is re-exported |
| 38 | --> $DIR/pub-priv1.rs:103:9 | 38 | --> $DIR/pub-priv1.rs:107:9 |
| 39 | | | 39 | | |
| 40 | LL | pub use priv_dep::E::V1; | 40 | LL | 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 | | ^^^^^^^^^^^^^^^^^^^^ |
| 66 | 66 | ||
| 67 | error: trait `OtherTrait` from private dependency 'priv_dep' in public interface | 67 | error: trait `OtherTrait` from private dependency 'priv_dep' in public interface |
| 68 | --> $DIR/pub-priv1.rs:50:1 | 68 | --> $DIR/pub-priv1.rs:54:1 |
| 69 | | | 69 | | |
| 70 | LL | pub trait WithSuperTrait: OtherTrait {} | 70 | LL | pub trait WithSuperTrait: OtherTrait {} |
| 71 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | 71 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 72 | 72 | ||
| 73 | error: type `OtherType` from private dependency 'priv_dep' in public interface | 73 | error: type `OtherType` from private dependency 'priv_dep' in public interface |
| 74 | --> $DIR/pub-priv1.rs:59:5 | 74 | --> $DIR/pub-priv1.rs:63:5 |
| 75 | | | 75 | | |
| 76 | LL | type X = OtherType; | 76 | LL | type X = OtherType; |
| 77 | | ^^^^^^ | 77 | | ^^^^^^ |
| 78 | 78 | ||
| 79 | error: trait `OtherTrait` from private dependency 'priv_dep' in public interface | 79 | error: trait `OtherTrait` from private dependency 'priv_dep' in public interface |
| 80 | --> $DIR/pub-priv1.rs:63:1 | 80 | --> $DIR/pub-priv1.rs:67:1 |
| 81 | | | 81 | | |
| 82 | LL | pub fn in_bounds<T: OtherTrait>(x: T) { unimplemented!() } | 82 | LL | pub fn in_bounds<T: OtherTrait>(x: T) { unimplemented!() } |
| 83 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | 83 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 84 | 84 | ||
| 85 | error: type `OtherType` from private dependency 'priv_dep' in public interface | 85 | error: type `OtherType` from private dependency 'priv_dep' in public interface |
| 86 | --> $DIR/pub-priv1.rs:66:1 | 86 | --> $DIR/pub-priv1.rs:70:1 |
| 87 | | | 87 | | |
| 88 | LL | pub fn private_in_generic() -> std::num::Saturating<OtherType> { unimplemented!() } | 88 | LL | pub fn private_in_generic() -> std::num::Saturating<OtherType> { unimplemented!() } |
| 89 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | 89 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 90 | 90 | ||
| 91 | error: type `OtherType` from private dependency 'priv_dep' in public interface | 91 | error: type `OtherType` from private dependency 'priv_dep' in public interface |
| 92 | --> $DIR/pub-priv1.rs:69:1 | 92 | --> $DIR/pub-priv1.rs:73:1 |
| 93 | | | 93 | | |
| 94 | LL | pub static STATIC: OtherType = OtherType; | 94 | LL | pub static STATIC: OtherType = OtherType; |
| 95 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | 95 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 96 | 96 | ||
| 97 | error: type `OtherType` from private dependency 'priv_dep' in public interface | 97 | error: type `OtherType` from private dependency 'priv_dep' in public interface |
| 98 | --> $DIR/pub-priv1.rs:72:1 | 98 | --> $DIR/pub-priv1.rs:76:1 |
| 99 | | | 99 | | |
| 100 | LL | pub const CONST: OtherType = OtherType; | 100 | LL | pub const CONST: OtherType = OtherType; |
| 101 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | 101 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 102 | 102 | ||
| 103 | error: type `OtherType` from private dependency 'priv_dep' in public interface | 103 | error: type `OtherType` from private dependency 'priv_dep' in public interface |
| 104 | --> $DIR/pub-priv1.rs:75:1 | 104 | --> $DIR/pub-priv1.rs:79:1 |
| 105 | | | 105 | | |
| 106 | LL | pub type Alias = OtherType; | 106 | LL | pub type Alias = OtherType; |
| 107 | | ^^^^^^^^^^^^^^ | 107 | | ^^^^^^^^^^^^^^ |
| 108 | 108 | ||
| 109 | error: trait `OtherTrait` from private dependency 'priv_dep' in public interface | 109 | error: trait `OtherTrait` from private dependency 'priv_dep' in public interface |
| 110 | --> $DIR/pub-priv1.rs:80:1 | 110 | --> $DIR/pub-priv1.rs:84:1 |
| 111 | | | 111 | | |
| 112 | LL | impl OtherTrait for PublicWithPrivateImpl {} | 112 | LL | impl OtherTrait for PublicWithPrivateImpl {} |
| 113 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | 113 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 114 | 114 | ||
| 115 | error: type `OtherType` from private dependency 'priv_dep' in public interface | 115 | error: type `OtherType` from private dependency 'priv_dep' in public interface |
| 116 | --> $DIR/pub-priv1.rs:85:1 | 116 | --> $DIR/pub-priv1.rs:89:1 |
| 117 | | | 117 | | |
| 118 | LL | impl PubTraitOnPrivate for OtherType {} | 118 | LL | impl PubTraitOnPrivate for OtherType {} |
| 119 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | 119 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 120 | 120 | ||
| 121 | error: type `OtherType` from private dependency 'priv_dep' in public interface | 121 | error: type `OtherType` from private dependency 'priv_dep' in public interface |
| 122 | --> $DIR/pub-priv1.rs:85:1 | 122 | --> $DIR/pub-priv1.rs:89:1 |
| 123 | | | 123 | | |
| 124 | LL | impl PubTraitOnPrivate for OtherType {} | 124 | LL | impl PubTraitOnPrivate for OtherType {} |
| 125 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | 125 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |