about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs11
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/effect_goals.rs51
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs8
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs8
4 files changed, 77 insertions, 1 deletions
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
index 5e604a5d74f..f6a5f20a639 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
@@ -100,6 +100,15 @@ where
         })
     }
 
+    /// Assemble additional assumptions for an alias that are not included
+    /// in the item bounds of the alias. For now, this is limited to the
+    /// `implied_const_bounds` for an associated type.
+    fn consider_additional_alias_assumptions(
+        ecx: &mut EvalCtxt<'_, D>,
+        goal: Goal<I, Self>,
+        alias_ty: ty::AliasTy<I>,
+    ) -> Vec<Candidate<I>>;
+
     fn consider_impl_candidate(
         ecx: &mut EvalCtxt<'_, D>,
         goal: Goal<I, Self>,
@@ -594,6 +603,8 @@ where
             ));
         }
 
+        candidates.extend(G::consider_additional_alias_assumptions(self, goal, alias_ty));
+
         if kind != ty::Projection {
             return;
         }
diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
index 62b4bb0004c..8d57ad8f255 100644
--- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
@@ -3,7 +3,7 @@
 
 use rustc_type_ir::fast_reject::DeepRejectCtxt;
 use rustc_type_ir::inherent::*;
-use rustc_type_ir::{self as ty, Interner};
+use rustc_type_ir::{self as ty, Interner, elaborate};
 use tracing::instrument;
 
 use super::assembly::Candidate;
@@ -70,6 +70,55 @@ where
         }
     }
 
+    /// Register additional assumptions for aliases corresponding to `~const` item bounds.
+    ///
+    /// Unlike item bounds, they are not simply implied by the well-formedness of the alias.
+    /// Instead, they only hold if the const conditons on the alias also hold. This is why
+    /// we also register the const conditions of the alias after matching the goal against
+    /// the assumption.
+    fn consider_additional_alias_assumptions(
+        ecx: &mut EvalCtxt<'_, D>,
+        goal: Goal<I, Self>,
+        alias_ty: ty::AliasTy<I>,
+    ) -> Vec<Candidate<I>> {
+        let cx = ecx.cx();
+        let mut candidates = vec![];
+
+        // FIXME(effects): We elaborate here because the implied const bounds
+        // aren't necessarily elaborated. We probably should prefix this query
+        // with `explicit_`...
+        for clause in elaborate::elaborate(
+            cx,
+            cx.implied_const_bounds(alias_ty.def_id)
+                .iter_instantiated(cx, alias_ty.args)
+                .map(|trait_ref| trait_ref.to_host_effect_clause(cx, goal.predicate.host)),
+        ) {
+            candidates.extend(Self::probe_and_match_goal_against_assumption(
+                ecx,
+                CandidateSource::AliasBound,
+                goal,
+                clause,
+                |ecx| {
+                    // Const conditions must hold for the implied const bound to hold.
+                    ecx.add_goals(
+                        GoalSource::Misc,
+                        cx.const_conditions(alias_ty.def_id)
+                            .iter_instantiated(cx, alias_ty.args)
+                            .map(|trait_ref| {
+                                goal.with(
+                                    cx,
+                                    trait_ref.to_host_effect_clause(cx, goal.predicate.host),
+                                )
+                            }),
+                    );
+                    ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+                },
+            ));
+        }
+
+        candidates
+    }
+
     fn consider_impl_candidate(
         ecx: &mut EvalCtxt<'_, D>,
         goal: Goal<I, Self>,
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
index c98fd853551..7287cdf74bf 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
@@ -193,6 +193,14 @@ where
         }
     }
 
+    fn consider_additional_alias_assumptions(
+        _ecx: &mut EvalCtxt<'_, D>,
+        _goal: Goal<I, Self>,
+        _alias_ty: ty::AliasTy<I>,
+    ) -> Vec<Candidate<I>> {
+        vec![]
+    }
+
     fn consider_impl_candidate(
         ecx: &mut EvalCtxt<'_, D>,
         goal: Goal<I, NormalizesTo<I>>,
diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
index 6b26f960286..08cc89d950e 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -39,6 +39,14 @@ where
         self.def_id()
     }
 
+    fn consider_additional_alias_assumptions(
+        _ecx: &mut EvalCtxt<'_, D>,
+        _goal: Goal<I, Self>,
+        _alias_ty: ty::AliasTy<I>,
+    ) -> Vec<Candidate<I>> {
+        vec![]
+    }
+
     fn consider_impl_candidate(
         ecx: &mut EvalCtxt<'_, D>,
         goal: Goal<I, TraitPredicate<I>>,