| author | bors <bors@rust-lang.org> 2024-06-26 07:22:41 UTC |
| committer | bors <bors@rust-lang.org> 2024-06-26 07:22:41 UTC |
| log | 773180257062f55ea1d8b5736d97b57c30a8b677 |
| tree | 66a375558e3c1bf9a8d157df3214a1f24a29b27e |
| parent | a299aa5df79dd8e5a1405b97ddd7b367b61eecc6 |
| parent | b2720867f1f2ae1a481e991e39a9725cacdce48d |
Rollup of 10 pull requests
Successful merges:
- #126724 (Fix a span in `parse_ty_bare_fn`.)
- #126812 (Rename `tcx` to `cx` in new solver generic code)
- #126879 (fix Drop items getting leaked in Filter::next_chunk)
- #126925 (Change E0369 to give note informations for foreign items.)
- #126938 (miri: make sure we can find link_section statics even for the local crate)
- #126954 (resolve: Tweak some naming around import ambiguities)
- #126964 (Migrate `lto-empty`, `invalid-so` and `issue-20626` `run-make` tests to rmake.rs)
- #126968 (Don't ICE during RPITIT refinement checking for resolution errors after normalization)
- #126971 (Bump black, ruff and platformdirs)
- #126973 (Fix bad replacement for unsafe extern block suggestion)
r? `@ghost`
`@rustbot` modify labels: rollup63 files changed, 919 insertions(+), 620 deletions(-)
compiler/rustc_ast/src/ast.rs+2-1| ... | ... | @@ -2126,7 +2126,8 @@ pub struct BareFnTy { |
| 2126 | 2126 | pub ext: Extern, |
| 2127 | 2127 | pub generic_params: ThinVec<GenericParam>, |
| 2128 | 2128 | pub decl: P<FnDecl>, |
| 2129 | /// Span of the `fn(...) -> ...` part. | |
| 2129 | /// Span of the `[unsafe] [extern] fn(...) -> ...` part, i.e. everything | |
| 2130 | /// after the generic params (if there are any, e.g. `for<'a>`). | |
| 2130 | 2131 | pub decl_span: Span, |
| 2131 | 2132 | } |
| 2132 | 2133 |
compiler/rustc_ast_passes/src/ast_validation.rs+1-1| ... | ... | @@ -464,7 +464,7 @@ impl<'a> AstValidator<'a> { |
| 464 | 464 | { |
| 465 | 465 | self.dcx().emit_err(errors::InvalidSafetyOnExtern { |
| 466 | 466 | item_span: span, |
| 467 | block: self.current_extern_span(), | |
| 467 | block: self.current_extern_span().shrink_to_lo(), | |
| 468 | 468 | }); |
| 469 | 469 | } |
| 470 | 470 | } |
compiler/rustc_ast_passes/src/errors.rs+1-1| ... | ... | @@ -221,7 +221,7 @@ pub enum ExternBlockSuggestion { |
| 221 | 221 | pub struct InvalidSafetyOnExtern { |
| 222 | 222 | #[primary_span] |
| 223 | 223 | pub item_span: Span, |
| 224 | #[suggestion(code = "", applicability = "maybe-incorrect")] | |
| 224 | #[suggestion(code = "unsafe ", applicability = "machine-applicable", style = "verbose")] | |
| 225 | 225 | pub block: Span, |
| 226 | 226 | } |
| 227 | 227 |
compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs+4-4| ... | ... | @@ -171,10 +171,10 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>( |
| 171 | 171 | } |
| 172 | 172 | // Resolve any lifetime variables that may have been introduced during normalization. |
| 173 | 173 | let Ok((trait_bounds, impl_bounds)) = infcx.fully_resolve((trait_bounds, impl_bounds)) else { |
| 174 | // This code path is not reached in any tests, but may be reachable. If | |
| 175 | // this is triggered, it should be converted to `delayed_bug` and the | |
| 176 | // triggering case turned into a test. | |
| 177 | tcx.dcx().bug("encountered errors when checking RPITIT refinement (resolution)"); | |
| 174 | // If resolution didn't fully complete, we cannot continue checking RPITIT refinement, and | |
| 175 | // delay a bug as the original code contains load-bearing errors. | |
| 176 | tcx.dcx().delayed_bug("encountered errors when checking RPITIT refinement (resolution)"); | |
| 177 | return; | |
| 178 | 178 | }; |
| 179 | 179 | |
| 180 | 180 | // For quicker lookup, use an `IndexSet` (we don't use one earlier because |
compiler/rustc_hir_typeck/src/method/suggest.rs+76-26| ... | ... | @@ -2831,32 +2831,38 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { |
| 2831 | 2831 | errors: Vec<FulfillmentError<'tcx>>, |
| 2832 | 2832 | suggest_derive: bool, |
| 2833 | 2833 | ) { |
| 2834 | let all_local_types_needing_impls = | |
| 2835 | errors.iter().all(|e| match e.obligation.predicate.kind().skip_binder() { | |
| 2834 | let preds: Vec<_> = errors | |
| 2835 | .iter() | |
| 2836 | .filter_map(|e| match e.obligation.predicate.kind().skip_binder() { | |
| 2836 | 2837 | ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => { |
| 2837 | 2838 | match pred.self_ty().kind() { |
| 2838 | ty::Adt(def, _) => def.did().is_local(), | |
| 2839 | _ => false, | |
| 2839 | ty::Adt(_, _) => Some(pred), | |
| 2840 | _ => None, | |
| 2840 | 2841 | } |
| 2841 | 2842 | } |
| 2842 | _ => false, | |
| 2843 | }); | |
| 2844 | let mut preds: Vec<_> = errors | |
| 2845 | .iter() | |
| 2846 | .filter_map(|e| match e.obligation.predicate.kind().skip_binder() { | |
| 2847 | ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => Some(pred), | |
| 2848 | 2843 | _ => None, |
| 2849 | 2844 | }) |
| 2850 | 2845 | .collect(); |
| 2851 | preds.sort_by_key(|pred| pred.trait_ref.to_string()); | |
| 2852 | let def_ids = preds | |
| 2846 | ||
| 2847 | // Note for local items and foreign items respectively. | |
| 2848 | let (mut local_preds, mut foreign_preds): (Vec<_>, Vec<_>) = | |
| 2849 | preds.iter().partition(|&pred| { | |
| 2850 | if let ty::Adt(def, _) = pred.self_ty().kind() { | |
| 2851 | def.did().is_local() | |
| 2852 | } else { | |
| 2853 | false | |
| 2854 | } | |
| 2855 | }); | |
| 2856 | ||
| 2857 | local_preds.sort_by_key(|pred: &&ty::TraitPredicate<'_>| pred.trait_ref.to_string()); | |
| 2858 | let local_def_ids = local_preds | |
| 2853 | 2859 | .iter() |
| 2854 | 2860 | .filter_map(|pred| match pred.self_ty().kind() { |
| 2855 | 2861 | ty::Adt(def, _) => Some(def.did()), |
| 2856 | 2862 | _ => None, |
| 2857 | 2863 | }) |
| 2858 | 2864 | .collect::<FxIndexSet<_>>(); |
| 2859 | let mut spans: MultiSpan = def_ids | |
| 2865 | let mut local_spans: MultiSpan = local_def_ids | |
| 2860 | 2866 | .iter() |
| 2861 | 2867 | .filter_map(|def_id| { |
| 2862 | 2868 | let span = self.tcx.def_span(*def_id); |
| ... | ... | @@ -2864,11 +2870,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { |
| 2864 | 2870 | }) |
| 2865 | 2871 | .collect::<Vec<_>>() |
| 2866 | 2872 | .into(); |
| 2867 | ||
| 2868 | for pred in &preds { | |
| 2873 | for pred in &local_preds { | |
| 2869 | 2874 | match pred.self_ty().kind() { |
| 2870 | ty::Adt(def, _) if def.did().is_local() => { | |
| 2871 | spans.push_span_label( | |
| 2875 | ty::Adt(def, _) => { | |
| 2876 | local_spans.push_span_label( | |
| 2872 | 2877 | self.tcx.def_span(def.did()), |
| 2873 | 2878 | format!("must implement `{}`", pred.trait_ref.print_trait_sugared()), |
| 2874 | 2879 | ); |
| ... | ... | @@ -2876,24 +2881,69 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { |
| 2876 | 2881 | _ => {} |
| 2877 | 2882 | } |
| 2878 | 2883 | } |
| 2879 | ||
| 2880 | if all_local_types_needing_impls && spans.primary_span().is_some() { | |
| 2881 | let msg = if preds.len() == 1 { | |
| 2884 | if local_spans.primary_span().is_some() { | |
| 2885 | let msg = if local_preds.len() == 1 { | |
| 2882 | 2886 | format!( |
| 2883 | 2887 | "an implementation of `{}` might be missing for `{}`", |
| 2884 | preds[0].trait_ref.print_trait_sugared(), | |
| 2885 | preds[0].self_ty() | |
| 2888 | local_preds[0].trait_ref.print_trait_sugared(), | |
| 2889 | local_preds[0].self_ty() | |
| 2886 | 2890 | ) |
| 2887 | 2891 | } else { |
| 2888 | 2892 | format!( |
| 2889 | 2893 | "the following type{} would have to `impl` {} required trait{} for this \ |
| 2890 | 2894 | operation to be valid", |
| 2891 | pluralize!(def_ids.len()), | |
| 2892 | if def_ids.len() == 1 { "its" } else { "their" }, | |
| 2893 | pluralize!(preds.len()), | |
| 2895 | pluralize!(local_def_ids.len()), | |
| 2896 | if local_def_ids.len() == 1 { "its" } else { "their" }, | |
| 2897 | pluralize!(local_preds.len()), | |
| 2898 | ) | |
| 2899 | }; | |
| 2900 | err.span_note(local_spans, msg); | |
| 2901 | } | |
| 2902 | ||
| 2903 | foreign_preds.sort_by_key(|pred: &&ty::TraitPredicate<'_>| pred.trait_ref.to_string()); | |
| 2904 | let foreign_def_ids = foreign_preds | |
| 2905 | .iter() | |
| 2906 | .filter_map(|pred| match pred.self_ty().kind() { | |
| 2907 | ty::Adt(def, _) => Some(def.did()), | |
| 2908 | _ => None, | |
| 2909 | }) | |
| 2910 | .collect::<FxIndexSet<_>>(); | |
| 2911 | let mut foreign_spans: MultiSpan = foreign_def_ids | |
| 2912 | .iter() | |
| 2913 | .filter_map(|def_id| { | |
| 2914 | let span = self.tcx.def_span(*def_id); | |
| 2915 | if span.is_dummy() { None } else { Some(span) } | |
| 2916 | }) | |
| 2917 | .collect::<Vec<_>>() | |
| 2918 | .into(); | |
| 2919 | for pred in &foreign_preds { | |
| 2920 | match pred.self_ty().kind() { | |
| 2921 | ty::Adt(def, _) => { | |
| 2922 | foreign_spans.push_span_label( | |
| 2923 | self.tcx.def_span(def.did()), | |
| 2924 | format!("not implement `{}`", pred.trait_ref.print_trait_sugared()), | |
| 2925 | ); | |
| 2926 | } | |
| 2927 | _ => {} | |
| 2928 | } | |
| 2929 | } | |
| 2930 | if foreign_spans.primary_span().is_some() { | |
| 2931 | let msg = if foreign_preds.len() == 1 { | |
| 2932 | format!( | |
| 2933 | "the foreign item type `{}` doesn't implement `{}`", | |
| 2934 | foreign_preds[0].self_ty(), | |
| 2935 | foreign_preds[0].trait_ref.print_trait_sugared() | |
| 2936 | ) | |
| 2937 | } else { | |
| 2938 | format!( | |
| 2939 | "the foreign item type{} {} implement required trait{} for this \ | |
| 2940 | operation to be valid", | |
| 2941 | pluralize!(foreign_def_ids.len()), | |
| 2942 | if foreign_def_ids.len() > 1 { "don't" } else { "doesn't" }, | |
| 2943 | pluralize!(foreign_preds.len()), | |
| 2894 | 2944 | ) |
| 2895 | 2945 | }; |
| 2896 | err.span_note(spans, msg); | |
| 2946 | err.span_note(foreign_spans, msg); | |
| 2897 | 2947 | } |
| 2898 | 2948 | |
| 2899 | 2949 | let preds: Vec<_> = errors |
compiler/rustc_next_trait_solver/src/solve/alias_relate.rs+3-3| ... | ... | @@ -32,14 +32,14 @@ where |
| 32 | 32 | &mut self, |
| 33 | 33 | goal: Goal<I, (I::Term, I::Term, ty::AliasRelationDirection)>, |
| 34 | 34 | ) -> QueryResult<I> { |
| 35 | let tcx = self.cx(); | |
| 35 | let cx = self.cx(); | |
| 36 | 36 | let Goal { param_env, predicate: (lhs, rhs, direction) } = goal; |
| 37 | 37 | debug_assert!(lhs.to_alias_term().is_some() || rhs.to_alias_term().is_some()); |
| 38 | 38 | |
| 39 | 39 | // Structurally normalize the lhs. |
| 40 | 40 | let lhs = if let Some(alias) = lhs.to_alias_term() { |
| 41 | 41 | let term = self.next_term_infer_of_kind(lhs); |
| 42 | self.add_normalizes_to_goal(goal.with(tcx, ty::NormalizesTo { alias, term })); | |
| 42 | self.add_normalizes_to_goal(goal.with(cx, ty::NormalizesTo { alias, term })); | |
| 43 | 43 | term |
| 44 | 44 | } else { |
| 45 | 45 | lhs |
| ... | ... | @@ -48,7 +48,7 @@ where |
| 48 | 48 | // Structurally normalize the rhs. |
| 49 | 49 | let rhs = if let Some(alias) = rhs.to_alias_term() { |
| 50 | 50 | let term = self.next_term_infer_of_kind(rhs); |
| 51 | self.add_normalizes_to_goal(goal.with(tcx, ty::NormalizesTo { alias, term })); | |
| 51 | self.add_normalizes_to_goal(goal.with(cx, ty::NormalizesTo { alias, term })); | |
| 52 | 52 | term |
| 53 | 53 | } else { |
| 54 | 54 | rhs |
compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs+42-43| ... | ... | @@ -36,11 +36,11 @@ where |
| 36 | 36 | { |
| 37 | 37 | fn self_ty(self) -> I::Ty; |
| 38 | 38 | |
| 39 | fn trait_ref(self, tcx: I) -> ty::TraitRef<I>; | |
| 39 | fn trait_ref(self, cx: I) -> ty::TraitRef<I>; | |
| 40 | 40 | |
| 41 | fn with_self_ty(self, tcx: I, self_ty: I::Ty) -> Self; | |
| 41 | fn with_self_ty(self, cx: I, self_ty: I::Ty) -> Self; | |
| 42 | 42 | |
| 43 | fn trait_def_id(self, tcx: I) -> I::DefId; | |
| 43 | fn trait_def_id(self, cx: I) -> I::DefId; | |
| 44 | 44 | |
| 45 | 45 | /// Try equating an assumption predicate against a goal's predicate. If it |
| 46 | 46 | /// holds, then execute the `then` callback, which should do any additional |
| ... | ... | @@ -82,7 +82,7 @@ where |
| 82 | 82 | assumption: I::Clause, |
| 83 | 83 | ) -> Result<Candidate<I>, NoSolution> { |
| 84 | 84 | Self::probe_and_match_goal_against_assumption(ecx, source, goal, assumption, |ecx| { |
| 85 | let tcx = ecx.cx(); | |
| 85 | let cx = ecx.cx(); | |
| 86 | 86 | let ty::Dynamic(bounds, _, _) = goal.predicate.self_ty().kind() else { |
| 87 | 87 | panic!("expected object type in `probe_and_consider_object_bound_candidate`"); |
| 88 | 88 | }; |
| ... | ... | @@ -91,7 +91,7 @@ where |
| 91 | 91 | structural_traits::predicates_for_object_candidate( |
| 92 | 92 | ecx, |
| 93 | 93 | goal.param_env, |
| 94 | goal.predicate.trait_ref(tcx), | |
| 94 | goal.predicate.trait_ref(cx), | |
| 95 | 95 | bounds, |
| 96 | 96 | ), |
| 97 | 97 | ); |
| ... | ... | @@ -340,15 +340,15 @@ where |
| 340 | 340 | goal: Goal<I, G>, |
| 341 | 341 | candidates: &mut Vec<Candidate<I>>, |
| 342 | 342 | ) { |
| 343 | let tcx = self.cx(); | |
| 344 | tcx.for_each_relevant_impl( | |
| 345 | goal.predicate.trait_def_id(tcx), | |
| 343 | let cx = self.cx(); | |
| 344 | cx.for_each_relevant_impl( | |
| 345 | goal.predicate.trait_def_id(cx), | |
| 346 | 346 | goal.predicate.self_ty(), |
| 347 | 347 | |impl_def_id| { |
| 348 | 348 | // For every `default impl`, there's always a non-default `impl` |
| 349 | 349 | // that will *also* apply. There's no reason to register a candidate |
| 350 | 350 | // for this impl, since it is *not* proof that the trait goal holds. |
| 351 | if tcx.impl_is_default(impl_def_id) { | |
| 351 | if cx.impl_is_default(impl_def_id) { | |
| 352 | 352 | return; |
| 353 | 353 | } |
| 354 | 354 | |
| ... | ... | @@ -366,8 +366,8 @@ where |
| 366 | 366 | goal: Goal<I, G>, |
| 367 | 367 | candidates: &mut Vec<Candidate<I>>, |
| 368 | 368 | ) { |
| 369 | let tcx = self.cx(); | |
| 370 | let trait_def_id = goal.predicate.trait_def_id(tcx); | |
| 369 | let cx = self.cx(); | |
| 370 | let trait_def_id = goal.predicate.trait_def_id(cx); | |
| 371 | 371 | |
| 372 | 372 | // N.B. When assembling built-in candidates for lang items that are also |
| 373 | 373 | // `auto` traits, then the auto trait candidate that is assembled in |
| ... | ... | @@ -378,47 +378,47 @@ where |
| 378 | 378 | // `solve::trait_goals` instead. |
| 379 | 379 | let result = if let Err(guar) = goal.predicate.error_reported() { |
| 380 | 380 | G::consider_error_guaranteed_candidate(self, guar) |
| 381 | } else if tcx.trait_is_auto(trait_def_id) { | |
| 381 | } else if cx.trait_is_auto(trait_def_id) { | |
| 382 | 382 | G::consider_auto_trait_candidate(self, goal) |
| 383 | } else if tcx.trait_is_alias(trait_def_id) { | |
| 383 | } else if cx.trait_is_alias(trait_def_id) { | |
| 384 | 384 | G::consider_trait_alias_candidate(self, goal) |
| 385 | } else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::Sized) { | |
| 385 | } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Sized) { | |
| 386 | 386 | G::consider_builtin_sized_candidate(self, goal) |
| 387 | } else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::Copy) | |
| 388 | || tcx.is_lang_item(trait_def_id, TraitSolverLangItem::Clone) | |
| 387 | } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Copy) | |
| 388 | || cx.is_lang_item(trait_def_id, TraitSolverLangItem::Clone) | |
| 389 | 389 | { |
| 390 | 390 | G::consider_builtin_copy_clone_candidate(self, goal) |
| 391 | } else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::PointerLike) { | |
| 391 | } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::PointerLike) { | |
| 392 | 392 | G::consider_builtin_pointer_like_candidate(self, goal) |
| 393 | } else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::FnPtrTrait) { | |
| 393 | } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::FnPtrTrait) { | |
| 394 | 394 | G::consider_builtin_fn_ptr_trait_candidate(self, goal) |
| 395 | 395 | } else if let Some(kind) = self.cx().fn_trait_kind_from_def_id(trait_def_id) { |
| 396 | 396 | G::consider_builtin_fn_trait_candidates(self, goal, kind) |
| 397 | 397 | } else if let Some(kind) = self.cx().async_fn_trait_kind_from_def_id(trait_def_id) { |
| 398 | 398 | G::consider_builtin_async_fn_trait_candidates(self, goal, kind) |
| 399 | } else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::AsyncFnKindHelper) { | |
| 399 | } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::AsyncFnKindHelper) { | |
| 400 | 400 | G::consider_builtin_async_fn_kind_helper_candidate(self, goal) |
| 401 | } else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::Tuple) { | |
| 401 | } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Tuple) { | |
| 402 | 402 | G::consider_builtin_tuple_candidate(self, goal) |
| 403 | } else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::PointeeTrait) { | |
| 403 | } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::PointeeTrait) { | |
| 404 | 404 | G::consider_builtin_pointee_candidate(self, goal) |
| 405 | } else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::Future) { | |
| 405 | } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Future) { | |
| 406 | 406 | G::consider_builtin_future_candidate(self, goal) |
| 407 | } else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::Iterator) { | |
| 407 | } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Iterator) { | |
| 408 | 408 | G::consider_builtin_iterator_candidate(self, goal) |
| 409 | } else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::FusedIterator) { | |
| 409 | } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::FusedIterator) { | |
| 410 | 410 | G::consider_builtin_fused_iterator_candidate(self, goal) |
| 411 | } else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::AsyncIterator) { | |
| 411 | } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::AsyncIterator) { | |
| 412 | 412 | G::consider_builtin_async_iterator_candidate(self, goal) |
| 413 | } else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::Coroutine) { | |
| 413 | } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Coroutine) { | |
| 414 | 414 | G::consider_builtin_coroutine_candidate(self, goal) |
| 415 | } else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::DiscriminantKind) { | |
| 415 | } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::DiscriminantKind) { | |
| 416 | 416 | G::consider_builtin_discriminant_kind_candidate(self, goal) |
| 417 | } else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::AsyncDestruct) { | |
| 417 | } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::AsyncDestruct) { | |
| 418 | 418 | G::consider_builtin_async_destruct_candidate(self, goal) |
| 419 | } else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::Destruct) { | |
| 419 | } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Destruct) { | |
| 420 | 420 | G::consider_builtin_destruct_candidate(self, goal) |
| 421 | } else if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::TransmuteTrait) { | |
| 421 | } else if cx.is_lang_item(trait_def_id, TraitSolverLangItem::TransmuteTrait) { | |
| 422 | 422 | G::consider_builtin_transmute_candidate(self, goal) |
| 423 | 423 | } else { |
| 424 | 424 | Err(NoSolution) |
| ... | ... | @@ -428,7 +428,7 @@ where |
| 428 | 428 | |
| 429 | 429 | // There may be multiple unsize candidates for a trait with several supertraits: |
| 430 | 430 | // `trait Foo: Bar<A> + Bar<B>` and `dyn Foo: Unsize<dyn Bar<_>>` |
| 431 | if tcx.is_lang_item(trait_def_id, TraitSolverLangItem::Unsize) { | |
| 431 | if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Unsize) { | |
| 432 | 432 | candidates.extend(G::consider_structural_builtin_unsize_candidates(self, goal)); |
| 433 | 433 | } |
| 434 | 434 | } |
| ... | ... | @@ -557,8 +557,8 @@ where |
| 557 | 557 | goal: Goal<I, G>, |
| 558 | 558 | candidates: &mut Vec<Candidate<I>>, |
| 559 | 559 | ) { |
| 560 | let tcx = self.cx(); | |
| 561 | if !tcx.trait_may_be_implemented_via_object(goal.predicate.trait_def_id(tcx)) { | |
| 560 | let cx = self.cx(); | |
| 561 | if !cx.trait_may_be_implemented_via_object(goal.predicate.trait_def_id(cx)) { | |
| 562 | 562 | return; |
| 563 | 563 | } |
| 564 | 564 | |
| ... | ... | @@ -596,7 +596,7 @@ where |
| 596 | 596 | }; |
| 597 | 597 | |
| 598 | 598 | // Do not consider built-in object impls for non-object-safe types. |
| 599 | if bounds.principal_def_id().is_some_and(|def_id| !tcx.trait_is_object_safe(def_id)) { | |
| 599 | if bounds.principal_def_id().is_some_and(|def_id| !cx.trait_is_object_safe(def_id)) { | |
| 600 | 600 | return; |
| 601 | 601 | } |
| 602 | 602 | |
| ... | ... | @@ -614,7 +614,7 @@ where |
| 614 | 614 | self, |
| 615 | 615 | CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), |
| 616 | 616 | goal, |
| 617 | bound.with_self_ty(tcx, self_ty), | |
| 617 | bound.with_self_ty(cx, self_ty), | |
| 618 | 618 | )); |
| 619 | 619 | } |
| 620 | 620 | } |
| ... | ... | @@ -624,14 +624,13 @@ where |
| 624 | 624 | // since we don't need to look at any supertrait or anything if we are doing |
| 625 | 625 | // a projection goal. |
| 626 | 626 | if let Some(principal) = bounds.principal() { |
| 627 | let principal_trait_ref = principal.with_self_ty(tcx, self_ty); | |
| 628 | for (idx, assumption) in D::elaborate_supertraits(tcx, principal_trait_ref).enumerate() | |
| 629 | { | |
| 627 | let principal_trait_ref = principal.with_self_ty(cx, self_ty); | |
| 628 | for (idx, assumption) in D::elaborate_supertraits(cx, principal_trait_ref).enumerate() { | |
| 630 | 629 | candidates.extend(G::probe_and_consider_object_bound_candidate( |
| 631 | 630 | self, |
| 632 | 631 | CandidateSource::BuiltinImpl(BuiltinImplSource::Object(idx)), |
| 633 | 632 | goal, |
| 634 | assumption.upcast(tcx), | |
| 633 | assumption.upcast(cx), | |
| 635 | 634 | )); |
| 636 | 635 | } |
| 637 | 636 | } |
| ... | ... | @@ -649,11 +648,11 @@ where |
| 649 | 648 | goal: Goal<I, G>, |
| 650 | 649 | candidates: &mut Vec<Candidate<I>>, |
| 651 | 650 | ) { |
| 652 | let tcx = self.cx(); | |
| 651 | let cx = self.cx(); | |
| 653 | 652 | |
| 654 | 653 | candidates.extend(self.probe_trait_candidate(CandidateSource::CoherenceUnknowable).enter( |
| 655 | 654 | |ecx| { |
| 656 | let trait_ref = goal.predicate.trait_ref(tcx); | |
| 655 | let trait_ref = goal.predicate.trait_ref(cx); | |
| 657 | 656 | if ecx.trait_ref_is_knowable(goal.param_env, trait_ref)? { |
| 658 | 657 | Err(NoSolution) |
| 659 | 658 | } else { |
| ... | ... | @@ -678,9 +677,9 @@ where |
| 678 | 677 | goal: Goal<I, G>, |
| 679 | 678 | candidates: &mut Vec<Candidate<I>>, |
| 680 | 679 | ) { |
| 681 | let tcx = self.cx(); | |
| 680 | let cx = self.cx(); | |
| 682 | 681 | let trait_goal: Goal<I, ty::TraitPredicate<I>> = |
| 683 | goal.with(tcx, goal.predicate.trait_ref(tcx)); | |
| 682 | goal.with(cx, goal.predicate.trait_ref(cx)); | |
| 684 | 683 | |
| 685 | 684 | let mut trait_candidates_from_env = vec![]; |
| 686 | 685 | self.probe(|_| ProbeKind::ShadowedEnvProbing).enter(|ecx| { |
compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs+55-57| ... | ... | @@ -23,7 +23,7 @@ where |
| 23 | 23 | D: SolverDelegate<Interner = I>, |
| 24 | 24 | I: Interner, |
| 25 | 25 | { |
| 26 | let tcx = ecx.cx(); | |
| 26 | let cx = ecx.cx(); | |
| 27 | 27 | match ty.kind() { |
| 28 | 28 | ty::Uint(_) |
| 29 | 29 | | ty::Int(_) |
| ... | ... | @@ -36,7 +36,7 @@ where |
| 36 | 36 | | ty::Char => Ok(vec![]), |
| 37 | 37 | |
| 38 | 38 | // Treat `str` like it's defined as `struct str([u8]);` |
| 39 | ty::Str => Ok(vec![ty::Binder::dummy(Ty::new_slice(tcx, Ty::new_u8(tcx)))]), | |
| 39 | ty::Str => Ok(vec![ty::Binder::dummy(Ty::new_slice(cx, Ty::new_u8(cx)))]), | |
| 40 | 40 | |
| 41 | 41 | ty::Dynamic(..) |
| 42 | 42 | | ty::Param(..) |
| ... | ... | @@ -79,21 +79,21 @@ where |
| 79 | 79 | .cx() |
| 80 | 80 | .bound_coroutine_hidden_types(def_id) |
| 81 | 81 | .into_iter() |
| 82 | .map(|bty| bty.instantiate(tcx, args)) | |
| 82 | .map(|bty| bty.instantiate(cx, args)) | |
| 83 | 83 | .collect()), |
| 84 | 84 | |
| 85 | 85 | // For `PhantomData<T>`, we pass `T`. |
| 86 | 86 | ty::Adt(def, args) if def.is_phantom_data() => Ok(vec![ty::Binder::dummy(args.type_at(0))]), |
| 87 | 87 | |
| 88 | 88 | ty::Adt(def, args) => { |
| 89 | Ok(def.all_field_tys(tcx).iter_instantiated(tcx, args).map(ty::Binder::dummy).collect()) | |
| 89 | Ok(def.all_field_tys(cx).iter_instantiated(cx, args).map(ty::Binder::dummy).collect()) | |
| 90 | 90 | } |
| 91 | 91 | |
| 92 | 92 | ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => { |
| 93 | 93 | // We can resolve the `impl Trait` to its concrete type, |
| 94 | 94 | // which enforces a DAG between the functions requiring |
| 95 | 95 | // the auto trait bounds in question. |
| 96 | Ok(vec![ty::Binder::dummy(tcx.type_of(def_id).instantiate(tcx, args))]) | |
| 96 | Ok(vec![ty::Binder::dummy(cx.type_of(def_id).instantiate(cx, args))]) | |
| 97 | 97 | } |
| 98 | 98 | } |
| 99 | 99 | } |
| ... | ... | @@ -247,18 +247,18 @@ where |
| 247 | 247 | |
| 248 | 248 | // Returns a binder of the tupled inputs types and output type from a builtin callable type. |
| 249 | 249 | pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<I: Interner>( |
| 250 | tcx: I, | |
| 250 | cx: I, | |
| 251 | 251 | self_ty: I::Ty, |
| 252 | 252 | goal_kind: ty::ClosureKind, |
| 253 | 253 | ) -> Result<Option<ty::Binder<I, (I::Ty, I::Ty)>>, NoSolution> { |
| 254 | 254 | match self_ty.kind() { |
| 255 | 255 | // keep this in sync with assemble_fn_pointer_candidates until the old solver is removed. |
| 256 | 256 | ty::FnDef(def_id, args) => { |
| 257 | let sig = tcx.fn_sig(def_id); | |
| 258 | if sig.skip_binder().is_fn_trait_compatible() && !tcx.has_target_features(def_id) { | |
| 257 | let sig = cx.fn_sig(def_id); | |
| 258 | if sig.skip_binder().is_fn_trait_compatible() && !cx.has_target_features(def_id) { | |
| 259 | 259 | Ok(Some( |
| 260 | sig.instantiate(tcx, args) | |
| 261 | .map_bound(|sig| (Ty::new_tup(tcx, sig.inputs().as_slice()), sig.output())), | |
| 260 | sig.instantiate(cx, args) | |
| 261 | .map_bound(|sig| (Ty::new_tup(cx, sig.inputs().as_slice()), sig.output())), | |
| 262 | 262 | )) |
| 263 | 263 | } else { |
| 264 | 264 | Err(NoSolution) |
| ... | ... | @@ -268,7 +268,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<I: Intern |
| 268 | 268 | ty::FnPtr(sig) => { |
| 269 | 269 | if sig.is_fn_trait_compatible() { |
| 270 | 270 | Ok(Some( |
| 271 | sig.map_bound(|sig| (Ty::new_tup(tcx, sig.inputs().as_slice()), sig.output())), | |
| 271 | sig.map_bound(|sig| (Ty::new_tup(cx, sig.inputs().as_slice()), sig.output())), | |
| 272 | 272 | )) |
| 273 | 273 | } else { |
| 274 | 274 | Err(NoSolution) |
| ... | ... | @@ -323,10 +323,10 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<I: Intern |
| 323 | 323 | } |
| 324 | 324 | |
| 325 | 325 | coroutine_closure_to_certain_coroutine( |
| 326 | tcx, | |
| 326 | cx, | |
| 327 | 327 | goal_kind, |
| 328 | 328 | // No captures by ref, so this doesn't matter. |
| 329 | Region::new_static(tcx), | |
| 329 | Region::new_static(cx), | |
| 330 | 330 | def_id, |
| 331 | 331 | args, |
| 332 | 332 | sig, |
| ... | ... | @@ -339,9 +339,9 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<I: Intern |
| 339 | 339 | } |
| 340 | 340 | |
| 341 | 341 | coroutine_closure_to_ambiguous_coroutine( |
| 342 | tcx, | |
| 342 | cx, | |
| 343 | 343 | goal_kind, // No captures by ref, so this doesn't matter. |
| 344 | Region::new_static(tcx), | |
| 344 | Region::new_static(cx), | |
| 345 | 345 | def_id, |
| 346 | 346 | args, |
| 347 | 347 | sig, |
| ... | ... | @@ -403,7 +403,7 @@ pub(in crate::solve) struct AsyncCallableRelevantTypes<I: Interner> { |
| 403 | 403 | // which enforces the closure is actually callable with the given trait. When we |
| 404 | 404 | // know the kind already, we can short-circuit this check. |
| 405 | 405 | pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I: Interner>( |
| 406 | tcx: I, | |
| 406 | cx: I, | |
| 407 | 407 | self_ty: I::Ty, |
| 408 | 408 | goal_kind: ty::ClosureKind, |
| 409 | 409 | env_region: I::Region, |
| ... | ... | @@ -422,9 +422,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I: |
| 422 | 422 | return Err(NoSolution); |
| 423 | 423 | } |
| 424 | 424 | |
| 425 | coroutine_closure_to_certain_coroutine( | |
| 426 | tcx, goal_kind, env_region, def_id, args, sig, | |
| 427 | ) | |
| 425 | coroutine_closure_to_certain_coroutine(cx, goal_kind, env_region, def_id, args, sig) | |
| 428 | 426 | } else { |
| 429 | 427 | // When we don't know the closure kind (and therefore also the closure's upvars, |
| 430 | 428 | // which are computed at the same time), we must delay the computation of the |
| ... | ... | @@ -435,15 +433,15 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I: |
| 435 | 433 | // coroutine upvars respecting the closure kind. |
| 436 | 434 | nested.push( |
| 437 | 435 | ty::TraitRef::new( |
| 438 | tcx, | |
| 439 | tcx.require_lang_item(TraitSolverLangItem::AsyncFnKindHelper), | |
| 440 | [kind_ty, Ty::from_closure_kind(tcx, goal_kind)], | |
| 436 | cx, | |
| 437 | cx.require_lang_item(TraitSolverLangItem::AsyncFnKindHelper), | |
| 438 | [kind_ty, Ty::from_closure_kind(cx, goal_kind)], | |
| 441 | 439 | ) |
| 442 | .upcast(tcx), | |
| 440 | .upcast(cx), | |
| 443 | 441 | ); |
| 444 | 442 | |
| 445 | 443 | coroutine_closure_to_ambiguous_coroutine( |
| 446 | tcx, goal_kind, env_region, def_id, args, sig, | |
| 444 | cx, goal_kind, env_region, def_id, args, sig, | |
| 447 | 445 | ) |
| 448 | 446 | }; |
| 449 | 447 | |
| ... | ... | @@ -458,21 +456,21 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I: |
| 458 | 456 | } |
| 459 | 457 | |
| 460 | 458 | ty::FnDef(..) | ty::FnPtr(..) => { |
| 461 | let bound_sig = self_ty.fn_sig(tcx); | |
| 459 | let bound_sig = self_ty.fn_sig(cx); | |
| 462 | 460 | let sig = bound_sig.skip_binder(); |
| 463 | let future_trait_def_id = tcx.require_lang_item(TraitSolverLangItem::Future); | |
| 461 | let future_trait_def_id = cx.require_lang_item(TraitSolverLangItem::Future); | |
| 464 | 462 | // `FnDef` and `FnPtr` only implement `AsyncFn*` when their |
| 465 | 463 | // return type implements `Future`. |
| 466 | 464 | let nested = vec![ |
| 467 | 465 | bound_sig |
| 468 | .rebind(ty::TraitRef::new(tcx, future_trait_def_id, [sig.output()])) | |
| 469 | .upcast(tcx), | |
| 466 | .rebind(ty::TraitRef::new(cx, future_trait_def_id, [sig.output()])) | |
| 467 | .upcast(cx), | |
| 470 | 468 | ]; |
| 471 | let future_output_def_id = tcx.require_lang_item(TraitSolverLangItem::FutureOutput); | |
| 472 | let future_output_ty = Ty::new_projection(tcx, future_output_def_id, [sig.output()]); | |
| 469 | let future_output_def_id = cx.require_lang_item(TraitSolverLangItem::FutureOutput); | |
| 470 | let future_output_ty = Ty::new_projection(cx, future_output_def_id, [sig.output()]); | |
| 473 | 471 | Ok(( |
| 474 | 472 | bound_sig.rebind(AsyncCallableRelevantTypes { |
| 475 | tupled_inputs_ty: Ty::new_tup(tcx, sig.inputs().as_slice()), | |
| 473 | tupled_inputs_ty: Ty::new_tup(cx, sig.inputs().as_slice()), | |
| 476 | 474 | output_coroutine_ty: sig.output(), |
| 477 | 475 | coroutine_return_ty: future_output_ty, |
| 478 | 476 | }), |
| ... | ... | @@ -483,13 +481,13 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I: |
| 483 | 481 | let args = args.as_closure(); |
| 484 | 482 | let bound_sig = args.sig(); |
| 485 | 483 | let sig = bound_sig.skip_binder(); |
| 486 | let future_trait_def_id = tcx.require_lang_item(TraitSolverLangItem::Future); | |
| 484 | let future_trait_def_id = cx.require_lang_item(TraitSolverLangItem::Future); | |
| 487 | 485 | // `Closure`s only implement `AsyncFn*` when their return type |
| 488 | 486 | // implements `Future`. |
| 489 | 487 | let mut nested = vec![ |
| 490 | 488 | bound_sig |
| 491 | .rebind(ty::TraitRef::new(tcx, future_trait_def_id, [sig.output()])) | |
| 492 | .upcast(tcx), | |
| 489 | .rebind(ty::TraitRef::new(cx, future_trait_def_id, [sig.output()])) | |
| 490 | .upcast(cx), | |
| 493 | 491 | ]; |
| 494 | 492 | |
| 495 | 493 | // Additionally, we need to check that the closure kind |
| ... | ... | @@ -501,7 +499,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I: |
| 501 | 499 | } |
| 502 | 500 | } else { |
| 503 | 501 | let async_fn_kind_trait_def_id = |
| 504 | tcx.require_lang_item(TraitSolverLangItem::AsyncFnKindHelper); | |
| 502 | cx.require_lang_item(TraitSolverLangItem::AsyncFnKindHelper); | |
| 505 | 503 | // When we don't know the closure kind (and therefore also the closure's upvars, |
| 506 | 504 | // which are computed at the same time), we must delay the computation of the |
| 507 | 505 | // generator's upvars. We do this using the `AsyncFnKindHelper`, which as a trait |
| ... | ... | @@ -511,16 +509,16 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I: |
| 511 | 509 | // coroutine upvars respecting the closure kind. |
| 512 | 510 | nested.push( |
| 513 | 511 | ty::TraitRef::new( |
| 514 | tcx, | |
| 512 | cx, | |
| 515 | 513 | async_fn_kind_trait_def_id, |
| 516 | [kind_ty, Ty::from_closure_kind(tcx, goal_kind)], | |
| 514 | [kind_ty, Ty::from_closure_kind(cx, goal_kind)], | |
| 517 | 515 | ) |
| 518 | .upcast(tcx), | |
| 516 | .upcast(cx), | |
| 519 | 517 | ); |
| 520 | 518 | } |
| 521 | 519 | |
| 522 | let future_output_def_id = tcx.require_lang_item(TraitSolverLangItem::FutureOutput); | |
| 523 | let future_output_ty = Ty::new_projection(tcx, future_output_def_id, [sig.output()]); | |
| 520 | let future_output_def_id = cx.require_lang_item(TraitSolverLangItem::FutureOutput); | |
| 521 | let future_output_ty = Ty::new_projection(cx, future_output_def_id, [sig.output()]); | |
| 524 | 522 | Ok(( |
| 525 | 523 | bound_sig.rebind(AsyncCallableRelevantTypes { |
| 526 | 524 | tupled_inputs_ty: sig.inputs().get(0).unwrap(), |
| ... | ... | @@ -565,7 +563,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I: |
| 565 | 563 | /// Given a coroutine-closure, project to its returned coroutine when we are *certain* |
| 566 | 564 | /// that the closure's kind is compatible with the goal. |
| 567 | 565 | fn coroutine_closure_to_certain_coroutine<I: Interner>( |
| 568 | tcx: I, | |
| 566 | cx: I, | |
| 569 | 567 | goal_kind: ty::ClosureKind, |
| 570 | 568 | goal_region: I::Region, |
| 571 | 569 | def_id: I::DefId, |
| ... | ... | @@ -573,9 +571,9 @@ fn coroutine_closure_to_certain_coroutine<I: Interner>( |
| 573 | 571 | sig: ty::CoroutineClosureSignature<I>, |
| 574 | 572 | ) -> I::Ty { |
| 575 | 573 | sig.to_coroutine_given_kind_and_upvars( |
| 576 | tcx, | |
| 574 | cx, | |
| 577 | 575 | args.parent_args(), |
| 578 | tcx.coroutine_for_closure(def_id), | |
| 576 | cx.coroutine_for_closure(def_id), | |
| 579 | 577 | goal_kind, |
| 580 | 578 | goal_region, |
| 581 | 579 | args.tupled_upvars_ty(), |
| ... | ... | @@ -589,20 +587,20 @@ fn coroutine_closure_to_certain_coroutine<I: Interner>( |
| 589 | 587 | /// |
| 590 | 588 | /// Note that we do not also push a `AsyncFnKindHelper` goal here. |
| 591 | 589 | fn coroutine_closure_to_ambiguous_coroutine<I: Interner>( |
| 592 | tcx: I, | |
| 590 | cx: I, | |
| 593 | 591 | goal_kind: ty::ClosureKind, |
| 594 | 592 | goal_region: I::Region, |
| 595 | 593 | def_id: I::DefId, |
| 596 | 594 | args: ty::CoroutineClosureArgs<I>, |
| 597 | 595 | sig: ty::CoroutineClosureSignature<I>, |
| 598 | 596 | ) -> I::Ty { |
| 599 | let upvars_projection_def_id = tcx.require_lang_item(TraitSolverLangItem::AsyncFnKindUpvars); | |
| 597 | let upvars_projection_def_id = cx.require_lang_item(TraitSolverLangItem::AsyncFnKindUpvars); | |
| 600 | 598 | let tupled_upvars_ty = Ty::new_projection( |
| 601 | tcx, | |
| 599 | cx, | |
| 602 | 600 | upvars_projection_def_id, |
| 603 | 601 | [ |
| 604 | 602 | I::GenericArg::from(args.kind_ty()), |
| 605 | Ty::from_closure_kind(tcx, goal_kind).into(), | |
| 603 | Ty::from_closure_kind(cx, goal_kind).into(), | |
| 606 | 604 | goal_region.into(), |
| 607 | 605 | sig.tupled_inputs_ty.into(), |
| 608 | 606 | args.tupled_upvars_ty().into(), |
| ... | ... | @@ -610,10 +608,10 @@ fn coroutine_closure_to_ambiguous_coroutine<I: Interner>( |
| 610 | 608 | ], |
| 611 | 609 | ); |
| 612 | 610 | sig.to_coroutine( |
| 613 | tcx, | |
| 611 | cx, | |
| 614 | 612 | args.parent_args(), |
| 615 | Ty::from_closure_kind(tcx, goal_kind), | |
| 616 | tcx.coroutine_for_closure(def_id), | |
| 613 | Ty::from_closure_kind(cx, goal_kind), | |
| 614 | cx.coroutine_for_closure(def_id), | |
| 617 | 615 | tupled_upvars_ty, |
| 618 | 616 | ) |
| 619 | 617 | } |
| ... | ... | @@ -668,28 +666,28 @@ where |
| 668 | 666 | D: SolverDelegate<Interner = I>, |
| 669 | 667 | I: Interner, |
| 670 | 668 | { |
| 671 | let tcx = ecx.cx(); | |
| 669 | let cx = ecx.cx(); | |
| 672 | 670 | let mut requirements = vec![]; |
| 673 | 671 | requirements |
| 674 | .extend(tcx.super_predicates_of(trait_ref.def_id).iter_instantiated(tcx, trait_ref.args)); | |
| 672 | .extend(cx.super_predicates_of(trait_ref.def_id).iter_instantiated(cx, trait_ref.args)); | |
| 675 | 673 | |
| 676 | 674 | // FIXME(associated_const_equality): Also add associated consts to |
| 677 | 675 | // the requirements here. |
| 678 | for associated_type_def_id in tcx.associated_type_def_ids(trait_ref.def_id) { | |
| 676 | for associated_type_def_id in cx.associated_type_def_ids(trait_ref.def_id) { | |
| 679 | 677 | // associated types that require `Self: Sized` do not show up in the built-in |
| 680 | 678 | // implementation of `Trait for dyn Trait`, and can be dropped here. |
| 681 | if tcx.generics_require_sized_self(associated_type_def_id) { | |
| 679 | if cx.generics_require_sized_self(associated_type_def_id) { | |
| 682 | 680 | continue; |
| 683 | 681 | } |
| 684 | 682 | |
| 685 | 683 | requirements |
| 686 | .extend(tcx.item_bounds(associated_type_def_id).iter_instantiated(tcx, trait_ref.args)); | |
| 684 | .extend(cx.item_bounds(associated_type_def_id).iter_instantiated(cx, trait_ref.args)); | |
| 687 | 685 | } |
| 688 | 686 | |
| 689 | 687 | let mut replace_projection_with = HashMap::default(); |
| 690 | 688 | for bound in object_bounds.iter() { |
| 691 | 689 | if let ty::ExistentialPredicate::Projection(proj) = bound.skip_binder() { |
| 692 | let proj = proj.with_self_ty(tcx, trait_ref.self_ty()); | |
| 690 | let proj = proj.with_self_ty(cx, trait_ref.self_ty()); | |
| 693 | 691 | let old_ty = replace_projection_with.insert(proj.def_id(), bound.rebind(proj)); |
| 694 | 692 | assert_eq!( |
| 695 | 693 | old_ty, |
| ... | ... | @@ -709,7 +707,7 @@ where |
| 709 | 707 | folder |
| 710 | 708 | .nested |
| 711 | 709 | .into_iter() |
| 712 | .chain(folded_requirements.into_iter().map(|clause| Goal::new(tcx, param_env, clause))) | |
| 710 | .chain(folded_requirements.into_iter().map(|clause| Goal::new(cx, param_env, clause))) | |
| 713 | 711 | .collect() |
| 714 | 712 | } |
| 715 | 713 |
compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs+11-11| ... | ... | @@ -239,14 +239,14 @@ where |
| 239 | 239 | /// This function takes care of setting up the inference context, setting the anchor, |
| 240 | 240 | /// and registering opaques from the canonicalized input. |
| 241 | 241 | fn enter_canonical<R>( |
| 242 | tcx: I, | |
| 242 | cx: I, | |
| 243 | 243 | search_graph: &'a mut search_graph::SearchGraph<I>, |
| 244 | 244 | canonical_input: CanonicalInput<I>, |
| 245 | 245 | canonical_goal_evaluation: &mut ProofTreeBuilder<D>, |
| 246 | 246 | f: impl FnOnce(&mut EvalCtxt<'_, D>, Goal<I, I::Predicate>) -> R, |
| 247 | 247 | ) -> R { |
| 248 | 248 | let (ref delegate, input, var_values) = |
| 249 | SolverDelegate::build_with_canonical(tcx, search_graph.solver_mode(), &canonical_input); | |
| 249 | SolverDelegate::build_with_canonical(cx, search_graph.solver_mode(), &canonical_input); | |
| 250 | 250 | |
| 251 | 251 | let mut ecx = EvalCtxt { |
| 252 | 252 | delegate, |
| ... | ... | @@ -292,9 +292,9 @@ where |
| 292 | 292 | /// Instead of calling this function directly, use either [EvalCtxt::evaluate_goal] |
| 293 | 293 | /// if you're inside of the solver or [SolverDelegateEvalExt::evaluate_root_goal] if you're |
| 294 | 294 | /// outside of it. |
| 295 | #[instrument(level = "debug", skip(tcx, search_graph, goal_evaluation), ret)] | |
| 295 | #[instrument(level = "debug", skip(cx, search_graph, goal_evaluation), ret)] | |
| 296 | 296 | fn evaluate_canonical_goal( |
| 297 | tcx: I, | |
| 297 | cx: I, | |
| 298 | 298 | search_graph: &'a mut search_graph::SearchGraph<I>, |
| 299 | 299 | canonical_input: CanonicalInput<I>, |
| 300 | 300 | goal_evaluation: &mut ProofTreeBuilder<D>, |
| ... | ... | @@ -307,12 +307,12 @@ where |
| 307 | 307 | // The actual solver logic happens in `ecx.compute_goal`. |
| 308 | 308 | let result = ensure_sufficient_stack(|| { |
| 309 | 309 | search_graph.with_new_goal( |
| 310 | tcx, | |
| 310 | cx, | |
| 311 | 311 | canonical_input, |
| 312 | 312 | &mut canonical_goal_evaluation, |
| 313 | 313 | |search_graph, canonical_goal_evaluation| { |
| 314 | 314 | EvalCtxt::enter_canonical( |
| 315 | tcx, | |
| 315 | cx, | |
| 316 | 316 | search_graph, |
| 317 | 317 | canonical_input, |
| 318 | 318 | canonical_goal_evaluation, |
| ... | ... | @@ -506,7 +506,7 @@ where |
| 506 | 506 | /// |
| 507 | 507 | /// Goals for the next step get directly added to the nested goals of the `EvalCtxt`. |
| 508 | 508 | fn evaluate_added_goals_step(&mut self) -> Result<Option<Certainty>, NoSolution> { |
| 509 | let tcx = self.cx(); | |
| 509 | let cx = self.cx(); | |
| 510 | 510 | let mut goals = core::mem::take(&mut self.nested_goals); |
| 511 | 511 | |
| 512 | 512 | // If this loop did not result in any progress, what's our final certainty. |
| ... | ... | @@ -516,7 +516,7 @@ where |
| 516 | 516 | // RHS does not affect projection candidate assembly. |
| 517 | 517 | let unconstrained_rhs = self.next_term_infer_of_kind(goal.predicate.term); |
| 518 | 518 | let unconstrained_goal = goal.with( |
| 519 | tcx, | |
| 519 | cx, | |
| 520 | 520 | ty::NormalizesTo { alias: goal.predicate.alias, term: unconstrained_rhs }, |
| 521 | 521 | ); |
| 522 | 522 | |
| ... | ... | @@ -777,7 +777,7 @@ where |
| 777 | 777 | // NOTE: this check is purely an optimization, the structural eq would |
| 778 | 778 | // always fail if the term is not an inference variable. |
| 779 | 779 | if term.is_infer() { |
| 780 | let tcx = self.cx(); | |
| 780 | let cx = self.cx(); | |
| 781 | 781 | // We need to relate `alias` to `term` treating only the outermost |
| 782 | 782 | // constructor as rigid, relating any contained generic arguments as |
| 783 | 783 | // normal. We do this by first structurally equating the `term` |
| ... | ... | @@ -787,8 +787,8 @@ where |
| 787 | 787 | // Alternatively we could modify `Equate` for this case by adding another |
| 788 | 788 | // variant to `StructurallyRelateAliases`. |
| 789 | 789 | let identity_args = self.fresh_args_for_item(alias.def_id); |
| 790 | let rigid_ctor = ty::AliasTerm::new_from_args(tcx, alias.def_id, identity_args); | |
| 791 | let ctor_term = rigid_ctor.to_term(tcx); | |
| 790 | let rigid_ctor = ty::AliasTerm::new_from_args(cx, alias.def_id, identity_args); | |
| 791 | let ctor_term = rigid_ctor.to_term(cx); | |
| 792 | 792 | let obligations = |
| 793 | 793 | self.delegate.eq_structurally_relating_aliases(param_env, term, ctor_term)?; |
| 794 | 794 | debug_assert!(obligations.is_empty()); |
compiler/rustc_next_trait_solver/src/solve/inspect/build.rs+2-2| ... | ... | @@ -323,13 +323,13 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> { |
| 323 | 323 | |
| 324 | 324 | pub fn finalize_canonical_goal_evaluation( |
| 325 | 325 | &mut self, |
| 326 | tcx: I, | |
| 326 | cx: I, | |
| 327 | 327 | ) -> Option<I::CanonicalGoalEvaluationStepRef> { |
| 328 | 328 | self.as_mut().map(|this| match this { |
| 329 | 329 | DebugSolver::CanonicalGoalEvaluation(evaluation) => { |
| 330 | 330 | let final_revision = mem::take(&mut evaluation.final_revision).unwrap(); |
| 331 | 331 | let final_revision = |
| 332 | tcx.intern_canonical_goal_evaluation_step(final_revision.finalize()); | |
| 332 | cx.intern_canonical_goal_evaluation_step(final_revision.finalize()); | |
| 333 | 333 | let kind = WipCanonicalGoalEvaluationKind::Interned { final_revision }; |
| 334 | 334 | assert_eq!(evaluation.kind.replace(kind), None); |
| 335 | 335 | final_revision |
compiler/rustc_next_trait_solver/src/solve/mod.rs+6-6| ... | ... | @@ -34,7 +34,7 @@ use crate::delegate::SolverDelegate; |
| 34 | 34 | /// How many fixpoint iterations we should attempt inside of the solver before bailing |
| 35 | 35 | /// with overflow. |
| 36 | 36 | /// |
| 37 | /// We previously used `tcx.recursion_limit().0.checked_ilog2().unwrap_or(0)` for this. | |
| 37 | /// We previously used `cx.recursion_limit().0.checked_ilog2().unwrap_or(0)` for this. | |
| 38 | 38 | /// However, it feels unlikely that uncreasing the recursion limit by a power of two |
| 39 | 39 | /// to get one more itereation is every useful or desirable. We now instead used a constant |
| 40 | 40 | /// here. If there ever ends up some use-cases where a bigger number of fixpoint iterations |
| ... | ... | @@ -285,7 +285,7 @@ where |
| 285 | 285 | } |
| 286 | 286 | |
| 287 | 287 | fn response_no_constraints_raw<I: Interner>( |
| 288 | tcx: I, | |
| 288 | cx: I, | |
| 289 | 289 | max_universe: ty::UniverseIndex, |
| 290 | 290 | variables: I::CanonicalVars, |
| 291 | 291 | certainty: Certainty, |
| ... | ... | @@ -294,10 +294,10 @@ fn response_no_constraints_raw<I: Interner>( |
| 294 | 294 | max_universe, |
| 295 | 295 | variables, |
| 296 | 296 | value: Response { |
| 297 | var_values: ty::CanonicalVarValues::make_identity(tcx, variables), | |
| 298 | // FIXME: maybe we should store the "no response" version in tcx, like | |
| 299 | // we do for tcx.types and stuff. | |
| 300 | external_constraints: tcx.mk_external_constraints(ExternalConstraintsData::default()), | |
| 297 | var_values: ty::CanonicalVarValues::make_identity(cx, variables), | |
| 298 | // FIXME: maybe we should store the "no response" version in cx, like | |
| 299 | // we do for cx.types and stuff. | |
| 300 | external_constraints: cx.mk_external_constraints(ExternalConstraintsData::default()), | |
| 301 | 301 | certainty, |
| 302 | 302 | }, |
| 303 | 303 | defining_opaque_types: Default::default(), |
compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs+9-9| ... | ... | @@ -19,21 +19,21 @@ where |
| 19 | 19 | &mut self, |
| 20 | 20 | goal: Goal<I, ty::NormalizesTo<I>>, |
| 21 | 21 | ) -> QueryResult<I> { |
| 22 | let tcx = self.cx(); | |
| 23 | let inherent = goal.predicate.alias.expect_ty(tcx); | |
| 22 | let cx = self.cx(); | |
| 23 | let inherent = goal.predicate.alias.expect_ty(cx); | |
| 24 | 24 | |
| 25 | let impl_def_id = tcx.parent(inherent.def_id); | |
| 25 | let impl_def_id = cx.parent(inherent.def_id); | |
| 26 | 26 | let impl_args = self.fresh_args_for_item(impl_def_id); |
| 27 | 27 | |
| 28 | 28 | // Equate impl header and add impl where clauses |
| 29 | 29 | self.eq( |
| 30 | 30 | goal.param_env, |
| 31 | 31 | inherent.self_ty(), |
| 32 | tcx.type_of(impl_def_id).instantiate(tcx, impl_args), | |
| 32 | cx.type_of(impl_def_id).instantiate(cx, impl_args), | |
| 33 | 33 | )?; |
| 34 | 34 | |
| 35 | 35 | // Equate IAT with the RHS of the project goal |
| 36 | let inherent_args = inherent.rebase_inherent_args_onto_impl(impl_args, tcx); | |
| 36 | let inherent_args = inherent.rebase_inherent_args_onto_impl(impl_args, cx); | |
| 37 | 37 | |
| 38 | 38 | // Check both where clauses on the impl and IAT |
| 39 | 39 | // |
| ... | ... | @@ -43,12 +43,12 @@ where |
| 43 | 43 | // and I don't think the assoc item where-bounds are allowed to be coinductive. |
| 44 | 44 | self.add_goals( |
| 45 | 45 | GoalSource::Misc, |
| 46 | tcx.predicates_of(inherent.def_id) | |
| 47 | .iter_instantiated(tcx, inherent_args) | |
| 48 | .map(|pred| goal.with(tcx, pred)), | |
| 46 | cx.predicates_of(inherent.def_id) | |
| 47 | .iter_instantiated(cx, inherent_args) | |
| 48 | .map(|pred| goal.with(cx, pred)), | |
| 49 | 49 | ); |
| 50 | 50 | |
| 51 | let normalized = tcx.type_of(inherent.def_id).instantiate(tcx, inherent_args); | |
| 51 | let normalized = cx.type_of(inherent.def_id).instantiate(cx, inherent_args); | |
| 52 | 52 | self.instantiate_normalizes_to_term(goal, normalized.into()); |
| 53 | 53 | self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) |
| 54 | 54 | } |
compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs+97-102| ... | ... | @@ -84,16 +84,16 @@ where |
| 84 | 84 | self.self_ty() |
| 85 | 85 | } |
| 86 | 86 | |
| 87 | fn trait_ref(self, tcx: I) -> ty::TraitRef<I> { | |
| 88 | self.alias.trait_ref(tcx) | |
| 87 | fn trait_ref(self, cx: I) -> ty::TraitRef<I> { | |
| 88 | self.alias.trait_ref(cx) | |
| 89 | 89 | } |
| 90 | 90 | |
| 91 | fn with_self_ty(self, tcx: I, self_ty: I::Ty) -> Self { | |
| 92 | self.with_self_ty(tcx, self_ty) | |
| 91 | fn with_self_ty(self, cx: I, self_ty: I::Ty) -> Self { | |
| 92 | self.with_self_ty(cx, self_ty) | |
| 93 | 93 | } |
| 94 | 94 | |
| 95 | fn trait_def_id(self, tcx: I) -> I::DefId { | |
| 96 | self.trait_def_id(tcx) | |
| 95 | fn trait_def_id(self, cx: I) -> I::DefId { | |
| 96 | self.trait_def_id(cx) | |
| 97 | 97 | } |
| 98 | 98 | |
| 99 | 99 | fn probe_and_match_goal_against_assumption( |
| ... | ... | @@ -105,7 +105,7 @@ where |
| 105 | 105 | ) -> Result<Candidate<I>, NoSolution> { |
| 106 | 106 | if let Some(projection_pred) = assumption.as_projection_clause() { |
| 107 | 107 | if projection_pred.projection_def_id() == goal.predicate.def_id() { |
| 108 | let tcx = ecx.cx(); | |
| 108 | let cx = ecx.cx(); | |
| 109 | 109 | ecx.probe_trait_candidate(source).enter(|ecx| { |
| 110 | 110 | let assumption_projection_pred = |
| 111 | 111 | ecx.instantiate_binder_with_infer(projection_pred); |
| ... | ... | @@ -120,9 +120,9 @@ where |
| 120 | 120 | // Add GAT where clauses from the trait's definition |
| 121 | 121 | ecx.add_goals( |
| 122 | 122 | GoalSource::Misc, |
| 123 | tcx.own_predicates_of(goal.predicate.def_id()) | |
| 124 | .iter_instantiated(tcx, goal.predicate.alias.args) | |
| 125 | .map(|pred| goal.with(tcx, pred)), | |
| 123 | cx.own_predicates_of(goal.predicate.def_id()) | |
| 124 | .iter_instantiated(cx, goal.predicate.alias.args) | |
| 125 | .map(|pred| goal.with(cx, pred)), | |
| 126 | 126 | ); |
| 127 | 127 | |
| 128 | 128 | then(ecx) |
| ... | ... | @@ -140,19 +140,19 @@ where |
| 140 | 140 | goal: Goal<I, NormalizesTo<I>>, |
| 141 | 141 | impl_def_id: I::DefId, |
| 142 | 142 | ) -> Result<Candidate<I>, NoSolution> { |
| 143 | let tcx = ecx.cx(); | |
| 143 | let cx = ecx.cx(); | |
| 144 | 144 | |
| 145 | let goal_trait_ref = goal.predicate.alias.trait_ref(tcx); | |
| 146 | let impl_trait_ref = tcx.impl_trait_ref(impl_def_id); | |
| 145 | let goal_trait_ref = goal.predicate.alias.trait_ref(cx); | |
| 146 | let impl_trait_ref = cx.impl_trait_ref(impl_def_id); | |
| 147 | 147 | if !ecx.cx().args_may_unify_deep( |
| 148 | goal.predicate.alias.trait_ref(tcx).args, | |
| 148 | goal.predicate.alias.trait_ref(cx).args, | |
| 149 | 149 | impl_trait_ref.skip_binder().args, |
| 150 | 150 | ) { |
| 151 | 151 | return Err(NoSolution); |
| 152 | 152 | } |
| 153 | 153 | |
| 154 | 154 | // We have to ignore negative impls when projecting. |
| 155 | let impl_polarity = tcx.impl_polarity(impl_def_id); | |
| 155 | let impl_polarity = cx.impl_polarity(impl_def_id); | |
| 156 | 156 | match impl_polarity { |
| 157 | 157 | ty::ImplPolarity::Negative => return Err(NoSolution), |
| 158 | 158 | ty::ImplPolarity::Reservation => { |
| ... | ... | @@ -163,22 +163,22 @@ where |
| 163 | 163 | |
| 164 | 164 | ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| { |
| 165 | 165 | let impl_args = ecx.fresh_args_for_item(impl_def_id); |
| 166 | let impl_trait_ref = impl_trait_ref.instantiate(tcx, impl_args); | |
| 166 | let impl_trait_ref = impl_trait_ref.instantiate(cx, impl_args); | |
| 167 | 167 | |
| 168 | 168 | ecx.eq(goal.param_env, goal_trait_ref, impl_trait_ref)?; |
| 169 | 169 | |
| 170 | let where_clause_bounds = tcx | |
| 170 | let where_clause_bounds = cx | |
| 171 | 171 | .predicates_of(impl_def_id) |
| 172 | .iter_instantiated(tcx, impl_args) | |
| 173 | .map(|pred| goal.with(tcx, pred)); | |
| 172 | .iter_instantiated(cx, impl_args) | |
| 173 | .map(|pred| goal.with(cx, pred)); | |
| 174 | 174 | ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds); |
| 175 | 175 | |
| 176 | 176 | // Add GAT where clauses from the trait's definition |
| 177 | 177 | ecx.add_goals( |
| 178 | 178 | GoalSource::Misc, |
| 179 | tcx.own_predicates_of(goal.predicate.def_id()) | |
| 180 | .iter_instantiated(tcx, goal.predicate.alias.args) | |
| 181 | .map(|pred| goal.with(tcx, pred)), | |
| 179 | cx.own_predicates_of(goal.predicate.def_id()) | |
| 180 | .iter_instantiated(cx, goal.predicate.alias.args) | |
| 181 | .map(|pred| goal.with(cx, pred)), | |
| 182 | 182 | ); |
| 183 | 183 | |
| 184 | 184 | // In case the associated item is hidden due to specialization, we have to |
| ... | ... | @@ -195,21 +195,21 @@ where |
| 195 | 195 | }; |
| 196 | 196 | |
| 197 | 197 | let error_response = |ecx: &mut EvalCtxt<'_, D>, msg: &str| { |
| 198 | let guar = tcx.delay_bug(msg); | |
| 199 | let error_term = match goal.predicate.alias.kind(tcx) { | |
| 200 | ty::AliasTermKind::ProjectionTy => Ty::new_error(tcx, guar).into(), | |
| 201 | ty::AliasTermKind::ProjectionConst => Const::new_error(tcx, guar).into(), | |
| 198 | let guar = cx.delay_bug(msg); | |
| 199 | let error_term = match goal.predicate.alias.kind(cx) { | |
| 200 | ty::AliasTermKind::ProjectionTy => Ty::new_error(cx, guar).into(), | |
| 201 | ty::AliasTermKind::ProjectionConst => Const::new_error(cx, guar).into(), | |
| 202 | 202 | kind => panic!("expected projection, found {kind:?}"), |
| 203 | 203 | }; |
| 204 | 204 | ecx.instantiate_normalizes_to_term(goal, error_term); |
| 205 | 205 | ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) |
| 206 | 206 | }; |
| 207 | 207 | |
| 208 | if !tcx.has_item_definition(target_item_def_id) { | |
| 208 | if !cx.has_item_definition(target_item_def_id) { | |
| 209 | 209 | return error_response(ecx, "missing item"); |
| 210 | 210 | } |
| 211 | 211 | |
| 212 | let target_container_def_id = tcx.parent(target_item_def_id); | |
| 212 | let target_container_def_id = cx.parent(target_item_def_id); | |
| 213 | 213 | |
| 214 | 214 | // Getting the right args here is complex, e.g. given: |
| 215 | 215 | // - a goal `<Vec<u32> as Trait<i32>>::Assoc<u64>` |
| ... | ... | @@ -229,22 +229,22 @@ where |
| 229 | 229 | target_container_def_id, |
| 230 | 230 | )?; |
| 231 | 231 | |
| 232 | if !tcx.check_args_compatible(target_item_def_id, target_args) { | |
| 232 | if !cx.check_args_compatible(target_item_def_id, target_args) { | |
| 233 | 233 | return error_response(ecx, "associated item has mismatched arguments"); |
| 234 | 234 | } |
| 235 | 235 | |
| 236 | 236 | // Finally we construct the actual value of the associated type. |
| 237 | let term = match goal.predicate.alias.kind(tcx) { | |
| 237 | let term = match goal.predicate.alias.kind(cx) { | |
| 238 | 238 | ty::AliasTermKind::ProjectionTy => { |
| 239 | tcx.type_of(target_item_def_id).map_bound(|ty| ty.into()) | |
| 239 | cx.type_of(target_item_def_id).map_bound(|ty| ty.into()) | |
| 240 | 240 | } |
| 241 | 241 | ty::AliasTermKind::ProjectionConst => { |
| 242 | if tcx.features().associated_const_equality() { | |
| 242 | if cx.features().associated_const_equality() { | |
| 243 | 243 | panic!("associated const projection is not supported yet") |
| 244 | 244 | } else { |
| 245 | 245 | ty::EarlyBinder::bind( |
| 246 | 246 | Const::new_error_with_message( |
| 247 | tcx, | |
| 247 | cx, | |
| 248 | 248 | "associated const projection is not supported yet", |
| 249 | 249 | ) |
| 250 | 250 | .into(), |
| ... | ... | @@ -254,7 +254,7 @@ where |
| 254 | 254 | kind => panic!("expected projection, found {kind:?}"), |
| 255 | 255 | }; |
| 256 | 256 | |
| 257 | ecx.instantiate_normalizes_to_term(goal, term.instantiate(tcx, target_args)); | |
| 257 | ecx.instantiate_normalizes_to_term(goal, term.instantiate(cx, target_args)); | |
| 258 | 258 | ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) |
| 259 | 259 | }) |
| 260 | 260 | } |
| ... | ... | @@ -316,10 +316,10 @@ where |
| 316 | 316 | goal: Goal<I, Self>, |
| 317 | 317 | goal_kind: ty::ClosureKind, |
| 318 | 318 | ) -> Result<Candidate<I>, NoSolution> { |
| 319 | let tcx = ecx.cx(); | |
| 319 | let cx = ecx.cx(); | |
| 320 | 320 | let tupled_inputs_and_output = |
| 321 | 321 | match structural_traits::extract_tupled_inputs_and_output_from_callable( |
| 322 | tcx, | |
| 322 | cx, | |
| 323 | 323 | goal.predicate.self_ty(), |
| 324 | 324 | goal_kind, |
| 325 | 325 | )? { |
| ... | ... | @@ -329,19 +329,19 @@ where |
| 329 | 329 | } |
| 330 | 330 | }; |
| 331 | 331 | let output_is_sized_pred = tupled_inputs_and_output.map_bound(|(_, output)| { |
| 332 | ty::TraitRef::new(tcx, tcx.require_lang_item(TraitSolverLangItem::Sized), [output]) | |
| 332 | ty::TraitRef::new(cx, cx.require_lang_item(TraitSolverLangItem::Sized), [output]) | |
| 333 | 333 | }); |
| 334 | 334 | |
| 335 | 335 | let pred = tupled_inputs_and_output |
| 336 | 336 | .map_bound(|(inputs, output)| ty::ProjectionPredicate { |
| 337 | 337 | projection_term: ty::AliasTerm::new( |
| 338 | tcx, | |
| 338 | cx, | |
| 339 | 339 | goal.predicate.def_id(), |
| 340 | 340 | [goal.predicate.self_ty(), inputs], |
| 341 | 341 | ), |
| 342 | 342 | term: output.into(), |
| 343 | 343 | }) |
| 344 | .upcast(tcx); | |
| 344 | .upcast(cx); | |
| 345 | 345 | |
| 346 | 346 | // A built-in `Fn` impl only holds if the output is sized. |
| 347 | 347 | // (FIXME: technically we only need to check this if the type is a fn ptr...) |
| ... | ... | @@ -350,7 +350,7 @@ where |
| 350 | 350 | CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), |
| 351 | 351 | goal, |
| 352 | 352 | pred, |
| 353 | [(GoalSource::ImplWhereBound, goal.with(tcx, output_is_sized_pred))], | |
| 353 | [(GoalSource::ImplWhereBound, goal.with(cx, output_is_sized_pred))], | |
| 354 | 354 | ) |
| 355 | 355 | } |
| 356 | 356 | |
| ... | ... | @@ -359,27 +359,23 @@ where |
| 359 | 359 | goal: Goal<I, Self>, |
| 360 | 360 | goal_kind: ty::ClosureKind, |
| 361 | 361 | ) -> Result<Candidate<I>, NoSolution> { |
| 362 | let tcx = ecx.cx(); | |
| 362 | let cx = ecx.cx(); | |
| 363 | 363 | |
| 364 | 364 | let env_region = match goal_kind { |
| 365 | 365 | ty::ClosureKind::Fn | ty::ClosureKind::FnMut => goal.predicate.alias.args.region_at(2), |
| 366 | 366 | // Doesn't matter what this region is |
| 367 | ty::ClosureKind::FnOnce => Region::new_static(tcx), | |
| 367 | ty::ClosureKind::FnOnce => Region::new_static(cx), | |
| 368 | 368 | }; |
| 369 | 369 | let (tupled_inputs_and_output_and_coroutine, nested_preds) = |
| 370 | 370 | structural_traits::extract_tupled_inputs_and_output_from_async_callable( |
| 371 | tcx, | |
| 371 | cx, | |
| 372 | 372 | goal.predicate.self_ty(), |
| 373 | 373 | goal_kind, |
| 374 | 374 | env_region, |
| 375 | 375 | )?; |
| 376 | 376 | let output_is_sized_pred = tupled_inputs_and_output_and_coroutine.map_bound( |
| 377 | 377 | |AsyncCallableRelevantTypes { output_coroutine_ty: output_ty, .. }| { |
| 378 | ty::TraitRef::new( | |
| 379 | tcx, | |
| 380 | tcx.require_lang_item(TraitSolverLangItem::Sized), | |
| 381 | [output_ty], | |
| 382 | ) | |
| 378 | ty::TraitRef::new(cx, cx.require_lang_item(TraitSolverLangItem::Sized), [output_ty]) | |
| 383 | 379 | }, |
| 384 | 380 | ); |
| 385 | 381 | |
| ... | ... | @@ -390,23 +386,23 @@ where |
| 390 | 386 | output_coroutine_ty, |
| 391 | 387 | coroutine_return_ty, |
| 392 | 388 | }| { |
| 393 | let (projection_term, term) = if tcx | |
| 389 | let (projection_term, term) = if cx | |
| 394 | 390 | .is_lang_item(goal.predicate.def_id(), TraitSolverLangItem::CallOnceFuture) |
| 395 | 391 | { |
| 396 | 392 | ( |
| 397 | 393 | ty::AliasTerm::new( |
| 398 | tcx, | |
| 394 | cx, | |
| 399 | 395 | goal.predicate.def_id(), |
| 400 | 396 | [goal.predicate.self_ty(), tupled_inputs_ty], |
| 401 | 397 | ), |
| 402 | 398 | output_coroutine_ty.into(), |
| 403 | 399 | ) |
| 404 | } else if tcx | |
| 400 | } else if cx | |
| 405 | 401 | .is_lang_item(goal.predicate.def_id(), TraitSolverLangItem::CallRefFuture) |
| 406 | 402 | { |
| 407 | 403 | ( |
| 408 | 404 | ty::AliasTerm::new( |
| 409 | tcx, | |
| 405 | cx, | |
| 410 | 406 | goal.predicate.def_id(), |
| 411 | 407 | [ |
| 412 | 408 | I::GenericArg::from(goal.predicate.self_ty()), |
| ... | ... | @@ -416,13 +412,13 @@ where |
| 416 | 412 | ), |
| 417 | 413 | output_coroutine_ty.into(), |
| 418 | 414 | ) |
| 419 | } else if tcx.is_lang_item( | |
| 415 | } else if cx.is_lang_item( | |
| 420 | 416 | goal.predicate.def_id(), |
| 421 | 417 | TraitSolverLangItem::AsyncFnOnceOutput, |
| 422 | 418 | ) { |
| 423 | 419 | ( |
| 424 | 420 | ty::AliasTerm::new( |
| 425 | tcx, | |
| 421 | cx, | |
| 426 | 422 | goal.predicate.def_id(), |
| 427 | 423 | [ |
| 428 | 424 | I::GenericArg::from(goal.predicate.self_ty()), |
| ... | ... | @@ -440,7 +436,7 @@ where |
| 440 | 436 | ty::ProjectionPredicate { projection_term, term } |
| 441 | 437 | }, |
| 442 | 438 | ) |
| 443 | .upcast(tcx); | |
| 439 | .upcast(cx); | |
| 444 | 440 | |
| 445 | 441 | // A built-in `AsyncFn` impl only holds if the output is sized. |
| 446 | 442 | // (FIXME: technically we only need to check this if the type is a fn ptr...) |
| ... | ... | @@ -449,9 +445,9 @@ where |
| 449 | 445 | CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), |
| 450 | 446 | goal, |
| 451 | 447 | pred, |
| 452 | [goal.with(tcx, output_is_sized_pred)] | |
| 448 | [goal.with(cx, output_is_sized_pred)] | |
| 453 | 449 | .into_iter() |
| 454 | .chain(nested_preds.into_iter().map(|pred| goal.with(tcx, pred))) | |
| 450 | .chain(nested_preds.into_iter().map(|pred| goal.with(cx, pred))) | |
| 455 | 451 | .map(|goal| (GoalSource::ImplWhereBound, goal)), |
| 456 | 452 | ) |
| 457 | 453 | } |
| ... | ... | @@ -514,8 +510,8 @@ where |
| 514 | 510 | ecx: &mut EvalCtxt<'_, D>, |
| 515 | 511 | goal: Goal<I, Self>, |
| 516 | 512 | ) -> Result<Candidate<I>, NoSolution> { |
| 517 | let tcx = ecx.cx(); | |
| 518 | let metadata_def_id = tcx.require_lang_item(TraitSolverLangItem::Metadata); | |
| 513 | let cx = ecx.cx(); | |
| 514 | let metadata_def_id = cx.require_lang_item(TraitSolverLangItem::Metadata); | |
| 519 | 515 | assert_eq!(metadata_def_id, goal.predicate.def_id()); |
| 520 | 516 | ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { |
| 521 | 517 | let metadata_ty = match goal.predicate.self_ty().kind() { |
| ... | ... | @@ -537,16 +533,16 @@ where |
| 537 | 533 | | ty::CoroutineWitness(..) |
| 538 | 534 | | ty::Never |
| 539 | 535 | | ty::Foreign(..) |
| 540 | | ty::Dynamic(_, _, ty::DynStar) => Ty::new_unit(tcx), | |
| 536 | | ty::Dynamic(_, _, ty::DynStar) => Ty::new_unit(cx), | |
| 541 | 537 | |
| 542 | ty::Error(e) => Ty::new_error(tcx, e), | |
| 538 | ty::Error(e) => Ty::new_error(cx, e), | |
| 543 | 539 | |
| 544 | ty::Str | ty::Slice(_) => Ty::new_usize(tcx), | |
| 540 | ty::Str | ty::Slice(_) => Ty::new_usize(cx), | |
| 545 | 541 | |
| 546 | 542 | ty::Dynamic(_, _, ty::Dyn) => { |
| 547 | let dyn_metadata = tcx.require_lang_item(TraitSolverLangItem::DynMetadata); | |
| 548 | tcx.type_of(dyn_metadata) | |
| 549 | .instantiate(tcx, &[I::GenericArg::from(goal.predicate.self_ty())]) | |
| 543 | let dyn_metadata = cx.require_lang_item(TraitSolverLangItem::DynMetadata); | |
| 544 | cx.type_of(dyn_metadata) | |
| 545 | .instantiate(cx, &[I::GenericArg::from(goal.predicate.self_ty())]) | |
| 550 | 546 | } |
| 551 | 547 | |
| 552 | 548 | ty::Alias(_, _) | ty::Param(_) | ty::Placeholder(..) => { |
| ... | ... | @@ -555,26 +551,26 @@ where |
| 555 | 551 | // FIXME(ptr_metadata): This impl overlaps with the other impls and shouldn't |
| 556 | 552 | // exist. Instead, `Pointee<Metadata = ()>` should be a supertrait of `Sized`. |
| 557 | 553 | let sized_predicate = ty::TraitRef::new( |
| 558 | tcx, | |
| 559 | tcx.require_lang_item(TraitSolverLangItem::Sized), | |
| 554 | cx, | |
| 555 | cx.require_lang_item(TraitSolverLangItem::Sized), | |
| 560 | 556 | [I::GenericArg::from(goal.predicate.self_ty())], |
| 561 | 557 | ); |
| 562 | 558 | // FIXME(-Znext-solver=coinductive): Should this be `GoalSource::ImplWhereBound`? |
| 563 | ecx.add_goal(GoalSource::Misc, goal.with(tcx, sized_predicate)); | |
| 564 | Ty::new_unit(tcx) | |
| 559 | ecx.add_goal(GoalSource::Misc, goal.with(cx, sized_predicate)); | |
| 560 | Ty::new_unit(cx) | |
| 565 | 561 | } |
| 566 | 562 | |
| 567 | ty::Adt(def, args) if def.is_struct() => match def.struct_tail_ty(tcx) { | |
| 568 | None => Ty::new_unit(tcx), | |
| 563 | ty::Adt(def, args) if def.is_struct() => match def.struct_tail_ty(cx) { | |
| 564 | None => Ty::new_unit(cx), | |
| 569 | 565 | Some(tail_ty) => { |
| 570 | Ty::new_projection(tcx, metadata_def_id, [tail_ty.instantiate(tcx, args)]) | |
| 566 | Ty::new_projection(cx, metadata_def_id, [tail_ty.instantiate(cx, args)]) | |
| 571 | 567 | } |
| 572 | 568 | }, |
| 573 | ty::Adt(_, _) => Ty::new_unit(tcx), | |
| 569 | ty::Adt(_, _) => Ty::new_unit(cx), | |
| 574 | 570 | |
| 575 | 571 | ty::Tuple(elements) => match elements.last() { |
| 576 | None => Ty::new_unit(tcx), | |
| 577 | Some(tail_ty) => Ty::new_projection(tcx, metadata_def_id, [tail_ty]), | |
| 572 | None => Ty::new_unit(cx), | |
| 573 | Some(tail_ty) => Ty::new_projection(cx, metadata_def_id, [tail_ty]), | |
| 578 | 574 | }, |
| 579 | 575 | |
| 580 | 576 | ty::Infer( |
| ... | ... | @@ -601,8 +597,8 @@ where |
| 601 | 597 | }; |
| 602 | 598 | |
| 603 | 599 | // Coroutines are not futures unless they come from `async` desugaring |
| 604 | let tcx = ecx.cx(); | |
| 605 | if !tcx.coroutine_is_async(def_id) { | |
| 600 | let cx = ecx.cx(); | |
| 601 | if !cx.coroutine_is_async(def_id) { | |
| 606 | 602 | return Err(NoSolution); |
| 607 | 603 | } |
| 608 | 604 | |
| ... | ... | @@ -616,7 +612,7 @@ where |
| 616 | 612 | projection_term: ty::AliasTerm::new(ecx.cx(), goal.predicate.def_id(), [self_ty]), |
| 617 | 613 | term, |
| 618 | 614 | } |
| 619 | .upcast(tcx), | |
| 615 | .upcast(cx), | |
| 620 | 616 | // Technically, we need to check that the future type is Sized, |
| 621 | 617 | // but that's already proven by the coroutine being WF. |
| 622 | 618 | [], |
| ... | ... | @@ -633,8 +629,8 @@ where |
| 633 | 629 | }; |
| 634 | 630 | |
| 635 | 631 | // Coroutines are not Iterators unless they come from `gen` desugaring |
| 636 | let tcx = ecx.cx(); | |
| 637 | if !tcx.coroutine_is_gen(def_id) { | |
| 632 | let cx = ecx.cx(); | |
| 633 | if !cx.coroutine_is_gen(def_id) { | |
| 638 | 634 | return Err(NoSolution); |
| 639 | 635 | } |
| 640 | 636 | |
| ... | ... | @@ -648,7 +644,7 @@ where |
| 648 | 644 | projection_term: ty::AliasTerm::new(ecx.cx(), goal.predicate.def_id(), [self_ty]), |
| 649 | 645 | term, |
| 650 | 646 | } |
| 651 | .upcast(tcx), | |
| 647 | .upcast(cx), | |
| 652 | 648 | // Technically, we need to check that the iterator type is Sized, |
| 653 | 649 | // but that's already proven by the generator being WF. |
| 654 | 650 | [], |
| ... | ... | @@ -672,8 +668,8 @@ where |
| 672 | 668 | }; |
| 673 | 669 | |
| 674 | 670 | // Coroutines are not AsyncIterators unless they come from `gen` desugaring |
| 675 | let tcx = ecx.cx(); | |
| 676 | if !tcx.coroutine_is_async_gen(def_id) { | |
| 671 | let cx = ecx.cx(); | |
| 672 | if !cx.coroutine_is_async_gen(def_id) { | |
| 677 | 673 | return Err(NoSolution); |
| 678 | 674 | } |
| 679 | 675 | |
| ... | ... | @@ -682,12 +678,12 @@ where |
| 682 | 678 | // Take `AsyncIterator<Item = I>` and turn it into the corresponding |
| 683 | 679 | // coroutine yield ty `Poll<Option<I>>`. |
| 684 | 680 | let wrapped_expected_ty = Ty::new_adt( |
| 685 | tcx, | |
| 686 | tcx.adt_def(tcx.require_lang_item(TraitSolverLangItem::Poll)), | |
| 687 | tcx.mk_args(&[Ty::new_adt( | |
| 688 | tcx, | |
| 689 | tcx.adt_def(tcx.require_lang_item(TraitSolverLangItem::Option)), | |
| 690 | tcx.mk_args(&[expected_ty.into()]), | |
| 681 | cx, | |
| 682 | cx.adt_def(cx.require_lang_item(TraitSolverLangItem::Poll)), | |
| 683 | cx.mk_args(&[Ty::new_adt( | |
| 684 | cx, | |
| 685 | cx.adt_def(cx.require_lang_item(TraitSolverLangItem::Option)), | |
| 686 | cx.mk_args(&[expected_ty.into()]), | |
| 691 | 687 | ) |
| 692 | 688 | .into()]), |
| 693 | 689 | ); |
| ... | ... | @@ -708,18 +704,17 @@ where |
| 708 | 704 | }; |
| 709 | 705 | |
| 710 | 706 | // `async`-desugared coroutines do not implement the coroutine trait |
| 711 | let tcx = ecx.cx(); | |
| 712 | if !tcx.is_general_coroutine(def_id) { | |
| 707 | let cx = ecx.cx(); | |
| 708 | if !cx.is_general_coroutine(def_id) { | |
| 713 | 709 | return Err(NoSolution); |
| 714 | 710 | } |
| 715 | 711 | |
| 716 | 712 | let coroutine = args.as_coroutine(); |
| 717 | 713 | |
| 718 | let term = if tcx | |
| 719 | .is_lang_item(goal.predicate.def_id(), TraitSolverLangItem::CoroutineReturn) | |
| 714 | let term = if cx.is_lang_item(goal.predicate.def_id(), TraitSolverLangItem::CoroutineReturn) | |
| 720 | 715 | { |
| 721 | 716 | coroutine.return_ty().into() |
| 722 | } else if tcx.is_lang_item(goal.predicate.def_id(), TraitSolverLangItem::CoroutineYield) { | |
| 717 | } else if cx.is_lang_item(goal.predicate.def_id(), TraitSolverLangItem::CoroutineYield) { | |
| 723 | 718 | coroutine.yield_ty().into() |
| 724 | 719 | } else { |
| 725 | 720 | panic!("unexpected associated item `{:?}` for `{self_ty:?}`", goal.predicate.def_id()) |
| ... | ... | @@ -737,7 +732,7 @@ where |
| 737 | 732 | ), |
| 738 | 733 | term, |
| 739 | 734 | } |
| 740 | .upcast(tcx), | |
| 735 | .upcast(cx), | |
| 741 | 736 | // Technically, we need to check that the coroutine type is Sized, |
| 742 | 737 | // but that's already proven by the coroutine being WF. |
| 743 | 738 | [], |
| ... | ... | @@ -884,29 +879,29 @@ where |
| 884 | 879 | impl_trait_ref: rustc_type_ir::TraitRef<I>, |
| 885 | 880 | target_container_def_id: I::DefId, |
| 886 | 881 | ) -> Result<I::GenericArgs, NoSolution> { |
| 887 | let tcx = self.cx(); | |
| 882 | let cx = self.cx(); | |
| 888 | 883 | Ok(if target_container_def_id == impl_trait_ref.def_id { |
| 889 | 884 | // Default value from the trait definition. No need to rebase. |
| 890 | 885 | goal.predicate.alias.args |
| 891 | 886 | } else if target_container_def_id == impl_def_id { |
| 892 | 887 | // Same impl, no need to fully translate, just a rebase from |
| 893 | 888 | // the trait is sufficient. |
| 894 | goal.predicate.alias.args.rebase_onto(tcx, impl_trait_ref.def_id, impl_args) | |
| 889 | goal.predicate.alias.args.rebase_onto(cx, impl_trait_ref.def_id, impl_args) | |
| 895 | 890 | } else { |
| 896 | 891 | let target_args = self.fresh_args_for_item(target_container_def_id); |
| 897 | 892 | let target_trait_ref = |
| 898 | tcx.impl_trait_ref(target_container_def_id).instantiate(tcx, target_args); | |
| 893 | cx.impl_trait_ref(target_container_def_id).instantiate(cx, target_args); | |
| 899 | 894 | // Relate source impl to target impl by equating trait refs. |
| 900 | 895 | self.eq(goal.param_env, impl_trait_ref, target_trait_ref)?; |
| 901 | 896 | // Also add predicates since they may be needed to constrain the |
| 902 | 897 | // target impl's params. |
| 903 | 898 | self.add_goals( |
| 904 | 899 | GoalSource::Misc, |
| 905 | tcx.predicates_of(target_container_def_id) | |
| 906 | .iter_instantiated(tcx, target_args) | |
| 907 | .map(|pred| goal.with(tcx, pred)), | |
| 900 | cx.predicates_of(target_container_def_id) | |
| 901 | .iter_instantiated(cx, target_args) | |
| 902 | .map(|pred| goal.with(cx, pred)), | |
| 908 | 903 | ); |
| 909 | goal.predicate.alias.args.rebase_onto(tcx, impl_trait_ref.def_id, target_args) | |
| 904 | goal.predicate.alias.args.rebase_onto(cx, impl_trait_ref.def_id, target_args) | |
| 910 | 905 | }) |
| 911 | 906 | } |
| 912 | 907 | } |
compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs+3-3| ... | ... | @@ -18,7 +18,7 @@ where |
| 18 | 18 | &mut self, |
| 19 | 19 | goal: Goal<I, ty::NormalizesTo<I>>, |
| 20 | 20 | ) -> QueryResult<I> { |
| 21 | let tcx = self.cx(); | |
| 21 | let cx = self.cx(); | |
| 22 | 22 | let opaque_ty = goal.predicate.alias; |
| 23 | 23 | let expected = goal.predicate.term.as_type().expect("no such thing as an opaque const"); |
| 24 | 24 | |
| ... | ... | @@ -86,7 +86,7 @@ where |
| 86 | 86 | } |
| 87 | 87 | (Reveal::All, _) => { |
| 88 | 88 | // FIXME: Add an assertion that opaque type storage is empty. |
| 89 | let actual = tcx.type_of(opaque_ty.def_id).instantiate(tcx, opaque_ty.args); | |
| 89 | let actual = cx.type_of(opaque_ty.def_id).instantiate(cx, opaque_ty.args); | |
| 90 | 90 | self.eq(goal.param_env, expected, actual)?; |
| 91 | 91 | self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) |
| 92 | 92 | } |
| ... | ... | @@ -98,7 +98,7 @@ where |
| 98 | 98 | /// |
| 99 | 99 | /// FIXME: Interner argument is needed to constrain the `I` parameter. |
| 100 | 100 | pub fn uses_unique_placeholders_ignoring_regions<I: Interner>( |
| 101 | _interner: I, | |
| 101 | _cx: I, | |
| 102 | 102 | args: I::GenericArgs, |
| 103 | 103 | ) -> Result<(), NotUniqueParam<I>> { |
| 104 | 104 | let mut seen = GrowableBitSet::default(); |
compiler/rustc_next_trait_solver/src/solve/normalizes_to/weak_types.rs+5-5| ... | ... | @@ -18,18 +18,18 @@ where |
| 18 | 18 | &mut self, |
| 19 | 19 | goal: Goal<I, ty::NormalizesTo<I>>, |
| 20 | 20 | ) -> QueryResult<I> { |
| 21 | let tcx = self.cx(); | |
| 21 | let cx = self.cx(); | |
| 22 | 22 | let weak_ty = goal.predicate.alias; |
| 23 | 23 | |
| 24 | 24 | // Check where clauses |
| 25 | 25 | self.add_goals( |
| 26 | 26 | GoalSource::Misc, |
| 27 | tcx.predicates_of(weak_ty.def_id) | |
| 28 | .iter_instantiated(tcx, weak_ty.args) | |
| 29 | .map(|pred| goal.with(tcx, pred)), | |
| 27 | cx.predicates_of(weak_ty.def_id) | |
| 28 | .iter_instantiated(cx, weak_ty.args) | |
| 29 | .map(|pred| goal.with(cx, pred)), | |
| 30 | 30 | ); |
| 31 | 31 | |
| 32 | let actual = tcx.type_of(weak_ty.def_id).instantiate(tcx, weak_ty.args); | |
| 32 | let actual = cx.type_of(weak_ty.def_id).instantiate(cx, weak_ty.args); | |
| 33 | 33 | self.instantiate_normalizes_to_term(goal, actual.into()); |
| 34 | 34 | |
| 35 | 35 | self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) |
compiler/rustc_next_trait_solver/src/solve/project_goals.rs+3-3| ... | ... | @@ -14,10 +14,10 @@ where |
| 14 | 14 | &mut self, |
| 15 | 15 | goal: Goal<I, ProjectionPredicate<I>>, |
| 16 | 16 | ) -> QueryResult<I> { |
| 17 | let tcx = self.cx(); | |
| 18 | let projection_term = goal.predicate.projection_term.to_term(tcx); | |
| 17 | let cx = self.cx(); | |
| 18 | let projection_term = goal.predicate.projection_term.to_term(cx); | |
| 19 | 19 | let goal = goal.with( |
| 20 | tcx, | |
| 20 | cx, | |
| 21 | 21 | ty::PredicateKind::AliasRelate( |
| 22 | 22 | projection_term, |
| 23 | 23 | goal.predicate.term, |
compiler/rustc_next_trait_solver/src/solve/search_graph.rs+30-30| ... | ... | @@ -164,7 +164,7 @@ impl<I: Interner> SearchGraph<I> { |
| 164 | 164 | /// the remaining depth of all nested goals to prevent hangs |
| 165 | 165 | /// in case there is exponential blowup. |
| 166 | 166 | fn allowed_depth_for_nested( |
| 167 | tcx: I, | |
| 167 | cx: I, | |
| 168 | 168 | stack: &IndexVec<StackDepth, StackEntry<I>>, |
| 169 | 169 | ) -> Option<SolverLimit> { |
| 170 | 170 | if let Some(last) = stack.raw.last() { |
| ... | ... | @@ -178,18 +178,18 @@ impl<I: Interner> SearchGraph<I> { |
| 178 | 178 | SolverLimit(last.available_depth.0 - 1) |
| 179 | 179 | }) |
| 180 | 180 | } else { |
| 181 | Some(SolverLimit(tcx.recursion_limit())) | |
| 181 | Some(SolverLimit(cx.recursion_limit())) | |
| 182 | 182 | } |
| 183 | 183 | } |
| 184 | 184 | |
| 185 | 185 | fn stack_coinductive_from( |
| 186 | tcx: I, | |
| 186 | cx: I, | |
| 187 | 187 | stack: &IndexVec<StackDepth, StackEntry<I>>, |
| 188 | 188 | head: StackDepth, |
| 189 | 189 | ) -> bool { |
| 190 | 190 | stack.raw[head.index()..] |
| 191 | 191 | .iter() |
| 192 | .all(|entry| entry.input.value.goal.predicate.is_coinductive(tcx)) | |
| 192 | .all(|entry| entry.input.value.goal.predicate.is_coinductive(cx)) | |
| 193 | 193 | } |
| 194 | 194 | |
| 195 | 195 | // When encountering a solver cycle, the result of the current goal |
| ... | ... | @@ -247,8 +247,8 @@ impl<I: Interner> SearchGraph<I> { |
| 247 | 247 | /// so we use a separate cache. Alternatively we could use |
| 248 | 248 | /// a single cache and share it between coherence and ordinary |
| 249 | 249 | /// trait solving. |
| 250 | pub(super) fn global_cache(&self, tcx: I) -> I::EvaluationCache { | |
| 251 | tcx.evaluation_cache(self.mode) | |
| 250 | pub(super) fn global_cache(&self, cx: I) -> I::EvaluationCache { | |
| 251 | cx.evaluation_cache(self.mode) | |
| 252 | 252 | } |
| 253 | 253 | |
| 254 | 254 | /// Probably the most involved method of the whole solver. |
| ... | ... | @@ -257,24 +257,24 @@ impl<I: Interner> SearchGraph<I> { |
| 257 | 257 | /// handles caching, overflow, and coinductive cycles. |
| 258 | 258 | pub(super) fn with_new_goal<D: SolverDelegate<Interner = I>>( |
| 259 | 259 | &mut self, |
| 260 | tcx: I, | |
| 260 | cx: I, | |
| 261 | 261 | input: CanonicalInput<I>, |
| 262 | 262 | inspect: &mut ProofTreeBuilder<D>, |
| 263 | 263 | mut prove_goal: impl FnMut(&mut Self, &mut ProofTreeBuilder<D>) -> QueryResult<I>, |
| 264 | 264 | ) -> QueryResult<I> { |
| 265 | 265 | self.check_invariants(); |
| 266 | 266 | // Check for overflow. |
| 267 | let Some(available_depth) = Self::allowed_depth_for_nested(tcx, &self.stack) else { | |
| 267 | let Some(available_depth) = Self::allowed_depth_for_nested(cx, &self.stack) else { | |
| 268 | 268 | if let Some(last) = self.stack.raw.last_mut() { |
| 269 | 269 | last.encountered_overflow = true; |
| 270 | 270 | } |
| 271 | 271 | |
| 272 | 272 | inspect |
| 273 | 273 | .canonical_goal_evaluation_kind(inspect::WipCanonicalGoalEvaluationKind::Overflow); |
| 274 | return Self::response_no_constraints(tcx, input, Certainty::overflow(true)); | |
| 274 | return Self::response_no_constraints(cx, input, Certainty::overflow(true)); | |
| 275 | 275 | }; |
| 276 | 276 | |
| 277 | if let Some(result) = self.lookup_global_cache(tcx, input, available_depth, inspect) { | |
| 277 | if let Some(result) = self.lookup_global_cache(cx, input, available_depth, inspect) { | |
| 278 | 278 | debug!("global cache hit"); |
| 279 | 279 | return result; |
| 280 | 280 | } |
| ... | ... | @@ -287,12 +287,12 @@ impl<I: Interner> SearchGraph<I> { |
| 287 | 287 | if let Some(entry) = cache_entry |
| 288 | 288 | .with_coinductive_stack |
| 289 | 289 | .as_ref() |
| 290 | .filter(|p| Self::stack_coinductive_from(tcx, &self.stack, p.head)) | |
| 290 | .filter(|p| Self::stack_coinductive_from(cx, &self.stack, p.head)) | |
| 291 | 291 | .or_else(|| { |
| 292 | 292 | cache_entry |
| 293 | 293 | .with_inductive_stack |
| 294 | 294 | .as_ref() |
| 295 | .filter(|p| !Self::stack_coinductive_from(tcx, &self.stack, p.head)) | |
| 295 | .filter(|p| !Self::stack_coinductive_from(cx, &self.stack, p.head)) | |
| 296 | 296 | }) |
| 297 | 297 | { |
| 298 | 298 | debug!("provisional cache hit"); |
| ... | ... | @@ -315,7 +315,7 @@ impl<I: Interner> SearchGraph<I> { |
| 315 | 315 | inspect.canonical_goal_evaluation_kind( |
| 316 | 316 | inspect::WipCanonicalGoalEvaluationKind::CycleInStack, |
| 317 | 317 | ); |
| 318 | let is_coinductive_cycle = Self::stack_coinductive_from(tcx, &self.stack, stack_depth); | |
| 318 | let is_coinductive_cycle = Self::stack_coinductive_from(cx, &self.stack, stack_depth); | |
| 319 | 319 | let usage_kind = if is_coinductive_cycle { |
| 320 | 320 | HasBeenUsed::COINDUCTIVE_CYCLE |
| 321 | 321 | } else { |
| ... | ... | @@ -328,9 +328,9 @@ impl<I: Interner> SearchGraph<I> { |
| 328 | 328 | return if let Some(result) = self.stack[stack_depth].provisional_result { |
| 329 | 329 | result |
| 330 | 330 | } else if is_coinductive_cycle { |
| 331 | Self::response_no_constraints(tcx, input, Certainty::Yes) | |
| 331 | Self::response_no_constraints(cx, input, Certainty::Yes) | |
| 332 | 332 | } else { |
| 333 | Self::response_no_constraints(tcx, input, Certainty::overflow(false)) | |
| 333 | Self::response_no_constraints(cx, input, Certainty::overflow(false)) | |
| 334 | 334 | }; |
| 335 | 335 | } else { |
| 336 | 336 | // No entry, we push this goal on the stack and try to prove it. |
| ... | ... | @@ -355,9 +355,9 @@ impl<I: Interner> SearchGraph<I> { |
| 355 | 355 | // not tracked by the cache key and from outside of this anon task, it |
| 356 | 356 | // must not be added to the global cache. Notably, this is the case for |
| 357 | 357 | // trait solver cycles participants. |
| 358 | let ((final_entry, result), dep_node) = tcx.with_cached_task(|| { | |
| 358 | let ((final_entry, result), dep_node) = cx.with_cached_task(|| { | |
| 359 | 359 | for _ in 0..FIXPOINT_STEP_LIMIT { |
| 360 | match self.fixpoint_step_in_task(tcx, input, inspect, &mut prove_goal) { | |
| 360 | match self.fixpoint_step_in_task(cx, input, inspect, &mut prove_goal) { | |
| 361 | 361 | StepResult::Done(final_entry, result) => return (final_entry, result), |
| 362 | 362 | StepResult::HasChanged => debug!("fixpoint changed provisional results"), |
| 363 | 363 | } |
| ... | ... | @@ -366,17 +366,17 @@ impl<I: Interner> SearchGraph<I> { |
| 366 | 366 | debug!("canonical cycle overflow"); |
| 367 | 367 | let current_entry = self.pop_stack(); |
| 368 | 368 | debug_assert!(current_entry.has_been_used.is_empty()); |
| 369 | let result = Self::response_no_constraints(tcx, input, Certainty::overflow(false)); | |
| 369 | let result = Self::response_no_constraints(cx, input, Certainty::overflow(false)); | |
| 370 | 370 | (current_entry, result) |
| 371 | 371 | }); |
| 372 | 372 | |
| 373 | let proof_tree = inspect.finalize_canonical_goal_evaluation(tcx); | |
| 373 | let proof_tree = inspect.finalize_canonical_goal_evaluation(cx); | |
| 374 | 374 | |
| 375 | 375 | // We're now done with this goal. In case this goal is involved in a larger cycle |
| 376 | 376 | // do not remove it from the provisional cache and update its provisional result. |
| 377 | 377 | // We only add the root of cycles to the global cache. |
| 378 | 378 | if let Some(head) = final_entry.non_root_cycle_participant { |
| 379 | let coinductive_stack = Self::stack_coinductive_from(tcx, &self.stack, head); | |
| 379 | let coinductive_stack = Self::stack_coinductive_from(cx, &self.stack, head); | |
| 380 | 380 | |
| 381 | 381 | let entry = self.provisional_cache.get_mut(&input).unwrap(); |
| 382 | 382 | entry.stack_depth = None; |
| ... | ... | @@ -396,8 +396,8 @@ impl<I: Interner> SearchGraph<I> { |
| 396 | 396 | // participant is on the stack. This is necessary to prevent unstable |
| 397 | 397 | // results. See the comment of `StackEntry::cycle_participants` for |
| 398 | 398 | // more details. |
| 399 | self.global_cache(tcx).insert( | |
| 400 | tcx, | |
| 399 | self.global_cache(cx).insert( | |
| 400 | cx, | |
| 401 | 401 | input, |
| 402 | 402 | proof_tree, |
| 403 | 403 | reached_depth, |
| ... | ... | @@ -418,15 +418,15 @@ impl<I: Interner> SearchGraph<I> { |
| 418 | 418 | /// this goal. |
| 419 | 419 | fn lookup_global_cache<D: SolverDelegate<Interner = I>>( |
| 420 | 420 | &mut self, |
| 421 | tcx: I, | |
| 421 | cx: I, | |
| 422 | 422 | input: CanonicalInput<I>, |
| 423 | 423 | available_depth: SolverLimit, |
| 424 | 424 | inspect: &mut ProofTreeBuilder<D>, |
| 425 | 425 | ) -> Option<QueryResult<I>> { |
| 426 | 426 | let CacheData { result, proof_tree, additional_depth, encountered_overflow } = self |
| 427 | .global_cache(tcx) | |
| 427 | .global_cache(cx) | |
| 428 | 428 | // FIXME: Awkward `Limit -> usize -> Limit`. |
| 429 | .get(tcx, input, self.stack.iter().map(|e| e.input), available_depth.0)?; | |
| 429 | .get(cx, input, self.stack.iter().map(|e| e.input), available_depth.0)?; | |
| 430 | 430 | |
| 431 | 431 | // If we're building a proof tree and the current cache entry does not |
| 432 | 432 | // contain a proof tree, we do not use the entry but instead recompute |
| ... | ... | @@ -467,7 +467,7 @@ impl<I: Interner> SearchGraph<I> { |
| 467 | 467 | /// point we are done. |
| 468 | 468 | fn fixpoint_step_in_task<D, F>( |
| 469 | 469 | &mut self, |
| 470 | tcx: I, | |
| 470 | cx: I, | |
| 471 | 471 | input: CanonicalInput<I>, |
| 472 | 472 | inspect: &mut ProofTreeBuilder<D>, |
| 473 | 473 | prove_goal: &mut F, |
| ... | ... | @@ -506,9 +506,9 @@ impl<I: Interner> SearchGraph<I> { |
| 506 | 506 | let reached_fixpoint = if let Some(r) = stack_entry.provisional_result { |
| 507 | 507 | r == result |
| 508 | 508 | } else if stack_entry.has_been_used == HasBeenUsed::COINDUCTIVE_CYCLE { |
| 509 | Self::response_no_constraints(tcx, input, Certainty::Yes) == result | |
| 509 | Self::response_no_constraints(cx, input, Certainty::Yes) == result | |
| 510 | 510 | } else if stack_entry.has_been_used == HasBeenUsed::INDUCTIVE_CYCLE { |
| 511 | Self::response_no_constraints(tcx, input, Certainty::overflow(false)) == result | |
| 511 | Self::response_no_constraints(cx, input, Certainty::overflow(false)) == result | |
| 512 | 512 | } else { |
| 513 | 513 | false |
| 514 | 514 | }; |
| ... | ... | @@ -528,11 +528,11 @@ impl<I: Interner> SearchGraph<I> { |
| 528 | 528 | } |
| 529 | 529 | |
| 530 | 530 | fn response_no_constraints( |
| 531 | tcx: I, | |
| 531 | cx: I, | |
| 532 | 532 | goal: CanonicalInput<I>, |
| 533 | 533 | certainty: Certainty, |
| 534 | 534 | ) -> QueryResult<I> { |
| 535 | Ok(super::response_no_constraints_raw(tcx, goal.max_universe, goal.variables, certainty)) | |
| 535 | Ok(super::response_no_constraints_raw(cx, goal.max_universe, goal.variables, certainty)) | |
| 536 | 536 | } |
| 537 | 537 | |
| 538 | 538 | #[allow(rustc::potential_query_instability)] |
compiler/rustc_next_trait_solver/src/solve/trait_goals.rs+67-73| ... | ... | @@ -30,8 +30,8 @@ where |
| 30 | 30 | self.trait_ref |
| 31 | 31 | } |
| 32 | 32 | |
| 33 | fn with_self_ty(self, tcx: I, self_ty: I::Ty) -> Self { | |
| 34 | self.with_self_ty(tcx, self_ty) | |
| 33 | fn with_self_ty(self, cx: I, self_ty: I::Ty) -> Self { | |
| 34 | self.with_self_ty(cx, self_ty) | |
| 35 | 35 | } |
| 36 | 36 | |
| 37 | 37 | fn trait_def_id(self, _: I) -> I::DefId { |
| ... | ... | @@ -43,18 +43,17 @@ where |
| 43 | 43 | goal: Goal<I, TraitPredicate<I>>, |
| 44 | 44 | impl_def_id: I::DefId, |
| 45 | 45 | ) -> Result<Candidate<I>, NoSolution> { |
| 46 | let tcx = ecx.cx(); | |
| 46 | let cx = ecx.cx(); | |
| 47 | 47 | |
| 48 | let impl_trait_ref = tcx.impl_trait_ref(impl_def_id); | |
| 49 | if !tcx | |
| 50 | .args_may_unify_deep(goal.predicate.trait_ref.args, impl_trait_ref.skip_binder().args) | |
| 48 | let impl_trait_ref = cx.impl_trait_ref(impl_def_id); | |
| 49 | if !cx.args_may_unify_deep(goal.predicate.trait_ref.args, impl_trait_ref.skip_binder().args) | |
| 51 | 50 | { |
| 52 | 51 | return Err(NoSolution); |
| 53 | 52 | } |
| 54 | 53 | |
| 55 | 54 | // An upper bound of the certainty of this goal, used to lower the certainty |
| 56 | 55 | // of reservation impl to ambiguous during coherence. |
| 57 | let impl_polarity = tcx.impl_polarity(impl_def_id); | |
| 56 | let impl_polarity = cx.impl_polarity(impl_def_id); | |
| 58 | 57 | let maximal_certainty = match (impl_polarity, goal.predicate.polarity) { |
| 59 | 58 | // In intercrate mode, this is ambiguous. But outside of intercrate, |
| 60 | 59 | // it's not a real impl. |
| ... | ... | @@ -77,13 +76,13 @@ where |
| 77 | 76 | ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| { |
| 78 | 77 | let impl_args = ecx.fresh_args_for_item(impl_def_id); |
| 79 | 78 | ecx.record_impl_args(impl_args); |
| 80 | let impl_trait_ref = impl_trait_ref.instantiate(tcx, impl_args); | |
| 79 | let impl_trait_ref = impl_trait_ref.instantiate(cx, impl_args); | |
| 81 | 80 | |
| 82 | 81 | ecx.eq(goal.param_env, goal.predicate.trait_ref, impl_trait_ref)?; |
| 83 | let where_clause_bounds = tcx | |
| 82 | let where_clause_bounds = cx | |
| 84 | 83 | .predicates_of(impl_def_id) |
| 85 | .iter_instantiated(tcx, impl_args) | |
| 86 | .map(|pred| goal.with(tcx, pred)); | |
| 84 | .iter_instantiated(cx, impl_args) | |
| 85 | .map(|pred| goal.with(cx, pred)); | |
| 87 | 86 | ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds); |
| 88 | 87 | |
| 89 | 88 | ecx.evaluate_added_goals_and_make_canonical_response(maximal_certainty) |
| ... | ... | @@ -181,13 +180,13 @@ where |
| 181 | 180 | return Err(NoSolution); |
| 182 | 181 | } |
| 183 | 182 | |
| 184 | let tcx = ecx.cx(); | |
| 183 | let cx = ecx.cx(); | |
| 185 | 184 | |
| 186 | 185 | ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { |
| 187 | let nested_obligations = tcx | |
| 186 | let nested_obligations = cx | |
| 188 | 187 | .predicates_of(goal.predicate.def_id()) |
| 189 | .iter_instantiated(tcx, goal.predicate.trait_ref.args) | |
| 190 | .map(|p| goal.with(tcx, p)); | |
| 188 | .iter_instantiated(cx, goal.predicate.trait_ref.args) | |
| 189 | .map(|p| goal.with(cx, p)); | |
| 191 | 190 | // FIXME(-Znext-solver=coinductive): Should this be `GoalSource::ImplWhereBound`? |
| 192 | 191 | ecx.add_goals(GoalSource::Misc, nested_obligations); |
| 193 | 192 | ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) |
| ... | ... | @@ -232,13 +231,13 @@ where |
| 232 | 231 | return Err(NoSolution); |
| 233 | 232 | } |
| 234 | 233 | |
| 235 | let tcx = ecx.cx(); | |
| 234 | let cx = ecx.cx(); | |
| 236 | 235 | // But if there are inference variables, we have to wait until it's resolved. |
| 237 | 236 | if (goal.param_env, goal.predicate.self_ty()).has_non_region_infer() { |
| 238 | 237 | return ecx.forced_ambiguity(MaybeCause::Ambiguity); |
| 239 | 238 | } |
| 240 | 239 | |
| 241 | if tcx.layout_is_pointer_like(goal.param_env, goal.predicate.self_ty()) { | |
| 240 | if cx.layout_is_pointer_like(goal.param_env, goal.predicate.self_ty()) { | |
| 242 | 241 | ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc) |
| 243 | 242 | .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)) |
| 244 | 243 | } else { |
| ... | ... | @@ -286,10 +285,10 @@ where |
| 286 | 285 | return Err(NoSolution); |
| 287 | 286 | } |
| 288 | 287 | |
| 289 | let tcx = ecx.cx(); | |
| 288 | let cx = ecx.cx(); | |
| 290 | 289 | let tupled_inputs_and_output = |
| 291 | 290 | match structural_traits::extract_tupled_inputs_and_output_from_callable( |
| 292 | tcx, | |
| 291 | cx, | |
| 293 | 292 | goal.predicate.self_ty(), |
| 294 | 293 | goal_kind, |
| 295 | 294 | )? { |
| ... | ... | @@ -299,14 +298,14 @@ where |
| 299 | 298 | } |
| 300 | 299 | }; |
| 301 | 300 | let output_is_sized_pred = tupled_inputs_and_output.map_bound(|(_, output)| { |
| 302 | ty::TraitRef::new(tcx, tcx.require_lang_item(TraitSolverLangItem::Sized), [output]) | |
| 301 | ty::TraitRef::new(cx, cx.require_lang_item(TraitSolverLangItem::Sized), [output]) | |
| 303 | 302 | }); |
| 304 | 303 | |
| 305 | 304 | let pred = tupled_inputs_and_output |
| 306 | 305 | .map_bound(|(inputs, _)| { |
| 307 | ty::TraitRef::new(tcx, goal.predicate.def_id(), [goal.predicate.self_ty(), inputs]) | |
| 306 | ty::TraitRef::new(cx, goal.predicate.def_id(), [goal.predicate.self_ty(), inputs]) | |
| 308 | 307 | }) |
| 309 | .upcast(tcx); | |
| 308 | .upcast(cx); | |
| 310 | 309 | // A built-in `Fn` impl only holds if the output is sized. |
| 311 | 310 | // (FIXME: technically we only need to check this if the type is a fn ptr...) |
| 312 | 311 | Self::probe_and_consider_implied_clause( |
| ... | ... | @@ -314,7 +313,7 @@ where |
| 314 | 313 | CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), |
| 315 | 314 | goal, |
| 316 | 315 | pred, |
| 317 | [(GoalSource::ImplWhereBound, goal.with(tcx, output_is_sized_pred))], | |
| 316 | [(GoalSource::ImplWhereBound, goal.with(cx, output_is_sized_pred))], | |
| 318 | 317 | ) |
| 319 | 318 | } |
| 320 | 319 | |
| ... | ... | @@ -327,20 +326,20 @@ where |
| 327 | 326 | return Err(NoSolution); |
| 328 | 327 | } |
| 329 | 328 | |
| 330 | let tcx = ecx.cx(); | |
| 329 | let cx = ecx.cx(); | |
| 331 | 330 | let (tupled_inputs_and_output_and_coroutine, nested_preds) = |
| 332 | 331 | structural_traits::extract_tupled_inputs_and_output_from_async_callable( |
| 333 | tcx, | |
| 332 | cx, | |
| 334 | 333 | goal.predicate.self_ty(), |
| 335 | 334 | goal_kind, |
| 336 | 335 | // This region doesn't matter because we're throwing away the coroutine type |
| 337 | Region::new_static(tcx), | |
| 336 | Region::new_static(cx), | |
| 338 | 337 | )?; |
| 339 | 338 | let output_is_sized_pred = tupled_inputs_and_output_and_coroutine.map_bound( |
| 340 | 339 | |AsyncCallableRelevantTypes { output_coroutine_ty, .. }| { |
| 341 | 340 | ty::TraitRef::new( |
| 342 | tcx, | |
| 343 | tcx.require_lang_item(TraitSolverLangItem::Sized), | |
| 341 | cx, | |
| 342 | cx.require_lang_item(TraitSolverLangItem::Sized), | |
| 344 | 343 | [output_coroutine_ty], |
| 345 | 344 | ) |
| 346 | 345 | }, |
| ... | ... | @@ -349,12 +348,12 @@ where |
| 349 | 348 | let pred = tupled_inputs_and_output_and_coroutine |
| 350 | 349 | .map_bound(|AsyncCallableRelevantTypes { tupled_inputs_ty, .. }| { |
| 351 | 350 | ty::TraitRef::new( |
| 352 | tcx, | |
| 351 | cx, | |
| 353 | 352 | goal.predicate.def_id(), |
| 354 | 353 | [goal.predicate.self_ty(), tupled_inputs_ty], |
| 355 | 354 | ) |
| 356 | 355 | }) |
| 357 | .upcast(tcx); | |
| 356 | .upcast(cx); | |
| 358 | 357 | // A built-in `AsyncFn` impl only holds if the output is sized. |
| 359 | 358 | // (FIXME: technically we only need to check this if the type is a fn ptr...) |
| 360 | 359 | Self::probe_and_consider_implied_clause( |
| ... | ... | @@ -362,9 +361,9 @@ where |
| 362 | 361 | CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), |
| 363 | 362 | goal, |
| 364 | 363 | pred, |
| 365 | [goal.with(tcx, output_is_sized_pred)] | |
| 364 | [goal.with(cx, output_is_sized_pred)] | |
| 366 | 365 | .into_iter() |
| 367 | .chain(nested_preds.into_iter().map(|pred| goal.with(tcx, pred))) | |
| 366 | .chain(nested_preds.into_iter().map(|pred| goal.with(cx, pred))) | |
| 368 | 367 | .map(|goal| (GoalSource::ImplWhereBound, goal)), |
| 369 | 368 | ) |
| 370 | 369 | } |
| ... | ... | @@ -437,8 +436,8 @@ where |
| 437 | 436 | }; |
| 438 | 437 | |
| 439 | 438 | // Coroutines are not futures unless they come from `async` desugaring |
| 440 | let tcx = ecx.cx(); | |
| 441 | if !tcx.coroutine_is_async(def_id) { | |
| 439 | let cx = ecx.cx(); | |
| 440 | if !cx.coroutine_is_async(def_id) { | |
| 442 | 441 | return Err(NoSolution); |
| 443 | 442 | } |
| 444 | 443 | |
| ... | ... | @@ -463,8 +462,8 @@ where |
| 463 | 462 | }; |
| 464 | 463 | |
| 465 | 464 | // Coroutines are not iterators unless they come from `gen` desugaring |
| 466 | let tcx = ecx.cx(); | |
| 467 | if !tcx.coroutine_is_gen(def_id) { | |
| 465 | let cx = ecx.cx(); | |
| 466 | if !cx.coroutine_is_gen(def_id) { | |
| 468 | 467 | return Err(NoSolution); |
| 469 | 468 | } |
| 470 | 469 | |
| ... | ... | @@ -489,8 +488,8 @@ where |
| 489 | 488 | }; |
| 490 | 489 | |
| 491 | 490 | // Coroutines are not iterators unless they come from `gen` desugaring |
| 492 | let tcx = ecx.cx(); | |
| 493 | if !tcx.coroutine_is_gen(def_id) { | |
| 491 | let cx = ecx.cx(); | |
| 492 | if !cx.coroutine_is_gen(def_id) { | |
| 494 | 493 | return Err(NoSolution); |
| 495 | 494 | } |
| 496 | 495 | |
| ... | ... | @@ -513,8 +512,8 @@ where |
| 513 | 512 | }; |
| 514 | 513 | |
| 515 | 514 | // Coroutines are not iterators unless they come from `gen` desugaring |
| 516 | let tcx = ecx.cx(); | |
| 517 | if !tcx.coroutine_is_async_gen(def_id) { | |
| 515 | let cx = ecx.cx(); | |
| 516 | if !cx.coroutine_is_async_gen(def_id) { | |
| 518 | 517 | return Err(NoSolution); |
| 519 | 518 | } |
| 520 | 519 | |
| ... | ... | @@ -540,8 +539,8 @@ where |
| 540 | 539 | }; |
| 541 | 540 | |
| 542 | 541 | // `async`-desugared coroutines do not implement the coroutine trait |
| 543 | let tcx = ecx.cx(); | |
| 544 | if !tcx.is_general_coroutine(def_id) { | |
| 542 | let cx = ecx.cx(); | |
| 543 | if !cx.is_general_coroutine(def_id) { | |
| 545 | 544 | return Err(NoSolution); |
| 546 | 545 | } |
| 547 | 546 | |
| ... | ... | @@ -550,8 +549,8 @@ where |
| 550 | 549 | ecx, |
| 551 | 550 | CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), |
| 552 | 551 | goal, |
| 553 | ty::TraitRef::new(tcx, goal.predicate.def_id(), [self_ty, coroutine.resume_ty()]) | |
| 554 | .upcast(tcx), | |
| 552 | ty::TraitRef::new(cx, goal.predicate.def_id(), [self_ty, coroutine.resume_ty()]) | |
| 553 | .upcast(cx), | |
| 555 | 554 | // Technically, we need to check that the coroutine types are Sized, |
| 556 | 555 | // but that's already proven by the coroutine being WF. |
| 557 | 556 | [], |
| ... | ... | @@ -727,7 +726,7 @@ where |
| 727 | 726 | b_data: I::BoundExistentialPredicates, |
| 728 | 727 | b_region: I::Region, |
| 729 | 728 | ) -> Vec<Candidate<I>> { |
| 730 | let tcx = self.cx(); | |
| 729 | let cx = self.cx(); | |
| 731 | 730 | let Goal { predicate: (a_ty, _b_ty), .. } = goal; |
| 732 | 731 | |
| 733 | 732 | let mut responses = vec![]; |
| ... | ... | @@ -745,7 +744,7 @@ where |
| 745 | 744 | )); |
| 746 | 745 | } else if let Some(a_principal) = a_data.principal() { |
| 747 | 746 | for new_a_principal in |
| 748 | D::elaborate_supertraits(self.cx(), a_principal.with_self_ty(tcx, a_ty)).skip(1) | |
| 747 | D::elaborate_supertraits(self.cx(), a_principal.with_self_ty(cx, a_ty)).skip(1) | |
| 749 | 748 | { |
| 750 | 749 | responses.extend(self.consider_builtin_upcast_to_principal( |
| 751 | 750 | goal, |
| ... | ... | @@ -755,7 +754,7 @@ where |
| 755 | 754 | b_data, |
| 756 | 755 | b_region, |
| 757 | 756 | Some(new_a_principal.map_bound(|trait_ref| { |
| 758 | ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref) | |
| 757 | ty::ExistentialTraitRef::erase_self_ty(cx, trait_ref) | |
| 759 | 758 | })), |
| 760 | 759 | )); |
| 761 | 760 | } |
| ... | ... | @@ -770,11 +769,11 @@ where |
| 770 | 769 | b_data: I::BoundExistentialPredicates, |
| 771 | 770 | b_region: I::Region, |
| 772 | 771 | ) -> Result<Candidate<I>, NoSolution> { |
| 773 | let tcx = self.cx(); | |
| 772 | let cx = self.cx(); | |
| 774 | 773 | let Goal { predicate: (a_ty, _), .. } = goal; |
| 775 | 774 | |
| 776 | 775 | // Can only unsize to an object-safe trait. |
| 777 | if b_data.principal_def_id().is_some_and(|def_id| !tcx.trait_is_object_safe(def_id)) { | |
| 776 | if b_data.principal_def_id().is_some_and(|def_id| !cx.trait_is_object_safe(def_id)) { | |
| 778 | 777 | return Err(NoSolution); |
| 779 | 778 | } |
| 780 | 779 | |
| ... | ... | @@ -783,24 +782,20 @@ where |
| 783 | 782 | // (i.e. the principal, all of the associated types match, and any auto traits) |
| 784 | 783 | ecx.add_goals( |
| 785 | 784 | GoalSource::ImplWhereBound, |
| 786 | b_data.iter().map(|pred| goal.with(tcx, pred.with_self_ty(tcx, a_ty))), | |
| 785 | b_data.iter().map(|pred| goal.with(cx, pred.with_self_ty(cx, a_ty))), | |
| 787 | 786 | ); |
| 788 | 787 | |
| 789 | 788 | // The type must be `Sized` to be unsized. |
| 790 | 789 | ecx.add_goal( |
| 791 | 790 | GoalSource::ImplWhereBound, |
| 792 | 791 | goal.with( |
| 793 | tcx, | |
| 794 | ty::TraitRef::new( | |
| 795 | tcx, | |
| 796 | tcx.require_lang_item(TraitSolverLangItem::Sized), | |
| 797 | [a_ty], | |
| 798 | ), | |
| 792 | cx, | |
| 793 | ty::TraitRef::new(cx, cx.require_lang_item(TraitSolverLangItem::Sized), [a_ty]), | |
| 799 | 794 | ), |
| 800 | 795 | ); |
| 801 | 796 | |
| 802 | 797 | // The type must outlive the lifetime of the `dyn` we're unsizing into. |
| 803 | ecx.add_goal(GoalSource::Misc, goal.with(tcx, ty::OutlivesPredicate(a_ty, b_region))); | |
| 798 | ecx.add_goal(GoalSource::Misc, goal.with(cx, ty::OutlivesPredicate(a_ty, b_region))); | |
| 804 | 799 | ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) |
| 805 | 800 | }) |
| 806 | 801 | } |
| ... | ... | @@ -941,28 +936,28 @@ where |
| 941 | 936 | a_args: I::GenericArgs, |
| 942 | 937 | b_args: I::GenericArgs, |
| 943 | 938 | ) -> Result<Candidate<I>, NoSolution> { |
| 944 | let tcx = self.cx(); | |
| 939 | let cx = self.cx(); | |
| 945 | 940 | let Goal { predicate: (_a_ty, b_ty), .. } = goal; |
| 946 | 941 | |
| 947 | let unsizing_params = tcx.unsizing_params_for_adt(def.def_id()); | |
| 942 | let unsizing_params = cx.unsizing_params_for_adt(def.def_id()); | |
| 948 | 943 | // We must be unsizing some type parameters. This also implies |
| 949 | 944 | // that the struct has a tail field. |
| 950 | 945 | if unsizing_params.is_empty() { |
| 951 | 946 | return Err(NoSolution); |
| 952 | 947 | } |
| 953 | 948 | |
| 954 | let tail_field_ty = def.struct_tail_ty(tcx).unwrap(); | |
| 949 | let tail_field_ty = def.struct_tail_ty(cx).unwrap(); | |
| 955 | 950 | |
| 956 | let a_tail_ty = tail_field_ty.instantiate(tcx, a_args); | |
| 957 | let b_tail_ty = tail_field_ty.instantiate(tcx, b_args); | |
| 951 | let a_tail_ty = tail_field_ty.instantiate(cx, a_args); | |
| 952 | let b_tail_ty = tail_field_ty.instantiate(cx, b_args); | |
| 958 | 953 | |
| 959 | 954 | // Instantiate just the unsizing params from B into A. The type after |
| 960 | 955 | // this instantiation must be equal to B. This is so we don't unsize |
| 961 | 956 | // unrelated type parameters. |
| 962 | let new_a_args = tcx.mk_args_from_iter(a_args.iter().enumerate().map(|(i, a)| { | |
| 957 | let new_a_args = cx.mk_args_from_iter(a_args.iter().enumerate().map(|(i, a)| { | |
| 963 | 958 | if unsizing_params.contains(i as u32) { b_args.get(i).unwrap() } else { a } |
| 964 | 959 | })); |
| 965 | let unsized_a_ty = Ty::new_adt(tcx, def, new_a_args); | |
| 960 | let unsized_a_ty = Ty::new_adt(cx, def, new_a_args); | |
| 966 | 961 | |
| 967 | 962 | // Finally, we require that `TailA: Unsize<TailB>` for the tail field |
| 968 | 963 | // types. |
| ... | ... | @@ -970,10 +965,10 @@ where |
| 970 | 965 | self.add_goal( |
| 971 | 966 | GoalSource::ImplWhereBound, |
| 972 | 967 | goal.with( |
| 973 | tcx, | |
| 968 | cx, | |
| 974 | 969 | ty::TraitRef::new( |
| 975 | tcx, | |
| 976 | tcx.require_lang_item(TraitSolverLangItem::Unsize), | |
| 970 | cx, | |
| 971 | cx.require_lang_item(TraitSolverLangItem::Unsize), | |
| 977 | 972 | [a_tail_ty, b_tail_ty], |
| 978 | 973 | ), |
| 979 | 974 | ), |
| ... | ... | @@ -998,25 +993,24 @@ where |
| 998 | 993 | a_tys: I::Tys, |
| 999 | 994 | b_tys: I::Tys, |
| 1000 | 995 | ) -> Result<Candidate<I>, NoSolution> { |
| 1001 | let tcx = self.cx(); | |
| 996 | let cx = self.cx(); | |
| 1002 | 997 | let Goal { predicate: (_a_ty, b_ty), .. } = goal; |
| 1003 | 998 | |
| 1004 | 999 | let (&a_last_ty, a_rest_tys) = a_tys.split_last().unwrap(); |
| 1005 | 1000 | let b_last_ty = b_tys.last().unwrap(); |
| 1006 | 1001 | |
| 1007 | 1002 | // Instantiate just the tail field of B., and require that they're equal. |
| 1008 | let unsized_a_ty = | |
| 1009 | Ty::new_tup_from_iter(tcx, a_rest_tys.iter().copied().chain([b_last_ty])); | |
| 1003 | let unsized_a_ty = Ty::new_tup_from_iter(cx, a_rest_tys.iter().copied().chain([b_last_ty])); | |
| 1010 | 1004 | self.eq(goal.param_env, unsized_a_ty, b_ty)?; |
| 1011 | 1005 | |
| 1012 | 1006 | // Similar to ADTs, require that we can unsize the tail. |
| 1013 | 1007 | self.add_goal( |
| 1014 | 1008 | GoalSource::ImplWhereBound, |
| 1015 | 1009 | goal.with( |
| 1016 | tcx, | |
| 1010 | cx, | |
| 1017 | 1011 | ty::TraitRef::new( |
| 1018 | tcx, | |
| 1019 | tcx.require_lang_item(TraitSolverLangItem::Unsize), | |
| 1012 | cx, | |
| 1013 | cx.require_lang_item(TraitSolverLangItem::Unsize), | |
| 1020 | 1014 | [a_last_ty, b_last_ty], |
| 1021 | 1015 | ), |
| 1022 | 1016 | ), |
compiler/rustc_parse/src/parser/ty.rs+1-1| ... | ... | @@ -608,7 +608,7 @@ impl<'a> Parser<'a> { |
| 608 | 608 | self.dcx().emit_err(FnPointerCannotBeAsync { span: whole_span, qualifier: span }); |
| 609 | 609 | } |
| 610 | 610 | // FIXME(gen_blocks): emit a similar error for `gen fn()` |
| 611 | let decl_span = span_start.to(self.token.span); | |
| 611 | let decl_span = span_start.to(self.prev_token.span); | |
| 612 | 612 | Ok(TyKind::BareFn(P(BareFnTy { ext, safety, generic_params: params, decl, decl_span }))) |
| 613 | 613 | } |
| 614 | 614 |
compiler/rustc_passes/src/reachable.rs+2-10| ... | ... | @@ -30,7 +30,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; |
| 30 | 30 | use rustc_hir::intravisit::{self, Visitor}; |
| 31 | 31 | use rustc_hir::Node; |
| 32 | 32 | use rustc_middle::bug; |
| 33 | use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; | |
| 33 | use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; | |
| 34 | 34 | use rustc_middle::middle::privacy::{self, Level}; |
| 35 | 35 | use rustc_middle::mir::interpret::{ConstAllocation, ErrorHandled, GlobalAlloc}; |
| 36 | 36 | use rustc_middle::query::Providers; |
| ... | ... | @@ -178,15 +178,7 @@ impl<'tcx> ReachableContext<'tcx> { |
| 178 | 178 | if !self.any_library { |
| 179 | 179 | // If we are building an executable, only explicitly extern |
| 180 | 180 | // types need to be exported. |
| 181 | let codegen_attrs = if self.tcx.def_kind(search_item).has_codegen_attrs() { | |
| 182 | self.tcx.codegen_fn_attrs(search_item) | |
| 183 | } else { | |
| 184 | CodegenFnAttrs::EMPTY | |
| 185 | }; | |
| 186 | let is_extern = codegen_attrs.contains_extern_indicator(); | |
| 187 | let std_internal = | |
| 188 | codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL); | |
| 189 | if is_extern || std_internal { | |
| 181 | if has_custom_linkage(self.tcx, search_item) { | |
| 190 | 182 | self.reachable_symbols.insert(search_item); |
| 191 | 183 | } |
| 192 | 184 | } else { |
compiler/rustc_resolve/src/effective_visibilities.rs+1-1| ... | ... | @@ -99,7 +99,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> { |
| 99 | 99 | // is the maximum value among visibilities of bindings corresponding to that def id. |
| 100 | 100 | for (binding, eff_vis) in visitor.import_effective_visibilities.iter() { |
| 101 | 101 | let NameBindingKind::Import { import, .. } = binding.kind else { unreachable!() }; |
| 102 | if !binding.is_ambiguity() { | |
| 102 | if !binding.is_ambiguity_recursive() { | |
| 103 | 103 | if let Some(node_id) = import.id() { |
| 104 | 104 | r.effective_visibilities.update_eff_vis(r.local_def_id(node_id), eff_vis, r.tcx) |
| 105 | 105 | } |
compiler/rustc_resolve/src/imports.rs+32-42| ... | ... | @@ -325,8 +325,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { |
| 325 | 325 | } |
| 326 | 326 | match (old_binding.is_glob_import(), binding.is_glob_import()) { |
| 327 | 327 | (true, true) => { |
| 328 | // FIXME: remove `!binding.is_ambiguity()` after delete the warning ambiguity. | |
| 329 | if !binding.is_ambiguity() | |
| 328 | // FIXME: remove `!binding.is_ambiguity_recursive()` after delete the warning ambiguity. | |
| 329 | if !binding.is_ambiguity_recursive() | |
| 330 | 330 | && let NameBindingKind::Import { import: old_import, .. } = |
| 331 | 331 | old_binding.kind |
| 332 | 332 | && let NameBindingKind::Import { import, .. } = binding.kind |
| ... | ... | @@ -337,21 +337,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { |
| 337 | 337 | // imported from the same glob-import statement. |
| 338 | 338 | resolution.binding = Some(binding); |
| 339 | 339 | } else if res != old_binding.res() { |
| 340 | let binding = if warn_ambiguity { | |
| 341 | this.warn_ambiguity(AmbiguityKind::GlobVsGlob, old_binding, binding) | |
| 342 | } else { | |
| 343 | this.ambiguity(AmbiguityKind::GlobVsGlob, old_binding, binding) | |
| 344 | }; | |
| 345 | resolution.binding = Some(binding); | |
| 340 | resolution.binding = Some(this.new_ambiguity_binding( | |
| 341 | AmbiguityKind::GlobVsGlob, | |
| 342 | old_binding, | |
| 343 | binding, | |
| 344 | warn_ambiguity, | |
| 345 | )); | |
| 346 | 346 | } else if !old_binding.vis.is_at_least(binding.vis, this.tcx) { |
| 347 | 347 | // We are glob-importing the same item but with greater visibility. |
| 348 | 348 | resolution.binding = Some(binding); |
| 349 | } else if binding.is_ambiguity() { | |
| 350 | resolution.binding = | |
| 351 | Some(self.arenas.alloc_name_binding(NameBindingData { | |
| 352 | warn_ambiguity: true, | |
| 353 | ..(*binding).clone() | |
| 354 | })); | |
| 349 | } else if binding.is_ambiguity_recursive() { | |
| 350 | resolution.binding = Some(this.new_warn_ambiguity_binding(binding)); | |
| 355 | 351 | } |
| 356 | 352 | } |
| 357 | 353 | (old_glob @ true, false) | (old_glob @ false, true) => { |
| ... | ... | @@ -361,24 +357,26 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { |
| 361 | 357 | && nonglob_binding.expansion != LocalExpnId::ROOT |
| 362 | 358 | && glob_binding.res() != nonglob_binding.res() |
| 363 | 359 | { |
| 364 | resolution.binding = Some(this.ambiguity( | |
| 360 | resolution.binding = Some(this.new_ambiguity_binding( | |
| 365 | 361 | AmbiguityKind::GlobVsExpanded, |
| 366 | 362 | nonglob_binding, |
| 367 | 363 | glob_binding, |
| 364 | false, | |
| 368 | 365 | )); |
| 369 | 366 | } else { |
| 370 | 367 | resolution.binding = Some(nonglob_binding); |
| 371 | 368 | } |
| 372 | 369 | |
| 373 | if let Some(old_binding) = resolution.shadowed_glob { | |
| 374 | assert!(old_binding.is_glob_import()); | |
| 375 | if glob_binding.res() != old_binding.res() { | |
| 376 | resolution.shadowed_glob = Some(this.ambiguity( | |
| 370 | if let Some(old_shadowed_glob) = resolution.shadowed_glob { | |
| 371 | assert!(old_shadowed_glob.is_glob_import()); | |
| 372 | if glob_binding.res() != old_shadowed_glob.res() { | |
| 373 | resolution.shadowed_glob = Some(this.new_ambiguity_binding( | |
| 377 | 374 | AmbiguityKind::GlobVsGlob, |
| 378 | old_binding, | |
| 375 | old_shadowed_glob, | |
| 379 | 376 | glob_binding, |
| 377 | false, | |
| 380 | 378 | )); |
| 381 | } else if !old_binding.vis.is_at_least(binding.vis, this.tcx) { | |
| 379 | } else if !old_shadowed_glob.vis.is_at_least(binding.vis, this.tcx) { | |
| 382 | 380 | resolution.shadowed_glob = Some(glob_binding); |
| 383 | 381 | } |
| 384 | 382 | } else { |
| ... | ... | @@ -397,29 +395,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { |
| 397 | 395 | }) |
| 398 | 396 | } |
| 399 | 397 | |
| 400 | fn ambiguity( | |
| 398 | fn new_ambiguity_binding( | |
| 401 | 399 | &self, |
| 402 | kind: AmbiguityKind, | |
| 400 | ambiguity_kind: AmbiguityKind, | |
| 403 | 401 | primary_binding: NameBinding<'a>, |
| 404 | 402 | secondary_binding: NameBinding<'a>, |
| 403 | warn_ambiguity: bool, | |
| 405 | 404 | ) -> NameBinding<'a> { |
| 406 | self.arenas.alloc_name_binding(NameBindingData { | |
| 407 | ambiguity: Some((secondary_binding, kind)), | |
| 408 | ..(*primary_binding).clone() | |
| 409 | }) | |
| 405 | let ambiguity = Some((secondary_binding, ambiguity_kind)); | |
| 406 | let data = NameBindingData { ambiguity, warn_ambiguity, ..*primary_binding }; | |
| 407 | self.arenas.alloc_name_binding(data) | |
| 410 | 408 | } |
| 411 | 409 | |
| 412 | fn warn_ambiguity( | |
| 413 | &self, | |
| 414 | kind: AmbiguityKind, | |
| 415 | primary_binding: NameBinding<'a>, | |
| 416 | secondary_binding: NameBinding<'a>, | |
| 417 | ) -> NameBinding<'a> { | |
| 418 | self.arenas.alloc_name_binding(NameBindingData { | |
| 419 | ambiguity: Some((secondary_binding, kind)), | |
| 420 | warn_ambiguity: true, | |
| 421 | ..(*primary_binding).clone() | |
| 422 | }) | |
| 410 | fn new_warn_ambiguity_binding(&self, binding: NameBinding<'a>) -> NameBinding<'a> { | |
| 411 | assert!(binding.is_ambiguity_recursive()); | |
| 412 | self.arenas.alloc_name_binding(NameBindingData { warn_ambiguity: true, ..*binding }) | |
| 423 | 413 | } |
| 424 | 414 | |
| 425 | 415 | // Use `f` to mutate the resolution of the name in the module. |
| ... | ... | @@ -1381,8 +1371,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { |
| 1381 | 1371 | target_bindings[ns].get(), |
| 1382 | 1372 | ) { |
| 1383 | 1373 | Ok(other_binding) => { |
| 1384 | is_redundant = | |
| 1385 | binding.res() == other_binding.res() && !other_binding.is_ambiguity(); | |
| 1374 | is_redundant = binding.res() == other_binding.res() | |
| 1375 | && !other_binding.is_ambiguity_recursive(); | |
| 1386 | 1376 | if is_redundant { |
| 1387 | 1377 | redundant_span[ns] = |
| 1388 | 1378 | Some((other_binding.span, other_binding.is_import())); |
| ... | ... | @@ -1455,7 +1445,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { |
| 1455 | 1445 | .resolution(import.parent_scope.module, key) |
| 1456 | 1446 | .borrow() |
| 1457 | 1447 | .binding() |
| 1458 | .is_some_and(|binding| binding.is_warn_ambiguity()); | |
| 1448 | .is_some_and(|binding| binding.warn_ambiguity_recursive()); | |
| 1459 | 1449 | let _ = self.try_define( |
| 1460 | 1450 | import.parent_scope.module, |
| 1461 | 1451 | key, |
| ... | ... | @@ -1480,7 +1470,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { |
| 1480 | 1470 | |
| 1481 | 1471 | module.for_each_child(self, |this, ident, _, binding| { |
| 1482 | 1472 | let res = binding.res().expect_non_local(); |
| 1483 | let error_ambiguity = binding.is_ambiguity() && !binding.warn_ambiguity; | |
| 1473 | let error_ambiguity = binding.is_ambiguity_recursive() && !binding.warn_ambiguity; | |
| 1484 | 1474 | if res != def::Res::Err && !error_ambiguity { |
| 1485 | 1475 | let mut reexport_chain = SmallVec::new(); |
| 1486 | 1476 | let mut next_binding = binding; |
compiler/rustc_resolve/src/late.rs+1-1| ... | ... | @@ -3730,7 +3730,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { |
| 3730 | 3730 | let ls_binding = self.maybe_resolve_ident_in_lexical_scope(ident, ValueNS)?; |
| 3731 | 3731 | let (res, binding) = match ls_binding { |
| 3732 | 3732 | LexicalScopeBinding::Item(binding) |
| 3733 | if is_syntactic_ambiguity && binding.is_ambiguity() => | |
| 3733 | if is_syntactic_ambiguity && binding.is_ambiguity_recursive() => | |
| 3734 | 3734 | { |
| 3735 | 3735 | // For ambiguous bindings we don't know all their definitions and cannot check |
| 3736 | 3736 | // whether they can be shadowed by fresh bindings or not, so force an error. |
compiler/rustc_resolve/src/lib.rs+8-6| ... | ... | @@ -694,10 +694,12 @@ impl<'a> fmt::Debug for Module<'a> { |
| 694 | 694 | } |
| 695 | 695 | |
| 696 | 696 | /// Records a possibly-private value, type, or module definition. |
| 697 | #[derive(Clone, Debug)] | |
| 697 | #[derive(Clone, Copy, Debug)] | |
| 698 | 698 | struct NameBindingData<'a> { |
| 699 | 699 | kind: NameBindingKind<'a>, |
| 700 | 700 | ambiguity: Option<(NameBinding<'a>, AmbiguityKind)>, |
| 701 | /// Produce a warning instead of an error when reporting ambiguities inside this binding. | |
| 702 | /// May apply to indirect ambiguities under imports, so `ambiguity.is_some()` is not required. | |
| 701 | 703 | warn_ambiguity: bool, |
| 702 | 704 | expansion: LocalExpnId, |
| 703 | 705 | span: Span, |
| ... | ... | @@ -718,7 +720,7 @@ impl<'a> ToNameBinding<'a> for NameBinding<'a> { |
| 718 | 720 | } |
| 719 | 721 | } |
| 720 | 722 | |
| 721 | #[derive(Clone, Debug)] | |
| 723 | #[derive(Clone, Copy, Debug)] | |
| 722 | 724 | enum NameBindingKind<'a> { |
| 723 | 725 | Res(Res), |
| 724 | 726 | Module(Module<'a>), |
| ... | ... | @@ -830,18 +832,18 @@ impl<'a> NameBindingData<'a> { |
| 830 | 832 | } |
| 831 | 833 | } |
| 832 | 834 | |
| 833 | fn is_ambiguity(&self) -> bool { | |
| 835 | fn is_ambiguity_recursive(&self) -> bool { | |
| 834 | 836 | self.ambiguity.is_some() |
| 835 | 837 | || match self.kind { |
| 836 | NameBindingKind::Import { binding, .. } => binding.is_ambiguity(), | |
| 838 | NameBindingKind::Import { binding, .. } => binding.is_ambiguity_recursive(), | |
| 837 | 839 | _ => false, |
| 838 | 840 | } |
| 839 | 841 | } |
| 840 | 842 | |
| 841 | fn is_warn_ambiguity(&self) -> bool { | |
| 843 | fn warn_ambiguity_recursive(&self) -> bool { | |
| 842 | 844 | self.warn_ambiguity |
| 843 | 845 | || match self.kind { |
| 844 | NameBindingKind::Import { binding, .. } => binding.is_warn_ambiguity(), | |
| 846 | NameBindingKind::Import { binding, .. } => binding.warn_ambiguity_recursive(), | |
| 845 | 847 | _ => false, |
| 846 | 848 | } |
| 847 | 849 | } |
library/core/src/iter/adapters/filter.rs+45-45| ... | ... | @@ -3,7 +3,7 @@ use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable, TrustedF |
| 3 | 3 | use crate::num::NonZero; |
| 4 | 4 | use crate::ops::Try; |
| 5 | 5 | use core::array; |
| 6 | use core::mem::{ManuallyDrop, MaybeUninit}; | |
| 6 | use core::mem::MaybeUninit; | |
| 7 | 7 | use core::ops::ControlFlow; |
| 8 | 8 | |
| 9 | 9 | /// An iterator that filters the elements of `iter` with `predicate`. |
| ... | ... | @@ -27,6 +27,42 @@ impl<I, P> Filter<I, P> { |
| 27 | 27 | } |
| 28 | 28 | } |
| 29 | 29 | |
| 30 | impl<I, P> Filter<I, P> | |
| 31 | where | |
| 32 | I: Iterator, | |
| 33 | P: FnMut(&I::Item) -> bool, | |
| 34 | { | |
| 35 | #[inline] | |
| 36 | fn next_chunk_dropless<const N: usize>( | |
| 37 | &mut self, | |
| 38 | ) -> Result<[I::Item; N], array::IntoIter<I::Item, N>> { | |
| 39 | let mut array: [MaybeUninit<I::Item>; N] = [const { MaybeUninit::uninit() }; N]; | |
| 40 | let mut initialized = 0; | |
| 41 | ||
| 42 | let result = self.iter.try_for_each(|element| { | |
| 43 | let idx = initialized; | |
| 44 | // branchless index update combined with unconditionally copying the value even when | |
| 45 | // it is filtered reduces branching and dependencies in the loop. | |
| 46 | initialized = idx + (self.predicate)(&element) as usize; | |
| 47 | // SAFETY: Loop conditions ensure the index is in bounds. | |
| 48 | unsafe { array.get_unchecked_mut(idx) }.write(element); | |
| 49 | ||
| 50 | if initialized < N { ControlFlow::Continue(()) } else { ControlFlow::Break(()) } | |
| 51 | }); | |
| 52 | ||
| 53 | match result { | |
| 54 | ControlFlow::Break(()) => { | |
| 55 | // SAFETY: The loop above is only explicitly broken when the array has been fully initialized | |
| 56 | Ok(unsafe { MaybeUninit::array_assume_init(array) }) | |
| 57 | } | |
| 58 | ControlFlow::Continue(()) => { | |
| 59 | // SAFETY: The range is in bounds since the loop breaks when reaching N elements. | |
| 60 | Err(unsafe { array::IntoIter::new_unchecked(array, 0..initialized) }) | |
| 61 | } | |
| 62 | } | |
| 63 | } | |
| 64 | } | |
| 65 | ||
| 30 | 66 | #[stable(feature = "core_impl_debug", since = "1.9.0")] |
| 31 | 67 | impl<I: fmt::Debug, P> fmt::Debug for Filter<I, P> { |
| 32 | 68 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| ... | ... | @@ -64,52 +100,16 @@ where |
| 64 | 100 | fn next_chunk<const N: usize>( |
| 65 | 101 | &mut self, |
| 66 | 102 | ) -> Result<[Self::Item; N], array::IntoIter<Self::Item, N>> { |
| 67 | let mut array: [MaybeUninit<Self::Item>; N] = [const { MaybeUninit::uninit() }; N]; | |
| 68 | ||
| 69 | struct Guard<'a, T> { | |
| 70 | array: &'a mut [MaybeUninit<T>], | |
| 71 | initialized: usize, | |
| 72 | } | |
| 73 | ||
| 74 | impl<T> Drop for Guard<'_, T> { | |
| 75 | #[inline] | |
| 76 | fn drop(&mut self) { | |
| 77 | if const { crate::mem::needs_drop::<T>() } { | |
| 78 | // SAFETY: self.initialized is always <= N, which also is the length of the array. | |
| 79 | unsafe { | |
| 80 | core::ptr::drop_in_place(MaybeUninit::slice_assume_init_mut( | |
| 81 | self.array.get_unchecked_mut(..self.initialized), | |
| 82 | )); | |
| 83 | } | |
| 84 | } | |
| 103 | // avoid codegen for the dead branch | |
| 104 | let fun = const { | |
| 105 | if crate::mem::needs_drop::<I::Item>() { | |
| 106 | array::iter_next_chunk::<I::Item, N> | |
| 107 | } else { | |
| 108 | Self::next_chunk_dropless::<N> | |
| 85 | 109 | } |
| 86 | } | |
| 87 | ||
| 88 | let mut guard = Guard { array: &mut array, initialized: 0 }; | |
| 89 | ||
| 90 | let result = self.iter.try_for_each(|element| { | |
| 91 | let idx = guard.initialized; | |
| 92 | guard.initialized = idx + (self.predicate)(&element) as usize; | |
| 93 | ||
| 94 | // SAFETY: Loop conditions ensure the index is in bounds. | |
| 95 | unsafe { guard.array.get_unchecked_mut(idx) }.write(element); | |
| 96 | ||
| 97 | if guard.initialized < N { ControlFlow::Continue(()) } else { ControlFlow::Break(()) } | |
| 98 | }); | |
| 110 | }; | |
| 99 | 111 | |
| 100 | let guard = ManuallyDrop::new(guard); | |
| 101 | ||
| 102 | match result { | |
| 103 | ControlFlow::Break(()) => { | |
| 104 | // SAFETY: The loop above is only explicitly broken when the array has been fully initialized | |
| 105 | Ok(unsafe { MaybeUninit::array_assume_init(array) }) | |
| 106 | } | |
| 107 | ControlFlow::Continue(()) => { | |
| 108 | let initialized = guard.initialized; | |
| 109 | // SAFETY: The range is in bounds since the loop breaks when reaching N elements. | |
| 110 | Err(unsafe { array::IntoIter::new_unchecked(array, 0..initialized) }) | |
| 111 | } | |
| 112 | } | |
| 112 | fun(self) | |
| 113 | 113 | } |
| 114 | 114 | |
| 115 | 115 | #[inline] |
library/core/tests/iter/adapters/filter.rs+13| ... | ... | @@ -1,4 +1,5 @@ |
| 1 | 1 | use core::iter::*; |
| 2 | use std::rc::Rc; | |
| 2 | 3 | |
| 3 | 4 | #[test] |
| 4 | 5 | fn test_iterator_filter_count() { |
| ... | ... | @@ -50,3 +51,15 @@ fn test_double_ended_filter() { |
| 50 | 51 | assert_eq!(it.next().unwrap(), &2); |
| 51 | 52 | assert_eq!(it.next_back(), None); |
| 52 | 53 | } |
| 54 | ||
| 55 | #[test] | |
| 56 | fn test_next_chunk_does_not_leak() { | |
| 57 | let drop_witness: [_; 5] = std::array::from_fn(|_| Rc::new(())); | |
| 58 | ||
| 59 | let v = (0..5).map(|i| drop_witness[i].clone()).collect::<Vec<_>>(); | |
| 60 | let _ = v.into_iter().filter(|_| false).next_chunk::<1>(); | |
| 61 | ||
| 62 | for ref w in drop_witness { | |
| 63 | assert_eq!(Rc::strong_count(w), 1); | |
| 64 | } | |
| 65 | } |
src/tools/miri/tests/pass/tls/win_tls_callback.rs created+16| ... | ... | @@ -0,0 +1,16 @@ |
| 1 | //! Ensure that we call Windows TLS callbacks in the local crate. | |
| 2 | //@only-target-windows | |
| 3 | // Calling eprintln in the callback seems to (re-)initialize some thread-local storage | |
| 4 | // and then leak the memory allocated for that. Let's just ignore these leaks, | |
| 5 | // that's not what this test is about. | |
| 6 | //@compile-flags: -Zmiri-ignore-leaks | |
| 7 | ||
| 8 | #[link_section = ".CRT$XLB"] | |
| 9 | #[used] // Miri only considers explicitly `#[used]` statics for `lookup_link_section` | |
| 10 | pub static CALLBACK: unsafe extern "system" fn(*const (), u32, *const ()) = tls_callback; | |
| 11 | ||
| 12 | unsafe extern "system" fn tls_callback(_h: *const (), _dw_reason: u32, _pv: *const ()) { | |
| 13 | eprintln!("in tls_callback"); | |
| 14 | } | |
| 15 | ||
| 16 | fn main() {} |
src/tools/miri/tests/pass/tls/win_tls_callback.stderr created+1| ... | ... | @@ -0,0 +1 @@ |
| 1 | in tls_callback |
src/tools/tidy/config/requirements.in+2-2| ... | ... | @@ -6,5 +6,5 @@ |
| 6 | 6 | # Note: this generation step should be run with the oldest supported python |
| 7 | 7 | # version (currently 3.9) to ensure backward compatibility |
| 8 | 8 | |
| 9 | black==23.3.0 | |
| 10 | ruff==0.0.272 | |
| 9 | black==24.4.2 | |
| 10 | ruff==0.4.9 |
src/tools/tidy/config/requirements.txt+44-47| ... | ... | @@ -4,32 +4,29 @@ |
| 4 | 4 | # |
| 5 | 5 | # pip-compile --generate-hashes --strip-extras src/tools/tidy/config/requirements.in |
| 6 | 6 | # |
| 7 | black==23.3.0 \ | |
| 8 | --hash=sha256:064101748afa12ad2291c2b91c960be28b817c0c7eaa35bec09cc63aa56493c5 \ | |
| 9 | --hash=sha256:0945e13506be58bf7db93ee5853243eb368ace1c08a24c65ce108986eac65915 \ | |
| 10 | --hash=sha256:11c410f71b876f961d1de77b9699ad19f939094c3a677323f43d7a29855fe326 \ | |
| 11 | --hash=sha256:1c7b8d606e728a41ea1ccbd7264677e494e87cf630e399262ced92d4a8dac940 \ | |
| 12 | --hash=sha256:1d06691f1eb8de91cd1b322f21e3bfc9efe0c7ca1f0e1eb1db44ea367dff656b \ | |
| 13 | --hash=sha256:3238f2aacf827d18d26db07524e44741233ae09a584273aa059066d644ca7b30 \ | |
| 14 | --hash=sha256:32daa9783106c28815d05b724238e30718f34155653d4d6e125dc7daec8e260c \ | |
| 15 | --hash=sha256:35d1381d7a22cc5b2be2f72c7dfdae4072a3336060635718cc7e1ede24221d6c \ | |
| 16 | --hash=sha256:3a150542a204124ed00683f0db1f5cf1c2aaaa9cc3495b7a3b5976fb136090ab \ | |
| 17 | --hash=sha256:48f9d345675bb7fbc3dd85821b12487e1b9a75242028adad0333ce36ed2a6d27 \ | |
| 18 | --hash=sha256:50cb33cac881766a5cd9913e10ff75b1e8eb71babf4c7104f2e9c52da1fb7de2 \ | |
| 19 | --hash=sha256:562bd3a70495facf56814293149e51aa1be9931567474993c7942ff7d3533961 \ | |
| 20 | --hash=sha256:67de8d0c209eb5b330cce2469503de11bca4085880d62f1628bd9972cc3366b9 \ | |
| 21 | --hash=sha256:6b39abdfb402002b8a7d030ccc85cf5afff64ee90fa4c5aebc531e3ad0175ddb \ | |
| 22 | --hash=sha256:6f3c333ea1dd6771b2d3777482429864f8e258899f6ff05826c3a4fcc5ce3f70 \ | |
| 23 | --hash=sha256:714290490c18fb0126baa0fca0a54ee795f7502b44177e1ce7624ba1c00f2331 \ | |
| 24 | --hash=sha256:7c3eb7cea23904399866c55826b31c1f55bbcd3890ce22ff70466b907b6775c2 \ | |
| 25 | --hash=sha256:92c543f6854c28a3c7f39f4d9b7694f9a6eb9d3c5e2ece488c327b6e7ea9b266 \ | |
| 26 | --hash=sha256:a6f6886c9869d4daae2d1715ce34a19bbc4b95006d20ed785ca00fa03cba312d \ | |
| 27 | --hash=sha256:a8a968125d0a6a404842fa1bf0b349a568634f856aa08ffaff40ae0dfa52e7c6 \ | |
| 28 | --hash=sha256:c7ab5790333c448903c4b721b59c0d80b11fe5e9803d8703e84dcb8da56fec1b \ | |
| 29 | --hash=sha256:e114420bf26b90d4b9daa597351337762b63039752bdf72bf361364c1aa05925 \ | |
| 30 | --hash=sha256:e198cf27888ad6f4ff331ca1c48ffc038848ea9f031a3b40ba36aced7e22f2c8 \ | |
| 31 | --hash=sha256:ec751418022185b0c1bb7d7736e6933d40bbb14c14a0abcf9123d1b159f98dd4 \ | |
| 32 | --hash=sha256:f0bd2f4a58d6666500542b26354978218a9babcdc972722f4bf90779524515f3 | |
| 7 | black==24.4.2 \ | |
| 8 | --hash=sha256:257d724c2c9b1660f353b36c802ccece186a30accc7742c176d29c146df6e474 \ | |
| 9 | --hash=sha256:37aae07b029fa0174d39daf02748b379399b909652a806e5708199bd93899da1 \ | |
| 10 | --hash=sha256:415e686e87dbbe6f4cd5ef0fbf764af7b89f9057b97c908742b6008cc554b9c0 \ | |
| 11 | --hash=sha256:48a85f2cb5e6799a9ef05347b476cce6c182d6c71ee36925a6c194d074336ef8 \ | |
| 12 | --hash=sha256:7768a0dbf16a39aa5e9a3ded568bb545c8c2727396d063bbaf847df05b08cd96 \ | |
| 13 | --hash=sha256:7e122b1c4fb252fd85df3ca93578732b4749d9be076593076ef4d07a0233c3e1 \ | |
| 14 | --hash=sha256:88c57dc656038f1ab9f92b3eb5335ee9b021412feaa46330d5eba4e51fe49b04 \ | |
| 15 | --hash=sha256:8e537d281831ad0e71007dcdcbe50a71470b978c453fa41ce77186bbe0ed6021 \ | |
| 16 | --hash=sha256:98e123f1d5cfd42f886624d84464f7756f60ff6eab89ae845210631714f6db94 \ | |
| 17 | --hash=sha256:accf49e151c8ed2c0cdc528691838afd217c50412534e876a19270fea1e28e2d \ | |
| 18 | --hash=sha256:b1530ae42e9d6d5b670a34db49a94115a64596bc77710b1d05e9801e62ca0a7c \ | |
| 19 | --hash=sha256:b9176b9832e84308818a99a561e90aa479e73c523b3f77afd07913380ae2eab7 \ | |
| 20 | --hash=sha256:bdde6f877a18f24844e381d45e9947a49e97933573ac9d4345399be37621e26c \ | |
| 21 | --hash=sha256:be8bef99eb46d5021bf053114442914baeb3649a89dc5f3a555c88737e5e98fc \ | |
| 22 | --hash=sha256:bf10f7310db693bb62692609b397e8d67257c55f949abde4c67f9cc574492cc7 \ | |
| 23 | --hash=sha256:c872b53057f000085da66a19c55d68f6f8ddcac2642392ad3a355878406fbd4d \ | |
| 24 | --hash=sha256:d36ed1124bb81b32f8614555b34cc4259c3fbc7eec17870e8ff8ded335b58d8c \ | |
| 25 | --hash=sha256:da33a1a5e49c4122ccdfd56cd021ff1ebc4a1ec4e2d01594fef9b6f267a9e741 \ | |
| 26 | --hash=sha256:dd1b5a14e417189db4c7b64a6540f31730713d173f0b63e55fabd52d61d8fdce \ | |
| 27 | --hash=sha256:e151054aa00bad1f4e1f04919542885f89f5f7d086b8a59e5000e6c616896ffb \ | |
| 28 | --hash=sha256:eaea3008c281f1038edb473c1aa8ed8143a5535ff18f978a318f10302b254063 \ | |
| 29 | --hash=sha256:ef703f83fc32e131e9bcc0a5094cfe85599e7109f896fe8bc96cc402f3eb4b6e | |
| 33 | 30 | # via -r src/tools/tidy/config/requirements.in |
| 34 | 31 | click==8.1.3 \ |
| 35 | 32 | --hash=sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e \ |
| ... | ... | @@ -47,28 +44,28 @@ pathspec==0.11.1 \ |
| 47 | 44 | --hash=sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687 \ |
| 48 | 45 | --hash=sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293 |
| 49 | 46 | # via black |
| 50 | platformdirs==3.6.0 \ | |
| 51 | --hash=sha256:57e28820ca8094678b807ff529196506d7a21e17156cb1cddb3e74cebce54640 \ | |
| 52 | --hash=sha256:ffa199e3fbab8365778c4a10e1fbf1b9cd50707de826eb304b50e57ec0cc8d38 | |
| 47 | platformdirs==4.2.2 \ | |
| 48 | --hash=sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee \ | |
| 49 | --hash=sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3 | |
| 53 | 50 | # via black |
| 54 | ruff==0.0.272 \ | |
| 55 | --hash=sha256:06b8ee4eb8711ab119db51028dd9f5384b44728c23586424fd6e241a5b9c4a3b \ | |
| 56 | --hash=sha256:1609b864a8d7ee75a8c07578bdea0a7db75a144404e75ef3162e0042bfdc100d \ | |
| 57 | --hash=sha256:19643d448f76b1eb8a764719072e9c885968971bfba872e14e7257e08bc2f2b7 \ | |
| 58 | --hash=sha256:273a01dc8c3c4fd4c2af7ea7a67c8d39bb09bce466e640dd170034da75d14cab \ | |
| 59 | --hash=sha256:27b2ea68d2aa69fff1b20b67636b1e3e22a6a39e476c880da1282c3e4bf6ee5a \ | |
| 60 | --hash=sha256:48eccf225615e106341a641f826b15224b8a4240b84269ead62f0afd6d7e2d95 \ | |
| 61 | --hash=sha256:677284430ac539bb23421a2b431b4ebc588097ef3ef918d0e0a8d8ed31fea216 \ | |
| 62 | --hash=sha256:691d72a00a99707a4e0b2846690961157aef7b17b6b884f6b4420a9f25cd39b5 \ | |
| 63 | --hash=sha256:86bc788245361a8148ff98667da938a01e1606b28a45e50ac977b09d3ad2c538 \ | |
| 64 | --hash=sha256:905ff8f3d6206ad56fcd70674453527b9011c8b0dc73ead27618426feff6908e \ | |
| 65 | --hash=sha256:9c4bfb75456a8e1efe14c52fcefb89cfb8f2a0d31ed8d804b82c6cf2dc29c42c \ | |
| 66 | --hash=sha256:a37ec80e238ead2969b746d7d1b6b0d31aa799498e9ba4281ab505b93e1f4b28 \ | |
| 67 | --hash=sha256:ae9b57546e118660175d45d264b87e9b4c19405c75b587b6e4d21e6a17bf4fdf \ | |
| 68 | --hash=sha256:bd2bbe337a3f84958f796c77820d55ac2db1e6753f39d1d1baed44e07f13f96d \ | |
| 69 | --hash=sha256:d5a208f8ef0e51d4746930589f54f9f92f84bb69a7d15b1de34ce80a7681bc00 \ | |
| 70 | --hash=sha256:dc406e5d756d932da95f3af082814d2467943631a587339ee65e5a4f4fbe83eb \ | |
| 71 | --hash=sha256:ee76b4f05fcfff37bd6ac209d1370520d509ea70b5a637bdf0a04d0c99e13dff | |
| 51 | ruff==0.4.9 \ | |
| 52 | --hash=sha256:06b60f91bfa5514bb689b500a25ba48e897d18fea14dce14b48a0c40d1635893 \ | |
| 53 | --hash=sha256:0e8e7b95673f22e0efd3571fb5b0cf71a5eaaa3cc8a776584f3b2cc878e46bff \ | |
| 54 | --hash=sha256:2d45ddc6d82e1190ea737341326ecbc9a61447ba331b0a8962869fcada758505 \ | |
| 55 | --hash=sha256:4555056049d46d8a381f746680db1c46e67ac3b00d714606304077682832998e \ | |
| 56 | --hash=sha256:5d5460f789ccf4efd43f265a58538a2c24dbce15dbf560676e430375f20a8198 \ | |
| 57 | --hash=sha256:673bddb893f21ab47a8334c8e0ea7fd6598ecc8e698da75bcd12a7b9d0a3206e \ | |
| 58 | --hash=sha256:732dd550bfa5d85af8c3c6cbc47ba5b67c6aed8a89e2f011b908fc88f87649db \ | |
| 59 | --hash=sha256:784d3ec9bd6493c3b720a0b76f741e6c2d7d44f6b2be87f5eef1ae8cc1d54c84 \ | |
| 60 | --hash=sha256:78de3fdb95c4af084087628132336772b1c5044f6e710739d440fc0bccf4d321 \ | |
| 61 | --hash=sha256:8064590fd1a50dcf4909c268b0e7c2498253273309ad3d97e4a752bb9df4f521 \ | |
| 62 | --hash=sha256:88bffe9c6a454bf8529f9ab9091c99490578a593cc9f9822b7fc065ee0712a06 \ | |
| 63 | --hash=sha256:8c1aff58c31948cc66d0b22951aa19edb5af0a3af40c936340cd32a8b1ab7438 \ | |
| 64 | --hash=sha256:98ec2775fd2d856dc405635e5ee4ff177920f2141b8e2d9eb5bd6efd50e80317 \ | |
| 65 | --hash=sha256:b262ed08d036ebe162123170b35703aaf9daffecb698cd367a8d585157732991 \ | |
| 66 | --hash=sha256:e0a22c4157e53d006530c902107c7f550b9233e9706313ab57b892d7197d8e52 \ | |
| 67 | --hash=sha256:e91175fbe48f8a2174c9aad70438fe9cb0a5732c4159b2a10a3565fea2d94cde \ | |
| 68 | --hash=sha256:f1cb0828ac9533ba0135d148d214e284711ede33640465e706772645483427e3 | |
| 72 | 69 | # via -r src/tools/tidy/config/requirements.in |
| 73 | 70 | tomli==2.0.1 \ |
| 74 | 71 | --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \ |
src/tools/tidy/config/ruff.toml+12-11| ... | ... | @@ -1,17 +1,7 @@ |
| 1 | 1 | # Configuration for ruff python linter, run as part of tidy external tools |
| 2 | 2 | |
| 3 | # B (bugbear), E (pycodestyle, standard), EXE (executables) F (flakes, standard) | |
| 4 | # ERM for error messages would be beneficial at some point | |
| 5 | select = ["B", "E", "EXE", "F"] | |
| 6 | ||
| 7 | ignore = [ | |
| 8 | "E501", # line-too-long | |
| 9 | "F403", # undefined-local-with-import-star | |
| 10 | "F405", # undefined-local-with-import-star-usage | |
| 11 | ] | |
| 12 | ||
| 13 | 3 | # lowest possible for ruff |
| 14 | target-version = "py37" | |
| 4 | target-version = "py39" | |
| 15 | 5 | |
| 16 | 6 | # Ignore all submodules |
| 17 | 7 | extend-exclude = [ |
| ... | ... | @@ -41,3 +31,14 @@ extend-exclude = [ |
| 41 | 31 | "../library/backtrace/", |
| 42 | 32 | "../src/tools/rustc-perf/", |
| 43 | 33 | ] |
| 34 | ||
| 35 | [lint] | |
| 36 | # B (bugbear), E (pycodestyle, standard), EXE (executables) F (flakes, standard) | |
| 37 | # ERM for error messages would be beneficial at some point | |
| 38 | select = ["B", "E", "EXE", "F"] | |
| 39 | ||
| 40 | ignore = [ | |
| 41 | "E501", # line-too-long | |
| 42 | "F403", # undefined-local-with-import-star | |
| 43 | "F405", # undefined-local-with-import-star-usage | |
| 44 | ] |
src/tools/tidy/src/allowed_run_make_makefiles.txt-3| ... | ... | @@ -55,13 +55,11 @@ run-make/incr-foreign-head-span/Makefile |
| 55 | 55 | run-make/interdependent-c-libraries/Makefile |
| 56 | 56 | run-make/intrinsic-unreachable/Makefile |
| 57 | 57 | run-make/invalid-library/Makefile |
| 58 | run-make/invalid-so/Makefile | |
| 59 | 58 | run-make/issue-107094/Makefile |
| 60 | 59 | run-make/issue-109934-lto-debuginfo/Makefile |
| 61 | 60 | run-make/issue-14698/Makefile |
| 62 | 61 | run-make/issue-15460/Makefile |
| 63 | 62 | run-make/issue-18943/Makefile |
| 64 | run-make/issue-20626/Makefile | |
| 65 | 63 | run-make/issue-22131/Makefile |
| 66 | 64 | run-make/issue-25581/Makefile |
| 67 | 65 | run-make/issue-26006/Makefile |
| ... | ... | @@ -97,7 +95,6 @@ run-make/long-linker-command-lines-cmd-exe/Makefile |
| 97 | 95 | run-make/long-linker-command-lines/Makefile |
| 98 | 96 | run-make/longjmp-across-rust/Makefile |
| 99 | 97 | run-make/lto-dylib-dep/Makefile |
| 100 | run-make/lto-empty/Makefile | |
| 101 | 98 | run-make/lto-linkage-used-attr/Makefile |
| 102 | 99 | run-make/lto-no-link-whole-rlib/Makefile |
| 103 | 100 | run-make/lto-smoke-c/Makefile |
src/tools/tidy/src/ext_tool_checks.rs+2-1| ... | ... | @@ -110,12 +110,13 @@ fn check_impl( |
| 110 | 110 | } |
| 111 | 111 | |
| 112 | 112 | let mut args = merge_args(&cfg_args_ruff, &file_args_ruff); |
| 113 | args.insert(0, "check".as_ref()); | |
| 113 | 114 | let res = py_runner(py_path.as_ref().unwrap(), "ruff", &args); |
| 114 | 115 | |
| 115 | 116 | if res.is_err() && show_diff { |
| 116 | 117 | eprintln!("\npython linting failed! Printing diff suggestions:"); |
| 117 | 118 | |
| 118 | args.insert(0, "--diff".as_ref()); | |
| 119 | args.insert(1, "--diff".as_ref()); | |
| 119 | 120 | let _ = py_runner(py_path.as_ref().unwrap(), "ruff", &args); |
| 120 | 121 | } |
| 121 | 122 | // Rethrow error |
tests/run-make/invalid-so/Makefile deleted-7| ... | ... | @@ -1,7 +0,0 @@ |
| 1 | include ../tools.mk | |
| 2 | ||
| 3 | DYLIB_NAME := $(shell echo | $(RUSTC) --crate-name foo --crate-type dylib --print file-names -) | |
| 4 | ||
| 5 | all: | |
| 6 | 	echo >> $(TMPDIR)/$(DYLIB_NAME) | |
| 7 | 	$(RUSTC) --crate-type lib --extern foo=$(TMPDIR)/$(DYLIB_NAME) bar.rs 2>&1 | $(CGREP) 'invalid metadata files for crate `foo`' |
tests/run-make/invalid-so/rmake.rs created+17| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | // When a fake library was given to the compiler, it would | |
| 2 | // result in an obscure and unhelpful error message. This test | |
| 3 | // creates a false "foo" dylib, and checks that the standard error | |
| 4 | // explains that the file exists, but that its metadata is incorrect. | |
| 5 | // See https://github.com/rust-lang/rust/pull/88368 | |
| 6 | ||
| 7 | use run_make_support::{dynamic_lib_name, fs_wrapper, rustc}; | |
| 8 | ||
| 9 | fn main() { | |
| 10 | fs_wrapper::create_file(dynamic_lib_name("foo")); | |
| 11 | rustc() | |
| 12 | .crate_type("lib") | |
| 13 | .extern_("foo", dynamic_lib_name("foo")) | |
| 14 | .input("bar.rs") | |
| 15 | .run_fail() | |
| 16 | .assert_stderr_contains("invalid metadata files for crate `foo`"); | |
| 17 | } |
tests/run-make/issue-20626/Makefile deleted-9| ... | ... | @@ -1,9 +0,0 @@ |
| 1 | # ignore-cross-compile | |
| 2 | include ../tools.mk | |
| 3 | ||
| 4 | # Test output to be four | |
| 5 | # The original error only occurred when printing, not when comparing using assert! | |
| 6 | ||
| 7 | all: | |
| 8 | 	$(RUSTC) foo.rs -O | |
| 9 | 	[ `$(call RUN,foo)` = "4" ] |
tests/run-make/issue-20626/foo.rs deleted-15| ... | ... | @@ -1,15 +0,0 @@ |
| 1 | fn identity(a: &u32) -> &u32 { | |
| 2 | a | |
| 3 | } | |
| 4 | ||
| 5 | fn print_foo(f: &fn(&u32) -> &u32, x: &u32) { | |
| 6 | print!("{}", (*f)(x)); | |
| 7 | } | |
| 8 | ||
| 9 | fn main() { | |
| 10 | let x = &4; | |
| 11 | let f: fn(&u32) -> &u32 = identity; | |
| 12 | ||
| 13 | // Didn't print 4 on optimized builds | |
| 14 | print_foo(&f, x); | |
| 15 | } |
tests/run-make/lto-empty/Makefile deleted-13| ... | ... | @@ -1,13 +0,0 @@ |
| 1 | # ignore-cross-compile | |
| 2 | include ../tools.mk | |
| 3 | ||
| 4 | all: cdylib-fat cdylib-thin | |
| 5 | ||
| 6 | cdylib-fat: | |
| 7 | 	$(RUSTC) lib.rs -C lto=fat -C opt-level=3 -C incremental=$(TMPDIR)/inc-fat | |
| 8 | 	$(RUSTC) lib.rs -C lto=fat -C opt-level=3 -C incremental=$(TMPDIR)/inc-fat | |
| 9 | ||
| 10 | cdylib-thin: | |
| 11 | 	$(RUSTC) lib.rs -C lto=thin -C opt-level=3 -C incremental=$(TMPDIR)/inc-thin | |
| 12 | 	$(RUSTC) lib.rs -C lto=thin -C opt-level=3 -C incremental=$(TMPDIR)/inc-thin | |
| 13 |
tests/run-make/lto-empty/rmake.rs created+17| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | // Compiling Rust code twice in a row with "fat" link-time-optimizations used to cause | |
| 2 | // an internal compiler error (ICE). This was due to how the compiler would cache some modules | |
| 3 | // to make subsequent compilations faster, at least one of which was required for LTO to link | |
| 4 | // into. After this was patched in #63956, this test checks that the bug does not make | |
| 5 | // a resurgence. | |
| 6 | // See https://github.com/rust-lang/rust/issues/63349 | |
| 7 | ||
| 8 | //@ ignore-cross-compile | |
| 9 | ||
| 10 | use run_make_support::rustc; | |
| 11 | ||
| 12 | fn main() { | |
| 13 | rustc().input("lib.rs").arg("-Clto=fat").opt_level("3").incremental("inc-fat").run(); | |
| 14 | rustc().input("lib.rs").arg("-Clto=fat").opt_level("3").incremental("inc-fat").run(); | |
| 15 | rustc().input("lib.rs").arg("-Clto=thin").opt_level("3").incremental("inc-thin").run(); | |
| 16 | rustc().input("lib.rs").arg("-Clto=thin").opt_level("3").incremental("inc-thin").run(); | |
| 17 | } |
tests/run-make/raw-fn-pointer-opt-undefined-behavior/foo.rs created+15| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | fn identity(a: &u32) -> &u32 { | |
| 2 | a | |
| 3 | } | |
| 4 | ||
| 5 | fn print_foo(f: &fn(&u32) -> &u32, x: &u32) { | |
| 6 | print!("{}", (*f)(x)); | |
| 7 | } | |
| 8 | ||
| 9 | fn main() { | |
| 10 | let x = &4; | |
| 11 | let f: fn(&u32) -> &u32 = identity; | |
| 12 | ||
| 13 | // Didn't print 4 on optimized builds | |
| 14 | print_foo(&f, x); | |
| 15 | } |
tests/run-make/raw-fn-pointer-opt-undefined-behavior/rmake.rs created+16| ... | ... | @@ -0,0 +1,16 @@ |
| 1 | // Despite the absence of any unsafe Rust code, foo.rs in this test would, | |
| 2 | // because of the raw function pointer, | |
| 3 | // cause undefined behavior and fail to print the expected result, "4" - | |
| 4 | // only when activating optimizations (opt-level 2). This test checks | |
| 5 | // that this bug does not make a resurgence. | |
| 6 | // Note that the bug cannot be observed in an assert_eq!, only in the stdout. | |
| 7 | // See https://github.com/rust-lang/rust/issues/20626 | |
| 8 | ||
| 9 | //@ ignore-cross-compile | |
| 10 | ||
| 11 | use run_make_support::{run, rustc}; | |
| 12 | ||
| 13 | fn main() { | |
| 14 | rustc().input("foo.rs").opt().run(); | |
| 15 | run("foo").assert_stdout_equals("4"); | |
| 16 | } |
tests/ui/array-slice-vec/vec-res-add.stderr+5| ... | ... | @@ -5,6 +5,11 @@ LL | let k = i + j; |
| 5 | 5 | | - ^ - Vec<R> |
| 6 | 6 | | | |
| 7 | 7 | | Vec<R> |
| 8 | | | |
| 9 | note: the foreign item type `Vec<R>` doesn't implement `Add` | |
| 10 | --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL | |
| 11 | | | |
| 12 | = note: not implement `Add` | |
| 8 | 13 | |
| 9 | 14 | error: aborting due to 1 previous error |
| 10 | 15 |
tests/ui/autoderef-full-lval.stderr+12| ... | ... | @@ -5,6 +5,12 @@ LL | let z: isize = a.x + b.y; |
| 5 | 5 | | --- ^ --- Box<isize> |
| 6 | 6 | | | |
| 7 | 7 | | Box<isize> |
| 8 | | | |
| 9 | note: the foreign item type `Box<isize>` doesn't implement `Add` | |
| 10 | --> $SRC_DIR/alloc/src/boxed.rs:LL:COL | |
| 11 | ::: $SRC_DIR/alloc/src/boxed.rs:LL:COL | |
| 12 | | | |
| 13 | = note: not implement `Add` | |
| 8 | 14 | |
| 9 | 15 | error[E0369]: cannot add `Box<isize>` to `Box<isize>` |
| 10 | 16 | --> $DIR/autoderef-full-lval.rs:21:33 |
| ... | ... | @@ -13,6 +19,12 @@ LL | let answer: isize = forty.a + two.a; |
| 13 | 19 | | ------- ^ ----- Box<isize> |
| 14 | 20 | | | |
| 15 | 21 | | Box<isize> |
| 22 | | | |
| 23 | note: the foreign item type `Box<isize>` doesn't implement `Add` | |
| 24 | --> $SRC_DIR/alloc/src/boxed.rs:LL:COL | |
| 25 | ::: $SRC_DIR/alloc/src/boxed.rs:LL:COL | |
| 26 | | | |
| 27 | = note: not implement `Add` | |
| 16 | 28 | |
| 17 | 29 | error: aborting due to 2 previous errors |
| 18 | 30 |
tests/ui/binop/binary-op-not-allowed-issue-125631.rs created+16| ... | ... | @@ -0,0 +1,16 @@ |
| 1 | use std::io::{Error, ErrorKind}; | |
| 2 | use std::thread; | |
| 3 | ||
| 4 | struct T1; | |
| 5 | struct T2; | |
| 6 | ||
| 7 | fn main() { | |
| 8 | (Error::new(ErrorKind::Other, "1"), T1, 1) == (Error::new(ErrorKind::Other, "1"), T1, 2); | |
| 9 | //~^ERROR binary operation `==` cannot be applied to type | |
| 10 | (Error::new(ErrorKind::Other, "2"), thread::current()) | |
| 11 | == (Error::new(ErrorKind::Other, "2"), thread::current()); | |
| 12 | //~^ERROR binary operation `==` cannot be applied to type | |
| 13 | (Error::new(ErrorKind::Other, "4"), thread::current(), T1, T2) | |
| 14 | == (Error::new(ErrorKind::Other, "4"), thread::current(), T1, T2); | |
| 15 | //~^ERROR binary operation `==` cannot be applied to type | |
| 16 | } |
tests/ui/binop/binary-op-not-allowed-issue-125631.stderr created+75| ... | ... | @@ -0,0 +1,75 @@ |
| 1 | error[E0369]: binary operation `==` cannot be applied to type `(std::io::Error, T1, {integer})` | |
| 2 | --> $DIR/binary-op-not-allowed-issue-125631.rs:8:48 | |
| 3 | | | |
| 4 | LL | (Error::new(ErrorKind::Other, "1"), T1, 1) == (Error::new(ErrorKind::Other, "1"), T1, 2); | |
| 5 | | ------------------------------------------ ^^ ------------------------------------------ (std::io::Error, T1, {integer}) | |
| 6 | | | | |
| 7 | | (std::io::Error, T1, {integer}) | |
| 8 | | | |
| 9 | note: an implementation of `PartialEq` might be missing for `T1` | |
| 10 | --> $DIR/binary-op-not-allowed-issue-125631.rs:4:1 | |
| 11 | | | |
| 12 | LL | struct T1; | |
| 13 | | ^^^^^^^^^ must implement `PartialEq` | |
| 14 | note: the foreign item type `std::io::Error` doesn't implement `PartialEq` | |
| 15 | --> $SRC_DIR/std/src/io/error.rs:LL:COL | |
| 16 | | | |
| 17 | = note: not implement `PartialEq` | |
| 18 | help: consider annotating `T1` with `#[derive(PartialEq)]` | |
| 19 | | | |
| 20 | LL + #[derive(PartialEq)] | |
| 21 | LL | struct T1; | |
| 22 | | | |
| 23 | ||
| 24 | error[E0369]: binary operation `==` cannot be applied to type `(std::io::Error, Thread)` | |
| 25 | --> $DIR/binary-op-not-allowed-issue-125631.rs:11:9 | |
| 26 | | | |
| 27 | LL | (Error::new(ErrorKind::Other, "2"), thread::current()) | |
| 28 | | ------------------------------------------------------ (std::io::Error, Thread) | |
| 29 | LL | == (Error::new(ErrorKind::Other, "2"), thread::current()); | |
| 30 | | ^^ ------------------------------------------------------ (std::io::Error, Thread) | |
| 31 | | | |
| 32 | note: the foreign item types don't implement required traits for this operation to be valid | |
| 33 | --> $SRC_DIR/std/src/io/error.rs:LL:COL | |
| 34 | | | |
| 35 | = note: not implement `PartialEq` | |
| 36 | --> $SRC_DIR/std/src/thread/mod.rs:LL:COL | |
| 37 | | | |
| 38 | = note: not implement `PartialEq` | |
| 39 | ||
| 40 | error[E0369]: binary operation `==` cannot be applied to type `(std::io::Error, Thread, T1, T2)` | |
| 41 | --> $DIR/binary-op-not-allowed-issue-125631.rs:14:9 | |
| 42 | | | |
| 43 | LL | (Error::new(ErrorKind::Other, "4"), thread::current(), T1, T2) | |
| 44 | | -------------------------------------------------------------- (std::io::Error, Thread, T1, T2) | |
| 45 | LL | == (Error::new(ErrorKind::Other, "4"), thread::current(), T1, T2); | |
| 46 | | ^^ -------------------------------------------------------------- (std::io::Error, Thread, T1, T2) | |
| 47 | | | |
| 48 | note: the following types would have to `impl` their required traits for this operation to be valid | |
| 49 | --> $DIR/binary-op-not-allowed-issue-125631.rs:4:1 | |
| 50 | | | |
| 51 | LL | struct T1; | |
| 52 | | ^^^^^^^^^ must implement `PartialEq` | |
| 53 | LL | struct T2; | |
| 54 | | ^^^^^^^^^ must implement `PartialEq` | |
| 55 | note: the foreign item types don't implement required traits for this operation to be valid | |
| 56 | --> $SRC_DIR/std/src/io/error.rs:LL:COL | |
| 57 | | | |
| 58 | = note: not implement `PartialEq` | |
| 59 | --> $SRC_DIR/std/src/thread/mod.rs:LL:COL | |
| 60 | | | |
| 61 | = note: not implement `PartialEq` | |
| 62 | help: consider annotating `T1` with `#[derive(PartialEq)]` | |
| 63 | | | |
| 64 | LL + #[derive(PartialEq)] | |
| 65 | LL | struct T1; | |
| 66 | | | |
| 67 | help: consider annotating `T2` with `#[derive(PartialEq)]` | |
| 68 | | | |
| 69 | LL + #[derive(PartialEq)] | |
| 70 | LL | struct T2; | |
| 71 | | | |
| 72 | ||
| 73 | error: aborting due to 3 previous errors | |
| 74 | ||
| 75 | For more information about this error, try `rustc --explain E0369`. |
tests/ui/binop/binop-bitxor-str.stderr+5| ... | ... | @@ -5,6 +5,11 @@ LL | fn main() { let x = "a".to_string() ^ "b".to_string(); } |
| 5 | 5 | | --------------- ^ --------------- String |
| 6 | 6 | | | |
| 7 | 7 | | String |
| 8 | | | |
| 9 | note: the foreign item type `String` doesn't implement `BitXor` | |
| 10 | --> $SRC_DIR/alloc/src/string.rs:LL:COL | |
| 11 | | | |
| 12 | = note: not implement `BitXor` | |
| 8 | 13 | |
| 9 | 14 | error: aborting due to 1 previous error |
| 10 | 15 |
tests/ui/error-codes/E0067.stderr+6| ... | ... | @@ -5,6 +5,12 @@ LL | LinkedList::new() += 1; |
| 5 | 5 | | -----------------^^^^^ |
| 6 | 6 | | | |
| 7 | 7 | | cannot use `+=` on type `LinkedList<_>` |
| 8 | | | |
| 9 | note: the foreign item type `LinkedList<_>` doesn't implement `AddAssign<{integer}>` | |
| 10 | --> $SRC_DIR/alloc/src/collections/linked_list.rs:LL:COL | |
| 11 | ::: $SRC_DIR/alloc/src/collections/linked_list.rs:LL:COL | |
| 12 | | | |
| 13 | = note: not implement `AddAssign<{integer}>` | |
| 8 | 14 | |
| 9 | 15 | error[E0067]: invalid left-hand side of assignment |
| 10 | 16 | --> $DIR/E0067.rs:4:23 |
tests/ui/impl-trait/in-trait/refine-resolution-errors.rs created+23| ... | ... | @@ -0,0 +1,23 @@ |
| 1 | // This is a non-regression test for issue #126670 where RPITIT refinement checking encountered | |
| 2 | // errors during resolution and ICEd. | |
| 3 | ||
| 4 | //@ edition: 2018 | |
| 5 | ||
| 6 | pub trait Mirror { | |
| 7 | type Assoc; | |
| 8 | } | |
| 9 | impl<T: ?Sized> Mirror for () { | |
| 10 | //~^ ERROR the type parameter `T` is not constrained | |
| 11 | type Assoc = T; | |
| 12 | } | |
| 13 | ||
| 14 | pub trait First { | |
| 15 | async fn first() -> <() as Mirror>::Assoc; | |
| 16 | //~^ ERROR type annotations needed | |
| 17 | } | |
| 18 | ||
| 19 | impl First for () { | |
| 20 | async fn first() {} | |
| 21 | } | |
| 22 | ||
| 23 | fn main() {} |
tests/ui/impl-trait/in-trait/refine-resolution-errors.stderr created+16| ... | ... | @@ -0,0 +1,16 @@ |
| 1 | error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates | |
| 2 | --> $DIR/refine-resolution-errors.rs:9:6 | |
| 3 | | | |
| 4 | LL | impl<T: ?Sized> Mirror for () { | |
| 5 | | ^ unconstrained type parameter | |
| 6 | ||
| 7 | error[E0282]: type annotations needed | |
| 8 | --> $DIR/refine-resolution-errors.rs:15:5 | |
| 9 | | | |
| 10 | LL | async fn first() -> <() as Mirror>::Assoc; | |
| 11 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type | |
| 12 | ||
| 13 | error: aborting due to 2 previous errors | |
| 14 | ||
| 15 | Some errors have detailed explanations: E0207, E0282. | |
| 16 | For more information about an error, try `rustc --explain E0207`. |
tests/ui/issues/issue-14915.stderr+6| ... | ... | @@ -5,6 +5,12 @@ LL | println!("{}", x + 1); |
| 5 | 5 | | - ^ - {integer} |
| 6 | 6 | | | |
| 7 | 7 | | Box<isize> |
| 8 | | | |
| 9 | note: the foreign item type `Box<isize>` doesn't implement `Add<{integer}>` | |
| 10 | --> $SRC_DIR/alloc/src/boxed.rs:LL:COL | |
| 11 | ::: $SRC_DIR/alloc/src/boxed.rs:LL:COL | |
| 12 | | | |
| 13 | = note: not implement `Add<{integer}>` | |
| 8 | 14 | |
| 9 | 15 | error: aborting due to 1 previous error |
| 10 | 16 |
tests/ui/minus-string.stderr+5| ... | ... | @@ -3,6 +3,11 @@ error[E0600]: cannot apply unary operator `-` to type `String` |
| 3 | 3 | | |
| 4 | 4 | LL | fn main() { -"foo".to_string(); } |
| 5 | 5 | | ^^^^^^^^^^^^^^^^^^ cannot apply unary operator `-` |
| 6 | | | |
| 7 | note: the foreign item type `String` doesn't implement `Neg` | |
| 8 | --> $SRC_DIR/alloc/src/string.rs:LL:COL | |
| 9 | | | |
| 10 | = note: not implement `Neg` | |
| 6 | 11 | |
| 7 | 12 | error: aborting due to 1 previous error |
| 8 | 13 |
tests/ui/parser/fn-header-semantic-fail.stderr+10-6| ... | ... | @@ -81,11 +81,13 @@ LL | async fn fe1(); |
| 81 | 81 | error: items in unadorned `extern` blocks cannot have safety qualifiers |
| 82 | 82 | --> $DIR/fn-header-semantic-fail.rs:47:9 |
| 83 | 83 | | |
| 84 | LL | extern "C" { | |
| 85 | | ---------- help: add unsafe to this `extern` block | |
| 86 | LL | async fn fe1(); | |
| 87 | 84 | LL | unsafe fn fe2(); |
| 88 | 85 | | ^^^^^^^^^^^^^^^^ |
| 86 | | | |
| 87 | help: add unsafe to this `extern` block | |
| 88 | | | |
| 89 | LL | unsafe extern "C" { | |
| 90 | | ++++++ | |
| 89 | 91 | |
| 90 | 92 | error: functions in `extern` blocks cannot have qualifiers |
| 91 | 93 | --> $DIR/fn-header-semantic-fail.rs:48:9 |
| ... | ... | @@ -135,11 +137,13 @@ LL | const async unsafe extern "C" fn fe5(); |
| 135 | 137 | error: items in unadorned `extern` blocks cannot have safety qualifiers |
| 136 | 138 | --> $DIR/fn-header-semantic-fail.rs:50:9 |
| 137 | 139 | | |
| 138 | LL | extern "C" { | |
| 139 | | ---------- help: add unsafe to this `extern` block | |
| 140 | ... | |
| 141 | 140 | LL | const async unsafe extern "C" fn fe5(); |
| 142 | 141 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 142 | | | |
| 143 | help: add unsafe to this `extern` block | |
| 144 | | | |
| 145 | LL | unsafe extern "C" { | |
| 146 | | ++++++ | |
| 143 | 147 | |
| 144 | 148 | error: functions cannot be both `const` and `async` |
| 145 | 149 | --> $DIR/fn-header-semantic-fail.rs:50:9 |
tests/ui/parser/no-const-fn-in-extern-block.stderr+5-3| ... | ... | @@ -18,11 +18,13 @@ LL | const unsafe fn bar(); |
| 18 | 18 | error: items in unadorned `extern` blocks cannot have safety qualifiers |
| 19 | 19 | --> $DIR/no-const-fn-in-extern-block.rs:4:5 |
| 20 | 20 | | |
| 21 | LL | extern "C" { | |
| 22 | | ---------- help: add unsafe to this `extern` block | |
| 23 | ... | |
| 24 | 21 | LL | const unsafe fn bar(); |
| 25 | 22 | | ^^^^^^^^^^^^^^^^^^^^^^ |
| 23 | | | |
| 24 | help: add unsafe to this `extern` block | |
| 25 | | | |
| 26 | LL | unsafe extern "C" { | |
| 27 | | ++++++ | |
| 26 | 28 | |
| 27 | 29 | error: aborting due to 3 previous errors |
| 28 | 30 |
tests/ui/parser/unsafe-foreign-mod-2.stderr+5-3| ... | ... | @@ -13,11 +13,13 @@ LL | extern "C" unsafe { |
| 13 | 13 | error: items in unadorned `extern` blocks cannot have safety qualifiers |
| 14 | 14 | --> $DIR/unsafe-foreign-mod-2.rs:4:5 |
| 15 | 15 | | |
| 16 | LL | extern "C" unsafe { | |
| 17 | | ----------------- help: add unsafe to this `extern` block | |
| 18 | ... | |
| 19 | 16 | LL | unsafe fn foo(); |
| 20 | 17 | | ^^^^^^^^^^^^^^^^ |
| 18 | | | |
| 19 | help: add unsafe to this `extern` block | |
| 20 | | | |
| 21 | LL | unsafe extern "C" unsafe { | |
| 22 | | ++++++ | |
| 21 | 23 | |
| 22 | 24 | error: aborting due to 3 previous errors |
| 23 | 25 |
tests/ui/pattern/pattern-tyvar-2.stderr+5| ... | ... | @@ -5,6 +5,11 @@ LL | fn foo(t: Bar) -> isize { match t { Bar::T1(_, Some(x)) => { return x * 3; |
| 5 | 5 | | - ^ - {integer} |
| 6 | 6 | | | |
| 7 | 7 | | Vec<isize> |
| 8 | | | |
| 9 | note: the foreign item type `Vec<isize>` doesn't implement `Mul<{integer}>` | |
| 10 | --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL | |
| 11 | | | |
| 12 | = note: not implement `Mul<{integer}>` | |
| 8 | 13 | |
| 9 | 14 | error: aborting due to 1 previous error |
| 10 | 15 |
tests/ui/rust-2024/safe-outside-extern.gated.stderr+1-1| ... | ... | @@ -26,7 +26,7 @@ error: function pointers cannot be declared with `safe` safety qualifier |
| 26 | 26 | --> $DIR/safe-outside-extern.rs:24:14 |
| 27 | 27 | | |
| 28 | 28 | LL | type FnPtr = safe fn(i32, i32) -> i32; |
| 29 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 29 | | ^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 30 | 30 | |
| 31 | 31 | error: aborting due to 5 previous errors |
| 32 | 32 |
tests/ui/rust-2024/safe-outside-extern.ungated.stderr+1-1| ... | ... | @@ -26,7 +26,7 @@ error: function pointers cannot be declared with `safe` safety qualifier |
| 26 | 26 | --> $DIR/safe-outside-extern.rs:24:14 |
| 27 | 27 | | |
| 28 | 28 | LL | type FnPtr = safe fn(i32, i32) -> i32; |
| 29 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 29 | | ^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 30 | 30 | |
| 31 | 31 | error[E0658]: `unsafe extern {}` blocks and `safe` keyword are experimental |
| 32 | 32 | --> $DIR/safe-outside-extern.rs:4:1 |
tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2021.stderr+10-6| ... | ... | @@ -1,20 +1,24 @@ |
| 1 | 1 | error: items in unadorned `extern` blocks cannot have safety qualifiers |
| 2 | 2 | --> $DIR/safe-unsafe-on-unadorned-extern-block.rs:10:5 |
| 3 | 3 | | |
| 4 | LL | extern "C" { | |
| 5 | | ---------- help: add unsafe to this `extern` block | |
| 6 | LL | | |
| 7 | 4 | LL | safe static TEST1: i32; |
| 8 | 5 | | ^^^^^^^^^^^^^^^^^^^^^^^ |
| 6 | | | |
| 7 | help: add unsafe to this `extern` block | |
| 8 | | | |
| 9 | LL | unsafe extern "C" { | |
| 10 | | ++++++ | |
| 9 | 11 | |
| 10 | 12 | error: items in unadorned `extern` blocks cannot have safety qualifiers |
| 11 | 13 | --> $DIR/safe-unsafe-on-unadorned-extern-block.rs:12:5 |
| 12 | 14 | | |
| 13 | LL | extern "C" { | |
| 14 | | ---------- help: add unsafe to this `extern` block | |
| 15 | ... | |
| 16 | 15 | LL | safe fn test1(i: i32); |
| 17 | 16 | | ^^^^^^^^^^^^^^^^^^^^^^ |
| 17 | | | |
| 18 | help: add unsafe to this `extern` block | |
| 19 | | | |
| 20 | LL | unsafe extern "C" { | |
| 21 | | ++++++ | |
| 18 | 22 | |
| 19 | 23 | error: aborting due to 2 previous errors |
| 20 | 24 |
tests/ui/rust-2024/unsafe-extern-blocks/safe-unsafe-on-unadorned-extern-block.edition2024.stderr+10-6| ... | ... | @@ -13,20 +13,24 @@ LL | | } |
| 13 | 13 | error: items in unadorned `extern` blocks cannot have safety qualifiers |
| 14 | 14 | --> $DIR/safe-unsafe-on-unadorned-extern-block.rs:10:5 |
| 15 | 15 | | |
| 16 | LL | extern "C" { | |
| 17 | | ---------- help: add unsafe to this `extern` block | |
| 18 | LL | | |
| 19 | 16 | LL | safe static TEST1: i32; |
| 20 | 17 | | ^^^^^^^^^^^^^^^^^^^^^^^ |
| 18 | | | |
| 19 | help: add unsafe to this `extern` block | |
| 20 | | | |
| 21 | LL | unsafe extern "C" { | |
| 22 | | ++++++ | |
| 21 | 23 | |
| 22 | 24 | error: items in unadorned `extern` blocks cannot have safety qualifiers |
| 23 | 25 | --> $DIR/safe-unsafe-on-unadorned-extern-block.rs:12:5 |
| 24 | 26 | | |
| 25 | LL | extern "C" { | |
| 26 | | ---------- help: add unsafe to this `extern` block | |
| 27 | ... | |
| 28 | 27 | LL | safe fn test1(i: i32); |
| 29 | 28 | | ^^^^^^^^^^^^^^^^^^^^^^ |
| 29 | | | |
| 30 | help: add unsafe to this `extern` block | |
| 31 | | | |
| 32 | LL | unsafe extern "C" { | |
| 33 | | ++++++ | |
| 30 | 34 | |
| 31 | 35 | error: aborting due to 3 previous errors |
| 32 | 36 |
tests/ui/rust-2024/unsafe-extern-blocks/unsafe-on-extern-block-issue-126756.fixed created+10| ... | ... | @@ -0,0 +1,10 @@ |
| 1 | //@ run-rustfix | |
| 2 | ||
| 3 | #![feature(unsafe_extern_blocks)] | |
| 4 | #![allow(dead_code)] | |
| 5 | ||
| 6 | unsafe extern "C" { | |
| 7 | unsafe fn foo(); //~ ERROR items in unadorned `extern` blocks cannot have safety qualifiers | |
| 8 | } | |
| 9 | ||
| 10 | fn main() {} |
tests/ui/rust-2024/unsafe-extern-blocks/unsafe-on-extern-block-issue-126756.rs created+10| ... | ... | @@ -0,0 +1,10 @@ |
| 1 | //@ run-rustfix | |
| 2 | ||
| 3 | #![feature(unsafe_extern_blocks)] | |
| 4 | #![allow(dead_code)] | |
| 5 | ||
| 6 | extern "C" { | |
| 7 | unsafe fn foo(); //~ ERROR items in unadorned `extern` blocks cannot have safety qualifiers | |
| 8 | } | |
| 9 | ||
| 10 | fn main() {} |
tests/ui/rust-2024/unsafe-extern-blocks/unsafe-on-extern-block-issue-126756.stderr created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | error: items in unadorned `extern` blocks cannot have safety qualifiers | |
| 2 | --> $DIR/unsafe-on-extern-block-issue-126756.rs:7:5 | |
| 3 | | | |
| 4 | LL | unsafe fn foo(); | |
| 5 | | ^^^^^^^^^^^^^^^^ | |
| 6 | | | |
| 7 | help: add unsafe to this `extern` block | |
| 8 | | | |
| 9 | LL | unsafe extern "C" { | |
| 10 | | ++++++ | |
| 11 | ||
| 12 | error: aborting due to 1 previous error | |
| 13 |
tests/ui/typeck/assign-non-lval-derefmut.stderr+8| ... | ... | @@ -19,6 +19,10 @@ LL | x.lock().unwrap() += 1; |
| 19 | 19 | | | |
| 20 | 20 | | cannot use `+=` on type `MutexGuard<'_, usize>` |
| 21 | 21 | | |
| 22 | note: the foreign item type `MutexGuard<'_, usize>` doesn't implement `AddAssign<{integer}>` | |
| 23 | --> $SRC_DIR/std/src/sync/mutex.rs:LL:COL | |
| 24 | | | |
| 25 | = note: not implement `AddAssign<{integer}>` | |
| 22 | 26 | help: `+=` can be used on `usize` if you dereference the left-hand side |
| 23 | 27 | | |
| 24 | 28 | LL | *x.lock().unwrap() += 1; |
| ... | ... | @@ -47,6 +51,10 @@ LL | y += 1; |
| 47 | 51 | | | |
| 48 | 52 | | cannot use `+=` on type `MutexGuard<'_, usize>` |
| 49 | 53 | | |
| 54 | note: the foreign item type `MutexGuard<'_, usize>` doesn't implement `AddAssign<{integer}>` | |
| 55 | --> $SRC_DIR/std/src/sync/mutex.rs:LL:COL | |
| 56 | | | |
| 57 | = note: not implement `AddAssign<{integer}>` | |
| 50 | 58 | help: `+=` can be used on `usize` if you dereference the left-hand side |
| 51 | 59 | | |
| 52 | 60 | LL | *y += 1; |