about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-01-17 18:19:11 +0000
committerMichael Goulet <michael@errs.io>2023-01-18 14:28:14 +0000
commit3d87a8e84850e2f5edc0f87ab2f4d3c2b67a48ac (patch)
tree888d76a3ac4d82c8e859f6e8019c0da010c81ade
parentf99b273d577914ee0c9073e2e6144aee17354717 (diff)
downloadrust-3d87a8e84850e2f5edc0f87ab2f4d3c2b67a48ac.tar.gz
rust-3d87a8e84850e2f5edc0f87ab2f4d3c2b67a48ac.zip
Assemble object bound candidates
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly.rs52
1 files changed, 52 insertions, 0 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/assembly.rs b/compiler/rustc_trait_selection/src/solve/assembly.rs
index c8611294449..0a82c14e226 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly.rs
@@ -4,6 +4,7 @@ use super::infcx_ext::InferCtxtExt;
 use super::{CanonicalResponse, EvalCtxt, Goal, QueryResult};
 use rustc_hir::def_id::DefId;
 use rustc_infer::traits::query::NoSolution;
+use rustc_infer::traits::util::elaborate_predicates;
 use rustc_middle::ty::TypeFoldable;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use std::fmt::Debug;
@@ -119,6 +120,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
 
         self.assemble_alias_bound_candidates(goal, &mut candidates);
 
+        self.assemble_object_bound_candidates(goal, &mut candidates);
+
         candidates
     }
 
@@ -272,4 +275,53 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             }
         }
     }
+
+    fn assemble_object_bound_candidates<G: GoalKind<'tcx>>(
+        &mut self,
+        goal: Goal<'tcx, G>,
+        candidates: &mut Vec<Candidate<'tcx>>,
+    ) {
+        let self_ty = goal.predicate.self_ty();
+        let bounds = match *self_ty.kind() {
+            ty::Bool
+            | ty::Char
+            | ty::Int(_)
+            | ty::Uint(_)
+            | ty::Float(_)
+            | ty::Adt(_, _)
+            | ty::Foreign(_)
+            | ty::Str
+            | ty::Array(_, _)
+            | ty::Slice(_)
+            | ty::RawPtr(_)
+            | ty::Ref(_, _, _)
+            | ty::FnDef(_, _)
+            | ty::FnPtr(_)
+            | ty::Alias(..)
+            | ty::Closure(..)
+            | ty::Generator(..)
+            | ty::GeneratorWitness(_)
+            | ty::Never
+            | ty::Tuple(_)
+            | ty::Param(_)
+            | ty::Placeholder(..)
+            | ty::Infer(_)
+            | ty::Error(_) => return,
+            ty::Bound(..) => bug!("unexpected bound type: {goal:?}"),
+            ty::Dynamic(bounds, ..) => bounds,
+        };
+
+        let tcx = self.tcx();
+        for assumption in
+            elaborate_predicates(tcx, bounds.iter().map(|bound| bound.with_self_ty(tcx, self_ty)))
+        {
+            match G::consider_assumption(self, goal, assumption.predicate)
+            {
+                Ok(result) => {
+                    candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result })
+                }
+                Err(NoSolution) => (),
+            }
+        }
+    }
 }