Rollup merge of #103255 - oli-obk:opaque_wrong_eq_relation, r=compiler-errors
Clean up hidden type registration work on https://github.com/rust-lang/rust/issues/101186 Actually passing down the relation and using it instead of `eq` for the hidden type comparison has *no* effect whatsoever and allows for no further improvements at the call sites. I decided the increased complexity was not worth it and thus did not include that change in this PR. r? `@compiler-errors`
This commit is contained in:
commit
16e74c78a1
@ -263,13 +263,11 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||
|
||||
// Require that the hidden type actually fulfills all the bounds of the opaque type, even without
|
||||
// the bounds that the function supplies.
|
||||
match infcx.register_hidden_type(
|
||||
OpaqueTypeKey { def_id, substs: id_substs },
|
||||
ObligationCause::misc(instantiated_ty.span, body_id),
|
||||
param_env,
|
||||
definition_ty,
|
||||
origin,
|
||||
) {
|
||||
let opaque_ty = self.tcx.mk_opaque(def_id.to_def_id(), id_substs);
|
||||
match infcx
|
||||
.at(&ObligationCause::misc(instantiated_ty.span, body_id), param_env)
|
||||
.eq(opaque_ty, definition_ty)
|
||||
{
|
||||
Ok(infer_ok) => {
|
||||
for obligation in infer_ok.obligations {
|
||||
fulfillment_cx.register_predicate_obligation(&infcx, obligation);
|
||||
@ -280,7 +278,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||
.err_ctxt()
|
||||
.report_mismatched_types(
|
||||
&ObligationCause::misc(instantiated_ty.span, body_id),
|
||||
self.tcx.mk_opaque(def_id.to_def_id(), id_substs),
|
||||
opaque_ty,
|
||||
definition_ty,
|
||||
err,
|
||||
)
|
||||
|
@ -1,6 +1,6 @@
|
||||
use rustc_infer::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRelatingDelegate};
|
||||
use rustc_infer::infer::NllRegionVariableOrigin;
|
||||
use rustc_infer::traits::ObligationCause;
|
||||
use rustc_infer::traits::PredicateObligations;
|
||||
use rustc_middle::mir::ConstraintCategory;
|
||||
use rustc_middle::ty::error::TypeError;
|
||||
use rustc_middle::ty::relate::TypeRelation;
|
||||
@ -155,27 +155,16 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
|
||||
true
|
||||
}
|
||||
|
||||
fn register_opaque_type(
|
||||
fn register_opaque_type_obligations(
|
||||
&mut self,
|
||||
a: Ty<'tcx>,
|
||||
b: Ty<'tcx>,
|
||||
a_is_expected: bool,
|
||||
obligations: PredicateObligations<'tcx>,
|
||||
) -> Result<(), TypeError<'tcx>> {
|
||||
let param_env = self.param_env();
|
||||
let span = self.span();
|
||||
let def_id = self.type_checker.body.source.def_id().expect_local();
|
||||
let body_id = self.type_checker.tcx().hir().local_def_id_to_hir_id(def_id);
|
||||
let cause = ObligationCause::misc(span, body_id);
|
||||
self.type_checker
|
||||
.fully_perform_op(
|
||||
self.locations,
|
||||
self.category,
|
||||
InstantiateOpaqueType {
|
||||
obligations: self
|
||||
.type_checker
|
||||
.infcx
|
||||
.handle_opaque_type(a, b, a_is_expected, &cause, param_env)?
|
||||
.obligations,
|
||||
obligations,
|
||||
// These fields are filled in during execution of the operation
|
||||
base_universe: None,
|
||||
region_constraints: None,
|
||||
|
@ -16,8 +16,8 @@ use crate::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRelating
|
||||
use crate::infer::region_constraints::{Constraint, RegionConstraintData};
|
||||
use crate::infer::{InferCtxt, InferOk, InferResult, NllRegionVariableOrigin};
|
||||
use crate::traits::query::{Fallible, NoSolution};
|
||||
use crate::traits::TraitEngine;
|
||||
use crate::traits::{Obligation, ObligationCause, PredicateObligation};
|
||||
use crate::traits::{PredicateObligations, TraitEngine};
|
||||
use rustc_data_structures::captures::Captures;
|
||||
use rustc_index::vec::Idx;
|
||||
use rustc_index::vec::IndexVec;
|
||||
@ -509,7 +509,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
for &(a, b) in &query_response.value.opaque_types {
|
||||
let a = substitute_value(self.tcx, &result_subst, a);
|
||||
let b = substitute_value(self.tcx, &result_subst, b);
|
||||
obligations.extend(self.handle_opaque_type(a, b, true, cause, param_env)?.obligations);
|
||||
obligations.extend(self.at(cause, param_env).eq(a, b)?.obligations);
|
||||
}
|
||||
|
||||
Ok(InferOk { value: result_subst, obligations })
|
||||
@ -741,17 +741,11 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
|
||||
true
|
||||
}
|
||||
|
||||
fn register_opaque_type(
|
||||
fn register_opaque_type_obligations(
|
||||
&mut self,
|
||||
a: Ty<'tcx>,
|
||||
b: Ty<'tcx>,
|
||||
a_is_expected: bool,
|
||||
obligations: PredicateObligations<'tcx>,
|
||||
) -> Result<(), TypeError<'tcx>> {
|
||||
self.obligations.extend(
|
||||
self.infcx
|
||||
.handle_opaque_type(a, b, a_is_expected, &self.cause, self.param_env)?
|
||||
.obligations,
|
||||
);
|
||||
self.obligations.extend(obligations);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,9 @@ use crate::infer::combine::ConstEquateRelation;
|
||||
use crate::infer::InferCtxt;
|
||||
use crate::infer::{ConstVarValue, ConstVariableValue};
|
||||
use crate::infer::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use crate::traits::PredicateObligation;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_middle::traits::ObligationCause;
|
||||
use rustc_middle::ty::error::TypeError;
|
||||
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
|
||||
use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
|
||||
@ -91,11 +93,9 @@ pub trait TypeRelatingDelegate<'tcx> {
|
||||
);
|
||||
|
||||
fn const_equate(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>);
|
||||
fn register_opaque_type(
|
||||
fn register_opaque_type_obligations(
|
||||
&mut self,
|
||||
a: Ty<'tcx>,
|
||||
b: Ty<'tcx>,
|
||||
a_is_expected: bool,
|
||||
obligations: Vec<PredicateObligation<'tcx>>,
|
||||
) -> Result<(), TypeError<'tcx>>;
|
||||
|
||||
/// Creates a new universe index. Used when instantiating placeholders.
|
||||
@ -414,7 +414,12 @@ where
|
||||
(_, &ty::Opaque(..)) => (generalize(a, true)?, b),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
self.delegate.register_opaque_type(a, b, true)?;
|
||||
let cause = ObligationCause::dummy_with_span(self.delegate.span());
|
||||
let obligations = self
|
||||
.infcx
|
||||
.handle_opaque_type(a, b, true, &cause, self.delegate.param_env())?
|
||||
.obligations;
|
||||
self.delegate.register_opaque_type_obligations(obligations)?;
|
||||
trace!(a = ?a.kind(), b = ?b.kind(), "opaque type instantiated");
|
||||
Ok(a)
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
return Ok(InferOk { value: (), obligations: vec![] });
|
||||
}
|
||||
let (a, b) = if a_is_expected { (a, b) } else { (b, a) };
|
||||
let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
|
||||
let process = |a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected| match *a.kind() {
|
||||
ty::Opaque(def_id, substs) if def_id.is_local() => {
|
||||
let def_id = def_id.expect_local();
|
||||
let origin = match self.defining_use_anchor {
|
||||
@ -169,13 +169,14 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
param_env,
|
||||
b,
|
||||
origin,
|
||||
a_is_expected,
|
||||
))
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
if let Some(res) = process(a, b) {
|
||||
if let Some(res) = process(a, b, true) {
|
||||
res
|
||||
} else if let Some(res) = process(b, a) {
|
||||
} else if let Some(res) = process(b, a, false) {
|
||||
res
|
||||
} else {
|
||||
let (a, b) = self.resolve_vars_if_possible((a, b));
|
||||
@ -514,13 +515,14 @@ impl UseKind {
|
||||
|
||||
impl<'tcx> InferCtxt<'tcx> {
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
pub fn register_hidden_type(
|
||||
fn register_hidden_type(
|
||||
&self,
|
||||
opaque_type_key: OpaqueTypeKey<'tcx>,
|
||||
cause: ObligationCause<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
hidden_ty: Ty<'tcx>,
|
||||
origin: hir::OpaqueTyOrigin,
|
||||
a_is_expected: bool,
|
||||
) -> InferResult<'tcx, ()> {
|
||||
let tcx = self.tcx;
|
||||
let OpaqueTypeKey { def_id, substs } = opaque_type_key;
|
||||
@ -539,7 +541,8 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
origin,
|
||||
);
|
||||
if let Some(prev) = prev {
|
||||
obligations = self.at(&cause, param_env).eq(prev, hidden_ty)?.obligations;
|
||||
obligations =
|
||||
self.at(&cause, param_env).eq_exp(a_is_expected, prev, hidden_ty)?.obligations;
|
||||
}
|
||||
|
||||
let item_bounds = tcx.bound_explicit_item_bounds(def_id.to_def_id());
|
||||
|
@ -2,9 +2,7 @@ use super::combine::{CombineFields, RelationDir};
|
||||
use super::SubregionOrigin;
|
||||
|
||||
use crate::infer::combine::ConstEquateRelation;
|
||||
use crate::infer::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use crate::traits::Obligation;
|
||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||
use rustc_middle::ty::relate::{Cause, Relate, RelateResult, TypeRelation};
|
||||
use rustc_middle::ty::visit::TypeVisitable;
|
||||
use rustc_middle::ty::TyVar;
|
||||
@ -130,39 +128,18 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
|
||||
(&ty::Opaque(did, ..), _) | (_, &ty::Opaque(did, ..))
|
||||
if self.fields.define_opaque_types && did.is_local() =>
|
||||
{
|
||||
let mut generalize = |ty, ty_is_expected| {
|
||||
let var = infcx.next_ty_var_id_in_universe(
|
||||
TypeVariableOrigin {
|
||||
kind: TypeVariableOriginKind::MiscVariable,
|
||||
span: self.fields.trace.cause.span,
|
||||
},
|
||||
ty::UniverseIndex::ROOT,
|
||||
);
|
||||
self.fields.instantiate(ty, RelationDir::SubtypeOf, var, ty_is_expected)?;
|
||||
Ok(infcx.tcx.mk_ty_var(var))
|
||||
};
|
||||
let (a, b) = if self.a_is_expected { (a, b) } else { (b, a) };
|
||||
let (ga, gb) = match (a.kind(), b.kind()) {
|
||||
(&ty::Opaque(..), _) => (a, generalize(b, true)?),
|
||||
(_, &ty::Opaque(..)) => (generalize(a, false)?, b),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
self.fields.obligations.extend(
|
||||
infcx
|
||||
.handle_opaque_type(ga, gb, true, &self.fields.trace.cause, self.param_env())
|
||||
// Don't leak any generalized type variables out of this
|
||||
// subtyping relation in the case of a type error.
|
||||
.map_err(|err| {
|
||||
let (ga, gb) = self.fields.infcx.resolve_vars_if_possible((ga, gb));
|
||||
if let TypeError::Sorts(sorts) = err && sorts.expected == ga && sorts.found == gb {
|
||||
TypeError::Sorts(ExpectedFound { expected: a, found: b })
|
||||
} else {
|
||||
err
|
||||
}
|
||||
})?
|
||||
.handle_opaque_type(
|
||||
a,
|
||||
b,
|
||||
self.a_is_expected,
|
||||
&self.fields.trace.cause,
|
||||
self.param_env(),
|
||||
)?
|
||||
.obligations,
|
||||
);
|
||||
Ok(ga)
|
||||
Ok(a)
|
||||
}
|
||||
// Optimization of GeneratorWitness relation since we know that all
|
||||
// free regions are replaced with bound regions during construction.
|
||||
|
Loading…
x
Reference in New Issue
Block a user