mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
Rollup merge of #112665 - compiler-errors:assumption-takes-clause, r=lcnr
Make assumption functions in new solver take `Binder<'tcx, Clause<'tcx>>` We just use an if-let to match on an optional clause at all the places where we transition from `Predicate` -> `Clause`, but I assume that when things like item-bounds and param-env start to only store `Clause`s then those can just be trivially dropped. r? ``@lcnr``
This commit is contained in:
commit
cef94ecedf
@ -586,6 +586,24 @@ pub enum Clause<'tcx> {
|
|||||||
ConstArgHasType(Const<'tcx>, Ty<'tcx>),
|
ConstArgHasType(Const<'tcx>, Ty<'tcx>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'tcx> Binder<'tcx, Clause<'tcx>> {
|
||||||
|
pub fn as_trait_clause(self) -> Option<Binder<'tcx, TraitPredicate<'tcx>>> {
|
||||||
|
if let ty::Clause::Trait(trait_clause) = self.skip_binder() {
|
||||||
|
Some(self.rebind(trait_clause))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_projection_clause(self) -> Option<Binder<'tcx, ProjectionPredicate<'tcx>>> {
|
||||||
|
if let ty::Clause::Projection(projection_clause) = self.skip_binder() {
|
||||||
|
Some(self.rebind(projection_clause))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
|
||||||
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
|
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
|
||||||
pub enum PredicateKind<'tcx> {
|
pub enum PredicateKind<'tcx> {
|
||||||
@ -1203,6 +1221,17 @@ impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'tcx> ToPredicate<'tcx, Binder<'tcx, Clause<'tcx>>> for TraitRef<'tcx> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> Binder<'tcx, Clause<'tcx>> {
|
||||||
|
Binder::dummy(Clause::Trait(TraitPredicate {
|
||||||
|
trait_ref: self,
|
||||||
|
constness: ty::BoundConstness::NotConst,
|
||||||
|
polarity: ty::ImplPolarity::Positive,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, TraitRef<'tcx>> {
|
impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, TraitRef<'tcx>> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
|
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
|
||||||
@ -1211,6 +1240,14 @@ impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, TraitRef<'tcx>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'tcx> ToPredicate<'tcx, Binder<'tcx, Clause<'tcx>>> for Binder<'tcx, TraitRef<'tcx>> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Binder<'tcx, Clause<'tcx>> {
|
||||||
|
let pred: PolyTraitPredicate<'tcx> = self.to_predicate(tcx);
|
||||||
|
pred.to_predicate(tcx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> ToPredicate<'tcx, PolyTraitPredicate<'tcx>> for Binder<'tcx, TraitRef<'tcx>> {
|
impl<'tcx> ToPredicate<'tcx, PolyTraitPredicate<'tcx>> for Binder<'tcx, TraitRef<'tcx>> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn to_predicate(self, _: TyCtxt<'tcx>) -> PolyTraitPredicate<'tcx> {
|
fn to_predicate(self, _: TyCtxt<'tcx>) -> PolyTraitPredicate<'tcx> {
|
||||||
@ -1240,6 +1277,12 @@ impl<'tcx> ToPredicate<'tcx> for PolyTraitPredicate<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'tcx> ToPredicate<'tcx, Binder<'tcx, Clause<'tcx>>> for PolyTraitPredicate<'tcx> {
|
||||||
|
fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> Binder<'tcx, Clause<'tcx>> {
|
||||||
|
self.map_bound(|p| Clause::Trait(p))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> {
|
impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> {
|
||||||
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
|
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
|
||||||
self.map_bound(|p| PredicateKind::Clause(Clause::RegionOutlives(p))).to_predicate(tcx)
|
self.map_bound(|p| PredicateKind::Clause(Clause::RegionOutlives(p))).to_predicate(tcx)
|
||||||
@ -1258,6 +1301,12 @@ impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'tcx> ToPredicate<'tcx, Binder<'tcx, Clause<'tcx>>> for PolyProjectionPredicate<'tcx> {
|
||||||
|
fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> Binder<'tcx, Clause<'tcx>> {
|
||||||
|
self.map_bound(|p| Clause::Projection(p))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> ToPredicate<'tcx> for TraitPredicate<'tcx> {
|
impl<'tcx> ToPredicate<'tcx> for TraitPredicate<'tcx> {
|
||||||
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
|
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
|
||||||
PredicateKind::Clause(Clause::Trait(self)).to_predicate(tcx)
|
PredicateKind::Clause(Clause::Trait(self)).to_predicate(tcx)
|
||||||
@ -1327,6 +1376,23 @@ impl<'tcx> Predicate<'tcx> {
|
|||||||
| PredicateKind::TypeWellFormedFromEnv(..) => None,
|
| PredicateKind::TypeWellFormedFromEnv(..) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn as_clause(self) -> Option<Binder<'tcx, Clause<'tcx>>> {
|
||||||
|
let predicate = self.kind();
|
||||||
|
match predicate.skip_binder() {
|
||||||
|
PredicateKind::Clause(clause) => Some(predicate.rebind(clause)),
|
||||||
|
PredicateKind::AliasRelate(..)
|
||||||
|
| PredicateKind::Subtype(..)
|
||||||
|
| PredicateKind::Coerce(..)
|
||||||
|
| PredicateKind::WellFormed(..)
|
||||||
|
| PredicateKind::ObjectSafe(..)
|
||||||
|
| PredicateKind::ClosureKind(..)
|
||||||
|
| PredicateKind::ConstEvaluatable(..)
|
||||||
|
| PredicateKind::ConstEquate(..)
|
||||||
|
| PredicateKind::Ambiguous
|
||||||
|
| PredicateKind::TypeWellFormedFromEnv(..) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents the bounds declared on a particular set of type
|
/// Represents the bounds declared on a particular set of type
|
||||||
|
@ -105,7 +105,7 @@ pub(super) trait GoalKind<'tcx>:
|
|||||||
fn probe_and_match_goal_against_assumption(
|
fn probe_and_match_goal_against_assumption(
|
||||||
ecx: &mut EvalCtxt<'_, 'tcx>,
|
ecx: &mut EvalCtxt<'_, 'tcx>,
|
||||||
goal: Goal<'tcx, Self>,
|
goal: Goal<'tcx, Self>,
|
||||||
assumption: ty::Predicate<'tcx>,
|
assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
|
||||||
then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
|
then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
|
||||||
) -> QueryResult<'tcx>;
|
) -> QueryResult<'tcx>;
|
||||||
|
|
||||||
@ -115,7 +115,7 @@ pub(super) trait GoalKind<'tcx>:
|
|||||||
fn consider_implied_clause(
|
fn consider_implied_clause(
|
||||||
ecx: &mut EvalCtxt<'_, 'tcx>,
|
ecx: &mut EvalCtxt<'_, 'tcx>,
|
||||||
goal: Goal<'tcx, Self>,
|
goal: Goal<'tcx, Self>,
|
||||||
assumption: ty::Predicate<'tcx>,
|
assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
|
||||||
requirements: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
|
requirements: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
|
||||||
) -> QueryResult<'tcx> {
|
) -> QueryResult<'tcx> {
|
||||||
Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| {
|
Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| {
|
||||||
@ -131,7 +131,7 @@ pub(super) trait GoalKind<'tcx>:
|
|||||||
fn consider_alias_bound_candidate(
|
fn consider_alias_bound_candidate(
|
||||||
ecx: &mut EvalCtxt<'_, 'tcx>,
|
ecx: &mut EvalCtxt<'_, 'tcx>,
|
||||||
goal: Goal<'tcx, Self>,
|
goal: Goal<'tcx, Self>,
|
||||||
assumption: ty::Predicate<'tcx>,
|
assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
|
||||||
) -> QueryResult<'tcx> {
|
) -> QueryResult<'tcx> {
|
||||||
Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| {
|
Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| {
|
||||||
ecx.validate_alias_bound_self_from_param_env(goal)
|
ecx.validate_alias_bound_self_from_param_env(goal)
|
||||||
@ -144,7 +144,7 @@ pub(super) trait GoalKind<'tcx>:
|
|||||||
fn consider_object_bound_candidate(
|
fn consider_object_bound_candidate(
|
||||||
ecx: &mut EvalCtxt<'_, 'tcx>,
|
ecx: &mut EvalCtxt<'_, 'tcx>,
|
||||||
goal: Goal<'tcx, Self>,
|
goal: Goal<'tcx, Self>,
|
||||||
assumption: ty::Predicate<'tcx>,
|
assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
|
||||||
) -> QueryResult<'tcx> {
|
) -> QueryResult<'tcx> {
|
||||||
Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| {
|
Self::probe_and_match_goal_against_assumption(ecx, goal, assumption, |ecx| {
|
||||||
let tcx = ecx.tcx();
|
let tcx = ecx.tcx();
|
||||||
@ -467,11 +467,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||||||
candidates: &mut Vec<Candidate<'tcx>>,
|
candidates: &mut Vec<Candidate<'tcx>>,
|
||||||
) {
|
) {
|
||||||
for (i, assumption) in goal.param_env.caller_bounds().iter().enumerate() {
|
for (i, assumption) in goal.param_env.caller_bounds().iter().enumerate() {
|
||||||
match G::consider_implied_clause(self, goal, assumption, []) {
|
if let Some(clause) = assumption.as_clause() {
|
||||||
Ok(result) => {
|
match G::consider_implied_clause(self, goal, clause, []) {
|
||||||
candidates.push(Candidate { source: CandidateSource::ParamEnv(i), result })
|
Ok(result) => {
|
||||||
|
candidates.push(Candidate { source: CandidateSource::ParamEnv(i), result })
|
||||||
|
}
|
||||||
|
Err(NoSolution) => (),
|
||||||
}
|
}
|
||||||
Err(NoSolution) => (),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -517,11 +519,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||||||
|
|
||||||
for assumption in self.tcx().item_bounds(alias_ty.def_id).subst(self.tcx(), alias_ty.substs)
|
for assumption in self.tcx().item_bounds(alias_ty.def_id).subst(self.tcx(), alias_ty.substs)
|
||||||
{
|
{
|
||||||
match G::consider_alias_bound_candidate(self, goal, assumption) {
|
if let Some(clause) = assumption.as_clause() {
|
||||||
Ok(result) => {
|
match G::consider_alias_bound_candidate(self, goal, clause) {
|
||||||
candidates.push(Candidate { source: CandidateSource::AliasBound, result })
|
Ok(result) => {
|
||||||
|
candidates.push(Candidate { source: CandidateSource::AliasBound, result })
|
||||||
|
}
|
||||||
|
Err(NoSolution) => (),
|
||||||
}
|
}
|
||||||
Err(NoSolution) => (),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -675,18 +679,20 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||||||
// projection predicates that we reach by elaborating the principal trait ref,
|
// projection predicates that we reach by elaborating the principal trait ref,
|
||||||
// since that'll cause ambiguity.
|
// since that'll cause ambiguity.
|
||||||
//
|
//
|
||||||
// We can remove this when we have implemented intersections in responses.
|
// We can remove this when we have implemented lifetime intersections in responses.
|
||||||
if assumption.to_opt_poly_projection_pred().is_some()
|
if assumption.to_opt_poly_projection_pred().is_some()
|
||||||
&& !own_bounds.contains(&assumption)
|
&& !own_bounds.contains(&assumption)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
match G::consider_object_bound_candidate(self, goal, assumption) {
|
if let Some(clause) = assumption.as_clause() {
|
||||||
Ok(result) => {
|
match G::consider_object_bound_candidate(self, goal, clause) {
|
||||||
candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result })
|
Ok(result) => {
|
||||||
|
candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result })
|
||||||
|
}
|
||||||
|
Err(NoSolution) => (),
|
||||||
}
|
}
|
||||||
Err(NoSolution) => (),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,15 +105,15 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
|
|||||||
fn probe_and_match_goal_against_assumption(
|
fn probe_and_match_goal_against_assumption(
|
||||||
ecx: &mut EvalCtxt<'_, 'tcx>,
|
ecx: &mut EvalCtxt<'_, 'tcx>,
|
||||||
goal: Goal<'tcx, Self>,
|
goal: Goal<'tcx, Self>,
|
||||||
assumption: ty::Predicate<'tcx>,
|
assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
|
||||||
then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
|
then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
|
||||||
) -> QueryResult<'tcx> {
|
) -> QueryResult<'tcx> {
|
||||||
if let Some(poly_projection_pred) = assumption.to_opt_poly_projection_pred()
|
if let Some(projection_pred) = assumption.as_projection_clause()
|
||||||
&& poly_projection_pred.projection_def_id() == goal.predicate.def_id()
|
&& projection_pred.projection_def_id() == goal.predicate.def_id()
|
||||||
{
|
{
|
||||||
ecx.probe(|ecx| {
|
ecx.probe(|ecx| {
|
||||||
let assumption_projection_pred =
|
let assumption_projection_pred =
|
||||||
ecx.instantiate_binder_with_infer(poly_projection_pred);
|
ecx.instantiate_binder_with_infer(projection_pred);
|
||||||
ecx.eq(
|
ecx.eq(
|
||||||
goal.param_env,
|
goal.param_env,
|
||||||
goal.predicate.projection_ty,
|
goal.predicate.projection_ty,
|
||||||
|
@ -81,17 +81,17 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
|||||||
fn probe_and_match_goal_against_assumption(
|
fn probe_and_match_goal_against_assumption(
|
||||||
ecx: &mut EvalCtxt<'_, 'tcx>,
|
ecx: &mut EvalCtxt<'_, 'tcx>,
|
||||||
goal: Goal<'tcx, Self>,
|
goal: Goal<'tcx, Self>,
|
||||||
assumption: ty::Predicate<'tcx>,
|
assumption: ty::Binder<'tcx, ty::Clause<'tcx>>,
|
||||||
then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
|
then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
|
||||||
) -> QueryResult<'tcx> {
|
) -> QueryResult<'tcx> {
|
||||||
if let Some(poly_trait_pred) = assumption.to_opt_poly_trait_pred()
|
if let Some(trait_clause) = assumption.as_trait_clause()
|
||||||
&& poly_trait_pred.def_id() == goal.predicate.def_id()
|
&& trait_clause.def_id() == goal.predicate.def_id()
|
||||||
&& poly_trait_pred.polarity() == goal.predicate.polarity
|
&& trait_clause.polarity() == goal.predicate.polarity
|
||||||
{
|
{
|
||||||
// FIXME: Constness
|
// FIXME: Constness
|
||||||
ecx.probe(|ecx| {
|
ecx.probe(|ecx| {
|
||||||
let assumption_trait_pred =
|
let assumption_trait_pred =
|
||||||
ecx.instantiate_binder_with_infer(poly_trait_pred);
|
ecx.instantiate_binder_with_infer(trait_clause);
|
||||||
ecx.eq(
|
ecx.eq(
|
||||||
goal.param_env,
|
goal.param_env,
|
||||||
goal.predicate.trait_ref,
|
goal.predicate.trait_ref,
|
||||||
|
Loading…
Reference in New Issue
Block a user