|
10 | 10 | //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/specialization.html
|
11 | 11 |
|
12 | 12 | pub mod specialization_graph;
|
| 13 | +use rustc_infer::traits::{TraitEngine, TraitEngineExt as _}; |
13 | 14 | use specialization_graph::GraphExt;
|
14 | 15 |
|
15 | 16 | use crate::errors::NegativePositiveConflict;
|
16 | 17 | use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt};
|
| 18 | +use crate::traits::engine::TraitEngineExt as _; |
17 | 19 | use crate::traits::select::IntercrateAmbiguityCause;
|
18 | 20 | use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause};
|
19 | 21 | use rustc_data_structures::fx::FxIndexSet;
|
@@ -200,36 +202,32 @@ fn fulfill_implication<'tcx>(
|
200 | 202 | return Err(());
|
201 | 203 | };
|
202 | 204 |
|
| 205 | + // Needs to be `in_snapshot` because this function is used to rebase |
| 206 | + // substitutions, which may happen inside of a select within a probe. |
| 207 | + let mut engine = <dyn TraitEngine<'tcx>>::new_in_snapshot(infcx.tcx); |
203 | 208 | // attempt to prove all of the predicates for impl2 given those for impl1
|
204 | 209 | // (which are packed up in penv)
|
| 210 | + engine.register_predicate_obligations(infcx, obligations.chain(more_obligations)); |
205 | 211 |
|
206 |
| - infcx.save_and_restore_in_snapshot_flag(|infcx| { |
207 |
| - let errors = traits::fully_solve_obligations(&infcx, obligations.chain(more_obligations)); |
208 |
| - match &errors[..] { |
209 |
| - [] => { |
210 |
| - debug!( |
211 |
| - "fulfill_implication: an impl for {:?} specializes {:?}", |
212 |
| - source_trait, target_trait |
213 |
| - ); |
| 212 | + let errors = engine.select_all_or_error(infcx); |
| 213 | + if !errors.is_empty() { |
| 214 | + // no dice! |
| 215 | + debug!( |
| 216 | + "fulfill_implication: for impls on {:?} and {:?}, \ |
| 217 | + could not fulfill: {:?} given {:?}", |
| 218 | + source_trait, |
| 219 | + target_trait, |
| 220 | + errors, |
| 221 | + param_env.caller_bounds() |
| 222 | + ); |
| 223 | + return Err(()); |
| 224 | + } |
214 | 225 |
|
215 |
| - // Now resolve the *substitution* we built for the target earlier, replacing |
216 |
| - // the inference variables inside with whatever we got from fulfillment. |
217 |
| - Ok(infcx.resolve_vars_if_possible(target_substs)) |
218 |
| - } |
219 |
| - errors => { |
220 |
| - // no dice! |
221 |
| - debug!( |
222 |
| - "fulfill_implication: for impls on {:?} and {:?}, \ |
223 |
| - could not fulfill: {:?} given {:?}", |
224 |
| - source_trait, |
225 |
| - target_trait, |
226 |
| - errors, |
227 |
| - param_env.caller_bounds() |
228 |
| - ); |
229 |
| - Err(()) |
230 |
| - } |
231 |
| - } |
232 |
| - }) |
| 226 | + debug!("fulfill_implication: an impl for {:?} specializes {:?}", source_trait, target_trait); |
| 227 | + |
| 228 | + // Now resolve the *substitution* we built for the target earlier, replacing |
| 229 | + // the inference variables inside with whatever we got from fulfillment. |
| 230 | + Ok(infcx.resolve_vars_if_possible(target_substs)) |
233 | 231 | }
|
234 | 232 |
|
235 | 233 | // Query provider for `specialization_graph_of`.
|
|
0 commit comments