Auto merge of #87648 - JulianKnodt:const_eq_constrain, r=oli-obk
allow eq constraints on associated constants Updates #70256 (cc `@varkor,` `@Centril)`
This commit is contained in:
commit
7bc7be860f
83 changed files with 776 additions and 382 deletions
|
@ -6,7 +6,7 @@ use super::*;
|
|||
use crate::infer::region_constraints::{Constraint, RegionConstraintData};
|
||||
use crate::infer::InferCtxt;
|
||||
use rustc_middle::ty::fold::TypeFolder;
|
||||
use rustc_middle::ty::{Region, RegionVid};
|
||||
use rustc_middle::ty::{Region, RegionVid, Term};
|
||||
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
|
||||
|
@ -606,7 +606,11 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
|||
}
|
||||
|
||||
fn is_self_referential_projection(&self, p: ty::PolyProjectionPredicate<'_>) -> bool {
|
||||
matches!(*p.ty().skip_binder().kind(), ty::Projection(proj) if proj == p.skip_binder().projection_ty)
|
||||
if let Term::Ty(ty) = p.term().skip_binder() {
|
||||
matches!(ty.kind(), ty::Projection(proj) if proj == &p.skip_binder().projection_ty)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn evaluate_nested_obligations(
|
||||
|
@ -663,7 +667,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
|||
// Additionally, we check if we've seen this predicate before,
|
||||
// to avoid rendering duplicate bounds to the user.
|
||||
if self.is_param_no_infer(p.skip_binder().projection_ty.substs)
|
||||
&& !p.ty().skip_binder().has_infer_types()
|
||||
&& !p.term().skip_binder().has_infer_types()
|
||||
&& is_new_pred
|
||||
{
|
||||
debug!(
|
||||
|
@ -752,7 +756,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
|||
// when we started out trying to unify
|
||||
// some inference variables. See the comment above
|
||||
// for more infomration
|
||||
if p.ty().skip_binder().has_infer_types() {
|
||||
if p.term().skip_binder().has_infer_types() {
|
||||
if !self.evaluate_nested_obligations(
|
||||
ty,
|
||||
v.into_iter(),
|
||||
|
@ -774,7 +778,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
|||
// However, we should always make progress (either by generating
|
||||
// subobligations or getting an error) when we started off with
|
||||
// inference variables
|
||||
if p.ty().skip_binder().has_infer_types() {
|
||||
if p.term().skip_binder().has_infer_types() {
|
||||
panic!("Unexpected result when selecting {:?} {:?}", ty, obligation)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1304,7 +1304,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
|||
|
||||
debug!(
|
||||
"report_projection_error normalized_ty={:?} data.ty={:?}",
|
||||
normalized_ty, data.ty
|
||||
normalized_ty, data.term,
|
||||
);
|
||||
|
||||
let is_normalized_ty_expected = !matches!(
|
||||
|
@ -1314,16 +1314,17 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
|||
| ObligationCauseCode::ObjectCastObligation(_)
|
||||
| ObligationCauseCode::OpaqueType
|
||||
);
|
||||
|
||||
// FIXME(associated_const_equality): Handle Consts here
|
||||
let data_ty = data.term.ty().unwrap();
|
||||
if let Err(error) = self.at(&obligation.cause, obligation.param_env).eq_exp(
|
||||
is_normalized_ty_expected,
|
||||
normalized_ty,
|
||||
data.ty,
|
||||
data_ty,
|
||||
) {
|
||||
values = Some(infer::ValuePairs::Types(ExpectedFound::new(
|
||||
is_normalized_ty_expected,
|
||||
normalized_ty,
|
||||
data.ty,
|
||||
data_ty,
|
||||
)));
|
||||
|
||||
err_buf = error;
|
||||
|
@ -1803,11 +1804,11 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
ty::PredicateKind::Projection(data) => {
|
||||
let self_ty = data.projection_ty.self_ty();
|
||||
let ty = data.ty;
|
||||
let term = data.term;
|
||||
if predicate.references_error() || self.is_tainted_by_errors() {
|
||||
return;
|
||||
}
|
||||
if self_ty.needs_infer() && ty.needs_infer() {
|
||||
if self_ty.needs_infer() && term.needs_infer() {
|
||||
// We do this for the `foo.collect()?` case to produce a suggestion.
|
||||
let mut err = self.emit_inference_failure_err(
|
||||
body_id,
|
||||
|
|
|
@ -571,7 +571,7 @@ fn object_ty_for_trait<'tcx>(
|
|||
// `trait MyTrait: for<'s> OtherTrait<&'s T, Output=bool>`.
|
||||
super_trait_ref.map_bound(|super_trait_ref| {
|
||||
ty::ExistentialPredicate::Projection(ty::ExistentialProjection {
|
||||
ty: tcx.mk_projection(item.def_id, super_trait_ref.substs),
|
||||
term: tcx.mk_projection(item.def_id, super_trait_ref.substs).into(),
|
||||
item_def_id: item.def_id,
|
||||
substs: super_trait_ref.substs,
|
||||
})
|
||||
|
|
|
@ -212,10 +212,9 @@ fn project_and_unify_type<'cx, 'tcx>(
|
|||
debug!(?normalized_ty, ?obligations, "project_and_unify_type result");
|
||||
|
||||
let infcx = selcx.infcx();
|
||||
match infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
.eq(normalized_ty, obligation.predicate.ty)
|
||||
{
|
||||
// FIXME(associated_const_equality): Handle consts here as well as types.
|
||||
let obligation_pred_ty = obligation.predicate.term.ty().unwrap();
|
||||
match infcx.at(&obligation.cause, obligation.param_env).eq(normalized_ty, obligation_pred_ty) {
|
||||
Ok(InferOk { obligations: inferred_obligations, value: () }) => {
|
||||
obligations.extend(inferred_obligations);
|
||||
Ok(Ok(Some(obligations)))
|
||||
|
@ -1615,7 +1614,7 @@ fn confirm_generator_candidate<'cx, 'tcx>(
|
|||
substs: trait_ref.substs,
|
||||
item_def_id: obligation.predicate.item_def_id,
|
||||
},
|
||||
ty,
|
||||
term: ty.into(),
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1641,7 +1640,7 @@ fn confirm_discriminant_kind_candidate<'cx, 'tcx>(
|
|||
|
||||
let predicate = ty::ProjectionPredicate {
|
||||
projection_ty: ty::ProjectionTy { substs, item_def_id: discriminant_def_id },
|
||||
ty: self_ty.discriminant_ty(tcx),
|
||||
term: self_ty.discriminant_ty(tcx).into(),
|
||||
};
|
||||
|
||||
// We get here from `poly_project_and_unify_type` which replaces bound vars
|
||||
|
@ -1674,7 +1673,7 @@ fn confirm_pointee_candidate<'cx, 'tcx>(
|
|||
|
||||
let predicate = ty::ProjectionPredicate {
|
||||
projection_ty: ty::ProjectionTy { substs, item_def_id: metadata_def_id },
|
||||
ty: metadata_ty,
|
||||
term: metadata_ty.into(),
|
||||
};
|
||||
|
||||
confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
|
||||
|
@ -1747,7 +1746,7 @@ fn confirm_callable_candidate<'cx, 'tcx>(
|
|||
substs: trait_ref.substs,
|
||||
item_def_id: fn_once_output_def_id,
|
||||
},
|
||||
ty: ret_type,
|
||||
term: ret_type.into(),
|
||||
});
|
||||
|
||||
confirm_param_env_candidate(selcx, obligation, predicate, true)
|
||||
|
@ -1803,7 +1802,9 @@ fn confirm_param_env_candidate<'cx, 'tcx>(
|
|||
Ok(InferOk { value: _, obligations }) => {
|
||||
nested_obligations.extend(obligations);
|
||||
assoc_ty_own_obligations(selcx, obligation, &mut nested_obligations);
|
||||
Progress { ty: cache_entry.ty, obligations: nested_obligations }
|
||||
// FIXME(associated_const_equality): Handle consts here as well? Maybe this progress type should just take
|
||||
// a term instead.
|
||||
Progress { ty: cache_entry.term.ty().unwrap(), obligations: nested_obligations }
|
||||
}
|
||||
Err(e) => {
|
||||
let msg = format!(
|
||||
|
|
|
@ -62,7 +62,7 @@ pub(crate) fn update<'tcx, T>(
|
|||
if let ty::PredicateKind::Projection(predicate) = obligation.predicate.kind().skip_binder() {
|
||||
// If the projection predicate (Foo::Bar == X) has X as a non-TyVid,
|
||||
// we need to make it into one.
|
||||
if let Some(vid) = predicate.ty.ty_vid() {
|
||||
if let Some(vid) = predicate.term.ty().and_then(|ty| ty.ty_vid()) {
|
||||
debug!("relationship: {:?}.output = true", vid);
|
||||
engine.relationships().entry(vid).or_default().output = true;
|
||||
}
|
||||
|
|
|
@ -116,7 +116,10 @@ pub fn predicate_obligations<'a, 'tcx>(
|
|||
}
|
||||
ty::PredicateKind::Projection(t) => {
|
||||
wf.compute_projection(t.projection_ty);
|
||||
wf.compute(t.ty.into());
|
||||
wf.compute(match t.term {
|
||||
ty::Term::Ty(ty) => ty.into(),
|
||||
ty::Term::Const(c) => c.into(),
|
||||
})
|
||||
}
|
||||
ty::PredicateKind::WellFormed(arg) => {
|
||||
wf.compute(arg);
|
||||
|
@ -219,7 +222,7 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
|
|||
// projection coming from another associated type. See
|
||||
// `src/test/ui/associated-types/point-at-type-on-obligation-failure.rs` and
|
||||
// `traits-assoc-type-in-supertrait-bad.rs`.
|
||||
if let ty::Projection(projection_ty) = proj.ty.kind() {
|
||||
if let Some(ty::Projection(projection_ty)) = proj.term.ty().map(|ty| ty.kind()) {
|
||||
if let Some(&impl_item_id) =
|
||||
tcx.impl_item_implementor_ids(impl_def_id).get(&projection_ty.item_def_id)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue