1
Fork 0

Implement dummy query responses and a jank instantiate

This commit is contained in:
Michael Goulet 2023-01-10 20:24:10 +00:00
parent 1bc3683b32
commit 5a31d5ebe2
5 changed files with 97 additions and 38 deletions

View file

@ -2,8 +2,8 @@
use super::infcx_ext::InferCtxtExt; use super::infcx_ext::InferCtxtExt;
use super::{ use super::{
fixme_instantiate_canonical_query_response, CanonicalGoal, CanonicalResponse, Certainty, instantiate_canonical_query_response, CanonicalGoal, CanonicalResponse, Certainty, EvalCtxt,
EvalCtxt, Goal, Goal,
}; };
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::TyCtxtInferExt;
@ -121,11 +121,8 @@ impl<'a, 'tcx, G: GoalKind<'tcx>> AssemblyCtxt<'a, 'tcx, G> {
// canonical wrt the caller. // canonical wrt the caller.
for Candidate { source, result } in normalized_candidates { for Candidate { source, result } in normalized_candidates {
self.infcx.probe(|_| { self.infcx.probe(|_| {
let candidate_certainty = fixme_instantiate_canonical_query_response( let candidate_certainty =
&self.infcx, instantiate_canonical_query_response(&self.infcx, &orig_values, result);
&orig_values,
result,
);
// FIXME: This is a bit scary if the `normalizes_to_goal` overflows. // FIXME: This is a bit scary if the `normalizes_to_goal` overflows.
// //

View file

@ -9,11 +9,12 @@
//! FIXME(@lcnr): Write that section, feel free to ping me if you need help here //! FIXME(@lcnr): Write that section, feel free to ping me if you need help here
//! before then or if I still haven't done that before January 2023. //! before then or if I still haven't done that before January 2023.
use super::overflow::OverflowData; use super::overflow::OverflowData;
use super::CanonicalGoal; use super::{CanonicalGoal, Certainty, MaybeCause, Response};
use super::{EvalCtxt, QueryResult}; use super::{EvalCtxt, QueryResult};
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_middle::ty::TyCtxt; use rustc_infer::infer::canonical::{Canonical, CanonicalVarKind, CanonicalVarValues};
use rustc_middle::ty::{self, TyCtxt};
use std::{cmp::Ordering, collections::hash_map::Entry}; use std::{cmp::Ordering, collections::hash_map::Entry};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -111,11 +112,11 @@ impl<'tcx> EvalCtxt<'tcx> {
// No entry, simply push this goal on the stack after dealing with overflow. // No entry, simply push this goal on the stack after dealing with overflow.
Entry::Vacant(v) => { Entry::Vacant(v) => {
if self.overflow_data.has_overflow(cache.stack.len()) { if self.overflow_data.has_overflow(cache.stack.len()) {
return Err(self.deal_with_overflow()); return Err(self.deal_with_overflow(goal));
} }
v.insert(ProvisionalEntry { v.insert(ProvisionalEntry {
response: fixme_response_yes_no_constraints(), response: response_no_constraints(self.tcx, goal, Certainty::Yes),
depth: cache.stack.len(), depth: cache.stack.len(),
}); });
cache.stack.push(StackElem { goal, has_been_used: false }); cache.stack.push(StackElem { goal, has_been_used: false });
@ -150,7 +151,11 @@ impl<'tcx> EvalCtxt<'tcx> {
{ {
Err(entry.response) Err(entry.response)
} else { } else {
Err(fixme_response_maybe_no_constraints()) Err(response_no_constraints(
self.tcx,
goal,
Certainty::Maybe(MaybeCause::Ambiguity),
))
} }
} }
} }
@ -248,10 +253,39 @@ impl<'tcx> EvalCtxt<'tcx> {
} }
} }
fn fixme_response_yes_no_constraints<'tcx>() -> QueryResult<'tcx> { pub(super) fn response_no_constraints<'tcx>(
unimplemented!() tcx: TyCtxt<'tcx>,
} goal: Canonical<'tcx, impl Sized>,
certainty: Certainty,
) -> QueryResult<'tcx> {
let var_values = goal
.variables
.iter()
.enumerate()
.map(|(i, info)| match info.kind {
CanonicalVarKind::Ty(_) | CanonicalVarKind::PlaceholderTy(_) => {
tcx.mk_ty(ty::Bound(ty::INNERMOST, ty::BoundVar::from_usize(i).into())).into()
}
CanonicalVarKind::Region(_) | CanonicalVarKind::PlaceholderRegion(_) => {
let br = ty::BoundRegion {
var: ty::BoundVar::from_usize(i),
kind: ty::BrAnon(i as u32, None),
};
tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)).into()
}
CanonicalVarKind::Const(_, ty) | CanonicalVarKind::PlaceholderConst(_, ty) => tcx
.mk_const(ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from_usize(i)), ty)
.into(),
})
.collect();
fn fixme_response_maybe_no_constraints<'tcx>() -> QueryResult<'tcx> { Ok(Canonical {
unimplemented!() max_universe: goal.max_universe,
variables: goal.variables,
value: Response {
var_values: CanonicalVarValues { var_values },
external_constraints: Default::default(),
certainty,
},
})
} }

View file

@ -62,7 +62,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
let mut errors = Vec::new(); let mut errors = Vec::new();
for i in 0.. { for i in 0.. {
if !infcx.tcx.recursion_limit().value_within_limit(i) { if !infcx.tcx.recursion_limit().value_within_limit(i) {
unimplemented!("overflow") unimplemented!("overflowed on pending obligations: {:?}", self.obligations);
} }
let mut has_changed = false; let mut has_changed = false;

View file

@ -19,15 +19,19 @@
use std::mem; use std::mem;
use rustc_infer::infer::canonical::OriginalQueryValues; use rustc_infer::infer::canonical::{OriginalQueryValues, QueryRegionConstraints, QueryResponse};
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; 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::{Canonical, CanonicalVarValues}; use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues};
use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::ty::{RegionOutlivesPredicate, ToPredicate, TypeOutlivesPredicate}; use rustc_middle::ty::{RegionOutlivesPredicate, ToPredicate, TypeOutlivesPredicate};
use rustc_span::DUMMY_SP; use rustc_span::DUMMY_SP;
use crate::traits::ObligationCause;
use self::cache::response_no_constraints;
use self::infcx_ext::InferCtxtExt; use self::infcx_ext::InferCtxtExt;
mod assembly; mod assembly;
@ -119,7 +123,7 @@ pub enum MaybeCause {
} }
/// Additional constraints returned on success. /// Additional constraints returned on success.
#[derive(Debug, PartialEq, Eq, Clone, Hash, TypeFoldable, TypeVisitable)] #[derive(Debug, PartialEq, Eq, Clone, Hash, TypeFoldable, TypeVisitable, Default)]
pub struct ExternalConstraints<'tcx> { pub struct ExternalConstraints<'tcx> {
// FIXME: implement this. // FIXME: implement this.
regions: (), regions: (),
@ -175,7 +179,7 @@ impl<'tcx> EvalCtxt<'tcx> {
let canonical_response = self.evaluate_canonical_goal(canonical_goal)?; let canonical_response = self.evaluate_canonical_goal(canonical_goal)?;
Ok(( Ok((
true, // FIXME: check whether `var_values` are an identity substitution. true, // FIXME: check whether `var_values` are an identity substitution.
fixme_instantiate_canonical_query_response(infcx, &orig_values, canonical_response), instantiate_canonical_query_response(infcx, &orig_values, canonical_response),
)) ))
} }
@ -208,6 +212,7 @@ impl<'tcx> EvalCtxt<'tcx> {
// of `PredicateKind` this is the case and it is and faster than instantiating and // of `PredicateKind` this is the case and it is and faster than instantiating and
// recanonicalizing. // recanonicalizing.
let Goal { param_env, predicate } = canonical_goal.value; let Goal { param_env, predicate } = canonical_goal.value;
if let Some(kind) = predicate.kind().no_bound_vars() { if let Some(kind) = predicate.kind().no_bound_vars() {
match kind { match kind {
ty::PredicateKind::Clause(ty::Clause::Trait(predicate)) => self.compute_trait_goal( ty::PredicateKind::Clause(ty::Clause::Trait(predicate)) => self.compute_trait_goal(
@ -234,7 +239,10 @@ impl<'tcx> EvalCtxt<'tcx> {
| ty::PredicateKind::ConstEvaluatable(_) | ty::PredicateKind::ConstEvaluatable(_)
| ty::PredicateKind::ConstEquate(_, _) | ty::PredicateKind::ConstEquate(_, _)
| ty::PredicateKind::TypeWellFormedFromEnv(_) | ty::PredicateKind::TypeWellFormedFromEnv(_)
| ty::PredicateKind::Ambiguous => unimplemented!(), | ty::PredicateKind::Ambiguous => {
// FIXME
response_no_constraints(self.tcx, canonical_goal, Certainty::Yes)
}
} }
} else { } else {
let (infcx, goal, var_values) = let (infcx, goal, var_values) =
@ -248,16 +256,18 @@ impl<'tcx> EvalCtxt<'tcx> {
fn compute_type_outlives_goal( fn compute_type_outlives_goal(
&mut self, &mut self,
_goal: CanonicalGoal<'tcx, TypeOutlivesPredicate<'tcx>>, goal: CanonicalGoal<'tcx, TypeOutlivesPredicate<'tcx>>,
) -> QueryResult<'tcx> { ) -> QueryResult<'tcx> {
todo!() // FIXME
response_no_constraints(self.tcx, goal, Certainty::Yes)
} }
fn compute_region_outlives_goal( fn compute_region_outlives_goal(
&mut self, &mut self,
_goal: CanonicalGoal<'tcx, RegionOutlivesPredicate<'tcx>>, goal: CanonicalGoal<'tcx, RegionOutlivesPredicate<'tcx>>,
) -> QueryResult<'tcx> { ) -> QueryResult<'tcx> {
todo!() // FIXME
response_no_constraints(self.tcx, goal, Certainty::Yes)
} }
} }
@ -300,10 +310,27 @@ impl<'tcx> EvalCtxt<'tcx> {
} }
} }
fn fixme_instantiate_canonical_query_response<'tcx>( fn instantiate_canonical_query_response<'tcx>(
_: &InferCtxt<'tcx>, infcx: &InferCtxt<'tcx>,
_: &OriginalQueryValues<'tcx>, original_values: &OriginalQueryValues<'tcx>,
_: CanonicalResponse<'tcx>, response: CanonicalResponse<'tcx>,
) -> Certainty { ) -> Certainty {
unimplemented!() let Ok(InferOk { value, obligations }) = infcx
.instantiate_query_response_and_region_obligations(
&ObligationCause::dummy(),
ty::ParamEnv::empty(),
original_values,
&response.unchecked_map(|resp| QueryResponse {
var_values: resp.var_values,
region_constraints: QueryRegionConstraints::default(),
certainty: match resp.certainty {
Certainty::Yes => OldCertainty::Proven,
Certainty::Maybe(_) => OldCertainty::Ambiguous,
},
opaque_types: resp.external_constraints.opaque_types,
value: resp.certainty,
}),
) else { bug!(); };
assert!(obligations.is_empty());
value
} }

View file

@ -1,7 +1,9 @@
use rustc_infer::infer::canonical::Canonical;
use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::query::NoSolution;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use rustc_session::Limit; use rustc_session::Limit;
use super::cache::response_no_constraints;
use super::{Certainty, EvalCtxt, MaybeCause, QueryResult}; use super::{Certainty, EvalCtxt, MaybeCause, QueryResult};
/// When detecting a solver overflow, we return ambiguity. Overflow can be /// When detecting a solver overflow, we return ambiguity. Overflow can be
@ -49,9 +51,12 @@ impl OverflowData {
} }
impl<'tcx> EvalCtxt<'tcx> { impl<'tcx> EvalCtxt<'tcx> {
pub(super) fn deal_with_overflow(&mut self) -> QueryResult<'tcx> { pub(super) fn deal_with_overflow(
&mut self,
goal: Canonical<'tcx, impl Sized>,
) -> QueryResult<'tcx> {
self.overflow_data.deal_with_overflow(); self.overflow_data.deal_with_overflow();
fixme_response_overflow_no_constraints() response_no_constraints(self.tcx, goal, Certainty::Maybe(MaybeCause::Overflow))
} }
/// A `while`-loop which tracks overflow. /// A `while`-loop which tracks overflow.
@ -74,7 +79,3 @@ impl<'tcx> EvalCtxt<'tcx> {
Ok(Certainty::Maybe(MaybeCause::Overflow)) Ok(Certainty::Maybe(MaybeCause::Overflow))
} }
} }
fn fixme_response_overflow_no_constraints<'tcx>() -> QueryResult<'tcx> {
unimplemented!()
}