18
18
//! [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html
19
19
20
20
use infer:: canonical:: substitute:: substitute_value;
21
- use infer:: canonical:: {
22
- Canonical , CanonicalVarKind , CanonicalVarValues , CanonicalizedQueryResult , Certainty ,
23
- QueryRegionConstraint , QueryResult ,
24
- } ;
21
+ use infer:: canonical:: { Canonical , CanonicalVarKind , CanonicalVarValues , CanonicalizedQueryResult ,
22
+ Certainty , QueryRegionConstraint , QueryResult } ;
25
23
use infer:: region_constraints:: { Constraint , RegionConstraintData } ;
24
+ use infer:: InferCtxtBuilder ;
26
25
use infer:: { InferCtxt , InferOk , InferResult , RegionObligation } ;
27
26
use rustc_data_structures:: indexed_vec:: Idx ;
28
27
use rustc_data_structures:: indexed_vec:: IndexVec ;
29
28
use rustc_data_structures:: sync:: Lrc ;
30
29
use std:: fmt:: Debug ;
31
30
use syntax:: ast;
32
- use traits:: query:: NoSolution ;
31
+ use syntax_pos:: DUMMY_SP ;
32
+ use traits:: query:: { Fallible , NoSolution } ;
33
33
use traits:: { FulfillmentContext , TraitEngine } ;
34
34
use traits:: { Obligation , ObligationCause , PredicateObligation } ;
35
35
use ty:: fold:: TypeFoldable ;
36
36
use ty:: subst:: { Kind , UnpackedKind } ;
37
37
use ty:: { self , CanonicalVar , Lift , TyCtxt } ;
38
38
39
+ impl < ' cx , ' gcx , ' tcx > InferCtxtBuilder < ' cx , ' gcx , ' tcx > {
40
+ /// The "main method" for a canonicalized trait query. Given the
41
+ /// canonical key `canonical_key`, this method will create a new
42
+ /// inference context, instantiate the key, and run your operation
43
+ /// `op`. The operation should yield up a result (of type `R`) as
44
+ /// well as a set of trait obligations that must be fully
45
+ /// satisfied. These obligations will be processed and the
46
+ /// canonical result created.
47
+ ///
48
+ /// Returns `NoSolution` in the event of any error.
49
+ pub fn enter_canonical_trait_query < K , R > (
50
+ & ' tcx mut self ,
51
+ canonical_key : & Canonical < ' tcx , K > ,
52
+ op : impl FnOnce ( & InferCtxt < ' _ , ' gcx , ' tcx > , K ) -> Fallible < InferOk < ' tcx , R > > ,
53
+ ) -> Fallible < CanonicalizedQueryResult < ' gcx , R > >
54
+ where
55
+ K : TypeFoldable < ' tcx > ,
56
+ R : Debug + Lift < ' gcx > + TypeFoldable < ' tcx > ,
57
+ {
58
+ self . enter ( |ref infcx| {
59
+ let ( key, canonical_inference_vars) =
60
+ infcx. instantiate_canonical_with_fresh_inference_vars ( DUMMY_SP , & canonical_key) ;
61
+ let InferOk { value, obligations } = op ( infcx, key) ?;
62
+ let fulfill_cx = & mut FulfillmentContext :: new ( ) ;
63
+ fulfill_cx. register_predicate_obligations ( infcx, obligations) ;
64
+ infcx. make_canonicalized_query_result ( canonical_inference_vars, value, fulfill_cx)
65
+ } )
66
+ }
67
+ }
68
+
39
69
impl < ' cx , ' gcx , ' tcx > InferCtxt < ' cx , ' gcx , ' tcx > {
40
70
/// This method is meant to be invoked as the final step of a canonical query
41
71
/// implementation. It is given:
@@ -61,7 +91,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
61
91
inference_vars : CanonicalVarValues < ' tcx > ,
62
92
answer : T ,
63
93
fulfill_cx : & mut FulfillmentContext < ' tcx > ,
64
- ) -> Result < CanonicalizedQueryResult < ' gcx , T > , NoSolution >
94
+ ) -> Fallible < CanonicalizedQueryResult < ' gcx , T > >
65
95
where
66
96
T : Debug + Lift < ' gcx > + TypeFoldable < ' tcx > ,
67
97
{
@@ -293,14 +323,13 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
293
323
let result_subst =
294
324
self . query_result_substitution_guess ( cause, original_values, query_result) ;
295
325
296
- let obligations = self
297
- . unify_query_result_substitution_guess (
298
- cause,
299
- param_env,
300
- original_values,
301
- & result_subst,
302
- query_result,
303
- ) ?
326
+ let obligations = self . unify_query_result_substitution_guess (
327
+ cause,
328
+ param_env,
329
+ original_values,
330
+ & result_subst,
331
+ query_result,
332
+ ) ?
304
333
. into_obligations ( ) ;
305
334
306
335
Ok ( InferOk {
0 commit comments