diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 162828ee80b..b63f51138c3 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -26,6 +26,7 @@ use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::AssertKind; use rustc_middle::mir::*; +use rustc_middle::traits::ObligationCause; use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::cast::CastTy; use rustc_middle::ty::subst::{SubstsRef, UserSubsts}; @@ -48,6 +49,7 @@ use rustc_mir_dataflow::impls::MaybeInitializedPlaces; use rustc_mir_dataflow::move_paths::MoveData; use rustc_mir_dataflow::ResultsCursor; +use crate::renumber::RegionCtxt; use crate::session_diagnostics::MoveUnsized; use crate::{ borrow_set::BorrowSet, @@ -183,6 +185,15 @@ pub(crate) fn type_check<'mir, 'tcx>( &mut borrowck_context, ); + // FIXME(-Ztrait-solver=next): A bit dubious that we're only registering + // predefined opaques in the typeck root. + // FIXME(-Ztrait-solver=next): This is also totally wrong for TAITs, since + // the HIR typeck map defining usages back to their definition params, + // they won't actually match up with the usages in this body... + if infcx.tcx.trait_solver_next() && !infcx.tcx.is_typeck_child(body.source.def_id()) { + checker.register_predefined_opaques_in_new_solver(); + } + let mut verifier = TypeVerifier::new(&mut checker, promoted); verifier.visit_body(&body); @@ -1023,6 +1034,57 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { checker } + pub(super) fn register_predefined_opaques_in_new_solver(&mut self) { + // OK to use the identity substitutions for each opaque type key, since + // we remap opaques from HIR typeck back to their definition params. + let opaques: Vec<_> = self + .infcx + .tcx + .typeck(self.body.source.def_id().expect_local()) + .concrete_opaque_types + .iter() + .map(|(&def_id, &hidden_ty)| { + let substs = ty::InternalSubsts::identity_for_item(self.infcx.tcx, def_id); + (ty::OpaqueTypeKey { def_id, substs }, hidden_ty) + }) + .collect(); + + let renumbered_opaques = self.infcx.tcx.fold_regions(opaques, |_, _| { + self.infcx.next_nll_region_var( + NllRegionVariableOrigin::Existential { from_forall: false }, + || RegionCtxt::Unknown, + ) + }); + + let param_env = self.param_env; + let result = self.fully_perform_op( + Locations::All(self.body.span), + ConstraintCategory::OpaqueType, + CustomTypeOp::new( + |ocx| { + for (key, hidden_ty) in renumbered_opaques { + ocx.register_infer_ok_obligations( + ocx.infcx.register_hidden_type_in_new_solver( + key, + param_env, + hidden_ty.ty, + )?, + ); + } + Ok(()) + }, + "register pre-defined opaques", + ), + ); + + if result.is_err() { + self.infcx.tcx.sess.delay_span_bug( + self.body.span, + "failed re-defining predefined opaques in mir typeck", + ); + } + } + fn body(&self) -> &Body<'tcx> { self.body } diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index 1427268f829..26ace28f5fd 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -239,34 +239,34 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { evaluate_normalizes_to(self, alias_rhs, lhs, direction, Invert::Yes).ok(), ); // Relate via substs - candidates.extend( - self.probe(|ecx| { - let span = tracing::span!( - tracing::Level::DEBUG, - "compute_alias_relate_goal(relate_via_substs)", - ?alias_lhs, - ?alias_rhs, - ?direction - ); - let _enter = span.enter(); + let subst_relate_response = self.probe(|ecx| { + let span = tracing::span!( + tracing::Level::DEBUG, + "compute_alias_relate_goal(relate_via_substs)", + ?alias_lhs, + ?alias_rhs, + ?direction + ); + let _enter = span.enter(); - match direction { - ty::AliasRelationDirection::Equate => { - ecx.eq(goal.param_env, alias_lhs, alias_rhs)?; - } - ty::AliasRelationDirection::Subtype => { - ecx.sub(goal.param_env, alias_lhs, alias_rhs)?; - } + match direction { + ty::AliasRelationDirection::Equate => { + ecx.eq(goal.param_env, alias_lhs, alias_rhs)?; } + ty::AliasRelationDirection::Subtype => { + ecx.sub(goal.param_env, alias_lhs, alias_rhs)?; + } + } - ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) - }) - .ok(), - ); + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }); + candidates.extend(subst_relate_response); debug!(?candidates); if let Some(merged) = self.try_merge_responses(&candidates) { Ok(merged) + } else if let Ok(subst_relate_response) = subst_relate_response { + Ok(subst_relate_response) } else { self.flounder(&candidates) } diff --git a/compiler/rustc_trait_selection/src/solve/opaques.rs b/compiler/rustc_trait_selection/src/solve/opaques.rs index 1d5bb46450c..f97f54e760e 100644 --- a/compiler/rustc_trait_selection/src/solve/opaques.rs +++ b/compiler/rustc_trait_selection/src/solve/opaques.rs @@ -1,6 +1,6 @@ use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::{Certainty, Goal, QueryResult}; -use rustc_middle::traits::{ObligationCause, Reveal}; +use rustc_middle::traits::Reveal; use rustc_middle::ty; use rustc_middle::ty::util::NotUniqueParam; @@ -37,11 +37,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { Ok(()) => {} } // Prefer opaques registered already. - let matches = self.unify_existing_opaque_tys( - goal.param_env, - opaque_ty, - expected - ); + let matches = + self.unify_existing_opaque_tys(goal.param_env, opaque_ty, expected); if !matches.is_empty() { if let Some(response) = self.try_merge_responses(&matches) { return Ok(response);