Rollup merge of #107272 - compiler-errors:new-solver-more-predicates, r=lcnr
Implement ObjectSafe and WF in the new solver r? ``@lcnr``
This commit is contained in:
commit
a84e060173
3 changed files with 70 additions and 13 deletions
|
@ -277,12 +277,15 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
|||
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 +365,32 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
|||
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::unnormalized_obligations(
|
||||
self.infcx,
|
||||
goal.param_env,
|
||||
goal.predicate,
|
||||
) {
|
||||
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> {
|
||||
|
|
|
@ -4,8 +4,8 @@ use rustc_hir as hir;
|
|||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable};
|
||||
use rustc_span::def_id::{DefId, LocalDefId};
|
||||
use rustc_span::Span;
|
||||
use rustc_span::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
|
||||
use std::iter;
|
||||
/// Returns the set of obligations needed to make `arg` well-formed.
|
||||
|
@ -75,6 +75,34 @@ pub fn obligations<'tcx>(
|
|||
Some(result)
|
||||
}
|
||||
|
||||
/// Compute the predicates that are required for a type to be well-formed.
|
||||
///
|
||||
/// This is only intended to be used in the new solver, since it does not
|
||||
/// take into account recursion depth or proper error-reporting spans.
|
||||
pub fn unnormalized_obligations<'tcx>(
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
arg: GenericArg<'tcx>,
|
||||
) -> Option<Vec<traits::PredicateObligation<'tcx>>> {
|
||||
if let ty::GenericArgKind::Lifetime(..) = arg.unpack() {
|
||||
return Some(vec![]);
|
||||
}
|
||||
|
||||
debug_assert_eq!(arg, infcx.resolve_vars_if_possible(arg));
|
||||
|
||||
let mut wf = WfPredicates {
|
||||
tcx: infcx.tcx,
|
||||
param_env,
|
||||
body_id: CRATE_DEF_ID,
|
||||
span: DUMMY_SP,
|
||||
out: vec![],
|
||||
recursion_depth: 0,
|
||||
item: None,
|
||||
};
|
||||
wf.compute(arg);
|
||||
Some(wf.out)
|
||||
}
|
||||
|
||||
/// Returns the obligations that make this trait reference
|
||||
/// well-formed. For example, if there is a trait `Set` defined like
|
||||
/// `trait Set<K:Eq>`, then the trait reference `Foo: Set<Bar>` is WF
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue