fix make_ambiguous_response_no_constraints

we previously had incorrect universes in the query response.
This commit is contained in:
lcnr 2023-08-03 14:30:13 +02:00
parent a090b4548d
commit ae3c353067
6 changed files with 41 additions and 47 deletions

View File

@ -3,11 +3,11 @@ use rustc_infer::infer::at::ToTrace;
use rustc_infer::infer::canonical::CanonicalVarValues;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::{
DefineOpaqueTypes, InferCtxt, InferOk, LateBoundRegionConversionTime, RegionVariableOrigin,
TyCtxtInferExt,
DefineOpaqueTypes, InferCtxt, InferOk, LateBoundRegionConversionTime, TyCtxtInferExt,
};
use rustc_infer::traits::query::NoSolution;
use rustc_infer::traits::ObligationCause;
use rustc_middle::infer::canonical::CanonicalVarInfos;
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
use rustc_middle::traits::solve::inspect;
use rustc_middle::traits::solve::{
@ -55,6 +55,9 @@ pub struct EvalCtxt<'a, 'tcx> {
/// the job already.
infcx: &'a InferCtxt<'tcx>,
/// The variable info for the `var_values`, only used to make an ambiguous response
/// with no constraints.
variables: CanonicalVarInfos<'tcx>,
pub(super) var_values: CanonicalVarValues<'tcx>,
predefined_opaques_in_body: PredefinedOpaques<'tcx>,
@ -184,18 +187,19 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
let mut ecx = EvalCtxt {
search_graph: &mut search_graph,
infcx: infcx,
infcx,
nested_goals: NestedGoals::new(),
inspect: ProofTreeBuilder::new_maybe_root(infcx.tcx, generate_proof_tree),
// Only relevant when canonicalizing the response,
// which we don't do within this evaluation context.
predefined_opaques_in_body: infcx
.tcx
.mk_predefined_opaques_in_body(PredefinedOpaquesData::default()),
// Only relevant when canonicalizing the response.
max_input_universe: ty::UniverseIndex::ROOT,
variables: ty::List::empty(),
var_values: CanonicalVarValues::dummy(),
nested_goals: NestedGoals::new(),
tainted: Ok(()),
inspect: ProofTreeBuilder::new_maybe_root(infcx.tcx, generate_proof_tree),
};
let result = f(&mut ecx);
@ -245,6 +249,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
let mut ecx = EvalCtxt {
infcx,
variables: canonical_input.variables,
var_values,
predefined_opaques_in_body: input.predefined_opaques_in_body,
max_input_universe: canonical_input.max_universe,
@ -593,10 +598,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
})
}
pub(super) fn next_region_infer(&self) -> ty::Region<'tcx> {
self.infcx.next_region_var(RegionVariableOrigin::MiscVariable(DUMMY_SP))
}
pub(super) fn next_const_infer(&self, ty: Ty<'tcx>) -> ty::Const<'tcx> {
self.infcx.next_const_var(
ty,

View File

@ -10,7 +10,7 @@
//! [c]: https://rustc-dev-guide.rust-lang.org/solve/canonicalization.html
use super::{CanonicalInput, Certainty, EvalCtxt, Goal};
use crate::solve::canonicalize::{CanonicalizeMode, Canonicalizer};
use crate::solve::{CanonicalResponse, QueryResult, Response};
use crate::solve::{response_no_constraints_raw, CanonicalResponse, QueryResult, Response};
use rustc_data_structures::fx::FxHashSet;
use rustc_index::IndexVec;
use rustc_infer::infer::canonical::query_response::make_query_region_constraints;
@ -109,29 +109,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
&self,
maybe_cause: MaybeCause,
) -> CanonicalResponse<'tcx> {
let unconstrained_response = Response {
var_values: CanonicalVarValues {
var_values: self.tcx().mk_args_from_iter(self.var_values.var_values.iter().map(
|arg| -> ty::GenericArg<'tcx> {
match arg.unpack() {
GenericArgKind::Lifetime(_) => self.next_region_infer().into(),
GenericArgKind::Type(_) => self.next_ty_infer().into(),
GenericArgKind::Const(ct) => self.next_const_infer(ct.ty()).into(),
}
},
)),
},
external_constraints: self
.tcx()
.mk_external_constraints(ExternalConstraintsData::default()),
certainty: Certainty::Maybe(maybe_cause),
};
Canonicalizer::canonicalize(
self.infcx,
CanonicalizeMode::Response { max_input_universe: self.max_input_universe },
&mut Default::default(),
unconstrained_response,
response_no_constraints_raw(
self.tcx(),
self.max_input_universe,
self.variables,
Certainty::Maybe(maybe_cause),
)
}

View File

@ -17,6 +17,7 @@ where
let mut nested_ecx = EvalCtxt {
infcx: outer_ecx.infcx,
variables: outer_ecx.variables,
var_values: outer_ecx.var_values,
predefined_opaques_in_body: outer_ecx.predefined_opaques_in_body,
max_input_universe: outer_ecx.max_input_universe,

View File

@ -17,10 +17,11 @@
use rustc_hir::def_id::DefId;
use rustc_infer::infer::canonical::{Canonical, CanonicalVarValues};
use rustc_infer::traits::query::NoSolution;
use rustc_middle::infer::canonical::CanonicalVarInfos;
use rustc_middle::traits::solve::{
CanonicalResponse, Certainty, ExternalConstraintsData, Goal, QueryResult, Response,
};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::ty::{self, Ty, TyCtxt, UniverseIndex};
use rustc_middle::ty::{
CoercePredicate, RegionOutlivesPredicate, SubtypePredicate, TypeOutlivesPredicate,
};
@ -284,20 +285,21 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
}
}
pub(super) fn response_no_constraints<'tcx>(
fn response_no_constraints_raw<'tcx>(
tcx: TyCtxt<'tcx>,
goal: Canonical<'tcx, impl Sized>,
max_universe: UniverseIndex,
variables: CanonicalVarInfos<'tcx>,
certainty: Certainty,
) -> QueryResult<'tcx> {
Ok(Canonical {
max_universe: goal.max_universe,
variables: goal.variables,
) -> CanonicalResponse<'tcx> {
Canonical {
max_universe,
variables,
value: Response {
var_values: CanonicalVarValues::make_identity(tcx, goal.variables),
var_values: CanonicalVarValues::make_identity(tcx, variables),
// FIXME: maybe we should store the "no response" version in tcx, like
// we do for tcx.types and stuff.
external_constraints: tcx.mk_external_constraints(ExternalConstraintsData::default()),
certainty,
},
})
}
}

View File

@ -107,7 +107,7 @@ impl<'tcx> SearchGraph<'tcx> {
}
let depth = self.stack.push(StackElem { input, has_been_used: false });
let response = super::response_no_constraints(tcx, input, Certainty::Yes);
let response = Self::response_no_constraints(tcx, input, Certainty::Yes);
let entry_index = cache.entries.push(ProvisionalEntry { response, depth, input });
v.insert(entry_index);
Ok(())
@ -144,7 +144,7 @@ impl<'tcx> SearchGraph<'tcx> {
{
Err(cache.provisional_result(entry_index))
} else {
Err(super::response_no_constraints(tcx, input, Certainty::OVERFLOW))
Err(Self::response_no_constraints(tcx, input, Certainty::OVERFLOW))
}
}
}
@ -283,4 +283,12 @@ impl<'tcx> SearchGraph<'tcx> {
result
}
fn response_no_constraints(
tcx: TyCtxt<'tcx>,
goal: CanonicalInput<'tcx>,
certainty: Certainty,
) -> QueryResult<'tcx> {
Ok(super::response_no_constraints_raw(tcx, goal.max_universe, goal.variables, certainty))
}
}

View File

@ -5,7 +5,7 @@ use rustc_middle::ty::TyCtxt;
use rustc_session::Limit;
use super::SearchGraph;
use crate::solve::{response_no_constraints, EvalCtxt};
use crate::solve::{response_no_constraints_raw, EvalCtxt};
/// When detecting a solver overflow, we return ambiguity. Overflow can be
/// *hidden* by either a fatal error in an **AND** or a trivial success in an **OR**.
@ -115,6 +115,6 @@ impl<'tcx> SearchGraph<'tcx> {
goal: Canonical<'tcx, impl Sized>,
) -> QueryResult<'tcx> {
self.overflow_data.deal_with_overflow();
response_no_constraints(tcx, goal, Certainty::OVERFLOW)
Ok(response_no_constraints_raw(tcx, goal.max_universe, goal.variables, Certainty::OVERFLOW))
}
}