3
3
// seems likely that they should eventually be merged into more
4
4
// general routines.
5
5
6
- use crate :: infer:: InferCtxt ;
7
- use crate :: traits:: {
8
- FulfillmentContext , Obligation , ObligationCause , SelectionContext , TraitEngine , Vtable ,
9
- } ;
10
6
use crate :: ty:: fold:: TypeFoldable ;
11
7
use crate :: ty:: subst:: { Subst , SubstsRef } ;
12
8
use crate :: ty:: { self , TyCtxt } ;
13
9
14
- /// Attempts to resolve an obligation to a vtable. The result is
15
- /// a shallow vtable resolution, meaning that we do not
16
- /// (necessarily) resolve all nested obligations on the impl. Note
17
- /// that type check should guarantee to us that all nested
18
- /// obligations *could be* resolved if we wanted to.
19
- /// Assumes that this is run after the entire crate has been successfully type-checked.
20
- pub fn codegen_fulfill_obligation < ' tcx > (
21
- ty : TyCtxt < ' tcx > ,
22
- ( param_env, trait_ref) : ( ty:: ParamEnv < ' tcx > , ty:: PolyTraitRef < ' tcx > ) ,
23
- ) -> Vtable < ' tcx , ( ) > {
24
- // Remove any references to regions; this helps improve caching.
25
- let trait_ref = ty. erase_regions ( & trait_ref) ;
26
-
27
- debug ! (
28
- "codegen_fulfill_obligation(trait_ref={:?}, def_id={:?})" ,
29
- ( param_env, trait_ref) ,
30
- trait_ref. def_id( )
31
- ) ;
32
-
33
- // Do the initial selection for the obligation. This yields the
34
- // shallow result we are looking for -- that is, what specific impl.
35
- ty. infer_ctxt ( ) . enter ( |infcx| {
36
- let mut selcx = SelectionContext :: new ( & infcx) ;
37
-
38
- let obligation_cause = ObligationCause :: dummy ( ) ;
39
- let obligation =
40
- Obligation :: new ( obligation_cause, param_env, trait_ref. to_poly_trait_predicate ( ) ) ;
41
-
42
- let selection = match selcx. select ( & obligation) {
43
- Ok ( Some ( selection) ) => selection,
44
- Ok ( None ) => {
45
- // Ambiguity can happen when monomorphizing during trans
46
- // expands to some humongo type that never occurred
47
- // statically -- this humongo type can then overflow,
48
- // leading to an ambiguous result. So report this as an
49
- // overflow bug, since I believe this is the only case
50
- // where ambiguity can result.
51
- bug ! (
52
- "Encountered ambiguity selecting `{:?}` during codegen, \
53
- presuming due to overflow",
54
- trait_ref
55
- )
56
- }
57
- Err ( e) => {
58
- bug ! ( "Encountered error `{:?}` selecting `{:?}` during codegen" , e, trait_ref)
59
- }
60
- } ;
61
-
62
- debug ! ( "fulfill_obligation: selection={:?}" , selection) ;
63
-
64
- // Currently, we use a fulfillment context to completely resolve
65
- // all nested obligations. This is because they can inform the
66
- // inference of the impl's type parameters.
67
- let mut fulfill_cx = FulfillmentContext :: new ( ) ;
68
- let vtable = selection. map ( |predicate| {
69
- debug ! ( "fulfill_obligation: register_predicate_obligation {:?}" , predicate) ;
70
- fulfill_cx. register_predicate_obligation ( & infcx, predicate) ;
71
- } ) ;
72
- let vtable = infcx. drain_fulfillment_cx_or_panic ( & mut fulfill_cx, & vtable) ;
73
-
74
- info ! ( "Cache miss: {:?} => {:?}" , trait_ref, vtable) ;
75
- vtable
76
- } )
77
- }
78
-
79
10
impl < ' tcx > TyCtxt < ' tcx > {
80
11
/// Monomorphizes a type from the AST by first applying the
81
12
/// in-scope substitutions and then normalizing any associated
@@ -100,37 +31,3 @@ impl<'tcx> TyCtxt<'tcx> {
100
31
self . normalize_erasing_regions ( param_env, substituted)
101
32
}
102
33
}
103
-
104
- // # Global Cache
105
-
106
- impl < ' a , ' tcx > InferCtxt < ' a , ' tcx > {
107
- /// Finishes processes any obligations that remain in the
108
- /// fulfillment context, and then returns the result with all type
109
- /// variables removed and regions erased. Because this is intended
110
- /// for use after type-check has completed, if any errors occur,
111
- /// it will panic. It is used during normalization and other cases
112
- /// where processing the obligations in `fulfill_cx` may cause
113
- /// type inference variables that appear in `result` to be
114
- /// unified, and hence we need to process those obligations to get
115
- /// the complete picture of the type.
116
- fn drain_fulfillment_cx_or_panic < T > (
117
- & self ,
118
- fulfill_cx : & mut FulfillmentContext < ' tcx > ,
119
- result : & T ,
120
- ) -> T
121
- where
122
- T : TypeFoldable < ' tcx > ,
123
- {
124
- debug ! ( "drain_fulfillment_cx_or_panic()" ) ;
125
-
126
- // In principle, we only need to do this so long as `result`
127
- // contains unbound type parameters. It could be a slight
128
- // optimization to stop iterating early.
129
- if let Err ( errors) = fulfill_cx. select_all_or_error ( self ) {
130
- bug ! ( "Encountered errors `{:?}` resolving bounds after type-checking" , errors) ;
131
- }
132
-
133
- let result = self . resolve_vars_if_possible ( result) ;
134
- self . tcx . erase_regions ( & result)
135
- }
136
- }
0 commit comments