From d0c877b901726471cede0e1054efe189200ab26b Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 17 Jan 2023 01:58:10 +0000 Subject: [PATCH] Revert PR "Rework some predicates_of/{Generic,Instantiated}Predicates code" Revert "Remove bound_{explicit,}_item_bounds" This reverts commit 90df86f474e9214fe3337181db8e88b9b785e6fe. Revert "drive-by: assert when iterating through InstantiatedPredicates" This reverts commit e1533a26f77000b6e22195987ef45d0aae3c710a. Revert "Make InstantiatedPredicates impl IntoIterator" This reverts commit 9b28edb6d7746f457e79f5ca2c4ade944f653113. Revert "instantiate_own doesn't need to return a pair of vectors" This reverts commit 91fd862df011168e7634f79fc2f2c9fb15a7afd3. --- .../src/diagnostics/conflict_errors.rs | 48 +++++++++++-------- .../src/type_check/canonical.rs | 6 ++- .../src/check/compare_impl_item.rs | 25 +++++----- .../rustc_hir_analysis/src/check/wfcheck.rs | 29 ++++++----- compiler/rustc_hir_typeck/src/callee.rs | 8 ++-- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 3 +- .../rustc_hir_typeck/src/method/confirm.rs | 10 ++-- .../src/infer/error_reporting/note.rs | 5 +- compiler/rustc_middle/src/ty/generics.rs | 12 +++-- compiler/rustc_middle/src/ty/mod.rs | 29 ----------- compiler/rustc_middle/src/ty/subst.rs | 15 ------ compiler/rustc_middle/src/ty/util.rs | 14 ++++++ .../src/traits/error_reporting/ambiguity.rs | 4 +- .../src/traits/error_reporting/suggestions.rs | 4 +- .../rustc_trait_selection/src/traits/mod.rs | 14 +++--- .../src/traits/project.rs | 40 ++++++++-------- .../src/traits/select/confirmation.rs | 5 +- .../src/traits/select/mod.rs | 13 ++--- .../src/traits/vtable.rs | 5 +- .../rustc_trait_selection/src/traits/wf.rs | 2 +- compiler/rustc_traits/src/chalk/db.rs | 15 +++--- compiler/rustc_traits/src/type_op.rs | 5 +- 22 files changed, 156 insertions(+), 155 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index e512099b93b13..968c1f49b95c0 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -673,34 +673,40 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let tcx = self.infcx.tcx; // Find out if the predicates show that the type is a Fn or FnMut - let find_fn_kind_from_did = |(pred, _): (ty::Predicate<'tcx>, _)| { - if let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) = pred.kind().skip_binder() - && pred.self_ty() == ty - { - if Some(pred.def_id()) == tcx.lang_items().fn_trait() { - return Some(hir::Mutability::Not); - } else if Some(pred.def_id()) == tcx.lang_items().fn_mut_trait() { - return Some(hir::Mutability::Mut); + let find_fn_kind_from_did = |predicates: ty::EarlyBinder< + &[(ty::Predicate<'tcx>, Span)], + >, + substs| { + predicates.0.iter().find_map(|(pred, _)| { + let pred = if let Some(substs) = substs { + predicates.rebind(*pred).subst(tcx, substs).kind().skip_binder() + } else { + pred.kind().skip_binder() + }; + if let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) = pred && pred.self_ty() == ty { + if Some(pred.def_id()) == tcx.lang_items().fn_trait() { + return Some(hir::Mutability::Not); + } else if Some(pred.def_id()) == tcx.lang_items().fn_mut_trait() { + return Some(hir::Mutability::Mut); + } } - } - None + None + }) }; // If the type is opaque/param/closure, and it is Fn or FnMut, let's suggest (mutably) // borrowing the type, since `&mut F: FnMut` iff `F: FnMut` and similarly for `Fn`. // These types seem reasonably opaque enough that they could be substituted with their // borrowed variants in a function body when we see a move error. - let borrow_level = match *ty.kind() { - ty::Param(_) => tcx - .explicit_predicates_of(self.mir_def_id().to_def_id()) - .predicates - .iter() - .copied() - .find_map(find_fn_kind_from_did), - ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => tcx - .bound_explicit_item_bounds(def_id) - .subst_iter_copied(tcx, substs) - .find_map(find_fn_kind_from_did), + let borrow_level = match ty.kind() { + ty::Param(_) => find_fn_kind_from_did( + tcx.bound_explicit_predicates_of(self.mir_def_id().to_def_id()) + .map_bound(|p| p.predicates), + None, + ), + ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => { + find_fn_kind_from_did(tcx.bound_explicit_item_bounds(*def_id), Some(*substs)) + } ty::Closure(_, substs) => match substs.as_closure().kind() { ty::ClosureKind::Fn => Some(hir::Mutability::Not), ty::ClosureKind::FnMut => Some(hir::Mutability::Mut), diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index 11729e2c83f0b..02222c0a03cb3 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -107,7 +107,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { instantiated_predicates: ty::InstantiatedPredicates<'tcx>, locations: Locations, ) { - for (predicate, span) in instantiated_predicates { + for (predicate, span) in instantiated_predicates + .predicates + .into_iter() + .zip(instantiated_predicates.spans.into_iter()) + { debug!(?predicate); let category = ConstraintCategory::Predicate(span); let predicate = self.normalize_with_category(predicate, locations, category); diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index c43bfd16ab1e4..770d7b6f927e4 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -209,11 +209,9 @@ fn compare_method_predicate_entailment<'tcx>( // // We then register the obligations from the impl_m and check to see // if all constraints hold. - hybrid_preds.predicates.extend( - trait_m_predicates - .instantiate_own(tcx, trait_to_placeholder_substs) - .map(|(predicate, _)| predicate), - ); + hybrid_preds + .predicates + .extend(trait_m_predicates.instantiate_own(tcx, trait_to_placeholder_substs).predicates); // Construct trait parameter environment and then shift it into the placeholder viewpoint. // The key step here is to update the caller_bounds's predicates to be @@ -232,7 +230,7 @@ fn compare_method_predicate_entailment<'tcx>( debug!("compare_impl_method: caller_bounds={:?}", param_env.caller_bounds()); let impl_m_own_bounds = impl_m_predicates.instantiate_own(tcx, impl_to_placeholder_substs); - for (predicate, span) in impl_m_own_bounds { + for (predicate, span) in iter::zip(impl_m_own_bounds.predicates, impl_m_own_bounds.spans) { let normalize_cause = traits::ObligationCause::misc(span, impl_m_hir_id); let predicate = ocx.normalize(&normalize_cause, param_env, predicate); @@ -1830,7 +1828,8 @@ fn compare_type_predicate_entailment<'tcx>( check_region_bounds_on_impl_item(tcx, impl_ty, trait_ty, false)?; let impl_ty_own_bounds = impl_ty_predicates.instantiate_own(tcx, impl_substs); - if impl_ty_own_bounds.len() == 0 { + + if impl_ty_own_bounds.is_empty() { // Nothing to check. return Ok(()); } @@ -1845,11 +1844,9 @@ fn compare_type_predicate_entailment<'tcx>( // associated type in the trait are assumed. let impl_predicates = tcx.predicates_of(impl_ty_predicates.parent.unwrap()); let mut hybrid_preds = impl_predicates.instantiate_identity(tcx); - hybrid_preds.predicates.extend( - trait_ty_predicates - .instantiate_own(tcx, trait_to_impl_substs) - .map(|(predicate, _)| predicate), - ); + hybrid_preds + .predicates + .extend(trait_ty_predicates.instantiate_own(tcx, trait_to_impl_substs).predicates); debug!("compare_type_predicate_entailment: bounds={:?}", hybrid_preds); @@ -1865,7 +1862,9 @@ fn compare_type_predicate_entailment<'tcx>( debug!("compare_type_predicate_entailment: caller_bounds={:?}", param_env.caller_bounds()); - for (predicate, span) in impl_ty_own_bounds { + assert_eq!(impl_ty_own_bounds.predicates.len(), impl_ty_own_bounds.spans.len()); + for (span, predicate) in std::iter::zip(impl_ty_own_bounds.spans, impl_ty_own_bounds.predicates) + { let cause = ObligationCause::misc(span, impl_ty_hir_id); let predicate = ocx.normalize(&cause, param_env, predicate); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 49dd1eb22f7fe..912e0ec560b49 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -32,6 +32,7 @@ use rustc_trait_selection::traits::{ }; use std::cell::LazyCell; +use std::iter; use std::ops::{ControlFlow, Deref}; pub(super) struct WfCheckingCtxt<'a, 'tcx> { @@ -1309,7 +1310,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id let infcx = wfcx.infcx; let tcx = wfcx.tcx(); - let predicates = tcx.predicates_of(def_id.to_def_id()); + let predicates = tcx.bound_predicates_of(def_id.to_def_id()); let generics = tcx.generics_of(def_id); let is_our_default = |def: &ty::GenericParamDef| match def.kind { @@ -1410,6 +1411,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id // Now we build the substituted predicates. let default_obligations = predicates + .0 .predicates .iter() .flat_map(|&(pred, sp)| { @@ -1440,13 +1442,13 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id } let mut param_count = CountParams::default(); let has_region = pred.visit_with(&mut param_count).is_break(); - let substituted_pred = ty::EarlyBinder(pred).subst(tcx, substs); + let substituted_pred = predicates.rebind(pred).subst(tcx, substs); // Don't check non-defaulted params, dependent defaults (including lifetimes) // or preds with multiple params. if substituted_pred.has_non_region_param() || param_count.params.len() > 1 || has_region { None - } else if predicates.predicates.iter().any(|&(p, _)| p == substituted_pred) { + } else if predicates.0.predicates.iter().any(|&(p, _)| p == substituted_pred) { // Avoid duplication of predicates that contain no parameters, for example. None } else { @@ -1472,21 +1474,22 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id traits::Obligation::new(tcx, cause, wfcx.param_env, pred) }); - let predicates = predicates.instantiate_identity(tcx); + let predicates = predicates.0.instantiate_identity(tcx); let predicates = wfcx.normalize(span, None, predicates); debug!(?predicates.predicates); assert_eq!(predicates.predicates.len(), predicates.spans.len()); - let wf_obligations = predicates.into_iter().flat_map(|(p, sp)| { - traits::wf::predicate_obligations( - infcx, - wfcx.param_env.without_const(), - wfcx.body_id, - p, - sp, - ) - }); + let wf_obligations = + iter::zip(&predicates.predicates, &predicates.spans).flat_map(|(&p, &sp)| { + traits::wf::predicate_obligations( + infcx, + wfcx.param_env.without_const(), + wfcx.body_id, + p, + sp, + ) + }); let obligations: Vec<_> = wf_obligations.chain(default_obligations).collect(); wfcx.register_obligations(obligations); diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index b617821fbd652..f1a4f94cd0151 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -375,12 +375,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if self.tcx.has_attr(def_id, sym::rustc_evaluate_where_clauses) { let predicates = self.tcx.predicates_of(def_id); let predicates = predicates.instantiate(self.tcx, subst); - for (predicate, predicate_span) in predicates { + for (predicate, predicate_span) in + predicates.predicates.iter().zip(&predicates.spans) + { let obligation = Obligation::new( self.tcx, ObligationCause::dummy_with_span(callee_expr.span), self.param_env, - predicate, + *predicate, ); let result = self.evaluate_obligation(&obligation); self.tcx @@ -389,7 +391,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { callee_expr.span, &format!("evaluate({:?}) = {:?}", predicate, result), ) - .span_label(predicate_span, "predicate") + .span_label(*predicate_span, "predicate") .emit(); } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index c9609e6943981..b9e13fd200924 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -2140,7 +2140,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // FIXME(compiler-errors): This could be problematic if something has two // fn-like predicates with different args, but callable types really never // do that, so it's OK. - for (predicate, span) in instantiated + for (predicate, span) in + std::iter::zip(instantiated.predicates, instantiated.spans) { if let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) = predicate.kind().skip_binder() && pred.self_ty().peel_refs() == callee_ty diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 372ea30ebd08e..4a33a791e1b7f 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -19,6 +19,7 @@ use rustc_middle::ty::{InternalSubsts, UserSubsts, UserType}; use rustc_span::{Span, DUMMY_SP}; use rustc_trait_selection::traits; +use std::iter; use std::ops::Deref; struct ConfirmContext<'a, 'tcx> { @@ -100,7 +101,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { let filler_substs = rcvr_substs .extend_to(self.tcx, pick.item.def_id, |def, _| self.tcx.mk_param_from_def(def)); let illegal_sized_bound = self.predicates_require_illegal_sized_bound( - self.tcx.predicates_of(pick.item.def_id).instantiate(self.tcx, filler_substs), + &self.tcx.predicates_of(pick.item.def_id).instantiate(self.tcx, filler_substs), ); // Unify the (adjusted) self type with what the method expects. @@ -564,7 +565,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { fn predicates_require_illegal_sized_bound( &self, - predicates: ty::InstantiatedPredicates<'tcx>, + predicates: &ty::InstantiatedPredicates<'tcx>, ) -> Option { let sized_def_id = self.tcx.lang_items().sized_trait()?; @@ -574,11 +575,10 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) if trait_pred.def_id() == sized_def_id => { - let span = predicates - .iter() + let span = iter::zip(&predicates.predicates, &predicates.spans) .find_map( |(p, span)| { - if p == obligation.predicate { Some(span) } else { None } + if *p == obligation.predicate { Some(*span) } else { None } }, ) .unwrap_or(rustc_span::DUMMY_SP); diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index b18cbd404d47f..021e741ee2f71 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -330,8 +330,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let Ok(trait_predicates) = self .tcx - .explicit_predicates_of(trait_item_def_id) - .instantiate_own(self.tcx, trait_item_substs) + .bound_explicit_predicates_of(trait_item_def_id) + .map_bound(|p| p.predicates) + .subst_iter_copied(self.tcx, trait_item_substs) .map(|(pred, _)| { if pred.is_suggestable(self.tcx, false) { Ok(pred.to_string()) diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 801ca60044568..8a5e765b9a306 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -341,9 +341,15 @@ impl<'tcx> GenericPredicates<'tcx> { &self, tcx: TyCtxt<'tcx>, substs: SubstsRef<'tcx>, - ) -> impl Iterator, Span)> + DoubleEndedIterator + ExactSizeIterator - { - EarlyBinder(self.predicates).subst_iter_copied(tcx, substs) + ) -> InstantiatedPredicates<'tcx> { + InstantiatedPredicates { + predicates: self + .predicates + .iter() + .map(|(p, _)| EarlyBinder(*p).subst(tcx, substs)) + .collect(), + spans: self.predicates.iter().map(|(_, sp)| *sp).collect(), + } } #[instrument(level = "debug", skip(self, tcx))] diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index bf8f45c50a3c9..e9bd0e9866fdc 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1252,35 +1252,6 @@ impl<'tcx> InstantiatedPredicates<'tcx> { pub fn is_empty(&self) -> bool { self.predicates.is_empty() } - - pub fn iter(&self) -> <&Self as IntoIterator>::IntoIter { - (&self).into_iter() - } -} - -impl<'tcx> IntoIterator for InstantiatedPredicates<'tcx> { - type Item = (Predicate<'tcx>, Span); - - type IntoIter = std::iter::Zip>, std::vec::IntoIter>; - - fn into_iter(self) -> Self::IntoIter { - debug_assert_eq!(self.predicates.len(), self.spans.len()); - std::iter::zip(self.predicates, self.spans) - } -} - -impl<'a, 'tcx> IntoIterator for &'a InstantiatedPredicates<'tcx> { - type Item = (Predicate<'tcx>, Span); - - type IntoIter = std::iter::Zip< - std::iter::Copied>>, - std::iter::Copied>, - >; - - fn into_iter(self) -> Self::IntoIter { - debug_assert_eq!(self.predicates.len(), self.spans.len()); - std::iter::zip(self.predicates.iter().copied(), self.spans.iter().copied()) - } } #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable, Lift)] diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 5dc9e311bf6b1..8f764011d0ac3 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -639,13 +639,6 @@ where } } -impl<'tcx, I: IntoIterator> ExactSizeIterator for SubstIter<'_, 'tcx, I> -where - I::IntoIter: ExactSizeIterator, - I::Item: TypeFoldable<'tcx>, -{ -} - impl<'tcx, 's, I: IntoIterator> EarlyBinder where I::Item: Deref, @@ -693,14 +686,6 @@ where } } -impl<'tcx, I: IntoIterator> ExactSizeIterator for SubstIterCopied<'_, 'tcx, I> -where - I::IntoIter: ExactSizeIterator, - I::Item: Deref, - ::Target: Copy + TypeFoldable<'tcx>, -{ -} - pub struct EarlyBinderIter { t: T, } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 37d3e12a66763..1286a5253c068 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -666,6 +666,20 @@ impl<'tcx> TyCtxt<'tcx> { ty::EarlyBinder(self.item_bounds(def_id)) } + pub fn bound_predicates_of( + self, + def_id: DefId, + ) -> ty::EarlyBinder> { + ty::EarlyBinder(self.predicates_of(def_id)) + } + + pub fn bound_explicit_predicates_of( + self, + def_id: DefId, + ) -> ty::EarlyBinder> { + ty::EarlyBinder(self.explicit_predicates_of(def_id)) + } + pub fn bound_impl_subject(self, def_id: DefId) -> ty::EarlyBinder> { ty::EarlyBinder(self.impl_subject(def_id)) } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs index 0419bb3f724f9..df57c0f60fa6d 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs @@ -82,7 +82,9 @@ pub fn recompute_applicable_impls<'tcx>( let predicates = tcx.predicates_of(obligation.cause.body_id.owner.to_def_id()).instantiate_identity(tcx); - for obligation in elaborate_predicates_with_span(tcx, predicates.into_iter()) { + for obligation in + elaborate_predicates_with_span(tcx, std::iter::zip(predicates.predicates, predicates.spans)) + { let kind = obligation.predicate.kind(); if let ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) = kind.skip_binder() && param_env_candidate_may_apply(kind.rebind(trait_pred)) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 6e2341a823b9b..5211f873a1e3b 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2070,7 +2070,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // Find another predicate whose self-type is equal to the expected self type, // but whose substs don't match. - let other_pred = predicates.into_iter() + let other_pred = std::iter::zip(&predicates.predicates, &predicates.spans) .enumerate() .find(|(other_idx, (pred, _))| match pred.kind().skip_binder() { ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) @@ -2095,7 +2095,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // If we found one, then it's very likely the cause of the error. if let Some((_, (_, other_pred_span))) = other_pred { err.span_note( - other_pred_span, + *other_pred_span, "closure inferred to have a different signature due to this bound", ); } diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 531aa23d6eac5..13aa067844a92 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -115,12 +115,14 @@ pub fn predicates_for_generics<'tcx>( param_env: ty::ParamEnv<'tcx>, generic_bounds: ty::InstantiatedPredicates<'tcx>, ) -> impl Iterator> { - generic_bounds.into_iter().enumerate().map(move |(idx, (predicate, span))| Obligation { - cause: cause(idx, span), - recursion_depth: 0, - param_env, - predicate, - }) + std::iter::zip(generic_bounds.predicates, generic_bounds.spans).enumerate().map( + move |(idx, (predicate, span))| Obligation { + cause: cause(idx, span), + recursion_depth: 0, + param_env, + predicate, + }, + ) } /// Determines whether the type `ty` is known to meet `bound` and diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 9c655aff0bac4..81966f3fcb231 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -2259,23 +2259,25 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>( tcx.predicates_of(impl_fn_def_id).instantiate(tcx, impl_fn_substs), &mut obligations, ); - obligations.extend(predicates.into_iter().map(|(pred, span)| { - Obligation::with_depth( - tcx, - ObligationCause::new( - obligation.cause.span, - obligation.cause.body_id, - if span.is_dummy() { - super::ItemObligation(impl_fn_def_id) - } else { - super::BindingObligation(impl_fn_def_id, span) - }, - ), - obligation.recursion_depth + 1, - obligation.param_env, - pred, - ) - })); + obligations.extend(std::iter::zip(predicates.predicates, predicates.spans).map( + |(pred, span)| { + Obligation::with_depth( + tcx, + ObligationCause::new( + obligation.cause.span, + obligation.cause.body_id, + if span.is_dummy() { + super::ItemObligation(impl_fn_def_id) + } else { + super::BindingObligation(impl_fn_def_id, span) + }, + ), + obligation.recursion_depth + 1, + obligation.param_env, + pred, + ) + }, + )); let ty = normalize_with_depth_to( selcx, @@ -2301,10 +2303,10 @@ fn assoc_ty_own_obligations<'cx, 'tcx>( nested: &mut Vec>, ) { let tcx = selcx.tcx(); - let predicates = tcx + let own = tcx .predicates_of(obligation.predicate.def_id) .instantiate_own(tcx, obligation.predicate.substs); - for (predicate, span) in predicates { + for (predicate, span) in std::iter::zip(own.predicates, own.spans) { let normalized = normalize_with_depth_to( selcx, obligation.param_env, diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index d4ac461690c90..a41d10f104358 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -185,8 +185,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { })?); if let ty::Alias(ty::Projection, ..) = placeholder_self_ty.kind() { - let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs); - for (predicate, _) in predicates { + let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs).predicates; + debug!(?predicates, "projection predicates"); + for predicate in predicates { let normalized = normalize_with_depth_to( self, obligation.param_env, diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 95c269d1b7853..ba4e668f52ddd 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2558,11 +2558,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // obligation will normalize to `<$0 as Iterator>::Item = $1` and // `$1: Copy`, so we must ensure the obligations are emitted in // that order. - let predicates = tcx.predicates_of(def_id); - assert_eq!(predicates.parent, None); - let predicates = predicates.instantiate_own(tcx, substs); - let mut obligations = Vec::with_capacity(predicates.len()); - for (predicate, span) in predicates { + let predicates = tcx.bound_predicates_of(def_id); + debug!(?predicates); + assert_eq!(predicates.0.parent, None); + let mut obligations = Vec::with_capacity(predicates.0.predicates.len()); + for (predicate, span) in predicates.0.predicates { + let span = *span; let cause = cause.clone().derived_cause(parent_trait_pred, |derived| { ImplDerivedObligation(Box::new(ImplDerivedObligationCause { derived, @@ -2575,7 +2576,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { param_env, cause.clone(), recursion_depth, - predicate, + predicates.rebind(*predicate).subst(tcx, substs), &mut obligations, ); obligations.push(Obligation { cause, recursion_depth, param_env, predicate }); diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index 64daca714c32d..5ec9c2a24cd44 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -261,10 +261,7 @@ fn vtable_entries<'tcx>( // Note that this method could then never be called, so we // do not want to try and codegen it, in that case (see #23435). let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs); - if impossible_predicates( - tcx, - predicates.map(|(predicate, _)| predicate).collect(), - ) { + if impossible_predicates(tcx, predicates.predicates) { debug!("vtable_entries: predicates do not hold"); return VtblEntry::Vacant; } diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 2cebad64c4373..fec4047ff49ba 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -736,7 +736,7 @@ impl<'tcx> WfPredicates<'tcx> { trace!("{:#?}", predicates); debug_assert_eq!(predicates.predicates.len(), origins.len()); - iter::zip(predicates, origins.into_iter().rev()) + iter::zip(iter::zip(predicates.predicates, predicates.spans), origins.into_iter().rev()) .map(|((mut pred, span), origin_def_id)| { let code = if span.is_dummy() { traits::ItemObligation(origin_def_id) diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index f146de3966ba1..7c0cae1e7bdc2 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -7,7 +7,7 @@ //! `crate::chalk::lowering` (to lower rustc types into Chalk types). use rustc_middle::traits::ChalkRustInterner as RustInterner; -use rustc_middle::ty::{self, AssocKind, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable}; +use rustc_middle::ty::{self, AssocKind, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable}; use rustc_middle::ty::{InternalSubsts, SubstsRef}; use rustc_target::abi::{Integer, IntegerType}; @@ -38,12 +38,13 @@ impl<'tcx> RustIrDatabase<'tcx> { def_id: DefId, bound_vars: SubstsRef<'tcx>, ) -> Vec>> { - self.interner - .tcx - .predicates_defined_on(def_id) - .instantiate_own(self.interner.tcx, bound_vars) - .filter_map(|(wc, _)| LowerInto::lower_into(wc, self.interner)) - .collect() + let predicates = self.interner.tcx.predicates_defined_on(def_id).predicates; + predicates + .iter() + .map(|(wc, _)| EarlyBinder(*wc).subst(self.interner.tcx, bound_vars)) + .filter_map(|wc| LowerInto::< + Option>> + >::lower_into(wc, self.interner)).collect() } fn bounds_for(&self, def_id: DefId, bound_vars: SubstsRef<'tcx>) -> Vec diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs index f35c5e44882df..aa5c83ac2e655 100644 --- a/compiler/rustc_traits/src/type_op.rs +++ b/compiler/rustc_traits/src/type_op.rs @@ -17,6 +17,7 @@ use rustc_trait_selection::traits::query::type_op::subtype::Subtype; use rustc_trait_selection::traits::query::{Fallible, NoSolution}; use rustc_trait_selection::traits::{Normalized, Obligation, ObligationCause, ObligationCtxt}; use std::fmt; +use std::iter::zip; pub(crate) fn provide(p: &mut Providers) { *p = Providers { @@ -107,7 +108,9 @@ fn relate_mir_and_user_substs<'tcx>( let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, substs); debug!(?instantiated_predicates); - for (instantiated_predicate, predicate_span) in instantiated_predicates { + for (instantiated_predicate, predicate_span) in + zip(instantiated_predicates.predicates, instantiated_predicates.spans) + { let span = if span == DUMMY_SP { predicate_span } else { span }; let cause = ObligationCause::new( span,