always make define_opaque_types
explicit
This commit is contained in:
parent
e84e5ff04a
commit
d2b7604db9
@ -9,8 +9,8 @@
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_hir::ItemKind;
|
||||
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_infer::infer::{self, RegionResolutionError};
|
||||
use rustc_infer::infer::{DefineOpaqueTypes, TyCtxtInferExt};
|
||||
use rustc_middle::ty::adjustment::CoerceUnsizedInfo;
|
||||
use rustc_middle::ty::{self, suggest_constraining_type_params, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
|
||||
@ -235,7 +235,8 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
|
||||
use rustc_type_ir::sty::TyKind::*;
|
||||
match (source.kind(), target.kind()) {
|
||||
(&Ref(r_a, _, mutbl_a), Ref(r_b, _, mutbl_b))
|
||||
if infcx.at(&cause, param_env).eq(r_a, *r_b).is_ok() && mutbl_a == *mutbl_b => {}
|
||||
if infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, r_a, *r_b).is_ok()
|
||||
&& mutbl_a == *mutbl_b => {}
|
||||
(&RawPtr(tm_a), &RawPtr(tm_b)) if tm_a.mutbl == tm_b.mutbl => (),
|
||||
(&Adt(def_a, substs_a), &Adt(def_b, substs_b))
|
||||
if def_a.is_struct() && def_b.is_struct() =>
|
||||
@ -278,7 +279,9 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(ok) = infcx.at(&cause, param_env).eq(ty_a, ty_b) {
|
||||
if let Ok(ok) =
|
||||
infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, ty_a, ty_b)
|
||||
{
|
||||
if ok.obligations.is_empty() {
|
||||
create_err(
|
||||
"the trait `DispatchFromDyn` may only be implemented \
|
||||
@ -504,7 +507,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
|
||||
// we may have to evaluate constraint
|
||||
// expressions in the course of execution.)
|
||||
// See e.g., #41936.
|
||||
if let Ok(ok) = infcx.at(&cause, param_env).eq(a, b) {
|
||||
if let Ok(ok) = infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, a, b) {
|
||||
if ok.obligations.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
@ -102,7 +102,7 @@
|
||||
use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::Node;
|
||||
use rustc_infer::infer::{InferOk, TyCtxtInferExt};
|
||||
use rustc_infer::infer::{DefineOpaqueTypes, InferOk, TyCtxtInferExt};
|
||||
use rustc_macros::fluent_messages;
|
||||
use rustc_middle::middle;
|
||||
use rustc_middle::ty::query::Providers;
|
||||
@ -165,7 +165,7 @@ fn require_same_types<'tcx>(
|
||||
) -> bool {
|
||||
let infcx = &tcx.infer_ctxt().build();
|
||||
let param_env = ty::ParamEnv::empty();
|
||||
let errors = match infcx.at(cause, param_env).eq(expected, actual) {
|
||||
let errors = match infcx.at(cause, param_env).eq(DefineOpaqueTypes::No, expected, actual) {
|
||||
Ok(InferOk { obligations, .. }) => traits::fully_solve_obligations(infcx, obligations),
|
||||
Err(err) => {
|
||||
infcx.err_ctxt().report_mismatched_types(cause, expected, actual, err).emit();
|
||||
|
@ -8,7 +8,7 @@
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_hir_analysis::astconv::AstConv;
|
||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use rustc_infer::infer::LateBoundRegionConversionTime;
|
||||
use rustc_infer::infer::{DefineOpaqueTypes, LateBoundRegionConversionTime};
|
||||
use rustc_infer::infer::{InferOk, InferResult};
|
||||
use rustc_macros::{TypeFoldable, TypeVisitable};
|
||||
use rustc_middle::ty::subst::InternalSubsts;
|
||||
@ -563,10 +563,11 @@ fn merge_supplied_sig_with_expectation(
|
||||
) {
|
||||
// Check that E' = S'.
|
||||
let cause = self.misc(hir_ty.span);
|
||||
let InferOk { value: (), obligations } = self
|
||||
.at(&cause, self.param_env)
|
||||
.define_opaque_types(true)
|
||||
.eq(*expected_ty, supplied_ty)?;
|
||||
let InferOk { value: (), obligations } = self.at(&cause, self.param_env).eq(
|
||||
DefineOpaqueTypes::Yes,
|
||||
*expected_ty,
|
||||
supplied_ty,
|
||||
)?;
|
||||
all_obligations.extend(obligations);
|
||||
}
|
||||
|
||||
@ -576,10 +577,11 @@ fn merge_supplied_sig_with_expectation(
|
||||
supplied_sig.output(),
|
||||
);
|
||||
let cause = &self.misc(decl.output.span());
|
||||
let InferOk { value: (), obligations } = self
|
||||
.at(cause, self.param_env)
|
||||
.define_opaque_types(true)
|
||||
.eq(expected_sigs.liberated_sig.output(), supplied_output_ty)?;
|
||||
let InferOk { value: (), obligations } = self.at(cause, self.param_env).eq(
|
||||
DefineOpaqueTypes::Yes,
|
||||
expected_sigs.liberated_sig.output(),
|
||||
supplied_output_ty,
|
||||
)?;
|
||||
all_obligations.extend(obligations);
|
||||
|
||||
let inputs = inputs.into_iter().map(|ty| self.resolve_vars_if_possible(ty));
|
||||
|
@ -45,7 +45,7 @@
|
||||
use rustc_hir::Expr;
|
||||
use rustc_hir_analysis::astconv::AstConv;
|
||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use rustc_infer::infer::{Coercion, InferOk, InferResult};
|
||||
use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult};
|
||||
use rustc_infer::traits::Obligation;
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_middle::ty::adjustment::{
|
||||
@ -143,11 +143,11 @@ fn new(
|
||||
fn unify(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> InferResult<'tcx, Ty<'tcx>> {
|
||||
debug!("unify(a: {:?}, b: {:?}, use_lub: {})", a, b, self.use_lub);
|
||||
self.commit_if_ok(|_| {
|
||||
let at = self.at(&self.cause, self.fcx.param_env).define_opaque_types(true);
|
||||
let at = self.at(&self.cause, self.fcx.param_env);
|
||||
if self.use_lub {
|
||||
at.lub(b, a)
|
||||
at.lub(DefineOpaqueTypes::Yes, b, a)
|
||||
} else {
|
||||
at.sup(b, a)
|
||||
at.sup(DefineOpaqueTypes::Yes, b, a)
|
||||
.map(|InferOk { value: (), obligations }| InferOk { value: a, obligations })
|
||||
}
|
||||
})
|
||||
@ -175,7 +175,7 @@ fn coerce(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
|
||||
// so this will have the side-effect of making sure we have no ambiguities
|
||||
// due to `[type error]` and `_` not coercing together.
|
||||
let _ = self.commit_if_ok(|_| {
|
||||
self.at(&self.cause, self.param_env).define_opaque_types(true).eq(a, b)
|
||||
self.at(&self.cause, self.param_env).eq(DefineOpaqueTypes::Yes, a, b)
|
||||
});
|
||||
return success(vec![], self.fcx.tcx.ty_error(guar), vec![]);
|
||||
}
|
||||
@ -1101,9 +1101,13 @@ fn try_find_coercion_lub<E>(
|
||||
(ty::FnDef(..), ty::FnDef(..)) => {
|
||||
// Don't reify if the function types have a LUB, i.e., they
|
||||
// are the same function and their parameters have a LUB.
|
||||
match self
|
||||
.commit_if_ok(|_| self.at(cause, self.param_env).lub(prev_ty, new_ty))
|
||||
{
|
||||
match self.commit_if_ok(|_| {
|
||||
self.at(cause, self.param_env).lub(
|
||||
DefineOpaqueTypes::No,
|
||||
prev_ty,
|
||||
new_ty,
|
||||
)
|
||||
}) {
|
||||
// We have a LUB of prev_ty and new_ty, just return it.
|
||||
Ok(ok) => return Ok(self.register_infer_ok_obligations(ok)),
|
||||
Err(_) => {
|
||||
@ -1153,7 +1157,7 @@ fn try_find_coercion_lub<E>(
|
||||
let sig = self
|
||||
.at(cause, self.param_env)
|
||||
.trace(prev_ty, new_ty)
|
||||
.lub(a_sig, b_sig)
|
||||
.lub(DefineOpaqueTypes::No, a_sig, b_sig)
|
||||
.map(|ok| self.register_infer_ok_obligations(ok))?;
|
||||
|
||||
// Reify both sides and return the reified fn pointer type.
|
||||
@ -1237,7 +1241,9 @@ fn try_find_coercion_lub<E>(
|
||||
);
|
||||
|
||||
return self
|
||||
.commit_if_ok(|_| self.at(cause, self.param_env).lub(prev_ty, new_ty))
|
||||
.commit_if_ok(|_| {
|
||||
self.at(cause, self.param_env).lub(DefineOpaqueTypes::No, prev_ty, new_ty)
|
||||
})
|
||||
.map(|ok| self.register_infer_ok_obligations(ok));
|
||||
}
|
||||
}
|
||||
@ -1248,8 +1254,10 @@ fn try_find_coercion_lub<E>(
|
||||
if let Some(e) = first_error {
|
||||
Err(e)
|
||||
} else {
|
||||
self.commit_if_ok(|_| self.at(cause, self.param_env).lub(prev_ty, new_ty))
|
||||
.map(|ok| self.register_infer_ok_obligations(ok))
|
||||
self.commit_if_ok(|_| {
|
||||
self.at(cause, self.param_env).lub(DefineOpaqueTypes::No, prev_ty, new_ty)
|
||||
})
|
||||
.map(|ok| self.register_infer_ok_obligations(ok))
|
||||
}
|
||||
}
|
||||
Ok(ok) => {
|
||||
@ -1487,8 +1495,12 @@ pub(crate) fn coerce_inner<'a>(
|
||||
assert!(expression_ty.is_unit(), "if let hack without unit type");
|
||||
fcx.at(cause, fcx.param_env)
|
||||
// needed for tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs
|
||||
.define_opaque_types(true)
|
||||
.eq_exp(label_expression_as_expected, expression_ty, self.merged_ty())
|
||||
.eq_exp(
|
||||
DefineOpaqueTypes::Yes,
|
||||
label_expression_as_expected,
|
||||
expression_ty,
|
||||
self.merged_ty(),
|
||||
)
|
||||
.map(|infer_ok| {
|
||||
fcx.register_infer_ok_obligations(infer_ok);
|
||||
expression_ty
|
||||
|
@ -8,7 +8,7 @@
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_hir::{is_range_literal, Node};
|
||||
use rustc_infer::infer::InferOk;
|
||||
use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_middle::middle::stability::EvalResult;
|
||||
use rustc_middle::ty::adjustment::AllowTwoPhase;
|
||||
@ -113,7 +113,7 @@ pub fn demand_suptype_with_origin(
|
||||
expected: Ty<'tcx>,
|
||||
actual: Ty<'tcx>,
|
||||
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
|
||||
match self.at(cause, self.param_env).define_opaque_types(true).sup(expected, actual) {
|
||||
match self.at(cause, self.param_env).sup(DefineOpaqueTypes::Yes, expected, actual) {
|
||||
Ok(InferOk { obligations, value: () }) => {
|
||||
self.register_predicates(obligations);
|
||||
None
|
||||
@ -143,7 +143,7 @@ pub fn demand_eqtype_with_origin(
|
||||
expected: Ty<'tcx>,
|
||||
actual: Ty<'tcx>,
|
||||
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
|
||||
match self.at(cause, self.param_env).define_opaque_types(true).eq(expected, actual) {
|
||||
match self.at(cause, self.param_env).eq(DefineOpaqueTypes::Yes, expected, actual) {
|
||||
Ok(InferOk { obligations, value: () }) => {
|
||||
self.register_predicates(obligations);
|
||||
None
|
||||
|
@ -36,6 +36,7 @@
|
||||
use rustc_hir_analysis::check::ty_kind_suggestion;
|
||||
use rustc_infer::infer;
|
||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use rustc_infer::infer::DefineOpaqueTypes;
|
||||
use rustc_infer::infer::InferOk;
|
||||
use rustc_infer::traits::ObligationCause;
|
||||
use rustc_middle::middle::stability;
|
||||
@ -1683,7 +1684,11 @@ fn check_expr_struct_fields(
|
||||
if let Some(_) = remaining_fields.remove(&ident) {
|
||||
let target_ty = self.field_ty(base_expr.span, f, substs);
|
||||
let cause = self.misc(base_expr.span);
|
||||
match self.at(&cause, self.param_env).sup(target_ty, fru_ty) {
|
||||
match self.at(&cause, self.param_env).sup(
|
||||
DefineOpaqueTypes::No,
|
||||
target_ty,
|
||||
fru_ty,
|
||||
) {
|
||||
Ok(InferOk { obligations, value: () }) => {
|
||||
self.register_predicates(obligations)
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
};
|
||||
use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
|
||||
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
|
||||
use rustc_infer::infer::InferResult;
|
||||
use rustc_infer::infer::{DefineOpaqueTypes, InferResult};
|
||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
|
||||
use rustc_middle::ty::error::TypeError;
|
||||
use rustc_middle::ty::fold::TypeFoldable;
|
||||
@ -558,7 +558,7 @@ fn save_generator_interior_predicates(&self, def_id: DefId) {
|
||||
let span = self.tcx.hir().body(body_id).value.span;
|
||||
let ok = self
|
||||
.at(&self.misc(span), self.param_env)
|
||||
.eq(interior, witness)
|
||||
.eq(DefineOpaqueTypes::No, interior, witness)
|
||||
.expect("Failed to unify generator interior type");
|
||||
let mut obligations = ok.obligations;
|
||||
|
||||
@ -1341,7 +1341,11 @@ fn inferred_kind(
|
||||
// This also occurs for an enum variant on a type alias.
|
||||
let impl_ty = self.normalize(span, tcx.type_of(impl_def_id).subst(tcx, substs));
|
||||
let self_ty = self.normalize(span, self_ty);
|
||||
match self.at(&self.misc(span), self.param_env).eq(impl_ty, self_ty) {
|
||||
match self.at(&self.misc(span), self.param_env).eq(
|
||||
DefineOpaqueTypes::No,
|
||||
impl_ty,
|
||||
self_ty,
|
||||
) {
|
||||
Ok(ok) => self.register_infer_ok_obligations(ok),
|
||||
Err(_) => {
|
||||
self.tcx.sess.delay_span_bug(
|
||||
|
@ -24,8 +24,8 @@
|
||||
use rustc_index::vec::IndexVec;
|
||||
use rustc_infer::infer::error_reporting::{FailureCode, ObligationCauseExt};
|
||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use rustc_infer::infer::InferOk;
|
||||
use rustc_infer::infer::TypeTrace;
|
||||
use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
|
||||
use rustc_middle::ty::adjustment::AllowTwoPhase;
|
||||
use rustc_middle::ty::visit::TypeVisitableExt;
|
||||
use rustc_middle::ty::{self, IsSuggestable, Ty};
|
||||
@ -301,9 +301,11 @@ pub(in super::super) fn check_argument_types(
|
||||
|
||||
// 3. Check if the formal type is a supertype of the checked one
|
||||
// and register any such obligations for future type checks
|
||||
let supertype_error = self
|
||||
.at(&self.misc(provided_arg.span), self.param_env)
|
||||
.sup(formal_input_ty, coerced_ty);
|
||||
let supertype_error = self.at(&self.misc(provided_arg.span), self.param_env).sup(
|
||||
DefineOpaqueTypes::No,
|
||||
formal_input_ty,
|
||||
coerced_ty,
|
||||
);
|
||||
let subtyping_error = match supertype_error {
|
||||
Ok(InferOk { obligations, value: () }) => {
|
||||
self.register_predicates(obligations);
|
||||
@ -585,7 +587,9 @@ fn has_error_or_infer<'tcx>(tys: impl IntoIterator<Item = Ty<'tcx>>) -> bool {
|
||||
|
||||
// Using probe here, since we don't want this subtyping to affect inference.
|
||||
let subtyping_error = self.probe(|_| {
|
||||
self.at(&self.misc(arg_span), self.param_env).sup(formal_input_ty, coerced_ty).err()
|
||||
self.at(&self.misc(arg_span), self.param_env)
|
||||
.sup(DefineOpaqueTypes::No, formal_input_ty, coerced_ty)
|
||||
.err()
|
||||
});
|
||||
|
||||
// Same as above: if either the coerce type or the checked type is an error type,
|
||||
|
@ -13,7 +13,7 @@
|
||||
use rustc_hir::hir_id::HirIdSet;
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_hir::{Arm, Expr, ExprKind, Guard, HirId, Pat, PatKind};
|
||||
use rustc_infer::infer::RegionVariableOrigin;
|
||||
use rustc_infer::infer::{DefineOpaqueTypes, RegionVariableOrigin};
|
||||
use rustc_middle::middle::region::{self, Scope, ScopeData, YieldData};
|
||||
use rustc_middle::ty::fold::FnMutDelegate;
|
||||
use rustc_middle::ty::{self, BoundVariableKind, RvalueScopes, Ty, TyCtxt, TypeVisitableExt};
|
||||
@ -327,7 +327,11 @@ pub fn resolve_interior<'a, 'tcx>(
|
||||
);
|
||||
|
||||
// Unify the type variable inside the generator with the new witness
|
||||
match fcx.at(&fcx.misc(body.value.span), fcx.param_env).eq(interior, witness) {
|
||||
match fcx.at(&fcx.misc(body.value.span), fcx.param_env).eq(
|
||||
DefineOpaqueTypes::No,
|
||||
interior,
|
||||
witness,
|
||||
) {
|
||||
Ok(ok) => fcx.register_infer_ok_obligations(ok),
|
||||
_ => bug!("failed to relate {interior} and {witness}"),
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
check_generic_arg_count_for_call, create_substs_for_generic_args,
|
||||
};
|
||||
use rustc_hir_analysis::astconv::{AstConv, CreateSubstsForGenericArgsCtxt, IsMethodCall};
|
||||
use rustc_infer::infer::{self, InferOk};
|
||||
use rustc_infer::infer::{self, DefineOpaqueTypes, InferOk};
|
||||
use rustc_middle::traits::{ObligationCauseCode, UnifyReceiverContext};
|
||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast};
|
||||
use rustc_middle::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
|
||||
@ -478,7 +478,7 @@ fn unify_receivers(
|
||||
substs,
|
||||
})),
|
||||
);
|
||||
match self.at(&cause, self.param_env).sup(method_self_ty, self_ty) {
|
||||
match self.at(&cause, self.param_env).sup(DefineOpaqueTypes::No, method_self_ty, self_ty) {
|
||||
Ok(InferOk { obligations, value: () }) => {
|
||||
self.register_predicates(obligations);
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
use rustc_hir_analysis::autoderef::{self, Autoderef};
|
||||
use rustc_infer::infer::canonical::OriginalQueryValues;
|
||||
use rustc_infer::infer::canonical::{Canonical, QueryResponse};
|
||||
use rustc_infer::infer::DefineOpaqueTypes;
|
||||
use rustc_infer::infer::{self, InferOk, TyCtxtInferExt};
|
||||
use rustc_middle::middle::stability;
|
||||
use rustc_middle::ty::fast_reject::TreatProjections;
|
||||
@ -930,7 +931,7 @@ fn matches_return_type(
|
||||
if let Some(self_ty) = self_ty {
|
||||
if self
|
||||
.at(&ObligationCause::dummy(), self.param_env)
|
||||
.sup(fty.inputs()[0], self_ty)
|
||||
.sup(DefineOpaqueTypes::No, fty.inputs()[0], self_ty)
|
||||
.is_err()
|
||||
{
|
||||
return false;
|
||||
@ -1436,9 +1437,11 @@ fn candidate_source(&self, candidate: &Candidate<'tcx>, self_ty: Ty<'tcx>) -> Ca
|
||||
CandidateSource::Trait(candidate.item.container_id(self.tcx))
|
||||
}
|
||||
TraitCandidate(trait_ref) => self.probe(|_| {
|
||||
let _ = self
|
||||
.at(&ObligationCause::dummy(), self.param_env)
|
||||
.sup(candidate.xform_self_ty, self_ty);
|
||||
let _ = self.at(&ObligationCause::dummy(), self.param_env).sup(
|
||||
DefineOpaqueTypes::No,
|
||||
candidate.xform_self_ty,
|
||||
self_ty,
|
||||
);
|
||||
match self.select_trait_candidate(trait_ref) {
|
||||
Ok(Some(traits::ImplSource::UserDefined(ref impl_data))) => {
|
||||
// If only a single impl matches, make the error message point
|
||||
@ -1465,10 +1468,11 @@ fn consider_probe(
|
||||
|
||||
self.probe(|_| {
|
||||
// First check that the self type can be related.
|
||||
let sub_obligations = match self
|
||||
.at(&ObligationCause::dummy(), self.param_env)
|
||||
.sup(probe.xform_self_ty, self_ty)
|
||||
{
|
||||
let sub_obligations = match self.at(&ObligationCause::dummy(), self.param_env).sup(
|
||||
DefineOpaqueTypes::No,
|
||||
probe.xform_self_ty,
|
||||
self_ty,
|
||||
) {
|
||||
Ok(InferOk { obligations, value: () }) => obligations,
|
||||
Err(err) => {
|
||||
debug!("--> cannot relate self-types {:?}", err);
|
||||
@ -1683,7 +1687,7 @@ fn consider_probe(
|
||||
if let ProbeResult::Match = result
|
||||
&& self
|
||||
.at(&ObligationCause::dummy(), self.param_env)
|
||||
.sup(return_ty, xform_ret_ty)
|
||||
.sup(DefineOpaqueTypes::No, return_ty, xform_ret_ty)
|
||||
.is_err()
|
||||
{
|
||||
result = ProbeResult::BadReturnType;
|
||||
|
@ -30,16 +30,20 @@
|
||||
use rustc_middle::ty::relate::{Relate, TypeRelation};
|
||||
use rustc_middle::ty::{Const, ImplSubject};
|
||||
|
||||
/// Whether we should define opaque types or just treat them opaquely.
|
||||
///
|
||||
/// Currently only used to prevent predicate matching from matching anything
|
||||
/// against opaque types.
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
pub enum DefineOpaqueTypes {
|
||||
Yes,
|
||||
No,
|
||||
}
|
||||
|
||||
pub struct At<'a, 'tcx> {
|
||||
pub infcx: &'a InferCtxt<'tcx>,
|
||||
pub cause: &'a ObligationCause<'tcx>,
|
||||
pub param_env: ty::ParamEnv<'tcx>,
|
||||
/// Whether we should define opaque types
|
||||
/// or just treat them opaquely.
|
||||
/// Currently only used to prevent predicate
|
||||
/// matching from matching anything against opaque
|
||||
/// types.
|
||||
pub define_opaque_types: bool,
|
||||
}
|
||||
|
||||
pub struct Trace<'a, 'tcx> {
|
||||
@ -55,7 +59,7 @@ pub fn at<'a>(
|
||||
cause: &'a ObligationCause<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> At<'a, 'tcx> {
|
||||
At { infcx: self, cause, param_env, define_opaque_types: false }
|
||||
At { infcx: self, cause, param_env }
|
||||
}
|
||||
|
||||
/// Forks the inference context, creating a new inference context with the same inference
|
||||
@ -93,33 +97,21 @@ fn to_trace(
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> At<'a, 'tcx> {
|
||||
pub fn define_opaque_types(self, define_opaque_types: bool) -> Self {
|
||||
Self { define_opaque_types, ..self }
|
||||
}
|
||||
|
||||
/// Hacky routine for equating two impl headers in coherence.
|
||||
pub fn eq_impl_headers(
|
||||
self,
|
||||
expected: &ty::ImplHeader<'tcx>,
|
||||
actual: &ty::ImplHeader<'tcx>,
|
||||
) -> InferResult<'tcx, ()> {
|
||||
debug!("eq_impl_header({:?} = {:?})", expected, actual);
|
||||
match (expected.trait_ref, actual.trait_ref) {
|
||||
(Some(a_ref), Some(b_ref)) => self.eq(a_ref, b_ref),
|
||||
(None, None) => self.eq(expected.self_ty, actual.self_ty),
|
||||
_ => bug!("mk_eq_impl_headers given mismatched impl kinds"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Makes `a <: b`, where `a` may or may not be expected.
|
||||
///
|
||||
/// See [`At::trace_exp`] and [`Trace::sub`] for a version of
|
||||
/// this method that only requires `T: Relate<'tcx>`
|
||||
pub fn sub_exp<T>(self, a_is_expected: bool, a: T, b: T) -> InferResult<'tcx, ()>
|
||||
pub fn sub_exp<T>(
|
||||
self,
|
||||
define_opaque_types: DefineOpaqueTypes,
|
||||
a_is_expected: bool,
|
||||
a: T,
|
||||
b: T,
|
||||
) -> InferResult<'tcx, ()>
|
||||
where
|
||||
T: ToTrace<'tcx>,
|
||||
{
|
||||
self.trace_exp(a_is_expected, a, b).sub(a, b)
|
||||
self.trace_exp(a_is_expected, a, b).sub(define_opaque_types, a, b)
|
||||
}
|
||||
|
||||
/// Makes `actual <: expected`. For example, if type-checking a
|
||||
@ -129,54 +121,81 @@ pub fn sub_exp<T>(self, a_is_expected: bool, a: T, b: T) -> InferResult<'tcx, ()
|
||||
///
|
||||
/// See [`At::trace`] and [`Trace::sub`] for a version of
|
||||
/// this method that only requires `T: Relate<'tcx>`
|
||||
pub fn sup<T>(self, expected: T, actual: T) -> InferResult<'tcx, ()>
|
||||
pub fn sup<T>(
|
||||
self,
|
||||
define_opaque_types: DefineOpaqueTypes,
|
||||
expected: T,
|
||||
actual: T,
|
||||
) -> InferResult<'tcx, ()>
|
||||
where
|
||||
T: ToTrace<'tcx>,
|
||||
{
|
||||
self.sub_exp(false, actual, expected)
|
||||
self.sub_exp(define_opaque_types, false, actual, expected)
|
||||
}
|
||||
|
||||
/// Makes `expected <: actual`.
|
||||
///
|
||||
/// See [`At::trace`] and [`Trace::sub`] for a version of
|
||||
/// this method that only requires `T: Relate<'tcx>`
|
||||
pub fn sub<T>(self, expected: T, actual: T) -> InferResult<'tcx, ()>
|
||||
pub fn sub<T>(
|
||||
self,
|
||||
define_opaque_types: DefineOpaqueTypes,
|
||||
expected: T,
|
||||
actual: T,
|
||||
) -> InferResult<'tcx, ()>
|
||||
where
|
||||
T: ToTrace<'tcx>,
|
||||
{
|
||||
self.sub_exp(true, expected, actual)
|
||||
self.sub_exp(define_opaque_types, true, expected, actual)
|
||||
}
|
||||
|
||||
/// Makes `expected <: actual`.
|
||||
///
|
||||
/// See [`At::trace_exp`] and [`Trace::eq`] for a version of
|
||||
/// this method that only requires `T: Relate<'tcx>`
|
||||
pub fn eq_exp<T>(self, a_is_expected: bool, a: T, b: T) -> InferResult<'tcx, ()>
|
||||
pub fn eq_exp<T>(
|
||||
self,
|
||||
define_opaque_types: DefineOpaqueTypes,
|
||||
a_is_expected: bool,
|
||||
a: T,
|
||||
b: T,
|
||||
) -> InferResult<'tcx, ()>
|
||||
where
|
||||
T: ToTrace<'tcx>,
|
||||
{
|
||||
self.trace_exp(a_is_expected, a, b).eq(a, b)
|
||||
self.trace_exp(a_is_expected, a, b).eq(define_opaque_types, a, b)
|
||||
}
|
||||
|
||||
/// Makes `expected <: actual`.
|
||||
///
|
||||
/// See [`At::trace`] and [`Trace::eq`] for a version of
|
||||
/// this method that only requires `T: Relate<'tcx>`
|
||||
pub fn eq<T>(self, expected: T, actual: T) -> InferResult<'tcx, ()>
|
||||
pub fn eq<T>(
|
||||
self,
|
||||
define_opaque_types: DefineOpaqueTypes,
|
||||
expected: T,
|
||||
actual: T,
|
||||
) -> InferResult<'tcx, ()>
|
||||
where
|
||||
T: ToTrace<'tcx>,
|
||||
{
|
||||
self.trace(expected, actual).eq(expected, actual)
|
||||
self.trace(expected, actual).eq(define_opaque_types, expected, actual)
|
||||
}
|
||||
|
||||
pub fn relate<T>(self, expected: T, variance: ty::Variance, actual: T) -> InferResult<'tcx, ()>
|
||||
pub fn relate<T>(
|
||||
self,
|
||||
define_opaque_types: DefineOpaqueTypes,
|
||||
expected: T,
|
||||
variance: ty::Variance,
|
||||
actual: T,
|
||||
) -> InferResult<'tcx, ()>
|
||||
where
|
||||
T: ToTrace<'tcx>,
|
||||
{
|
||||
match variance {
|
||||
ty::Variance::Covariant => self.sub(expected, actual),
|
||||
ty::Variance::Invariant => self.eq(expected, actual),
|
||||
ty::Variance::Contravariant => self.sup(expected, actual),
|
||||
ty::Variance::Covariant => self.sub(define_opaque_types, expected, actual),
|
||||
ty::Variance::Invariant => self.eq(define_opaque_types, expected, actual),
|
||||
ty::Variance::Contravariant => self.sup(define_opaque_types, expected, actual),
|
||||
|
||||
// We could make this make sense but it's not readily
|
||||
// exposed and I don't feel like dealing with it. Note
|
||||
@ -195,11 +214,16 @@ pub fn relate<T>(self, expected: T, variance: ty::Variance, actual: T) -> InferR
|
||||
///
|
||||
/// See [`At::trace`] and [`Trace::lub`] for a version of
|
||||
/// this method that only requires `T: Relate<'tcx>`
|
||||
pub fn lub<T>(self, expected: T, actual: T) -> InferResult<'tcx, T>
|
||||
pub fn lub<T>(
|
||||
self,
|
||||
define_opaque_types: DefineOpaqueTypes,
|
||||
expected: T,
|
||||
actual: T,
|
||||
) -> InferResult<'tcx, T>
|
||||
where
|
||||
T: ToTrace<'tcx>,
|
||||
{
|
||||
self.trace(expected, actual).lub(expected, actual)
|
||||
self.trace(expected, actual).lub(define_opaque_types, expected, actual)
|
||||
}
|
||||
|
||||
/// Computes the greatest-lower-bound, or mutual subtype, of two
|
||||
@ -208,11 +232,16 @@ pub fn lub<T>(self, expected: T, actual: T) -> InferResult<'tcx, T>
|
||||
///
|
||||
/// See [`At::trace`] and [`Trace::glb`] for a version of
|
||||
/// this method that only requires `T: Relate<'tcx>`
|
||||
pub fn glb<T>(self, expected: T, actual: T) -> InferResult<'tcx, T>
|
||||
pub fn glb<T>(
|
||||
self,
|
||||
define_opaque_types: DefineOpaqueTypes,
|
||||
expected: T,
|
||||
actual: T,
|
||||
) -> InferResult<'tcx, T>
|
||||
where
|
||||
T: ToTrace<'tcx>,
|
||||
{
|
||||
self.trace(expected, actual).glb(expected, actual)
|
||||
self.trace(expected, actual).glb(define_opaque_types, expected, actual)
|
||||
}
|
||||
|
||||
/// Sets the "trace" values that will be used for
|
||||
@ -242,13 +271,13 @@ impl<'a, 'tcx> Trace<'a, 'tcx> {
|
||||
/// Makes `a <: b` where `a` may or may not be expected (if
|
||||
/// `a_is_expected` is true, then `a` is expected).
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
pub fn sub<T>(self, a: T, b: T) -> InferResult<'tcx, ()>
|
||||
pub fn sub<T>(self, define_opaque_types: DefineOpaqueTypes, a: T, b: T) -> InferResult<'tcx, ()>
|
||||
where
|
||||
T: Relate<'tcx>,
|
||||
{
|
||||
let Trace { at, trace, a_is_expected } = self;
|
||||
at.infcx.commit_if_ok(|_| {
|
||||
let mut fields = at.infcx.combine_fields(trace, at.param_env, at.define_opaque_types);
|
||||
let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
|
||||
fields
|
||||
.sub(a_is_expected)
|
||||
.relate(a, b)
|
||||
@ -259,13 +288,13 @@ pub fn sub<T>(self, a: T, b: T) -> InferResult<'tcx, ()>
|
||||
/// Makes `a == b`; the expectation is set by the call to
|
||||
/// `trace()`.
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
pub fn eq<T>(self, a: T, b: T) -> InferResult<'tcx, ()>
|
||||
pub fn eq<T>(self, define_opaque_types: DefineOpaqueTypes, a: T, b: T) -> InferResult<'tcx, ()>
|
||||
where
|
||||
T: Relate<'tcx>,
|
||||
{
|
||||
let Trace { at, trace, a_is_expected } = self;
|
||||
at.infcx.commit_if_ok(|_| {
|
||||
let mut fields = at.infcx.combine_fields(trace, at.param_env, at.define_opaque_types);
|
||||
let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
|
||||
fields
|
||||
.equate(a_is_expected)
|
||||
.relate(a, b)
|
||||
@ -274,13 +303,13 @@ pub fn eq<T>(self, a: T, b: T) -> InferResult<'tcx, ()>
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
pub fn lub<T>(self, a: T, b: T) -> InferResult<'tcx, T>
|
||||
pub fn lub<T>(self, define_opaque_types: DefineOpaqueTypes, a: T, b: T) -> InferResult<'tcx, T>
|
||||
where
|
||||
T: Relate<'tcx>,
|
||||
{
|
||||
let Trace { at, trace, a_is_expected } = self;
|
||||
at.infcx.commit_if_ok(|_| {
|
||||
let mut fields = at.infcx.combine_fields(trace, at.param_env, at.define_opaque_types);
|
||||
let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
|
||||
fields
|
||||
.lub(a_is_expected)
|
||||
.relate(a, b)
|
||||
@ -289,13 +318,13 @@ pub fn lub<T>(self, a: T, b: T) -> InferResult<'tcx, T>
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
pub fn glb<T>(self, a: T, b: T) -> InferResult<'tcx, T>
|
||||
pub fn glb<T>(self, define_opaque_types: DefineOpaqueTypes, a: T, b: T) -> InferResult<'tcx, T>
|
||||
where
|
||||
T: Relate<'tcx>,
|
||||
{
|
||||
let Trace { at, trace, a_is_expected } = self;
|
||||
at.infcx.commit_if_ok(|_| {
|
||||
let mut fields = at.infcx.combine_fields(trace, at.param_env, at.define_opaque_types);
|
||||
let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
|
||||
fields
|
||||
.glb(a_is_expected)
|
||||
.relate(a, b)
|
||||
|
@ -14,7 +14,7 @@
|
||||
};
|
||||
use crate::infer::nll_relate::{TypeRelating, TypeRelatingDelegate};
|
||||
use crate::infer::region_constraints::{Constraint, RegionConstraintData};
|
||||
use crate::infer::{InferCtxt, InferOk, InferResult, NllRegionVariableOrigin};
|
||||
use crate::infer::{DefineOpaqueTypes, InferCtxt, InferOk, InferResult, NllRegionVariableOrigin};
|
||||
use crate::traits::query::{Fallible, NoSolution};
|
||||
use crate::traits::{Obligation, ObligationCause, PredicateObligation};
|
||||
use crate::traits::{PredicateObligations, TraitEngine, TraitEngineExt};
|
||||
@ -510,7 +510,7 @@ fn query_response_substitution_guess<R>(
|
||||
let b = substitute_value(self.tcx, &result_subst, b);
|
||||
debug!(?a, ?b, "constrain opaque type");
|
||||
obligations
|
||||
.extend(self.at(cause, param_env).define_opaque_types(true).eq(a, b)?.obligations);
|
||||
.extend(self.at(cause, param_env).eq(DefineOpaqueTypes::Yes, a, b)?.obligations);
|
||||
}
|
||||
|
||||
Ok(InferOk { value: result_subst, obligations })
|
||||
@ -603,8 +603,11 @@ fn unify_canonical_vars(
|
||||
|
||||
match (value1.unpack(), value2.unpack()) {
|
||||
(GenericArgKind::Type(v1), GenericArgKind::Type(v2)) => {
|
||||
obligations
|
||||
.extend(self.at(cause, param_env).eq(v1, v2)?.into_obligations());
|
||||
obligations.extend(
|
||||
self.at(cause, param_env)
|
||||
.eq(DefineOpaqueTypes::Yes, v1, v2)?
|
||||
.into_obligations(),
|
||||
);
|
||||
}
|
||||
(GenericArgKind::Lifetime(re1), GenericArgKind::Lifetime(re2))
|
||||
if re1.is_erased() && re2.is_erased() =>
|
||||
@ -612,11 +615,14 @@ fn unify_canonical_vars(
|
||||
// no action needed
|
||||
}
|
||||
(GenericArgKind::Lifetime(v1), GenericArgKind::Lifetime(v2)) => {
|
||||
obligations
|
||||
.extend(self.at(cause, param_env).eq(v1, v2)?.into_obligations());
|
||||
obligations.extend(
|
||||
self.at(cause, param_env)
|
||||
.eq(DefineOpaqueTypes::Yes, v1, v2)?
|
||||
.into_obligations(),
|
||||
);
|
||||
}
|
||||
(GenericArgKind::Const(v1), GenericArgKind::Const(v2)) => {
|
||||
let ok = self.at(cause, param_env).eq(v1, v2)?;
|
||||
let ok = self.at(cause, param_env).eq(DefineOpaqueTypes::Yes, v1, v2)?;
|
||||
obligations.extend(ok.into_obligations());
|
||||
}
|
||||
_ => {
|
||||
|
@ -27,7 +27,7 @@
|
||||
use super::lub::Lub;
|
||||
use super::sub::Sub;
|
||||
use super::type_variable::TypeVariableValue;
|
||||
use super::{InferCtxt, MiscVariable, TypeTrace};
|
||||
use super::{DefineOpaqueTypes, InferCtxt, MiscVariable, TypeTrace};
|
||||
use crate::traits::{Obligation, PredicateObligations};
|
||||
use rustc_data_structures::sso::SsoHashMap;
|
||||
use rustc_hir::def_id::DefId;
|
||||
@ -52,12 +52,7 @@ pub struct CombineFields<'infcx, 'tcx> {
|
||||
pub cause: Option<ty::relate::Cause>,
|
||||
pub param_env: ty::ParamEnv<'tcx>,
|
||||
pub obligations: PredicateObligations<'tcx>,
|
||||
/// Whether we should define opaque types
|
||||
/// or just treat them opaquely.
|
||||
/// Currently only used to prevent predicate
|
||||
/// matching from matching anything against opaque
|
||||
/// types.
|
||||
pub define_opaque_types: bool,
|
||||
pub define_opaque_types: DefineOpaqueTypes,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::infer::DefineOpaqueTypes;
|
||||
use crate::traits::PredicateObligations;
|
||||
|
||||
use super::combine::{CombineFields, ObligationEmittingRelation, RelationDir};
|
||||
@ -110,7 +111,8 @@ fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
|
||||
}
|
||||
(&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _)
|
||||
| (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }))
|
||||
if self.fields.define_opaque_types && def_id.is_local() =>
|
||||
if self.fields.define_opaque_types == DefineOpaqueTypes::Yes
|
||||
&& def_id.is_local() =>
|
||||
{
|
||||
self.fields.obligations.extend(
|
||||
infcx
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
use super::combine::{CombineFields, ObligationEmittingRelation};
|
||||
use super::lattice::{self, LatticeDir};
|
||||
use super::InferCtxt;
|
||||
use super::Subtype;
|
||||
use super::{DefineOpaqueTypes, InferCtxt};
|
||||
|
||||
use crate::traits::{ObligationCause, PredicateObligations};
|
||||
use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
|
||||
@ -142,7 +142,7 @@ fn relate_bound(&mut self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResul
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn define_opaque_types(&self) -> bool {
|
||||
fn define_opaque_types(&self) -> DefineOpaqueTypes {
|
||||
self.fields.define_opaque_types
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
use super::combine::ObligationEmittingRelation;
|
||||
use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use super::InferCtxt;
|
||||
use super::{DefineOpaqueTypes, InferCtxt};
|
||||
|
||||
use crate::traits::ObligationCause;
|
||||
use rustc_middle::ty::relate::RelateResult;
|
||||
@ -36,7 +36,7 @@ pub trait LatticeDir<'f, 'tcx>: ObligationEmittingRelation<'tcx> {
|
||||
|
||||
fn cause(&self) -> &ObligationCause<'tcx>;
|
||||
|
||||
fn define_opaque_types(&self) -> bool;
|
||||
fn define_opaque_types(&self) -> DefineOpaqueTypes;
|
||||
|
||||
// Relates the type `v` to `a` and `b` such that `v` represents
|
||||
// the LUB/GLB of `a` and `b` as appropriate.
|
||||
@ -110,7 +110,7 @@ pub fn super_lattice_tys<'a, 'tcx: 'a, L>(
|
||||
) if a_def_id == b_def_id => infcx.super_combine_tys(this, a, b),
|
||||
(&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _)
|
||||
| (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }))
|
||||
if this.define_opaque_types() && def_id.is_local() =>
|
||||
if this.define_opaque_types() == DefineOpaqueTypes::Yes && def_id.is_local() =>
|
||||
{
|
||||
this.register_obligations(
|
||||
infcx
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
use super::combine::{CombineFields, ObligationEmittingRelation};
|
||||
use super::lattice::{self, LatticeDir};
|
||||
use super::InferCtxt;
|
||||
use super::Subtype;
|
||||
use super::{DefineOpaqueTypes, InferCtxt};
|
||||
|
||||
use crate::traits::{ObligationCause, PredicateObligations};
|
||||
use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
|
||||
@ -142,7 +142,7 @@ fn relate_bound(&mut self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResul
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn define_opaque_types(&self) -> bool {
|
||||
fn define_opaque_types(&self) -> DefineOpaqueTypes {
|
||||
self.fields.define_opaque_types
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
pub use self::at::DefineOpaqueTypes;
|
||||
pub use self::freshen::TypeFreshener;
|
||||
pub use self::lexical_region_resolve::RegionResolutionError;
|
||||
pub use self::LateBoundRegionConversionTime::*;
|
||||
@ -729,7 +730,7 @@ fn combine_fields<'a>(
|
||||
&'a self,
|
||||
trace: TypeTrace<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
define_opaque_types: bool,
|
||||
define_opaque_types: DefineOpaqueTypes,
|
||||
) -> CombineFields<'a, 'tcx> {
|
||||
CombineFields {
|
||||
infcx: self,
|
||||
@ -860,7 +861,7 @@ pub fn can_sub<T>(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> bool
|
||||
T: at::ToTrace<'tcx>,
|
||||
{
|
||||
let origin = &ObligationCause::dummy();
|
||||
self.probe(|_| self.at(origin, param_env).sub(a, b).is_ok())
|
||||
self.probe(|_| self.at(origin, param_env).sub(DefineOpaqueTypes::No, a, b).is_ok())
|
||||
}
|
||||
|
||||
pub fn can_eq<T>(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> bool
|
||||
@ -868,7 +869,7 @@ pub fn can_eq<T>(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> bool
|
||||
T: at::ToTrace<'tcx>,
|
||||
{
|
||||
let origin = &ObligationCause::dummy();
|
||||
self.probe(|_| self.at(origin, param_env).eq(a, b).is_ok())
|
||||
self.probe(|_| self.at(origin, param_env).eq(DefineOpaqueTypes::No, a, b).is_ok())
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
@ -963,7 +964,8 @@ pub fn subtype_predicate(
|
||||
let ty::SubtypePredicate { a_is_expected, a, b } =
|
||||
self.instantiate_binder_with_placeholders(predicate);
|
||||
|
||||
let ok = self.at(cause, param_env).sub_exp(a_is_expected, a, b)?;
|
||||
let ok =
|
||||
self.at(cause, param_env).sub_exp(DefineOpaqueTypes::No, a_is_expected, a, b)?;
|
||||
|
||||
Ok(ok.unit())
|
||||
}))
|
||||
|
@ -1,3 +1,5 @@
|
||||
use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use super::{DefineOpaqueTypes, InferResult};
|
||||
use crate::errors::OpaqueHiddenTypeDiag;
|
||||
use crate::infer::{DefiningAnchor, InferCtxt, InferOk};
|
||||
use crate::traits;
|
||||
@ -16,18 +18,13 @@
|
||||
TypeVisitable, TypeVisitableExt, TypeVisitor,
|
||||
};
|
||||
use rustc_span::Span;
|
||||
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
pub type OpaqueTypeMap<'tcx> = VecMap<OpaqueTypeKey<'tcx>, OpaqueTypeDecl<'tcx>>;
|
||||
|
||||
mod table;
|
||||
|
||||
pub type OpaqueTypeMap<'tcx> = VecMap<OpaqueTypeKey<'tcx>, OpaqueTypeDecl<'tcx>>;
|
||||
pub use table::{OpaqueTypeStorage, OpaqueTypeTable};
|
||||
|
||||
use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use super::InferResult;
|
||||
|
||||
/// Information about the opaque types whose values we
|
||||
/// are inferring in this function (these are the `impl Trait` that
|
||||
/// appear in the return type).
|
||||
@ -547,8 +544,7 @@ fn register_hidden_type(
|
||||
if let Some(prev) = prev {
|
||||
obligations = self
|
||||
.at(&cause, param_env)
|
||||
.define_opaque_types(true)
|
||||
.eq_exp(a_is_expected, prev, hidden_ty)?
|
||||
.eq_exp(DefineOpaqueTypes::Yes, a_is_expected, prev, hidden_ty)?
|
||||
.obligations;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
use super::combine::{CombineFields, RelationDir};
|
||||
use super::{ObligationEmittingRelation, SubregionOrigin};
|
||||
use super::{DefineOpaqueTypes, ObligationEmittingRelation, SubregionOrigin};
|
||||
|
||||
use crate::traits::{Obligation, PredicateObligations};
|
||||
use rustc_middle::ty::relate::{Cause, Relate, RelateResult, TypeRelation};
|
||||
@ -138,7 +138,8 @@ fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
|
||||
}
|
||||
(&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _)
|
||||
| (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }))
|
||||
if self.fields.define_opaque_types && def_id.is_local() =>
|
||||
if self.fields.define_opaque_types == DefineOpaqueTypes::Yes
|
||||
&& def_id.is_local() =>
|
||||
{
|
||||
self.fields.obligations.extend(
|
||||
infcx
|
||||
|
@ -2,7 +2,7 @@
|
||||
use rustc_infer::infer::at::ToTrace;
|
||||
use rustc_infer::infer::canonical::CanonicalVarValues;
|
||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use rustc_infer::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
|
||||
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk, LateBoundRegionConversionTime};
|
||||
use rustc_infer::traits::query::NoSolution;
|
||||
use rustc_infer::traits::ObligationCause;
|
||||
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
|
||||
@ -144,7 +144,7 @@ pub(super) fn eq<T: ToTrace<'tcx>>(
|
||||
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
|
||||
self.infcx
|
||||
.at(&ObligationCause::dummy(), param_env)
|
||||
.eq(lhs, rhs)
|
||||
.eq(DefineOpaqueTypes::No, lhs, rhs)
|
||||
.map(|InferOk { value: (), obligations }| {
|
||||
obligations.into_iter().map(|o| o.into()).collect()
|
||||
})
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_infer::infer::canonical::{Canonical, CanonicalVarValues};
|
||||
use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt};
|
||||
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk, TyCtxtInferExt};
|
||||
use rustc_infer::traits::query::NoSolution;
|
||||
use rustc_middle::traits::solve::{
|
||||
CanonicalGoal, CanonicalResponse, Certainty, ExternalConstraints, ExternalConstraintsData,
|
||||
@ -268,7 +268,7 @@ fn compute_subtype_goal(
|
||||
let InferOk { value: (), obligations } = self
|
||||
.infcx
|
||||
.at(&ObligationCause::dummy(), goal.param_env)
|
||||
.sub(goal.predicate.a, goal.predicate.b)?;
|
||||
.sub(DefineOpaqueTypes::No, goal.predicate.a, goal.predicate.b)?;
|
||||
self.evaluate_all_and_make_canonical_response(
|
||||
obligations.into_iter().map(|pred| pred.into()).collect(),
|
||||
)
|
||||
|
@ -7,6 +7,7 @@
|
||||
use crate::infer::region_constraints::{Constraint, RegionConstraintData};
|
||||
use crate::infer::InferCtxt;
|
||||
use crate::traits::project::ProjectAndUnifyResult;
|
||||
use rustc_infer::infer::DefineOpaqueTypes;
|
||||
use rustc_middle::mir::interpret::ErrorHandled;
|
||||
use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
|
||||
use rustc_middle::ty::visit::TypeVisitableExt;
|
||||
@ -814,7 +815,7 @@ fn evaluate_nested_obligations(
|
||||
|
||||
match (evaluate(c1), evaluate(c2)) {
|
||||
(Ok(c1), Ok(c2)) => {
|
||||
match selcx.infcx.at(&obligation.cause, obligation.param_env).eq(c1, c2)
|
||||
match selcx.infcx.at(&obligation.cause, obligation.param_env).eq(DefineOpaqueTypes::No,c1, c2)
|
||||
{
|
||||
Ok(_) => (),
|
||||
Err(_) => return false,
|
||||
|
@ -17,7 +17,7 @@
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_errors::Diagnostic;
|
||||
use rustc_hir::def_id::{DefId, CRATE_DEF_ID, LOCAL_CRATE};
|
||||
use rustc_infer::infer::{DefiningAnchor, InferCtxt, TyCtxtInferExt};
|
||||
use rustc_infer::infer::{DefineOpaqueTypes, DefiningAnchor, InferCtxt, TyCtxtInferExt};
|
||||
use rustc_infer::traits::util;
|
||||
use rustc_middle::traits::specialization_graph::OverlapMode;
|
||||
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
|
||||
@ -181,7 +181,7 @@ fn overlap_within_probe<'cx, 'tcx>(
|
||||
let impl1_header = with_fresh_ty_vars(selcx, param_env, impl1_def_id);
|
||||
let impl2_header = with_fresh_ty_vars(selcx, param_env, impl2_def_id);
|
||||
|
||||
let obligations = equate_impl_headers(selcx, &impl1_header, &impl2_header)?;
|
||||
let obligations = equate_impl_headers(selcx.infcx, &impl1_header, &impl2_header)?;
|
||||
debug!("overlap: unification check succeeded");
|
||||
|
||||
if overlap_mode.use_implicit_negative() {
|
||||
@ -207,20 +207,25 @@ fn overlap_within_probe<'cx, 'tcx>(
|
||||
Some(OverlapResult { impl_header, intercrate_ambiguity_causes, involves_placeholder })
|
||||
}
|
||||
|
||||
fn equate_impl_headers<'cx, 'tcx>(
|
||||
selcx: &mut SelectionContext<'cx, 'tcx>,
|
||||
impl1_header: &ty::ImplHeader<'tcx>,
|
||||
impl2_header: &ty::ImplHeader<'tcx>,
|
||||
#[instrument(level = "debug", skip(infcx), ret)]
|
||||
fn equate_impl_headers<'tcx>(
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
impl1: &ty::ImplHeader<'tcx>,
|
||||
impl2: &ty::ImplHeader<'tcx>,
|
||||
) -> Option<PredicateObligations<'tcx>> {
|
||||
// Do `a` and `b` unify? If not, no overlap.
|
||||
debug!("equate_impl_headers(impl1_header={:?}, impl2_header={:?}", impl1_header, impl2_header);
|
||||
selcx
|
||||
.infcx
|
||||
.at(&ObligationCause::dummy(), ty::ParamEnv::empty())
|
||||
.define_opaque_types(true)
|
||||
.eq_impl_headers(impl1_header, impl2_header)
|
||||
.map(|infer_ok| infer_ok.obligations)
|
||||
.ok()
|
||||
let result = match (impl1.trait_ref, impl2.trait_ref) {
|
||||
(Some(impl1_ref), Some(impl2_ref)) => infcx
|
||||
.at(&ObligationCause::dummy(), ty::ParamEnv::empty())
|
||||
.eq(DefineOpaqueTypes::Yes, impl1_ref, impl2_ref),
|
||||
(None, None) => infcx.at(&ObligationCause::dummy(), ty::ParamEnv::empty()).eq(
|
||||
DefineOpaqueTypes::Yes,
|
||||
impl1.self_ty,
|
||||
impl2.self_ty,
|
||||
),
|
||||
_ => bug!("mk_eq_impl_headers given mismatched impl kinds"),
|
||||
};
|
||||
|
||||
result.map(|infer_ok| infer_ok.obligations).ok()
|
||||
}
|
||||
|
||||
/// Given impl1 and impl2 check if both impls can be satisfied by a common type (including
|
||||
@ -325,7 +330,7 @@ fn equate<'tcx>(
|
||||
) -> bool {
|
||||
// do the impls unify? If not, not disjoint.
|
||||
let Ok(InferOk { obligations: more_obligations, .. }) =
|
||||
infcx.at(&ObligationCause::dummy(), impl_env).eq(subject1, subject2)
|
||||
infcx.at(&ObligationCause::dummy(), impl_env).eq(DefineOpaqueTypes::No,subject1, subject2)
|
||||
else {
|
||||
debug!("explicit_disjoint: {:?} does not unify with {:?}", subject1, subject2);
|
||||
return true;
|
||||
|
@ -11,7 +11,7 @@
|
||||
use rustc_infer::infer::canonical::{
|
||||
Canonical, CanonicalQueryResponse, CanonicalVarValues, QueryResponse,
|
||||
};
|
||||
use rustc_infer::infer::{InferCtxt, InferOk};
|
||||
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk};
|
||||
use rustc_infer::traits::query::Fallible;
|
||||
use rustc_infer::traits::{
|
||||
FulfillmentError, Obligation, ObligationCause, PredicateObligation, TraitEngineExt as _,
|
||||
@ -128,8 +128,7 @@ pub fn eq_exp<T>(
|
||||
{
|
||||
self.infcx
|
||||
.at(cause, param_env)
|
||||
.define_opaque_types(true)
|
||||
.eq_exp(a_is_expected, a, b)
|
||||
.eq_exp(DefineOpaqueTypes::Yes, a_is_expected, a, b)
|
||||
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
|
||||
}
|
||||
|
||||
@ -142,8 +141,7 @@ pub fn eq<T: ToTrace<'tcx>>(
|
||||
) -> Result<(), TypeError<'tcx>> {
|
||||
self.infcx
|
||||
.at(cause, param_env)
|
||||
.define_opaque_types(true)
|
||||
.eq(expected, actual)
|
||||
.eq(DefineOpaqueTypes::Yes, expected, actual)
|
||||
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
|
||||
}
|
||||
|
||||
@ -157,8 +155,7 @@ pub fn sub<T: ToTrace<'tcx>>(
|
||||
) -> Result<(), TypeError<'tcx>> {
|
||||
self.infcx
|
||||
.at(cause, param_env)
|
||||
.define_opaque_types(true)
|
||||
.sub(expected, actual)
|
||||
.sub(DefineOpaqueTypes::Yes, expected, actual)
|
||||
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
|
||||
}
|
||||
|
||||
@ -172,8 +169,7 @@ pub fn sup<T: ToTrace<'tcx>>(
|
||||
) -> Result<(), TypeError<'tcx>> {
|
||||
self.infcx
|
||||
.at(cause, param_env)
|
||||
.define_opaque_types(true)
|
||||
.sup(expected, actual)
|
||||
.sup(DefineOpaqueTypes::Yes, expected, actual)
|
||||
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
use rustc_data_structures::obligation_forest::ProcessResult;
|
||||
use rustc_data_structures::obligation_forest::{Error, ForestObligation, Outcome};
|
||||
use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProcessor};
|
||||
use rustc_infer::infer::DefineOpaqueTypes;
|
||||
use rustc_infer::traits::ProjectionCacheKey;
|
||||
use rustc_infer::traits::{SelectionError, TraitEngine, TraitObligation};
|
||||
use rustc_middle::mir::interpret::ErrorHandled;
|
||||
@ -515,7 +516,7 @@ fn process_obligation(
|
||||
if let Ok(new_obligations) = infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
.trace(c1, c2)
|
||||
.eq(a.substs, b.substs)
|
||||
.eq(DefineOpaqueTypes::No, a.substs, b.substs)
|
||||
{
|
||||
return ProcessResult::Changed(mk_pending(
|
||||
new_obligations.into_obligations(),
|
||||
@ -524,8 +525,9 @@ fn process_obligation(
|
||||
}
|
||||
(_, Unevaluated(_)) | (Unevaluated(_), _) => (),
|
||||
(_, _) => {
|
||||
if let Ok(new_obligations) =
|
||||
infcx.at(&obligation.cause, obligation.param_env).eq(c1, c2)
|
||||
if let Ok(new_obligations) = infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
.eq(DefineOpaqueTypes::No, c1, c2)
|
||||
{
|
||||
return ProcessResult::Changed(mk_pending(
|
||||
new_obligations.into_obligations(),
|
||||
@ -565,12 +567,11 @@ fn process_obligation(
|
||||
|
||||
match (evaluate(c1), evaluate(c2)) {
|
||||
(Ok(c1), Ok(c2)) => {
|
||||
match self
|
||||
.selcx
|
||||
.infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
.eq(c1, c2)
|
||||
{
|
||||
match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq(
|
||||
DefineOpaqueTypes::No,
|
||||
c1,
|
||||
c2,
|
||||
) {
|
||||
Ok(inf_ok) => {
|
||||
ProcessResult::Changed(mk_pending(inf_ok.into_obligations()))
|
||||
}
|
||||
@ -610,12 +611,11 @@ fn process_obligation(
|
||||
bug!("AliasEq is only used for new solver")
|
||||
}
|
||||
ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(ct, ty)) => {
|
||||
match self
|
||||
.selcx
|
||||
.infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
.eq(ct.ty(), ty)
|
||||
{
|
||||
match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq(
|
||||
DefineOpaqueTypes::No,
|
||||
ct.ty(),
|
||||
ty,
|
||||
) {
|
||||
Ok(inf_ok) => ProcessResult::Changed(mk_pending(inf_ok.into_obligations())),
|
||||
Err(_) => ProcessResult::Error(FulfillmentErrorCode::CodeSelectionError(
|
||||
SelectionError::Unimplemented,
|
||||
|
@ -28,6 +28,7 @@
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_infer::infer::at::At;
|
||||
use rustc_infer::infer::resolve::OpportunisticRegionResolver;
|
||||
use rustc_infer::infer::DefineOpaqueTypes;
|
||||
use rustc_infer::traits::ImplSourceBuiltinData;
|
||||
use rustc_middle::traits::select::OverflowError;
|
||||
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
||||
@ -285,12 +286,12 @@ fn project_and_unify_type<'cx, 'tcx>(
|
||||
);
|
||||
obligations.extend(new);
|
||||
|
||||
match infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
// This is needed to support nested opaque types like `impl Fn() -> impl Trait`
|
||||
.define_opaque_types(true)
|
||||
.eq(normalized, actual)
|
||||
{
|
||||
// Need to define opaque types to support nested opaque types like `impl Fn() -> impl Trait`
|
||||
match infcx.at(&obligation.cause, obligation.param_env).eq(
|
||||
DefineOpaqueTypes::Yes,
|
||||
normalized,
|
||||
actual,
|
||||
) {
|
||||
Ok(InferOk { obligations: inferred_obligations, value: () }) => {
|
||||
obligations.extend(inferred_obligations);
|
||||
ProjectAndUnifyResult::Holds(obligations)
|
||||
@ -2064,7 +2065,11 @@ fn confirm_param_env_candidate<'cx, 'tcx>(
|
||||
|
||||
debug!(?cache_projection, ?obligation_projection);
|
||||
|
||||
match infcx.at(cause, param_env).eq(cache_projection, obligation_projection) {
|
||||
match infcx.at(cause, param_env).eq(
|
||||
DefineOpaqueTypes::No,
|
||||
cache_projection,
|
||||
obligation_projection,
|
||||
) {
|
||||
Ok(InferOk { value: _, obligations }) => {
|
||||
nested_obligations.extend(obligations);
|
||||
assoc_ty_own_obligations(selcx, obligation, &mut nested_obligations);
|
||||
|
@ -8,8 +8,8 @@
|
||||
//! https://rustc-dev-guide.rust-lang.org/traits/resolution.html#confirmation
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_infer::infer::InferOk;
|
||||
use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType;
|
||||
use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
|
||||
use rustc_middle::ty::{
|
||||
self, Binder, GenericParamDefKind, InternalSubsts, SubstsRef, ToPolyTraitRef, ToPredicate,
|
||||
TraitRef, Ty, TyCtxt, TypeVisitableExt,
|
||||
@ -177,7 +177,7 @@ fn confirm_projection_candidate(
|
||||
obligations.extend(self.infcx.commit_if_ok(|_| {
|
||||
self.infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
.sup(placeholder_trait_predicate, candidate)
|
||||
.sup(DefineOpaqueTypes::No, placeholder_trait_predicate, candidate)
|
||||
.map(|InferOk { obligations, .. }| obligations)
|
||||
.map_err(|_| Unimplemented)
|
||||
})?);
|
||||
@ -462,7 +462,7 @@ fn confirm_object_candidate(
|
||||
nested.extend(self.infcx.commit_if_ok(|_| {
|
||||
self.infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
.sup(obligation_trait_ref, upcast_trait_ref)
|
||||
.sup(DefineOpaqueTypes::No, obligation_trait_ref, upcast_trait_ref)
|
||||
.map(|InferOk { obligations, .. }| obligations)
|
||||
.map_err(|_| Unimplemented)
|
||||
})?);
|
||||
@ -827,11 +827,10 @@ fn confirm_poly_trait_refs(
|
||||
)
|
||||
});
|
||||
|
||||
// needed to define opaque types for tests/ui/type-alias-impl-trait/assoc-projection-ice.rs
|
||||
self.infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
// needed for tests/ui/type-alias-impl-trait/assoc-projection-ice.rs
|
||||
.define_opaque_types(true)
|
||||
.sup(obligation_trait_ref, expected_trait_ref)
|
||||
.sup(DefineOpaqueTypes::Yes, obligation_trait_ref, expected_trait_ref)
|
||||
.map(|InferOk { mut obligations, .. }| {
|
||||
obligations.extend(nested);
|
||||
obligations
|
||||
@ -896,7 +895,7 @@ fn confirm_trait_upcasting_unsize_candidate(
|
||||
let InferOk { obligations, .. } = self
|
||||
.infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
.sup(target, source_trait)
|
||||
.sup(DefineOpaqueTypes::No, target, source_trait)
|
||||
.map_err(|_| Unimplemented)?;
|
||||
nested.extend(obligations);
|
||||
|
||||
@ -995,7 +994,7 @@ fn confirm_builtin_unsize_candidate(
|
||||
let InferOk { obligations, .. } = self
|
||||
.infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
.sup(target, source_trait)
|
||||
.sup(DefineOpaqueTypes::No, target, source_trait)
|
||||
.map_err(|_| Unimplemented)?;
|
||||
nested.extend(obligations);
|
||||
|
||||
@ -1066,7 +1065,7 @@ fn confirm_builtin_unsize_candidate(
|
||||
let InferOk { obligations, .. } = self
|
||||
.infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
.eq(b, a)
|
||||
.eq(DefineOpaqueTypes::No, b, a)
|
||||
.map_err(|_| Unimplemented)?;
|
||||
nested.extend(obligations);
|
||||
}
|
||||
@ -1114,7 +1113,7 @@ fn confirm_builtin_unsize_candidate(
|
||||
let InferOk { obligations, .. } = self
|
||||
.infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
.eq(target, new_struct)
|
||||
.eq(DefineOpaqueTypes::No, target, new_struct)
|
||||
.map_err(|_| Unimplemented)?;
|
||||
nested.extend(obligations);
|
||||
|
||||
@ -1144,7 +1143,7 @@ fn confirm_builtin_unsize_candidate(
|
||||
let InferOk { obligations, .. } = self
|
||||
.infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
.eq(target, new_tuple)
|
||||
.eq(DefineOpaqueTypes::No, target, new_tuple)
|
||||
.map_err(|_| Unimplemented)?;
|
||||
nested.extend(obligations);
|
||||
|
||||
|
@ -38,6 +38,7 @@
|
||||
use rustc_errors::Diagnostic;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_infer::infer::DefineOpaqueTypes;
|
||||
use rustc_infer::infer::LateBoundRegionConversionTime;
|
||||
use rustc_infer::traits::TraitEngine;
|
||||
use rustc_infer::traits::TraitEngineExt;
|
||||
@ -912,7 +913,7 @@ fn evaluate_predicate_recursively<'o>(
|
||||
.infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
.trace(c1, c2)
|
||||
.eq(a.substs, b.substs)
|
||||
.eq(DefineOpaqueTypes::No, a.substs, b.substs)
|
||||
{
|
||||
let mut obligations = new_obligations.obligations;
|
||||
self.add_depth(
|
||||
@ -930,7 +931,7 @@ fn evaluate_predicate_recursively<'o>(
|
||||
if let Ok(new_obligations) = self
|
||||
.infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
.eq(c1, c2)
|
||||
.eq(DefineOpaqueTypes::No, c1, c2)
|
||||
{
|
||||
let mut obligations = new_obligations.obligations;
|
||||
self.add_depth(
|
||||
@ -964,8 +965,11 @@ fn evaluate_predicate_recursively<'o>(
|
||||
|
||||
match (evaluate(c1), evaluate(c2)) {
|
||||
(Ok(c1), Ok(c2)) => {
|
||||
match self.infcx.at(&obligation.cause, obligation.param_env).eq(c1, c2)
|
||||
{
|
||||
match self.infcx.at(&obligation.cause, obligation.param_env).eq(
|
||||
DefineOpaqueTypes::No,
|
||||
c1,
|
||||
c2,
|
||||
) {
|
||||
Ok(inf_ok) => self.evaluate_predicates_recursively(
|
||||
previous_stack,
|
||||
inf_ok.into_obligations(),
|
||||
@ -993,7 +997,11 @@ fn evaluate_predicate_recursively<'o>(
|
||||
}
|
||||
ty::PredicateKind::Ambiguous => Ok(EvaluatedToAmbig),
|
||||
ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(ct, ty)) => {
|
||||
match self.infcx.at(&obligation.cause, obligation.param_env).eq(ct.ty(), ty) {
|
||||
match self.infcx.at(&obligation.cause, obligation.param_env).eq(
|
||||
DefineOpaqueTypes::No,
|
||||
ct.ty(),
|
||||
ty,
|
||||
) {
|
||||
Ok(inf_ok) => self.evaluate_predicates_recursively(
|
||||
previous_stack,
|
||||
inf_ok.into_obligations(),
|
||||
@ -1751,7 +1759,7 @@ fn match_normalize_trait_ref(
|
||||
});
|
||||
self.infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
.sup(ty::Binder::dummy(placeholder_trait_ref), trait_bound)
|
||||
.sup(DefineOpaqueTypes::No, ty::Binder::dummy(placeholder_trait_ref), trait_bound)
|
||||
.map(|InferOk { obligations: _, value: () }| {
|
||||
// This method is called within a probe, so we can't have
|
||||
// inference variables and placeholders escape.
|
||||
@ -1813,7 +1821,7 @@ pub(super) fn match_projection_projections(
|
||||
let is_match = self
|
||||
.infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
.sup(obligation.predicate, infer_projection)
|
||||
.sup(DefineOpaqueTypes::No, obligation.predicate, infer_projection)
|
||||
.map_or(false, |InferOk { obligations, value: () }| {
|
||||
self.evaluate_predicates_recursively(
|
||||
TraitObligationStackList::empty(&ProvisionalEvaluationCache::default()),
|
||||
@ -2534,7 +2542,7 @@ fn match_impl(
|
||||
let InferOk { obligations, .. } = self
|
||||
.infcx
|
||||
.at(&cause, obligation.param_env)
|
||||
.eq(placeholder_obligation_trait_ref, impl_trait_ref)
|
||||
.eq(DefineOpaqueTypes::No, placeholder_obligation_trait_ref, impl_trait_ref)
|
||||
.map_err(|e| {
|
||||
debug!("match_impl: failed eq_trait_refs due to `{}`", e.to_string(self.tcx()))
|
||||
})?;
|
||||
@ -2584,7 +2592,7 @@ fn match_poly_trait_ref(
|
||||
) -> Result<Vec<PredicateObligation<'tcx>>, ()> {
|
||||
self.infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
.sup(obligation.predicate.to_poly_trait_ref(), poly_trait_ref)
|
||||
.sup(DefineOpaqueTypes::No, obligation.predicate.to_poly_trait_ref(), poly_trait_ref)
|
||||
.map(|InferOk { obligations, .. }| obligations)
|
||||
.map_err(|_| ())
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/specialization.html
|
||||
|
||||
pub mod specialization_graph;
|
||||
use rustc_infer::infer::DefineOpaqueTypes;
|
||||
use specialization_graph::GraphExt;
|
||||
|
||||
use crate::errors::NegativePositiveConflict;
|
||||
@ -193,7 +194,7 @@ fn fulfill_implication<'tcx>(
|
||||
|
||||
// do the impls unify? If not, no specialization.
|
||||
let Ok(InferOk { obligations: more_obligations, .. }) =
|
||||
infcx.at(&ObligationCause::dummy(), param_env).eq(source_trait, target_trait)
|
||||
infcx.at(&ObligationCause::dummy(), param_env, ).eq(DefineOpaqueTypes::No,source_trait, target_trait)
|
||||
else {
|
||||
debug!(
|
||||
"fulfill_implication: {:?} does not unify with {:?}",
|
||||
|
@ -1,15 +1,14 @@
|
||||
use super::NormalizeExt;
|
||||
use super::{Obligation, ObligationCause, PredicateObligation, SelectionContext};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::Diagnostic;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_infer::infer::InferOk;
|
||||
use rustc_middle::ty::{self, ImplSubject, ToPredicate, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_middle::ty::{GenericArg, SubstsRef};
|
||||
use rustc_span::Span;
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::ty::{self, ImplSubject, ToPredicate, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_middle::ty::{GenericArg, SubstsRef};
|
||||
|
||||
use super::NormalizeExt;
|
||||
use super::{Obligation, ObligationCause, PredicateObligation, SelectionContext};
|
||||
use rustc_infer::infer::InferOk;
|
||||
pub use rustc_infer::traits::{self, util::*};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
@ -201,6 +200,7 @@ pub fn impl_subject_and_oblig<'a, 'tcx>(
|
||||
) -> (ImplSubject<'tcx>, impl Iterator<Item = PredicateObligation<'tcx>>) {
|
||||
let subject = selcx.tcx().bound_impl_subject(impl_def_id);
|
||||
let subject = subject.subst(selcx.tcx(), impl_substs);
|
||||
|
||||
let InferOk { value: subject, obligations: normalization_obligations1 } =
|
||||
selcx.infcx.at(&ObligationCause::dummy(), param_env).normalize(subject);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
|
||||
use rustc_hir as hir;
|
||||
use rustc_infer::infer::{InferOk, TyCtxtInferExt};
|
||||
use rustc_infer::infer::{DefineOpaqueTypes, InferOk, TyCtxtInferExt};
|
||||
use rustc_infer::traits;
|
||||
use rustc_middle::ty::ToPredicate;
|
||||
use rustc_span::DUMMY_SP;
|
||||
@ -47,8 +47,7 @@ pub(crate) fn get_blanket_impls(&mut self, item_def_id: DefId) -> Vec<Item> {
|
||||
|
||||
// Require the type the impl is implemented on to match
|
||||
// our type, and ignore the impl if there was a mismatch.
|
||||
let cause = traits::ObligationCause::dummy();
|
||||
let Ok(eq_result) = infcx.at(&cause, param_env).eq(impl_trait_ref.self_ty(), impl_ty) else {
|
||||
let Ok(eq_result) = infcx.at(&traits::ObligationCause::dummy(), param_env).eq(DefineOpaqueTypes::No, impl_trait_ref.self_ty(), impl_ty) else {
|
||||
continue
|
||||
};
|
||||
let InferOk { value: (), obligations } = eq_result;
|
||||
|
Loading…
Reference in New Issue
Block a user