mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Uplift ExternalConstraintData
This commit is contained in:
parent
f93ee19fd7
commit
9d207cfbc8
@ -110,7 +110,7 @@ macro_rules! arena_types {
|
||||
rustc_hir::def_id::DefId,
|
||||
rustc_middle::ty::EarlyBinder<'tcx, rustc_middle::ty::Ty<'tcx>>
|
||||
>,
|
||||
[] external_constraints: rustc_middle::traits::solve::ExternalConstraintsData<'tcx>,
|
||||
[] external_constraints: rustc_middle::traits::solve::ExternalConstraintsData<rustc_middle::ty::TyCtxt<'tcx>>,
|
||||
[] predefined_opaques_in_body: rustc_middle::traits::solve::PredefinedOpaquesData<'tcx>,
|
||||
[decode] doc_link_resolutions: rustc_hir::def::DocLinkResMap,
|
||||
[] stripped_cfg_items: rustc_ast::expand::StrippedCfgItem,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use rustc_ast_ir::try_visit;
|
||||
use rustc_data_structures::intern::Interned;
|
||||
use rustc_macros::{HashStable, TypeFoldable, TypeVisitable};
|
||||
use rustc_macros::HashStable;
|
||||
use rustc_type_ir as ir;
|
||||
pub use rustc_type_ir::solve::*;
|
||||
|
||||
@ -37,37 +37,18 @@ impl<'tcx> std::ops::Deref for PredefinedOpaques<'tcx> {
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, HashStable)]
|
||||
pub struct ExternalConstraints<'tcx>(pub(crate) Interned<'tcx, ExternalConstraintsData<'tcx>>);
|
||||
pub struct ExternalConstraints<'tcx>(
|
||||
pub(crate) Interned<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
|
||||
);
|
||||
|
||||
impl<'tcx> std::ops::Deref for ExternalConstraints<'tcx> {
|
||||
type Target = ExternalConstraintsData<'tcx>;
|
||||
type Target = ExternalConstraintsData<TyCtxt<'tcx>>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
/// Additional constraints returned on success.
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Hash, HashStable, Default, TypeVisitable, TypeFoldable)]
|
||||
pub struct ExternalConstraintsData<'tcx> {
|
||||
// FIXME: implement this.
|
||||
pub region_constraints: Vec<ty::OutlivesPredicate<'tcx, ty::GenericArg<'tcx>>>,
|
||||
pub opaque_types: Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>,
|
||||
pub normalization_nested_goals: NestedNormalizationGoals<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Hash, HashStable, Default, TypeVisitable, TypeFoldable)]
|
||||
pub struct NestedNormalizationGoals<'tcx>(pub Vec<(GoalSource, Goal<'tcx, ty::Predicate<'tcx>>)>);
|
||||
impl<'tcx> NestedNormalizationGoals<'tcx> {
|
||||
pub fn empty() -> Self {
|
||||
NestedNormalizationGoals(vec![])
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Having to clone `region_constraints` for folding feels bad and
|
||||
// probably isn't great wrt performance.
|
||||
//
|
||||
|
@ -88,6 +88,7 @@ use std::ops::{Bound, Deref};
|
||||
#[allow(rustc::usage_of_ty_tykind)]
|
||||
impl<'tcx> Interner for TyCtxt<'tcx> {
|
||||
type DefId = DefId;
|
||||
type LocalDefId = LocalDefId;
|
||||
type AdtDef = ty::AdtDef<'tcx>;
|
||||
|
||||
type GenericArgs = ty::GenericArgsRef<'tcx>;
|
||||
@ -382,7 +383,7 @@ pub struct CtxtInterners<'tcx> {
|
||||
bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
|
||||
layout: InternedSet<'tcx, LayoutS<FieldIdx, VariantIdx>>,
|
||||
adt_def: InternedSet<'tcx, AdtDefData>,
|
||||
external_constraints: InternedSet<'tcx, ExternalConstraintsData<'tcx>>,
|
||||
external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
|
||||
predefined_opaques_in_body: InternedSet<'tcx, PredefinedOpaquesData<'tcx>>,
|
||||
fields: InternedSet<'tcx, List<FieldIdx>>,
|
||||
local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
|
||||
@ -2093,7 +2094,7 @@ direct_interners! {
|
||||
const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
|
||||
layout: pub mk_layout(LayoutS<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
|
||||
adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
|
||||
external_constraints: pub mk_external_constraints(ExternalConstraintsData<'tcx>):
|
||||
external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
|
||||
ExternalConstraints -> ExternalConstraints<'tcx>,
|
||||
predefined_opaques_in_body: pub mk_predefined_opaques_in_body(PredefinedOpaquesData<'tcx>):
|
||||
PredefinedOpaques -> PredefinedOpaques<'tcx>,
|
||||
|
@ -14,6 +14,7 @@ use crate::solve::{
|
||||
inspect, response_no_constraints_raw, CanonicalResponse, QueryResult, Response,
|
||||
};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_infer::infer::canonical::query_response::make_query_region_constraints;
|
||||
use rustc_infer::infer::canonical::{CanonicalExt, QueryRegionConstraints};
|
||||
@ -178,8 +179,8 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||
fn compute_external_query_constraints(
|
||||
&self,
|
||||
certainty: Certainty,
|
||||
normalization_nested_goals: NestedNormalizationGoals<'tcx>,
|
||||
) -> ExternalConstraintsData<'tcx> {
|
||||
normalization_nested_goals: NestedNormalizationGoals<TyCtxt<'tcx>>,
|
||||
) -> ExternalConstraintsData<TyCtxt<'tcx>> {
|
||||
// We only return region constraints once the certainty is `Yes`. This
|
||||
// is necessary as we may drop nested goals on ambiguity, which may result
|
||||
// in unconstrained inference variables in the region constraints. It also
|
||||
@ -213,13 +214,20 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||
Default::default()
|
||||
};
|
||||
|
||||
let mut opaque_types = self.infcx.clone_opaque_types_for_query_response();
|
||||
// Only return opaque type keys for newly-defined opaques
|
||||
opaque_types.retain(|(a, _)| {
|
||||
self.predefined_opaques_in_body.opaque_types.iter().all(|(pa, _)| pa != a)
|
||||
});
|
||||
|
||||
ExternalConstraintsData { region_constraints, opaque_types, normalization_nested_goals }
|
||||
ExternalConstraintsData {
|
||||
region_constraints,
|
||||
opaque_types: self
|
||||
.infcx
|
||||
.clone_opaque_types_for_query_response()
|
||||
.into_iter()
|
||||
// Only return *newly defined* opaque types.
|
||||
.filter(|(a, _)| {
|
||||
self.predefined_opaques_in_body.opaque_types.iter().all(|(pa, _)| pa != a)
|
||||
})
|
||||
.map(|(key, value)| (key.def_id, key.args, value))
|
||||
.collect(),
|
||||
normalization_nested_goals,
|
||||
}
|
||||
}
|
||||
|
||||
/// After calling a canonical query, we apply the constraints returned
|
||||
@ -235,7 +243,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
original_values: Vec<ty::GenericArg<'tcx>>,
|
||||
response: CanonicalResponse<'tcx>,
|
||||
) -> (NestedNormalizationGoals<'tcx>, Certainty) {
|
||||
) -> (NestedNormalizationGoals<TyCtxt<'tcx>>, Certainty) {
|
||||
let instantiation = Self::compute_query_response_instantiation_values(
|
||||
self.infcx,
|
||||
&original_values,
|
||||
@ -385,10 +393,14 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||
}
|
||||
}
|
||||
|
||||
fn register_new_opaque_types(&mut self, opaque_types: &[(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)]) {
|
||||
for &(key, ty) in opaque_types {
|
||||
fn register_new_opaque_types(
|
||||
&mut self,
|
||||
opaque_types: &[(LocalDefId, ty::GenericArgsRef<'tcx>, Ty<'tcx>)],
|
||||
) {
|
||||
for &(def_id, args, ty) in opaque_types {
|
||||
let hidden_ty = ty::OpaqueHiddenType { ty, span: DUMMY_SP };
|
||||
self.infcx.inject_new_hidden_type_unchecked(key, hidden_ty);
|
||||
self.infcx
|
||||
.inject_new_hidden_type_unchecked(ty::OpaqueTypeKey { def_id, args }, hidden_ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -337,7 +337,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
|
||||
goal_evaluation_kind: GoalEvaluationKind,
|
||||
_source: GoalSource,
|
||||
goal: Goal<'tcx, ty::Predicate<'tcx>>,
|
||||
) -> Result<(NestedNormalizationGoals<'tcx>, bool, Certainty), NoSolution> {
|
||||
) -> Result<(NestedNormalizationGoals<TyCtxt<'tcx>>, bool, Certainty), NoSolution> {
|
||||
let (orig_values, canonical_goal) = self.canonicalize_goal(goal);
|
||||
let mut goal_evaluation =
|
||||
self.inspect.new_goal_evaluation(goal, &orig_values, goal_evaluation_kind);
|
||||
@ -380,7 +380,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
original_values: Vec<ty::GenericArg<'tcx>>,
|
||||
response: CanonicalResponse<'tcx>,
|
||||
) -> (NestedNormalizationGoals<'tcx>, Certainty, bool) {
|
||||
) -> (NestedNormalizationGoals<TyCtxt<'tcx>>, Certainty, bool) {
|
||||
if let Certainty::Maybe(MaybeCause::Overflow { .. }) = response.value.certainty {
|
||||
return (NestedNormalizationGoals::empty(), response.value.certainty, false);
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ pub trait Interner:
|
||||
+ IrPrint<ty::FnSig<Self>>
|
||||
{
|
||||
type DefId: Copy + Debug + Hash + Eq + TypeFoldable<Self>;
|
||||
type LocalDefId: Copy + Debug + Hash + Eq + TypeFoldable<Self>;
|
||||
type AdtDef: AdtDef<Self>;
|
||||
|
||||
type GenericArgs: GenericArgs<Self>;
|
||||
|
@ -7,7 +7,7 @@ use std::hash::Hash;
|
||||
use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
|
||||
use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
|
||||
use crate::{Canonical, CanonicalVarValues, Interner, Upcast};
|
||||
use crate::{self as ty, Canonical, CanonicalVarValues, Interner, Upcast};
|
||||
|
||||
/// Depending on the stage of compilation, we want projection to be
|
||||
/// more or less conservative.
|
||||
@ -254,6 +254,47 @@ pub struct Response<I: Interner> {
|
||||
pub external_constraints: I::ExternalConstraints,
|
||||
}
|
||||
|
||||
/// Additional constraints returned on success.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Hash(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = ""),
|
||||
Debug(bound = ""),
|
||||
Default(bound = "")
|
||||
)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
|
||||
pub struct ExternalConstraintsData<I: Interner> {
|
||||
pub region_constraints: Vec<ty::OutlivesPredicate<I, I::GenericArg>>,
|
||||
pub opaque_types: Vec<(I::LocalDefId, I::GenericArgs, I::Ty)>,
|
||||
pub normalization_nested_goals: NestedNormalizationGoals<I>,
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Hash(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = ""),
|
||||
Debug(bound = ""),
|
||||
Default(bound = "")
|
||||
)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
|
||||
pub struct NestedNormalizationGoals<I: Interner>(pub Vec<(GoalSource, Goal<I, I::Predicate>)>);
|
||||
|
||||
impl<I: Interner> NestedNormalizationGoals<I> {
|
||||
pub fn empty() -> Self {
|
||||
NestedNormalizationGoals(vec![])
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
|
||||
#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
|
||||
pub enum Certainty {
|
||||
|
Loading…
Reference in New Issue
Block a user