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::canonical::CanonicalVarValues;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::{ use rustc_infer::infer::{
DefineOpaqueTypes, InferCtxt, InferOk, LateBoundRegionConversionTime, RegionVariableOrigin, DefineOpaqueTypes, InferCtxt, InferOk, LateBoundRegionConversionTime, TyCtxtInferExt,
TyCtxtInferExt,
}; };
use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::query::NoSolution;
use rustc_infer::traits::ObligationCause; use rustc_infer::traits::ObligationCause;
use rustc_middle::infer::canonical::CanonicalVarInfos;
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
use rustc_middle::traits::solve::inspect; use rustc_middle::traits::solve::inspect;
use rustc_middle::traits::solve::{ use rustc_middle::traits::solve::{
@ -55,6 +55,9 @@ pub struct EvalCtxt<'a, 'tcx> {
/// the job already. /// the job already.
infcx: &'a InferCtxt<'tcx>, 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>, pub(super) var_values: CanonicalVarValues<'tcx>,
predefined_opaques_in_body: PredefinedOpaques<'tcx>, predefined_opaques_in_body: PredefinedOpaques<'tcx>,
@ -184,18 +187,19 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
let mut ecx = EvalCtxt { let mut ecx = EvalCtxt {
search_graph: &mut search_graph, 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, // Only relevant when canonicalizing the response,
// which we don't do within this evaluation context. // which we don't do within this evaluation context.
predefined_opaques_in_body: infcx predefined_opaques_in_body: infcx
.tcx .tcx
.mk_predefined_opaques_in_body(PredefinedOpaquesData::default()), .mk_predefined_opaques_in_body(PredefinedOpaquesData::default()),
// Only relevant when canonicalizing the response.
max_input_universe: ty::UniverseIndex::ROOT, max_input_universe: ty::UniverseIndex::ROOT,
variables: ty::List::empty(),
var_values: CanonicalVarValues::dummy(), var_values: CanonicalVarValues::dummy(),
nested_goals: NestedGoals::new(),
tainted: Ok(()), tainted: Ok(()),
inspect: ProofTreeBuilder::new_maybe_root(infcx.tcx, generate_proof_tree),
}; };
let result = f(&mut ecx); let result = f(&mut ecx);
@ -245,6 +249,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
let mut ecx = EvalCtxt { let mut ecx = EvalCtxt {
infcx, infcx,
variables: canonical_input.variables,
var_values, var_values,
predefined_opaques_in_body: input.predefined_opaques_in_body, predefined_opaques_in_body: input.predefined_opaques_in_body,
max_input_universe: canonical_input.max_universe, 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> { pub(super) fn next_const_infer(&self, ty: Ty<'tcx>) -> ty::Const<'tcx> {
self.infcx.next_const_var( self.infcx.next_const_var(
ty, ty,

View File

@ -10,7 +10,7 @@
//! [c]: https://rustc-dev-guide.rust-lang.org/solve/canonicalization.html //! [c]: https://rustc-dev-guide.rust-lang.org/solve/canonicalization.html
use super::{CanonicalInput, Certainty, EvalCtxt, Goal}; use super::{CanonicalInput, Certainty, EvalCtxt, Goal};
use crate::solve::canonicalize::{CanonicalizeMode, Canonicalizer}; 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_data_structures::fx::FxHashSet;
use rustc_index::IndexVec; use rustc_index::IndexVec;
use rustc_infer::infer::canonical::query_response::make_query_region_constraints; use rustc_infer::infer::canonical::query_response::make_query_region_constraints;
@ -109,29 +109,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
&self, &self,
maybe_cause: MaybeCause, maybe_cause: MaybeCause,
) -> CanonicalResponse<'tcx> { ) -> CanonicalResponse<'tcx> {
let unconstrained_response = Response { response_no_constraints_raw(
var_values: CanonicalVarValues { self.tcx(),
var_values: self.tcx().mk_args_from_iter(self.var_values.var_values.iter().map( self.max_input_universe,
|arg| -> ty::GenericArg<'tcx> { self.variables,
match arg.unpack() { Certainty::Maybe(maybe_cause),
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,
) )
} }

View File

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

View File

@ -17,10 +17,11 @@
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_infer::infer::canonical::{Canonical, CanonicalVarValues}; use rustc_infer::infer::canonical::{Canonical, CanonicalVarValues};
use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::query::NoSolution;
use rustc_middle::infer::canonical::CanonicalVarInfos;
use rustc_middle::traits::solve::{ use rustc_middle::traits::solve::{
CanonicalResponse, Certainty, ExternalConstraintsData, Goal, QueryResult, Response, 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::{ use rustc_middle::ty::{
CoercePredicate, RegionOutlivesPredicate, SubtypePredicate, TypeOutlivesPredicate, 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>, tcx: TyCtxt<'tcx>,
goal: Canonical<'tcx, impl Sized>, max_universe: UniverseIndex,
variables: CanonicalVarInfos<'tcx>,
certainty: Certainty, certainty: Certainty,
) -> QueryResult<'tcx> { ) -> CanonicalResponse<'tcx> {
Ok(Canonical { Canonical {
max_universe: goal.max_universe, max_universe,
variables: goal.variables, variables,
value: Response { 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 // FIXME: maybe we should store the "no response" version in tcx, like
// we do for tcx.types and stuff. // we do for tcx.types and stuff.
external_constraints: tcx.mk_external_constraints(ExternalConstraintsData::default()), external_constraints: tcx.mk_external_constraints(ExternalConstraintsData::default()),
certainty, certainty,
}, },
}) }
} }

View File

@ -107,7 +107,7 @@ impl<'tcx> SearchGraph<'tcx> {
} }
let depth = self.stack.push(StackElem { input, has_been_used: false }); 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 }); let entry_index = cache.entries.push(ProvisionalEntry { response, depth, input });
v.insert(entry_index); v.insert(entry_index);
Ok(()) Ok(())
@ -144,7 +144,7 @@ impl<'tcx> SearchGraph<'tcx> {
{ {
Err(cache.provisional_result(entry_index)) Err(cache.provisional_result(entry_index))
} else { } 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 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 rustc_session::Limit;
use super::SearchGraph; 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 /// 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**. /// *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>, goal: Canonical<'tcx, impl Sized>,
) -> QueryResult<'tcx> { ) -> QueryResult<'tcx> {
self.overflow_data.deal_with_overflow(); 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))
} }
} }