Skip to content

Commit 5bea48b

Browse files
separate calculation and interning of external query constraints
1 parent defed62 commit 5bea48b

File tree

1 file changed

+28
-27
lines changed
  • compiler/rustc_trait_selection/src/solve/eval_ctxt

1 file changed

+28
-27
lines changed

compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use rustc_infer::infer::canonical::CanonicalVarValues;
1818
use rustc_infer::infer::canonical::{CanonicalExt, QueryRegionConstraints};
1919
use rustc_middle::traits::query::NoSolution;
2020
use rustc_middle::traits::solve::{
21-
ExternalConstraints, ExternalConstraintsData, MaybeCause, PredefinedOpaquesData, QueryInput,
21+
ExternalConstraintsData, MaybeCause, PredefinedOpaquesData, QueryInput,
2222
};
2323
use rustc_middle::ty::{self, BoundVar, GenericArgKind, Ty, TyCtxt, TypeFoldable};
2424
use rustc_span::DUMMY_SP;
@@ -69,35 +69,36 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
6969
previous call to `try_evaluate_added_goals!`"
7070
);
7171

72-
let certainty = certainty.unify_with(goals_certainty);
72+
if let Certainty::OVERFLOW = certainty {
73+
// If we have overflow, it's probable that we're substituting a type
74+
// into itself infinitely and any partial substitutions in the query
75+
// response are probably not useful anyways, so just return an empty
76+
// query response.
77+
//
78+
// This may prevent us from potentially useful inference, e.g.
79+
// 2 candidates, one ambiguous and one overflow, which both
80+
// have the same inference constraints.
81+
//
82+
// Changing this to retain some constraints in the future
83+
// won't be a breaking change, so this is good enough for now.
84+
return Ok(self.make_ambiguous_response_no_constraints(MaybeCause::Overflow));
85+
}
7386

74-
let response = match certainty {
75-
Certainty::Yes | Certainty::Maybe(MaybeCause::Ambiguity) => {
76-
let external_constraints = self.compute_external_query_constraints()?;
77-
Response { var_values: self.var_values, external_constraints, certainty }
78-
}
79-
Certainty::Maybe(MaybeCause::Overflow) => {
80-
// If we have overflow, it's probable that we're substituting a type
81-
// into itself infinitely and any partial substitutions in the query
82-
// response are probably not useful anyways, so just return an empty
83-
// query response.
84-
//
85-
// This may prevent us from potentially useful inference, e.g.
86-
// 2 candidates, one ambiguous and one overflow, which both
87-
// have the same inference constraints.
88-
//
89-
// Changing this to retain some constraints in the future
90-
// won't be a breaking change, so this is good enough for now.
91-
return Ok(self.make_ambiguous_response_no_constraints(MaybeCause::Overflow));
92-
}
93-
};
87+
let certainty = certainty.unify_with(goals_certainty);
88+
let var_values = self.var_values;
89+
let external_constraints = self.compute_external_query_constraints()?;
9490

9591
let canonical = Canonicalizer::canonicalize(
9692
self.infcx,
9793
CanonicalizeMode::Response { max_input_universe: self.max_input_universe },
9894
&mut Default::default(),
99-
response,
95+
Response {
96+
var_values,
97+
certainty,
98+
external_constraints: self.tcx().mk_external_constraints(external_constraints),
99+
},
100100
);
101+
101102
Ok(canonical)
102103
}
103104

@@ -143,7 +144,9 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
143144
/// further constrained by inference, that will be passed back in the var
144145
/// values.
145146
#[instrument(level = "debug", skip(self), ret)]
146-
fn compute_external_query_constraints(&self) -> Result<ExternalConstraints<'tcx>, NoSolution> {
147+
fn compute_external_query_constraints(
148+
&self,
149+
) -> Result<ExternalConstraintsData<'tcx>, NoSolution> {
147150
// We only check for leaks from universes which were entered inside
148151
// of the query.
149152
self.infcx.leak_check(self.max_input_universe, None).map_err(|e| {
@@ -173,9 +176,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
173176
self.predefined_opaques_in_body.opaque_types.iter().all(|(pa, _)| pa != a)
174177
});
175178

176-
Ok(self
177-
.tcx()
178-
.mk_external_constraints(ExternalConstraintsData { region_constraints, opaque_types }))
179+
Ok(ExternalConstraintsData { region_constraints, opaque_types })
179180
}
180181

181182
/// After calling a canonical query, we apply the constraints returned

0 commit comments

Comments
 (0)