Use ObligationCtxt in custom type ops
This commit is contained in:
parent
70db836922
commit
521a0bcd1f
5 changed files with 66 additions and 60 deletions
|
@ -128,7 +128,7 @@ impl<'tcx> ToUniverseInfo<'tcx>
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx, F, G> ToUniverseInfo<'tcx> for Canonical<'tcx, type_op::custom::CustomTypeOp<F, G>> {
|
||||
impl<'tcx, F> ToUniverseInfo<'tcx> for Canonical<'tcx, type_op::custom::CustomTypeOp<F>> {
|
||||
fn to_universe_info(self, _base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {
|
||||
// We can't rerun custom type ops.
|
||||
UniverseInfo::other()
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
use std::fmt;
|
||||
|
||||
use rustc_infer::infer::{canonical::Canonical, InferOk};
|
||||
use rustc_infer::infer::canonical::Canonical;
|
||||
use rustc_middle::mir::ConstraintCategory;
|
||||
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::traits::query::type_op::{self, TypeOpOutput};
|
||||
use rustc_trait_selection::traits::query::{Fallible, NoSolution};
|
||||
use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt};
|
||||
use rustc_trait_selection::traits::ObligationCause;
|
||||
|
||||
use crate::diagnostics::{ToUniverseInfo, UniverseInfo};
|
||||
|
||||
|
@ -219,20 +219,17 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
|
||||
let cause = ObligationCause::dummy_with_span(span);
|
||||
let param_env = self.param_env;
|
||||
let op = |infcx: &'_ _| {
|
||||
let ocx = ObligationCtxt::new_in_snapshot(infcx);
|
||||
let user_ty = ocx.normalize(&cause, param_env, user_ty);
|
||||
ocx.eq(&cause, param_env, user_ty, mir_ty)?;
|
||||
if !ocx.select_all_or_error().is_empty() {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
Ok(InferOk { value: (), obligations: vec![] })
|
||||
};
|
||||
|
||||
self.fully_perform_op(
|
||||
Locations::All(span),
|
||||
ConstraintCategory::Boring,
|
||||
type_op::custom::CustomTypeOp::new(op, || "ascribe_user_type_skip_wf".to_string()),
|
||||
type_op::custom::CustomTypeOp::new(
|
||||
|ocx| {
|
||||
let user_ty = ocx.normalize(&cause, param_env, user_ty);
|
||||
ocx.eq(&cause, param_env, user_ty, mir_ty)?;
|
||||
Ok(())
|
||||
},
|
||||
"ascribe_user_type_skip_wf",
|
||||
),
|
||||
)
|
||||
.unwrap_or_else(|err| {
|
||||
span_mirbug!(
|
||||
|
|
|
@ -20,7 +20,7 @@ use rustc_infer::infer::outlives::env::RegionBoundPairs;
|
|||
use rustc_infer::infer::region_constraints::RegionConstraintData;
|
||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use rustc_infer::infer::{
|
||||
InferCtxt, InferOk, LateBoundRegion, LateBoundRegionConversionTime, NllRegionVariableOrigin,
|
||||
InferCtxt, LateBoundRegion, LateBoundRegionConversionTime, NllRegionVariableOrigin,
|
||||
};
|
||||
use rustc_middle::mir::tcx::PlaceTy;
|
||||
use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
|
||||
|
@ -218,16 +218,16 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
|||
Locations::All(body.span),
|
||||
ConstraintCategory::OpaqueType,
|
||||
CustomTypeOp::new(
|
||||
|infcx| {
|
||||
infcx.register_member_constraints(
|
||||
|ocx| {
|
||||
ocx.infcx.register_member_constraints(
|
||||
param_env,
|
||||
opaque_type_key,
|
||||
decl.hidden_type.ty,
|
||||
decl.hidden_type.span,
|
||||
);
|
||||
Ok(InferOk { value: (), obligations: vec![] })
|
||||
Ok(())
|
||||
},
|
||||
|| "opaque_type_map".to_string(),
|
||||
"opaque_type_map",
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -2713,8 +2713,9 @@ impl<'tcx> TypeOp<'tcx> for InstantiateOpaqueType<'tcx> {
|
|||
type ErrorInfo = InstantiateOpaqueType<'tcx>;
|
||||
|
||||
fn fully_perform(mut self, infcx: &InferCtxt<'tcx>) -> Fallible<TypeOpOutput<'tcx, Self>> {
|
||||
let (mut output, region_constraints) = scrape_region_constraints(infcx, || {
|
||||
Ok(InferOk { value: (), obligations: self.obligations.clone() })
|
||||
let (mut output, region_constraints) = scrape_region_constraints(infcx, |ocx| {
|
||||
ocx.register_obligations(self.obligations.clone());
|
||||
Ok(())
|
||||
})?;
|
||||
self.region_constraints = Some(region_constraints);
|
||||
output.error_info = Some(self);
|
||||
|
|
|
@ -185,17 +185,25 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
|
|||
}
|
||||
|
||||
fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
|
||||
self.type_checker
|
||||
.fully_perform_op(
|
||||
self.locations,
|
||||
self.category,
|
||||
InstantiateOpaqueType {
|
||||
obligations,
|
||||
// These fields are filled in during execution of the operation
|
||||
base_universe: None,
|
||||
region_constraints: None,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
match self.type_checker.fully_perform_op(
|
||||
self.locations,
|
||||
self.category,
|
||||
InstantiateOpaqueType {
|
||||
obligations,
|
||||
// These fields are filled in during execution of the operation
|
||||
base_universe: None,
|
||||
region_constraints: None,
|
||||
},
|
||||
) {
|
||||
Ok(()) => {}
|
||||
Err(_) => {
|
||||
// It's a bit redundant to delay a bug here, but I'd rather
|
||||
// delay more bugs than accidentally not delay a bug at all.
|
||||
self.type_checker.tcx().sess.delay_span_bug(
|
||||
self.locations.span(self.type_checker.body),
|
||||
"errors selecting obligation during MIR typeck",
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue