|
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