Split out make_ambiguous_response_no_constraints
This commit is contained in:
parent
5fa82092ae
commit
ee8942138a
@ -70,25 +70,14 @@ pub(in crate::solve) fn evaluate_added_goals_and_make_canonical_response(
|
|||||||
// into itself infinitely and any partial substitutions in the query
|
// into itself infinitely and any partial substitutions in the query
|
||||||
// response are probably not useful anyways, so just return an empty
|
// response are probably not useful anyways, so just return an empty
|
||||||
// query response.
|
// query response.
|
||||||
Response {
|
//
|
||||||
var_values: CanonicalVarValues {
|
// This may prevent us from potentially useful inference, e.g.
|
||||||
var_values: self.tcx().mk_substs_from_iter(
|
// 2 candidates, one ambiguous and one overflow, which both
|
||||||
self.var_values.var_values.iter().map(|arg| -> ty::GenericArg<'tcx> {
|
// have the same inference constraints.
|
||||||
match arg.unpack() {
|
//
|
||||||
GenericArgKind::Lifetime(_) => self.next_region_infer().into(),
|
// Changing this to retain some constraints in the future
|
||||||
GenericArgKind::Type(_) => self.next_ty_infer().into(),
|
// won't be a breaking change, so this is good enough for now.
|
||||||
GenericArgKind::Const(ct) => {
|
return Ok(self.make_ambiguous_response_no_constraints(MaybeCause::Overflow));
|
||||||
self.next_const_infer(ct.ty()).into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
external_constraints: self
|
|
||||||
.tcx()
|
|
||||||
.mk_external_constraints(ExternalConstraintsData::default()),
|
|
||||||
certainty,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -101,6 +90,40 @@ pub(in crate::solve) fn evaluate_added_goals_and_make_canonical_response(
|
|||||||
Ok(canonical)
|
Ok(canonical)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Constructs a totally unconstrained, ambiguous response to a goal.
|
||||||
|
///
|
||||||
|
/// Take care when using this, since often it's useful to respond with
|
||||||
|
/// ambiguity but return constrained variables to guide inference.
|
||||||
|
pub(in crate::solve) fn make_ambiguous_response_no_constraints(
|
||||||
|
&self,
|
||||||
|
maybe_cause: MaybeCause,
|
||||||
|
) -> CanonicalResponse<'tcx> {
|
||||||
|
let unconstrained_response = Response {
|
||||||
|
var_values: CanonicalVarValues {
|
||||||
|
var_values: self.tcx().mk_substs_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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self), ret)]
|
#[instrument(level = "debug", skip(self), ret)]
|
||||||
fn compute_external_query_constraints(&self) -> Result<ExternalConstraints<'tcx>, NoSolution> {
|
fn compute_external_query_constraints(&self) -> Result<ExternalConstraints<'tcx>, NoSolution> {
|
||||||
// Cannot use `take_registered_region_obligations` as we may compute the response
|
// Cannot use `take_registered_region_obligations` as we may compute the response
|
||||||
|
@ -340,17 +340,17 @@ fn flounder(&mut self, responses: &[CanonicalResponse<'tcx>]) -> QueryResult<'tc
|
|||||||
if responses.is_empty() {
|
if responses.is_empty() {
|
||||||
return Err(NoSolution);
|
return Err(NoSolution);
|
||||||
}
|
}
|
||||||
let certainty = responses.iter().fold(Certainty::AMBIGUOUS, |certainty, response| {
|
|
||||||
certainty.unify_with(response.value.certainty)
|
|
||||||
});
|
|
||||||
|
|
||||||
let response = self.evaluate_added_goals_and_make_canonical_response(certainty);
|
let Certainty::Maybe(maybe_cause) = responses.iter().fold(
|
||||||
if let Ok(response) = response {
|
Certainty::AMBIGUOUS,
|
||||||
assert!(response.has_no_inference_or_external_constraints());
|
|certainty, response| {
|
||||||
Ok(response)
|
certainty.unify_with(response.value.certainty)
|
||||||
} else {
|
},
|
||||||
bug!("failed to make floundered response: {responses:?}");
|
) else {
|
||||||
}
|
bug!("expected flounder response to be ambiguous")
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(self.make_ambiguous_response_no_constraints(maybe_cause))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user