Pre-populate MIR with opaques, prefer subst-relate candidate
This commit is contained in:
parent
e3f8beaed6
commit
a2d806d56d
3 changed files with 86 additions and 27 deletions
|
@ -26,6 +26,7 @@ use rustc_middle::mir::tcx::PlaceTy;
|
||||||
use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
|
use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
|
||||||
use rustc_middle::mir::AssertKind;
|
use rustc_middle::mir::AssertKind;
|
||||||
use rustc_middle::mir::*;
|
use rustc_middle::mir::*;
|
||||||
|
use rustc_middle::traits::ObligationCause;
|
||||||
use rustc_middle::ty::adjustment::PointerCast;
|
use rustc_middle::ty::adjustment::PointerCast;
|
||||||
use rustc_middle::ty::cast::CastTy;
|
use rustc_middle::ty::cast::CastTy;
|
||||||
use rustc_middle::ty::subst::{SubstsRef, UserSubsts};
|
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::move_paths::MoveData;
|
||||||
use rustc_mir_dataflow::ResultsCursor;
|
use rustc_mir_dataflow::ResultsCursor;
|
||||||
|
|
||||||
|
use crate::renumber::RegionCtxt;
|
||||||
use crate::session_diagnostics::MoveUnsized;
|
use crate::session_diagnostics::MoveUnsized;
|
||||||
use crate::{
|
use crate::{
|
||||||
borrow_set::BorrowSet,
|
borrow_set::BorrowSet,
|
||||||
|
@ -183,6 +185,15 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
||||||
&mut borrowck_context,
|
&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);
|
let mut verifier = TypeVerifier::new(&mut checker, promoted);
|
||||||
verifier.visit_body(&body);
|
verifier.visit_body(&body);
|
||||||
|
|
||||||
|
@ -1023,6 +1034,57 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
checker
|
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> {
|
fn body(&self) -> &Body<'tcx> {
|
||||||
self.body
|
self.body
|
||||||
}
|
}
|
||||||
|
|
|
@ -239,8 +239,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
||||||
evaluate_normalizes_to(self, alias_rhs, lhs, direction, Invert::Yes).ok(),
|
evaluate_normalizes_to(self, alias_rhs, lhs, direction, Invert::Yes).ok(),
|
||||||
);
|
);
|
||||||
// Relate via substs
|
// Relate via substs
|
||||||
candidates.extend(
|
let subst_relate_response = self.probe(|ecx| {
|
||||||
self.probe(|ecx| {
|
|
||||||
let span = tracing::span!(
|
let span = tracing::span!(
|
||||||
tracing::Level::DEBUG,
|
tracing::Level::DEBUG,
|
||||||
"compute_alias_relate_goal(relate_via_substs)",
|
"compute_alias_relate_goal(relate_via_substs)",
|
||||||
|
@ -260,13 +259,14 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||||
})
|
});
|
||||||
.ok(),
|
candidates.extend(subst_relate_response);
|
||||||
);
|
|
||||||
debug!(?candidates);
|
debug!(?candidates);
|
||||||
|
|
||||||
if let Some(merged) = self.try_merge_responses(&candidates) {
|
if let Some(merged) = self.try_merge_responses(&candidates) {
|
||||||
Ok(merged)
|
Ok(merged)
|
||||||
|
} else if let Ok(subst_relate_response) = subst_relate_response {
|
||||||
|
Ok(subst_relate_response)
|
||||||
} else {
|
} else {
|
||||||
self.flounder(&candidates)
|
self.flounder(&candidates)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use rustc_middle::traits::query::NoSolution;
|
use rustc_middle::traits::query::NoSolution;
|
||||||
use rustc_middle::traits::solve::{Certainty, Goal, QueryResult};
|
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;
|
||||||
use rustc_middle::ty::util::NotUniqueParam;
|
use rustc_middle::ty::util::NotUniqueParam;
|
||||||
|
|
||||||
|
@ -37,11 +37,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
}
|
}
|
||||||
// Prefer opaques registered already.
|
// Prefer opaques registered already.
|
||||||
let matches = self.unify_existing_opaque_tys(
|
let matches =
|
||||||
goal.param_env,
|
self.unify_existing_opaque_tys(goal.param_env, opaque_ty, expected);
|
||||||
opaque_ty,
|
|
||||||
expected
|
|
||||||
);
|
|
||||||
if !matches.is_empty() {
|
if !matches.is_empty() {
|
||||||
if let Some(response) = self.try_merge_responses(&matches) {
|
if let Some(response) = self.try_merge_responses(&matches) {
|
||||||
return Ok(response);
|
return Ok(response);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue