From d2b7604db9d3262fd9fe9ab39efb60652e252448 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 15 Mar 2023 14:00:15 +0100 Subject: [PATCH] always make `define_opaque_types` explicit --- .../src/coherence/builtin.rs | 11 +- compiler/rustc_hir_analysis/src/lib.rs | 4 +- compiler/rustc_hir_typeck/src/closure.rs | 20 +-- compiler/rustc_hir_typeck/src/coercion.rs | 40 ++++-- compiler/rustc_hir_typeck/src/demand.rs | 6 +- compiler/rustc_hir_typeck/src/expr.rs | 7 +- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 10 +- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 14 +- .../src/generator_interior/mod.rs | 8 +- .../rustc_hir_typeck/src/method/confirm.rs | 4 +- compiler/rustc_hir_typeck/src/method/probe.rs | 22 +-- compiler/rustc_infer/src/infer/at.rs | 131 +++++++++++------- .../src/infer/canonical/query_response.rs | 20 ++- compiler/rustc_infer/src/infer/combine.rs | 9 +- compiler/rustc_infer/src/infer/equate.rs | 4 +- compiler/rustc_infer/src/infer/glb.rs | 4 +- compiler/rustc_infer/src/infer/lattice.rs | 6 +- compiler/rustc_infer/src/infer/lub.rs | 4 +- compiler/rustc_infer/src/infer/mod.rs | 10 +- .../rustc_infer/src/infer/opaque_types.rs | 12 +- compiler/rustc_infer/src/infer/sub.rs | 5 +- .../src/solve/eval_ctxt.rs | 4 +- .../rustc_trait_selection/src/solve/mod.rs | 4 +- .../src/traits/auto_trait.rs | 3 +- .../src/traits/coherence.rs | 37 ++--- .../src/traits/engine.rs | 14 +- .../src/traits/fulfill.rs | 30 ++-- .../src/traits/project.rs | 19 ++- .../src/traits/select/confirmation.rs | 21 ++- .../src/traits/select/mod.rs | 26 ++-- .../src/traits/specialize/mod.rs | 3 +- .../rustc_trait_selection/src/traits/util.rs | 14 +- src/librustdoc/clean/blanket_impl.rs | 5 +- 33 files changed, 307 insertions(+), 224 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 5e8f69677cf3d..0e1cf3e6c6a7d 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -9,8 +9,8 @@ use rustc_hir::def_id::{DefId, LocalDefId}; 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; } diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 62abcbbdc9f6e..08786fe9b1ef9 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -102,7 +102,7 @@ use rustc_errors::ErrorGuaranteed; 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(); diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index 773ac0e40c571..6becf4892acb2 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -8,7 +8,7 @@ use rustc_hir as hir; 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { // 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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)); diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 00b86890b33f4..3d6274ede8146 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -45,7 +45,7 @@ use rustc_hir::intravisit::{self, Visitor}; 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 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { 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 @@ impl<'f, 'tcx> Coerce<'f, '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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { 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 diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 0ec10dc9ea32d..f65f16e317d49 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -8,7 +8,7 @@ use rustc_hir::def::CtorKind; 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Ty<'tcx>, actual: Ty<'tcx>, ) -> Option> { - 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Ty<'tcx>, actual: Ty<'tcx>, ) -> Option> { - 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 diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 7fc4ccb04ee0b..afef331ec1d93 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -36,6 +36,7 @@ use rustc_hir_analysis::astconv::AstConv as _; 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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) } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index ac73cd7cc6e17..e539693402af9 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -19,7 +19,7 @@ use rustc_hir_analysis::astconv::{ }; 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // 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( diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index ea54b76bdec96..7064ff6538487 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -24,8 +24,8 @@ use rustc_hir_analysis::structured_errors::StructuredDiagnostic; 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // 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, diff --git a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs index 2e41c2041f888..9ecc870a70dbd 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs @@ -13,7 +13,7 @@ use rustc_hir::def_id::DefId; 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}"), } diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 169f128e0a003..a0aa43deadcfd 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -8,7 +8,7 @@ use rustc_hir_analysis::astconv::generics::{ 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 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { 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); } diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 3254a93034236..8f31a79e7b393 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -13,6 +13,7 @@ use rustc_hir_analysis::astconv::InferCtxtExt as _; 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 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { 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 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { 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 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { 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 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { 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; diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 7d9bae735e55d..678832fc8d6f4 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -30,16 +30,20 @@ use super::*; 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 @@ impl<'tcx> InferCtxt<'tcx> { 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 @@ pub trait ToTrace<'tcx>: Relate<'tcx> + Copy { } 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(self, a_is_expected: bool, a: T, b: T) -> InferResult<'tcx, ()> + pub fn sub_exp( + 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 @@ impl<'a, 'tcx> At<'a, 'tcx> { /// /// See [`At::trace`] and [`Trace::sub`] for a version of /// this method that only requires `T: Relate<'tcx>` - pub fn sup(self, expected: T, actual: T) -> InferResult<'tcx, ()> + pub fn sup( + 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(self, expected: T, actual: T) -> InferResult<'tcx, ()> + pub fn sub( + 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(self, a_is_expected: bool, a: T, b: T) -> InferResult<'tcx, ()> + pub fn eq_exp( + 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(self, expected: T, actual: T) -> InferResult<'tcx, ()> + pub fn eq( + 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(self, expected: T, variance: ty::Variance, actual: T) -> InferResult<'tcx, ()> + pub fn relate( + 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 @@ impl<'a, 'tcx> At<'a, 'tcx> { /// /// See [`At::trace`] and [`Trace::lub`] for a version of /// this method that only requires `T: Relate<'tcx>` - pub fn lub(self, expected: T, actual: T) -> InferResult<'tcx, T> + pub fn lub( + 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 @@ impl<'a, 'tcx> At<'a, 'tcx> { /// /// See [`At::trace`] and [`Trace::glb`] for a version of /// this method that only requires `T: Relate<'tcx>` - pub fn glb(self, expected: T, actual: T) -> InferResult<'tcx, T> + pub fn glb( + 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(self, a: T, b: T) -> InferResult<'tcx, ()> + pub fn sub(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 @@ impl<'a, 'tcx> Trace<'a, 'tcx> { /// Makes `a == b`; the expectation is set by the call to /// `trace()`. #[instrument(skip(self), level = "debug")] - pub fn eq(self, a: T, b: T) -> InferResult<'tcx, ()> + pub fn eq(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 @@ impl<'a, 'tcx> Trace<'a, 'tcx> { } #[instrument(skip(self), level = "debug")] - pub fn lub(self, a: T, b: T) -> InferResult<'tcx, T> + pub fn lub(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 @@ impl<'a, 'tcx> Trace<'a, 'tcx> { } #[instrument(skip(self), level = "debug")] - pub fn glb(self, a: T, b: T) -> InferResult<'tcx, T> + pub fn glb(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) diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 90e89a187822d..7c649b3a65649 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -14,7 +14,7 @@ use crate::infer::canonical::{ }; 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 @@ impl<'tcx> InferCtxt<'tcx> { 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 @@ impl<'tcx> InferCtxt<'tcx> { 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 @@ impl<'tcx> InferCtxt<'tcx> { // 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()); } _ => { diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index a2332797e8680..bb6fdd2ffc2c9 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -27,7 +27,7 @@ use super::glb::Glb; 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, 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)] diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs index 54a62326ef7bd..c92a74b6241a6 100644 --- a/compiler/rustc_infer/src/infer/equate.rs +++ b/compiler/rustc_infer/src/infer/equate.rs @@ -1,3 +1,4 @@ +use crate::infer::DefineOpaqueTypes; use crate::traits::PredicateObligations; use super::combine::{CombineFields, ObligationEmittingRelation, RelationDir}; @@ -110,7 +111,8 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, '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 diff --git a/compiler/rustc_infer/src/infer/glb.rs b/compiler/rustc_infer/src/infer/glb.rs index 49df393d83b3e..5c12351226aa5 100644 --- a/compiler/rustc_infer/src/infer/glb.rs +++ b/compiler/rustc_infer/src/infer/glb.rs @@ -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 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Glb<'combine, 'infcx, Ok(()) } - fn define_opaque_types(&self) -> bool { + fn define_opaque_types(&self) -> DefineOpaqueTypes { self.fields.define_opaque_types } } diff --git a/compiler/rustc_infer/src/infer/lattice.rs b/compiler/rustc_infer/src/infer/lattice.rs index f377ac1d19e9c..7f4c141b97af2 100644 --- a/compiler/rustc_infer/src/infer/lattice.rs +++ b/compiler/rustc_infer/src/infer/lattice.rs @@ -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 @@ where ) 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 diff --git a/compiler/rustc_infer/src/infer/lub.rs b/compiler/rustc_infer/src/infer/lub.rs index c871ccb21f8de..dbef42db8f1bf 100644 --- a/compiler/rustc_infer/src/infer/lub.rs +++ b/compiler/rustc_infer/src/infer/lub.rs @@ -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 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Lub<'combine, 'infcx, Ok(()) } - fn define_opaque_types(&self) -> bool { + fn define_opaque_types(&self) -> DefineOpaqueTypes { self.fields.define_opaque_types } } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 66fb1db46185d..2976c145150df 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -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 @@ impl<'tcx> InferCtxt<'tcx> { &'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 @@ impl<'tcx> InferCtxt<'tcx> { 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(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> bool @@ -868,7 +869,7 @@ impl<'tcx> InferCtxt<'tcx> { 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 @@ impl<'tcx> InferCtxt<'tcx> { 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()) })) diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index d5c824d4c41c8..ed4bc594d1a54 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -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 @@ use rustc_middle::ty::{ TypeVisitable, TypeVisitableExt, TypeVisitor, }; use rustc_span::Span; - use std::ops::ControlFlow; -pub type OpaqueTypeMap<'tcx> = VecMap, OpaqueTypeDecl<'tcx>>; - mod table; +pub type OpaqueTypeMap<'tcx> = VecMap, 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 @@ impl<'tcx> InferCtxt<'tcx> { 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; } diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs index 3e8c2052de89d..230cadb11842e 100644 --- a/compiler/rustc_infer/src/infer/sub.rs +++ b/compiler/rustc_infer/src/infer/sub.rs @@ -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 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, '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 diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs index ca438a103cf34..856f1eec4433b 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs @@ -2,7 +2,7 @@ use rustc_hir::def_id::DefId; 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 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { ) -> Result>>, 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() }) diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index 55d361b120441..a873060687d35 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -19,7 +19,7 @@ use std::mem; 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 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { 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(), ) diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 1fb8659bb27d3..1870d3a2daf32 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -7,6 +7,7 @@ use crate::errors::UnableToConstructConstantValue; 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 @@ impl<'tcx> AutoTraitFinder<'tcx> { 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, diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index aeaade1d66c2b..bb207b5832ea9 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -17,7 +17,7 @@ use crate::traits::{ 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> { - // 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; diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 62d5e50dbc548..8acc31cd410bd 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -11,7 +11,7 @@ use rustc_infer::infer::at::ToTrace; 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 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { { 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 @@ impl<'a, 'tcx> ObligationCtxt<'a, '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 @@ impl<'a, 'tcx> ObligationCtxt<'a, '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 @@ impl<'a, 'tcx> ObligationCtxt<'a, '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)) } diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 944436ab82f91..1aaadae12ddd9 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -2,6 +2,7 @@ use crate::infer::{InferCtxt, TyOrConstInferVar}; 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 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { 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 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { } (_, 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 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { 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 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { 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, diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 01075d7c55aee..abc5a5eef73d9 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -28,6 +28,7 @@ use rustc_hir::def::DefKind; 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); diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index ee41d840bae92..3d5dd18f4c1d7 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { 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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { 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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) }); + // 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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { 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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { 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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { 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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { 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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { 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); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 38cdaddc1e707..bc1c72da1e175 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -38,6 +38,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack; 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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { 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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { 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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } 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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }); 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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { 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 @@ impl<'tcx> SelectionContext<'_, 'tcx> { 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 @@ impl<'tcx> SelectionContext<'_, 'tcx> { ) -> Result>, ()> { 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(|_| ()) } diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index fcfb60b26030f..8e229dd8d6b98 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -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 {:?}", diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index bcf63d5a6f628..ab4c36975a0ec 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -1,15 +1,14 @@ -use rustc_errors::Diagnostic; -use rustc_span::Span; -use smallvec::SmallVec; - +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 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>) { 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); diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index bcdbbcacc4bcd..3a3bf6a7ab9e8 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -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 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { // 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;