Skip to content

Commit a2d806d

Browse files
Pre-populate MIR with opaques, prefer subst-relate candidate
1 parent e3f8bea commit a2d806d

File tree

3 files changed

+87
-28
lines changed

3 files changed

+87
-28
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

+62
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use rustc_middle::mir::tcx::PlaceTy;
2626
use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
2727
use rustc_middle::mir::AssertKind;
2828
use rustc_middle::mir::*;
29+
use rustc_middle::traits::ObligationCause;
2930
use rustc_middle::ty::adjustment::PointerCast;
3031
use rustc_middle::ty::cast::CastTy;
3132
use rustc_middle::ty::subst::{SubstsRef, UserSubsts};
@@ -48,6 +49,7 @@ use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
4849
use rustc_mir_dataflow::move_paths::MoveData;
4950
use rustc_mir_dataflow::ResultsCursor;
5051

52+
use crate::renumber::RegionCtxt;
5153
use crate::session_diagnostics::MoveUnsized;
5254
use crate::{
5355
borrow_set::BorrowSet,
@@ -183,6 +185,15 @@ pub(crate) fn type_check<'mir, 'tcx>(
183185
&mut borrowck_context,
184186
);
185187

188+
// FIXME(-Ztrait-solver=next): A bit dubious that we're only registering
189+
// predefined opaques in the typeck root.
190+
// FIXME(-Ztrait-solver=next): This is also totally wrong for TAITs, since
191+
// the HIR typeck map defining usages back to their definition params,
192+
// they won't actually match up with the usages in this body...
193+
if infcx.tcx.trait_solver_next() && !infcx.tcx.is_typeck_child(body.source.def_id()) {
194+
checker.register_predefined_opaques_in_new_solver();
195+
}
196+
186197
let mut verifier = TypeVerifier::new(&mut checker, promoted);
187198
verifier.visit_body(&body);
188199

@@ -1023,6 +1034,57 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
10231034
checker
10241035
}
10251036

1037+
pub(super) fn register_predefined_opaques_in_new_solver(&mut self) {
1038+
// OK to use the identity substitutions for each opaque type key, since
1039+
// we remap opaques from HIR typeck back to their definition params.
1040+
let opaques: Vec<_> = self
1041+
.infcx
1042+
.tcx
1043+
.typeck(self.body.source.def_id().expect_local())
1044+
.concrete_opaque_types
1045+
.iter()
1046+
.map(|(&def_id, &hidden_ty)| {
1047+
let substs = ty::InternalSubsts::identity_for_item(self.infcx.tcx, def_id);
1048+
(ty::OpaqueTypeKey { def_id, substs }, hidden_ty)
1049+
})
1050+
.collect();
1051+
1052+
let renumbered_opaques = self.infcx.tcx.fold_regions(opaques, |_, _| {
1053+
self.infcx.next_nll_region_var(
1054+
NllRegionVariableOrigin::Existential { from_forall: false },
1055+
|| RegionCtxt::Unknown,
1056+
)
1057+
});
1058+
1059+
let param_env = self.param_env;
1060+
let result = self.fully_perform_op(
1061+
Locations::All(self.body.span),
1062+
ConstraintCategory::OpaqueType,
1063+
CustomTypeOp::new(
1064+
|ocx| {
1065+
for (key, hidden_ty) in renumbered_opaques {
1066+
ocx.register_infer_ok_obligations(
1067+
ocx.infcx.register_hidden_type_in_new_solver(
1068+
key,
1069+
param_env,
1070+
hidden_ty.ty,
1071+
)?,
1072+
);
1073+
}
1074+
Ok(())
1075+
},
1076+
"register pre-defined opaques",
1077+
),
1078+
);
1079+
1080+
if result.is_err() {
1081+
self.infcx.tcx.sess.delay_span_bug(
1082+
self.body.span,
1083+
"failed re-defining predefined opaques in mir typeck",
1084+
);
1085+
}
1086+
}
1087+
10261088
fn body(&self) -> &Body<'tcx> {
10271089
self.body
10281090
}

compiler/rustc_trait_selection/src/solve/mod.rs

+22-22
Original file line numberDiff line numberDiff line change
@@ -239,34 +239,34 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
239239
evaluate_normalizes_to(self, alias_rhs, lhs, direction, Invert::Yes).ok(),
240240
);
241241
// Relate via substs
242-
candidates.extend(
243-
self.probe(|ecx| {
244-
let span = tracing::span!(
245-
tracing::Level::DEBUG,
246-
"compute_alias_relate_goal(relate_via_substs)",
247-
?alias_lhs,
248-
?alias_rhs,
249-
?direction
250-
);
251-
let _enter = span.enter();
252-
253-
match direction {
254-
ty::AliasRelationDirection::Equate => {
255-
ecx.eq(goal.param_env, alias_lhs, alias_rhs)?;
256-
}
257-
ty::AliasRelationDirection::Subtype => {
258-
ecx.sub(goal.param_env, alias_lhs, alias_rhs)?;
259-
}
242+
let subst_relate_response = self.probe(|ecx| {
243+
let span = tracing::span!(
244+
tracing::Level::DEBUG,
245+
"compute_alias_relate_goal(relate_via_substs)",
246+
?alias_lhs,
247+
?alias_rhs,
248+
?direction
249+
);
250+
let _enter = span.enter();
251+
252+
match direction {
253+
ty::AliasRelationDirection::Equate => {
254+
ecx.eq(goal.param_env, alias_lhs, alias_rhs)?;
255+
}
256+
ty::AliasRelationDirection::Subtype => {
257+
ecx.sub(goal.param_env, alias_lhs, alias_rhs)?;
260258
}
259+
}
261260

262-
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
263-
})
264-
.ok(),
265-
);
261+
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
262+
});
263+
candidates.extend(subst_relate_response);
266264
debug!(?candidates);
267265

268266
if let Some(merged) = self.try_merge_responses(&candidates) {
269267
Ok(merged)
268+
} else if let Ok(subst_relate_response) = subst_relate_response {
269+
Ok(subst_relate_response)
270270
} else {
271271
self.flounder(&candidates)
272272
}

compiler/rustc_trait_selection/src/solve/opaques.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rustc_middle::traits::query::NoSolution;
22
use rustc_middle::traits::solve::{Certainty, Goal, QueryResult};
3-
use rustc_middle::traits::{ObligationCause, Reveal};
3+
use rustc_middle::traits::Reveal;
44
use rustc_middle::ty;
55
use rustc_middle::ty::util::NotUniqueParam;
66

@@ -37,11 +37,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
3737
Ok(()) => {}
3838
}
3939
// Prefer opaques registered already.
40-
let matches = self.unify_existing_opaque_tys(
41-
goal.param_env,
42-
opaque_ty,
43-
expected
44-
);
40+
let matches =
41+
self.unify_existing_opaque_tys(goal.param_env, opaque_ty, expected);
4542
if !matches.is_empty() {
4643
if let Some(response) = self.try_merge_responses(&matches) {
4744
return Ok(response);

0 commit comments

Comments
 (0)