--- /dev/null
+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(())
+ }
+}
};
use crate::thir::Thir;
use crate::traits;
+use crate::traits::solve::{ExternalConstraints, ExternalConstraintsData};
use crate::ty::query::{self, TyCtxtAt};
use crate::ty::{
self, AdtDef, AdtDefData, AdtKind, Binder, Const, ConstData, DefIdTree, FloatTy, FloatVar,
bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
layout: InternedSet<'tcx, LayoutS<VariantIdx>>,
adt_def: InternedSet<'tcx, AdtDefData>,
+ external_constraints: InternedSet<'tcx, ExternalConstraintsData<'tcx>>,
}
impl<'tcx> CtxtInterners<'tcx> {
bound_variable_kinds: Default::default(),
layout: Default::default(),
adt_def: Default::default(),
+ external_constraints: Default::default(),
}
}
const_allocation: intern_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
layout: intern_layout(LayoutS<VariantIdx>): Layout -> Layout<'tcx>,
adt_def: intern_adt_def(AdtDefData): AdtDef -> AdtDef<'tcx>,
+ external_constraints: intern_external_constraints(ExternalConstraintsData<'tcx>): ExternalConstraints -> ExternalConstraints<'tcx>,
}
macro_rules! slice_interners {
use rustc_infer::traits::query::NoSolution;
use rustc_infer::traits::Obligation;
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::{
CoercePredicate, RegionOutlivesPredicate, SubtypePredicate, ToPredicate, TypeOutlivesPredicate,
};
Goal { param_env: obligation.param_env, predicate: obligation.predicate }
}
}
-
-#[derive(Debug, PartialEq, Eq, Clone, Hash, TypeFoldable, TypeVisitable)]
+#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, TypeFoldable, TypeVisitable)]
pub struct Response<'tcx> {
pub var_values: CanonicalVarValues<'tcx>,
/// Additional constraints returned by this query.
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 CanonicalResponse<'tcx> = Canonical<'tcx, Response<'tcx>>;
/// The result of evaluating a canonical query.
EvalCtxt { infcx, var_values, search_graph, in_projection_eq_hack: false };
let result = ecx.compute_goal(goal);
- // FIXME: `Response` should be `Copy`
- if search_graph.try_finalize_goal(tcx, canonical_goal, result.clone()) {
+ if search_graph.try_finalize_goal(tcx, canonical_goal, result) {
return result;
}
}
}
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 {
var_values: self.var_values,
}
#[instrument(level = "debug", skip(infcx), ret)]
-fn take_external_constraints<'tcx>(
+fn compute_external_query_constraints<'tcx>(
infcx: &InferCtxt<'tcx>,
) -> Result<ExternalConstraints<'tcx>, NoSolution> {
let region_obligations = infcx.take_registered_region_obligations();
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 :)
//
// Should also do the leak check here I think
regions: drop(region_obligations),
opaque_types,
- })
+ }))
}
fn instantiate_canonical_query_response<'tcx>(
Certainty::Yes => OldCertainty::Proven,
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,
}),
) else { bug!(); };
variables: goal.variables,
value: Response {
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,
},
})