Address goal nits
This commit is contained in:
parent
d6a411c086
commit
444cbcd729
@ -1,7 +1,7 @@
|
|||||||
//! Code shared by trait and projection goals for candidate assembly.
|
//! Code shared by trait and projection goals for candidate assembly.
|
||||||
|
|
||||||
use super::infcx_ext::InferCtxtExt;
|
use super::infcx_ext::InferCtxtExt;
|
||||||
use super::{CanonicalResponse, Certainty, EvalCtxt, Goal, MaybeCause, QueryResult};
|
use super::{CanonicalResponse, Certainty, EvalCtxt, Goal, QueryResult};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_infer::traits::query::NoSolution;
|
use rustc_infer::traits::query::NoSolution;
|
||||||
use rustc_infer::traits::util::elaborate_predicates;
|
use rustc_infer::traits::util::elaborate_predicates;
|
||||||
@ -148,9 +148,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||||||
if goal.predicate.self_ty().is_ty_var() {
|
if goal.predicate.self_ty().is_ty_var() {
|
||||||
return vec![Candidate {
|
return vec![Candidate {
|
||||||
source: CandidateSource::BuiltinImpl,
|
source: CandidateSource::BuiltinImpl,
|
||||||
result: self
|
result: self.make_canonical_response(Certainty::AMBIGUOUS).unwrap(),
|
||||||
.make_canonical_response(Certainty::Maybe(MaybeCause::Ambiguity))
|
|
||||||
.unwrap(),
|
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_infer::infer::canonical::{Canonical, CanonicalVarKind, CanonicalVarValues};
|
use rustc_infer::infer::canonical::{Canonical, CanonicalVarKind, CanonicalVarValues};
|
||||||
use rustc_infer::infer::canonical::{OriginalQueryValues, QueryRegionConstraints, QueryResponse};
|
use rustc_infer::infer::canonical::{OriginalQueryValues, QueryRegionConstraints, QueryResponse};
|
||||||
use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt};
|
use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt};
|
||||||
@ -27,7 +28,7 @@ use rustc_infer::traits::Obligation;
|
|||||||
use rustc_middle::infer::canonical::Certainty as OldCertainty;
|
use rustc_middle::infer::canonical::Certainty as OldCertainty;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
RegionOutlivesPredicate, SubtypePredicate, ToPredicate, TypeOutlivesPredicate,
|
CoercePredicate, RegionOutlivesPredicate, SubtypePredicate, ToPredicate, TypeOutlivesPredicate,
|
||||||
};
|
};
|
||||||
use rustc_span::DUMMY_SP;
|
use rustc_span::DUMMY_SP;
|
||||||
|
|
||||||
@ -89,6 +90,8 @@ pub enum Certainty {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Certainty {
|
impl Certainty {
|
||||||
|
pub const AMBIGUOUS: Certainty = Certainty::Maybe(MaybeCause::Ambiguity);
|
||||||
|
|
||||||
/// When proving multiple goals using **AND**, e.g. nested obligations for an impl,
|
/// When proving multiple goals using **AND**, e.g. nested obligations for an impl,
|
||||||
/// use this function to unify the certainty of these goals
|
/// use this function to unify the certainty of these goals
|
||||||
pub fn unify_and(self, other: Certainty) -> Certainty {
|
pub fn unify_and(self, other: Certainty) -> Certainty {
|
||||||
@ -248,21 +251,15 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
|||||||
ty::PredicateKind::Subtype(predicate) => {
|
ty::PredicateKind::Subtype(predicate) => {
|
||||||
self.compute_subtype_goal(Goal { param_env, predicate })
|
self.compute_subtype_goal(Goal { param_env, predicate })
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Coerce(predicate) => self.compute_subtype_goal(Goal {
|
ty::PredicateKind::Coerce(predicate) => {
|
||||||
param_env,
|
self.compute_coerce_goal(Goal { param_env, predicate })
|
||||||
predicate: SubtypePredicate {
|
|
||||||
a_is_expected: true,
|
|
||||||
a: predicate.a,
|
|
||||||
b: predicate.b,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
ty::PredicateKind::ClosureKind(_, substs, kind) => self.compute_closure_kind_goal(
|
|
||||||
substs.as_closure().kind_ty().to_opt_closure_kind(),
|
|
||||||
kind,
|
|
||||||
),
|
|
||||||
ty::PredicateKind::Ambiguous => {
|
|
||||||
self.make_canonical_response(Certainty::Maybe(MaybeCause::Ambiguity))
|
|
||||||
}
|
}
|
||||||
|
ty::PredicateKind::ClosureKind(def_id, substs, kind) => self
|
||||||
|
.compute_closure_kind_goal(Goal {
|
||||||
|
param_env,
|
||||||
|
predicate: (def_id, substs, kind),
|
||||||
|
}),
|
||||||
|
ty::PredicateKind::Ambiguous => self.make_canonical_response(Certainty::AMBIGUOUS),
|
||||||
// FIXME: implement these predicates :)
|
// FIXME: implement these predicates :)
|
||||||
ty::PredicateKind::WellFormed(_)
|
ty::PredicateKind::WellFormed(_)
|
||||||
| ty::PredicateKind::ObjectSafe(_)
|
| ty::PredicateKind::ObjectSafe(_)
|
||||||
@ -296,28 +293,50 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
|||||||
self.make_canonical_response(Certainty::Yes)
|
self.make_canonical_response(Certainty::Yes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn compute_coerce_goal(
|
||||||
|
&mut self,
|
||||||
|
goal: Goal<'tcx, CoercePredicate<'tcx>>,
|
||||||
|
) -> QueryResult<'tcx> {
|
||||||
|
self.compute_subtype_goal(Goal {
|
||||||
|
param_env: goal.param_env,
|
||||||
|
predicate: SubtypePredicate {
|
||||||
|
a_is_expected: false,
|
||||||
|
a: goal.predicate.a,
|
||||||
|
b: goal.predicate.b,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn compute_subtype_goal(
|
fn compute_subtype_goal(
|
||||||
&mut self,
|
&mut self,
|
||||||
goal: Goal<'tcx, SubtypePredicate<'tcx>>,
|
goal: Goal<'tcx, SubtypePredicate<'tcx>>,
|
||||||
) -> QueryResult<'tcx> {
|
) -> QueryResult<'tcx> {
|
||||||
self.infcx.probe(|_| {
|
if goal.predicate.a.is_ty_var() && goal.predicate.b.is_ty_var() {
|
||||||
let InferOk { value: (), obligations } = self
|
// FIXME: Do we want to register a subtype relation between these vars?
|
||||||
.infcx
|
// That won't actually reflect in the query response, so it seems moot.
|
||||||
.at(&ObligationCause::dummy(), goal.param_env)
|
self.make_canonical_response(Certainty::AMBIGUOUS)
|
||||||
.sub(goal.predicate.a, goal.predicate.b)?;
|
} else {
|
||||||
self.evaluate_all_and_make_canonical_response(
|
self.infcx.probe(|_| {
|
||||||
obligations.into_iter().map(|pred| pred.into()).collect(),
|
let InferOk { value: (), obligations } = self
|
||||||
)
|
.infcx
|
||||||
})
|
.at(&ObligationCause::dummy(), goal.param_env)
|
||||||
|
.sub(goal.predicate.a, goal.predicate.b)?;
|
||||||
|
self.evaluate_all_and_make_canonical_response(
|
||||||
|
obligations.into_iter().map(|pred| pred.into()).collect(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute_closure_kind_goal(
|
fn compute_closure_kind_goal(
|
||||||
&mut self,
|
&mut self,
|
||||||
found_kind: Option<ty::ClosureKind>,
|
goal: Goal<'tcx, (DefId, ty::SubstsRef<'tcx>, ty::ClosureKind)>,
|
||||||
expected_kind: ty::ClosureKind,
|
|
||||||
) -> QueryResult<'tcx> {
|
) -> QueryResult<'tcx> {
|
||||||
|
let (_, substs, expected_kind) = goal.predicate;
|
||||||
|
let found_kind = substs.as_closure().kind_ty().to_opt_closure_kind();
|
||||||
|
|
||||||
let Some(found_kind) = found_kind else {
|
let Some(found_kind) = found_kind else {
|
||||||
return self.make_canonical_response(Certainty::Maybe(MaybeCause::Ambiguity));
|
return self.make_canonical_response(Certainty::AMBIGUOUS);
|
||||||
};
|
};
|
||||||
if found_kind.extends(expected_kind) {
|
if found_kind.extends(expected_kind) {
|
||||||
self.make_canonical_response(Certainty::Yes)
|
self.make_canonical_response(Certainty::Yes)
|
||||||
|
@ -3,7 +3,7 @@ use crate::traits::{specialization_graph, translate_substs};
|
|||||||
use super::assembly::{self, Candidate, CandidateSource};
|
use super::assembly::{self, Candidate, CandidateSource};
|
||||||
use super::infcx_ext::InferCtxtExt;
|
use super::infcx_ext::InferCtxtExt;
|
||||||
use super::trait_goals::structural_traits;
|
use super::trait_goals::structural_traits;
|
||||||
use super::{Certainty, EvalCtxt, Goal, MaybeCause, QueryResult};
|
use super::{Certainty, EvalCtxt, Goal, QueryResult};
|
||||||
use rustc_errors::ErrorGuaranteed;
|
use rustc_errors::ErrorGuaranteed;
|
||||||
use rustc_hir::def::DefKind;
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
@ -229,8 +229,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
|
|||||||
goal.predicate.def_id(),
|
goal.predicate.def_id(),
|
||||||
impl_def_id
|
impl_def_id
|
||||||
)? else {
|
)? else {
|
||||||
let certainty = Certainty::Maybe(MaybeCause::Ambiguity);
|
return ecx.make_canonical_response(trait_ref_certainty.unify_and(Certainty::AMBIGUOUS));
|
||||||
return ecx.make_canonical_response(trait_ref_certainty.unify_and(certainty));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if !assoc_def.item.defaultness(tcx).has_value() {
|
if !assoc_def.item.defaultness(tcx).has_value() {
|
||||||
@ -382,7 +381,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
|
|||||||
.to_predicate(ecx.tcx());
|
.to_predicate(ecx.tcx());
|
||||||
Self::consider_assumption(ecx, goal, pred)
|
Self::consider_assumption(ecx, goal, pred)
|
||||||
} else {
|
} else {
|
||||||
ecx.make_canonical_response(Certainty::Maybe(MaybeCause::Ambiguity))
|
ecx.make_canonical_response(Certainty::AMBIGUOUS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ use std::iter;
|
|||||||
|
|
||||||
use super::assembly::{self, Candidate, CandidateSource};
|
use super::assembly::{self, Candidate, CandidateSource};
|
||||||
use super::infcx_ext::InferCtxtExt;
|
use super::infcx_ext::InferCtxtExt;
|
||||||
use super::{Certainty, EvalCtxt, Goal, MaybeCause, QueryResult};
|
use super::{Certainty, EvalCtxt, Goal, QueryResult};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_infer::infer::InferCtxt;
|
use rustc_infer::infer::InferCtxt;
|
||||||
use rustc_infer::traits::query::NoSolution;
|
use rustc_infer::traits::query::NoSolution;
|
||||||
@ -133,7 +133,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
|||||||
goal: Goal<'tcx, Self>,
|
goal: Goal<'tcx, Self>,
|
||||||
) -> QueryResult<'tcx> {
|
) -> QueryResult<'tcx> {
|
||||||
if goal.predicate.self_ty().has_non_region_infer() {
|
if goal.predicate.self_ty().has_non_region_infer() {
|
||||||
return ecx.make_canonical_response(Certainty::Maybe(MaybeCause::Ambiguity));
|
return ecx.make_canonical_response(Certainty::AMBIGUOUS);
|
||||||
}
|
}
|
||||||
|
|
||||||
let tcx = ecx.tcx();
|
let tcx = ecx.tcx();
|
||||||
@ -171,7 +171,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
|||||||
.to_predicate(ecx.tcx());
|
.to_predicate(ecx.tcx());
|
||||||
Self::consider_assumption(ecx, goal, pred)
|
Self::consider_assumption(ecx, goal, pred)
|
||||||
} else {
|
} else {
|
||||||
ecx.make_canonical_response(Certainty::Maybe(MaybeCause::Ambiguity))
|
ecx.make_canonical_response(Certainty::AMBIGUOUS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user