about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-06-15 01:04:37 +0000
committerMichael Goulet <michael@errs.io>2023-06-27 18:28:27 +0000
commitde0e7d32fda38cde6f604df76e72bd6f26cea8ab (patch)
tree9ffb5f9fb2932923caa411b1287f1323fbed47c8
parent858a861fff3c054f5eccb74c22d061f1765e9cbd (diff)
downloadrust-de0e7d32fda38cde6f604df76e72bd6f26cea8ab.tar.gz
rust-de0e7d32fda38cde6f604df76e72bd6f26cea8ab.zip
pass PredicateFilter to compute_bounds
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/bounds.rs62
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs18
-rw-r--r--compiler/rustc_hir_analysis/src/collect/item_bounds.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs37
4 files changed, 51 insertions, 72 deletions
diff --git a/compiler/rustc_hir_analysis/src/astconv/bounds.rs b/compiler/rustc_hir_analysis/src/astconv/bounds.rs
index d29601e9008..89677141f38 100644
--- a/compiler/rustc_hir_analysis/src/astconv/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/bounds.rs
@@ -9,12 +9,12 @@ use rustc_span::symbol::Ident;
 use rustc_span::{ErrorGuaranteed, Span};
 use rustc_trait_selection::traits;
 
-use crate::astconv::{AstConv, ConvertedBinding, ConvertedBindingKind};
+use crate::astconv::{
+    AstConv, ConvertedBinding, ConvertedBindingKind, OnlySelfBounds, PredicateFilter,
+};
 use crate::bounds::Bounds;
 use crate::errors::{MultipleRelaxedDefaultBounds, ValueOfAssociatedStructAlreadySpecified};
 
-use super::OnlySelfBounds;
-
 impl<'tcx> dyn AstConv<'tcx> + '_ {
     /// Sets `implicitly_sized` to true on `Bounds` if necessary
     pub(crate) fn add_implicitly_sized(
@@ -176,47 +176,39 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
         &self,
         param_ty: Ty<'tcx>,
         ast_bounds: &[hir::GenericBound<'_>],
-        only_self_bounds: OnlySelfBounds,
+        filter: PredicateFilter,
     ) -> Bounds<'tcx> {
         let mut bounds = Bounds::default();
-        self.add_bounds(
-            param_ty,
-            ast_bounds.iter(),
-            &mut bounds,
-            ty::List::empty(),
-            only_self_bounds,
-        );
-        debug!(?bounds);
 
-        bounds
-    }
-
-    /// Convert the bounds in `ast_bounds` that refer to traits which define an associated type
-    /// named `assoc_name` into ty::Bounds. Ignore the rest.
-    pub(crate) fn compute_bounds_that_match_assoc_item(
-        &self,
-        param_ty: Ty<'tcx>,
-        ast_bounds: &[hir::GenericBound<'_>],
-        assoc_name: Ident,
-    ) -> Bounds<'tcx> {
-        let mut result = Vec::new();
-
-        for ast_bound in ast_bounds {
-            if let Some(trait_ref) = ast_bound.trait_ref()
-                && let Some(trait_did) = trait_ref.trait_def_id()
-                && self.tcx().trait_may_define_assoc_item(trait_did, assoc_name)
-            {
-                result.push(ast_bound.clone());
+        let only_self_bounds = match filter {
+            PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {
+                OnlySelfBounds(false)
             }
-        }
+            PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => OnlySelfBounds(true),
+        };
 
-        let mut bounds = Bounds::default();
         self.add_bounds(
             param_ty,
-            result.iter(),
+            ast_bounds.iter().filter(|bound| {
+                match filter {
+                PredicateFilter::All
+                | PredicateFilter::SelfOnly
+                | PredicateFilter::SelfAndAssociatedTypeBounds => true,
+                PredicateFilter::SelfThatDefines(assoc_name) => {
+                    if let Some(trait_ref) = bound.trait_ref()
+                        && let Some(trait_did) = trait_ref.trait_def_id()
+                        && self.tcx().trait_may_define_assoc_item(trait_did, assoc_name)
+                    {
+                        true
+                    } else {
+                        false
+                    }
+                }
+            }
+            }),
             &mut bounds,
             ty::List::empty(),
-            OnlySelfBounds(true),
+            only_self_bounds,
         );
         debug!(?bounds);
 
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 6a59aa36ec7..5032378923b 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -58,6 +58,24 @@ pub struct PathSeg(pub DefId, pub usize);
 #[derive(Copy, Clone, Debug)]
 pub struct OnlySelfBounds(pub bool);
 
+#[derive(Copy, Clone, Debug)]
+pub enum PredicateFilter {
+    /// All predicates may be implied by the trait.
+    All,
+
+    /// Only traits that reference `Self: ..` are implied by the trait.
+    SelfOnly,
+
+    /// Only traits that reference `Self: ..` and define an associated type
+    /// with the given ident are implied by the trait.
+    SelfThatDefines(Ident),
+
+    /// Only traits that reference `Self: ..` and their associated type bounds.
+    /// For example, given `Self: Tr<A: B>`, this would expand to `Self: Tr`
+    /// and `<Self as Tr>::A: B`.
+    SelfAndAssociatedTypeBounds,
+}
+
 pub trait AstConv<'tcx> {
     fn tcx(&self) -> TyCtxt<'tcx>;
 
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
index 44c393bfe82..8b3f98493c1 100644
--- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
+++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
@@ -1,5 +1,5 @@
 use super::ItemCtxt;
-use crate::astconv::{AstConv, OnlySelfBounds};
+use crate::astconv::{AstConv, PredicateFilter};
 use rustc_hir as hir;
 use rustc_infer::traits::util;
 use rustc_middle::ty::subst::InternalSubsts;
@@ -26,7 +26,7 @@ fn associated_type_bounds<'tcx>(
     );
 
     let icx = ItemCtxt::new(tcx, assoc_item_def_id);
-    let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, OnlySelfBounds(false));
+    let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, PredicateFilter::All);
     // Associated types are implicitly sized unless a `?Sized` bound is found
     icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span);
 
@@ -68,7 +68,7 @@ fn opaque_type_bounds<'tcx>(
 ) -> &'tcx [(ty::Clause<'tcx>, Span)] {
     ty::print::with_no_queries!({
         let icx = ItemCtxt::new(tcx, opaque_def_id);
-        let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, OnlySelfBounds(false));
+        let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds, PredicateFilter::All);
         // Opaque types are implicitly sized unless a `?Sized` bound is found
         icx.astconv().add_implicitly_sized(&mut bounds, item_ty, ast_bounds, None, span);
         debug!(?bounds);
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index 5605901fbcb..d9b2aacab9d 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -1,4 +1,4 @@
-use crate::astconv::{AstConv, OnlySelfBounds};
+use crate::astconv::{AstConv, OnlySelfBounds, PredicateFilter};
 use crate::bounds::Bounds;
 use crate::collect::ItemCtxt;
 use crate::constrained_generic_params as cgp;
@@ -125,7 +125,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
     if let Some(self_bounds) = is_trait {
         predicates.extend(
             icx.astconv()
-                .compute_bounds(tcx.types.self_param, self_bounds, OnlySelfBounds(false))
+                .compute_bounds(tcx.types.self_param, self_bounds, PredicateFilter::All)
                 .clauses(),
         );
     }
@@ -530,24 +530,6 @@ pub(super) fn explicit_predicates_of<'tcx>(
     }
 }
 
-#[derive(Copy, Clone, Debug)]
-pub enum PredicateFilter {
-    /// All predicates may be implied by the trait.
-    All,
-
-    /// Only traits that reference `Self: ..` are implied by the trait.
-    SelfOnly,
-
-    /// Only traits that reference `Self: ..` and define an associated type
-    /// with the given ident are implied by the trait.
-    SelfThatDefines(Ident),
-
-    /// Only traits that reference `Self: ..` and their associated type bounds.
-    /// For example, given `Self: Tr<A: B>`, this would expand to `Self: Tr`
-    /// and `<Self as Tr>::A: B`.
-    SelfAndAssociatedTypeBounds,
-}
-
 /// Ensures that the super-predicates of the trait with a `DefId`
 /// of `trait_def_id` are converted and stored. This also ensures that
 /// the transitive super-predicates are converted.
@@ -610,20 +592,7 @@ pub(super) fn implied_predicates_with_filter(
     let icx = ItemCtxt::new(tcx, trait_def_id);
 
     let self_param_ty = tcx.types.self_param;
-    let superbounds = match filter {
-        // Should imply both "real" supertraits, and also associated type bounds
-        // from the supertraits position.
-        PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {
-            icx.astconv().compute_bounds(self_param_ty, bounds, OnlySelfBounds(false))
-        }
-        // Should only imply "real" supertraits, i.e. predicates with the self type `Self`.
-        PredicateFilter::SelfOnly => {
-            icx.astconv().compute_bounds(self_param_ty, bounds, OnlySelfBounds(true))
-        }
-        PredicateFilter::SelfThatDefines(assoc_name) => {
-            icx.astconv().compute_bounds_that_match_assoc_item(self_param_ty, bounds, assoc_name)
-        }
-    };
+    let superbounds = icx.astconv().compute_bounds(self_param_ty, bounds, filter);
 
     let where_bounds_that_match = icx.type_parameter_bounds_in_generics(
         generics,