diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index 70f09401445..a920f04621d 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -20,6 +20,7 @@ use std::mem; use rustc_hir::def_id::DefId; +use rustc_hir::CRATE_HIR_ID; use rustc_infer::infer::canonical::{Canonical, CanonicalVarKind, CanonicalVarValues}; use rustc_infer::infer::canonical::{OriginalQueryValues, QueryRegionConstraints, QueryResponse}; use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt}; @@ -277,12 +278,15 @@ fn compute_goal(&mut self, goal: Goal<'tcx, ty::Predicate<'tcx>>) -> QueryResult param_env, predicate: (def_id, substs, kind), }), + ty::PredicateKind::ObjectSafe(trait_def_id) => { + self.compute_object_safe_goal(trait_def_id) + } + ty::PredicateKind::WellFormed(arg) => { + self.compute_well_formed_goal(Goal { param_env, predicate: arg }) + } ty::PredicateKind::Ambiguous => self.make_canonical_response(Certainty::AMBIGUOUS), // FIXME: implement these predicates :) - ty::PredicateKind::WellFormed(_) - | ty::PredicateKind::ObjectSafe(_) - | ty::PredicateKind::ConstEvaluatable(_) - | ty::PredicateKind::ConstEquate(_, _) => { + ty::PredicateKind::ConstEvaluatable(_) | ty::PredicateKind::ConstEquate(_, _) => { self.make_canonical_response(Certainty::Yes) } ty::PredicateKind::TypeWellFormedFromEnv(..) => { @@ -362,6 +366,35 @@ fn compute_closure_kind_goal( Err(NoSolution) } } + + fn compute_object_safe_goal(&mut self, trait_def_id: DefId) -> QueryResult<'tcx> { + if self.tcx().is_object_safe(trait_def_id) { + self.make_canonical_response(Certainty::Yes) + } else { + Err(NoSolution) + } + } + + fn compute_well_formed_goal( + &mut self, + goal: Goal<'tcx, ty::GenericArg<'tcx>>, + ) -> QueryResult<'tcx> { + self.infcx.probe(|_| { + match crate::traits::wf::obligations( + self.infcx, + goal.param_env, + CRATE_HIR_ID, // FIXME body id + 0, + goal.predicate, + DUMMY_SP, + ) { + Some(obligations) => self.evaluate_all_and_make_canonical_response( + obligations.into_iter().map(|o| o.into()).collect(), + ), + None => self.make_canonical_response(Certainty::AMBIGUOUS), + } + }) + } } impl<'tcx> EvalCtxt<'_, 'tcx> {