mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 00:34:06 +00:00
intern external constraints
This commit is contained in:
parent
658fad6c55
commit
41883fd19a
@ -112,6 +112,7 @@ macro_rules! arena_types {
|
|||||||
|
|
||||||
[decode] trait_impl_trait_tys: rustc_data_structures::fx::FxHashMap<rustc_hir::def_id::DefId, rustc_middle::ty::Ty<'tcx>>,
|
[decode] trait_impl_trait_tys: rustc_data_structures::fx::FxHashMap<rustc_hir::def_id::DefId, rustc_middle::ty::Ty<'tcx>>,
|
||||||
[] bit_set_u32: rustc_index::bit_set::BitSet<u32>,
|
[] bit_set_u32: rustc_index::bit_set::BitSet<u32>,
|
||||||
|
[] external_constraints: rustc_middle::traits::solve::ExternalConstraintsData<'tcx>,
|
||||||
]);
|
]);
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
mod chalk;
|
mod chalk;
|
||||||
pub mod query;
|
pub mod query;
|
||||||
pub mod select;
|
pub mod select;
|
||||||
|
pub mod solve;
|
||||||
pub mod specialization_graph;
|
pub mod specialization_graph;
|
||||||
mod structural_impls;
|
mod structural_impls;
|
||||||
pub mod util;
|
pub mod util;
|
||||||
|
55
compiler/rustc_middle/src/traits/solve.rs
Normal file
55
compiler/rustc_middle/src/traits/solve.rs
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
use std::ops::ControlFlow;
|
||||||
|
|
||||||
|
use rustc_data_structures::intern::Interned;
|
||||||
|
|
||||||
|
use crate::ty::{FallibleTypeFolder, Ty, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor};
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
|
||||||
|
pub struct ExternalConstraints<'tcx>(pub(crate) Interned<'tcx, ExternalConstraintsData<'tcx>>);
|
||||||
|
|
||||||
|
impl<'tcx> std::ops::Deref for ExternalConstraints<'tcx> {
|
||||||
|
type Target = ExternalConstraintsData<'tcx>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&*self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Additional constraints returned on success.
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone, Hash, Default)]
|
||||||
|
pub struct ExternalConstraintsData<'tcx> {
|
||||||
|
// FIXME: implement this.
|
||||||
|
pub regions: (),
|
||||||
|
pub opaque_types: Vec<(Ty<'tcx>, Ty<'tcx>)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> TypeFoldable<'tcx> for ExternalConstraints<'tcx> {
|
||||||
|
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||||
|
Ok(FallibleTypeFolder::tcx(folder).intern_external_constraints(ExternalConstraintsData {
|
||||||
|
regions: (),
|
||||||
|
opaque_types: self
|
||||||
|
.opaque_types
|
||||||
|
.iter()
|
||||||
|
.map(|opaque| opaque.try_fold_with(folder))
|
||||||
|
.collect::<Result<_, F::Error>>()?,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||||
|
TypeFolder::tcx(folder).intern_external_constraints(ExternalConstraintsData {
|
||||||
|
regions: (),
|
||||||
|
opaque_types: self.opaque_types.iter().map(|opaque| opaque.fold_with(folder)).collect(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> TypeVisitable<'tcx> for ExternalConstraints<'tcx> {
|
||||||
|
fn visit_with<V: TypeVisitor<'tcx>>(
|
||||||
|
&self,
|
||||||
|
visitor: &mut V,
|
||||||
|
) -> std::ops::ControlFlow<V::BreakTy> {
|
||||||
|
self.regions.visit_with(visitor)?;
|
||||||
|
self.opaque_types.visit_with(visitor)?;
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
}
|
||||||
|
}
|
@ -17,6 +17,7 @@ use crate::mir::{
|
|||||||
};
|
};
|
||||||
use crate::thir::Thir;
|
use crate::thir::Thir;
|
||||||
use crate::traits;
|
use crate::traits;
|
||||||
|
use crate::traits::solve::{ExternalConstraints, ExternalConstraintsData};
|
||||||
use crate::ty::query::{self, TyCtxtAt};
|
use crate::ty::query::{self, TyCtxtAt};
|
||||||
use crate::ty::{
|
use crate::ty::{
|
||||||
self, AdtDef, AdtDefData, AdtKind, Binder, Const, ConstData, DefIdTree, FloatTy, FloatVar,
|
self, AdtDef, AdtDefData, AdtKind, Binder, Const, ConstData, DefIdTree, FloatTy, FloatVar,
|
||||||
@ -148,6 +149,7 @@ pub struct CtxtInterners<'tcx> {
|
|||||||
bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
|
bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
|
||||||
layout: InternedSet<'tcx, LayoutS<VariantIdx>>,
|
layout: InternedSet<'tcx, LayoutS<VariantIdx>>,
|
||||||
adt_def: InternedSet<'tcx, AdtDefData>,
|
adt_def: InternedSet<'tcx, AdtDefData>,
|
||||||
|
external_constraints: InternedSet<'tcx, ExternalConstraintsData<'tcx>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> CtxtInterners<'tcx> {
|
impl<'tcx> CtxtInterners<'tcx> {
|
||||||
@ -169,6 +171,7 @@ impl<'tcx> CtxtInterners<'tcx> {
|
|||||||
bound_variable_kinds: Default::default(),
|
bound_variable_kinds: Default::default(),
|
||||||
layout: Default::default(),
|
layout: Default::default(),
|
||||||
adt_def: Default::default(),
|
adt_def: Default::default(),
|
||||||
|
external_constraints: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1449,6 +1452,7 @@ direct_interners! {
|
|||||||
const_allocation: intern_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
|
const_allocation: intern_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
|
||||||
layout: intern_layout(LayoutS<VariantIdx>): Layout -> Layout<'tcx>,
|
layout: intern_layout(LayoutS<VariantIdx>): Layout -> Layout<'tcx>,
|
||||||
adt_def: intern_adt_def(AdtDefData): AdtDef -> AdtDef<'tcx>,
|
adt_def: intern_adt_def(AdtDefData): AdtDef -> AdtDef<'tcx>,
|
||||||
|
external_constraints: intern_external_constraints(ExternalConstraintsData<'tcx>): ExternalConstraints -> ExternalConstraints<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! slice_interners {
|
macro_rules! slice_interners {
|
||||||
|
@ -24,7 +24,8 @@ use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt};
|
|||||||
use rustc_infer::traits::query::NoSolution;
|
use rustc_infer::traits::query::NoSolution;
|
||||||
use rustc_infer::traits::Obligation;
|
use rustc_infer::traits::Obligation;
|
||||||
use rustc_middle::infer::canonical::Certainty as OldCertainty;
|
use rustc_middle::infer::canonical::Certainty as OldCertainty;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::traits::solve::{ExternalConstraints, ExternalConstraintsData};
|
||||||
|
use rustc_middle::ty::{self, TyCtxt};
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
CoercePredicate, RegionOutlivesPredicate, SubtypePredicate, ToPredicate, TypeOutlivesPredicate,
|
CoercePredicate, RegionOutlivesPredicate, SubtypePredicate, ToPredicate, TypeOutlivesPredicate,
|
||||||
};
|
};
|
||||||
@ -72,8 +73,7 @@ impl<'tcx, P> From<Obligation<'tcx, P>> for Goal<'tcx, P> {
|
|||||||
Goal { param_env: obligation.param_env, predicate: obligation.predicate }
|
Goal { param_env: obligation.param_env, predicate: obligation.predicate }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, TypeFoldable, TypeVisitable)]
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Hash, TypeFoldable, TypeVisitable)]
|
|
||||||
pub struct Response<'tcx> {
|
pub struct Response<'tcx> {
|
||||||
pub var_values: CanonicalVarValues<'tcx>,
|
pub var_values: CanonicalVarValues<'tcx>,
|
||||||
/// Additional constraints returned by this query.
|
/// Additional constraints returned by this query.
|
||||||
@ -121,14 +121,6 @@ pub enum MaybeCause {
|
|||||||
Overflow,
|
Overflow,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Additional constraints returned on success.
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Hash, TypeFoldable, TypeVisitable, Default)]
|
|
||||||
pub struct ExternalConstraints<'tcx> {
|
|
||||||
// FIXME: implement this.
|
|
||||||
regions: (),
|
|
||||||
opaque_types: Vec<(Ty<'tcx>, Ty<'tcx>)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
type CanonicalGoal<'tcx, T = ty::Predicate<'tcx>> = Canonical<'tcx, Goal<'tcx, T>>;
|
type CanonicalGoal<'tcx, T = ty::Predicate<'tcx>> = Canonical<'tcx, Goal<'tcx, T>>;
|
||||||
type CanonicalResponse<'tcx> = Canonical<'tcx, Response<'tcx>>;
|
type CanonicalResponse<'tcx> = Canonical<'tcx, Response<'tcx>>;
|
||||||
/// The result of evaluating a canonical query.
|
/// The result of evaluating a canonical query.
|
||||||
@ -218,15 +210,14 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
|||||||
EvalCtxt { infcx, var_values, search_graph, in_projection_eq_hack: false };
|
EvalCtxt { infcx, var_values, search_graph, in_projection_eq_hack: false };
|
||||||
let result = ecx.compute_goal(goal);
|
let result = ecx.compute_goal(goal);
|
||||||
|
|
||||||
// FIXME: `Response` should be `Copy`
|
if search_graph.try_finalize_goal(tcx, canonical_goal, result) {
|
||||||
if search_graph.try_finalize_goal(tcx, canonical_goal, result.clone()) {
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_canonical_response(&self, certainty: Certainty) -> QueryResult<'tcx> {
|
fn make_canonical_response(&self, certainty: Certainty) -> QueryResult<'tcx> {
|
||||||
let external_constraints = take_external_constraints(self.infcx)?;
|
let external_constraints = compute_external_query_constraints(self.infcx)?;
|
||||||
|
|
||||||
Ok(self.infcx.canonicalize_response(Response {
|
Ok(self.infcx.canonicalize_response(Response {
|
||||||
var_values: self.var_values,
|
var_values: self.var_values,
|
||||||
@ -461,18 +452,18 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(infcx), ret)]
|
#[instrument(level = "debug", skip(infcx), ret)]
|
||||||
fn take_external_constraints<'tcx>(
|
fn compute_external_query_constraints<'tcx>(
|
||||||
infcx: &InferCtxt<'tcx>,
|
infcx: &InferCtxt<'tcx>,
|
||||||
) -> Result<ExternalConstraints<'tcx>, NoSolution> {
|
) -> Result<ExternalConstraints<'tcx>, NoSolution> {
|
||||||
let region_obligations = infcx.take_registered_region_obligations();
|
let region_obligations = infcx.take_registered_region_obligations();
|
||||||
let opaque_types = infcx.take_opaque_types_for_query_response();
|
let opaque_types = infcx.take_opaque_types_for_query_response();
|
||||||
Ok(ExternalConstraints {
|
Ok(infcx.tcx.intern_external_constraints(ExternalConstraintsData {
|
||||||
// FIXME: Now that's definitely wrong :)
|
// FIXME: Now that's definitely wrong :)
|
||||||
//
|
//
|
||||||
// Should also do the leak check here I think
|
// Should also do the leak check here I think
|
||||||
regions: drop(region_obligations),
|
regions: drop(region_obligations),
|
||||||
opaque_types,
|
opaque_types,
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn instantiate_canonical_query_response<'tcx>(
|
fn instantiate_canonical_query_response<'tcx>(
|
||||||
@ -492,7 +483,10 @@ fn instantiate_canonical_query_response<'tcx>(
|
|||||||
Certainty::Yes => OldCertainty::Proven,
|
Certainty::Yes => OldCertainty::Proven,
|
||||||
Certainty::Maybe(_) => OldCertainty::Ambiguous,
|
Certainty::Maybe(_) => OldCertainty::Ambiguous,
|
||||||
},
|
},
|
||||||
opaque_types: resp.external_constraints.opaque_types,
|
// FIXME: This to_owned makes me sad, but we should eventually impl
|
||||||
|
// `instantiate_query_response_and_region_obligations` separately
|
||||||
|
// instead of piggybacking off of the old implementation.
|
||||||
|
opaque_types: resp.external_constraints.opaque_types.to_owned(),
|
||||||
value: resp.certainty,
|
value: resp.certainty,
|
||||||
}),
|
}),
|
||||||
) else { bug!(); };
|
) else { bug!(); };
|
||||||
@ -510,7 +504,10 @@ pub(super) fn response_no_constraints<'tcx>(
|
|||||||
variables: goal.variables,
|
variables: goal.variables,
|
||||||
value: Response {
|
value: Response {
|
||||||
var_values: CanonicalVarValues::make_identity(tcx, goal.variables),
|
var_values: CanonicalVarValues::make_identity(tcx, goal.variables),
|
||||||
external_constraints: Default::default(),
|
// FIXME: maybe we should store the "no response" version in tcx, like
|
||||||
|
// we do for tcx.types and stuff.
|
||||||
|
external_constraints: tcx
|
||||||
|
.intern_external_constraints(ExternalConstraintsData::default()),
|
||||||
certainty,
|
certainty,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -95,8 +95,7 @@ impl<'tcx> ProvisionalCache<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn provisional_result(&self, entry_index: EntryIndex) -> QueryResult<'tcx> {
|
pub(super) fn provisional_result(&self, entry_index: EntryIndex) -> QueryResult<'tcx> {
|
||||||
// FIXME: Responses should probably be `Copy` as well
|
self.entries[entry_index].response
|
||||||
self.entries[entry_index].response.clone()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,7 +250,8 @@ new_pr = true
|
|||||||
|
|
||||||
[autolabel."WG-trait-system-refactor"]
|
[autolabel."WG-trait-system-refactor"]
|
||||||
trigger_files = [
|
trigger_files = [
|
||||||
"compiler/rustc_trait_selection/src/solve"
|
"compiler/rustc_trait_selection/src/solve",
|
||||||
|
"compiler/rustc_middle/src/traits/solve.rs"
|
||||||
]
|
]
|
||||||
|
|
||||||
[notify-zulip."I-prioritize"]
|
[notify-zulip."I-prioritize"]
|
||||||
|
Loading…
Reference in New Issue
Block a user