3
3
// seems likely that they should eventually be merged into more
4
4
// general routines.
5
5
6
- use crate :: infer:: { InferCtxt , TyCtxtInferExt } ;
6
+ use crate :: infer:: TyCtxtInferExt ;
7
7
use crate :: traits:: {
8
8
FulfillmentContext , ImplSource , Obligation , ObligationCause , SelectionContext , TraitEngine ,
9
9
Unimplemented ,
10
10
} ;
11
- use rustc_errors:: ErrorGuaranteed ;
12
- use rustc_middle:: ty:: fold:: TypeFoldable ;
11
+ use rustc_middle:: traits:: CodegenObligationError ;
13
12
use rustc_middle:: ty:: { self , TyCtxt } ;
14
13
15
14
/// Attempts to resolve an obligation to an `ImplSource`. The result is
@@ -23,7 +22,7 @@ use rustc_middle::ty::{self, TyCtxt};
23
22
pub fn codegen_fulfill_obligation < ' tcx > (
24
23
tcx : TyCtxt < ' tcx > ,
25
24
( param_env, trait_ref) : ( ty:: ParamEnv < ' tcx > , ty:: PolyTraitRef < ' tcx > ) ,
26
- ) -> Result < & ' tcx ImplSource < ' tcx , ( ) > , ErrorGuaranteed > {
25
+ ) -> Result < & ' tcx ImplSource < ' tcx , ( ) > , CodegenObligationError > {
27
26
// Remove any references to regions; this helps improve caching.
28
27
let trait_ref = tcx. erase_regions ( trait_ref) ;
29
28
// We expect the input to be fully normalized.
@@ -40,37 +39,8 @@ pub fn codegen_fulfill_obligation<'tcx>(
40
39
41
40
let selection = match selcx. select ( & obligation) {
42
41
Ok ( Some ( selection) ) => selection,
43
- Ok ( None ) => {
44
- // Ambiguity can happen when monomorphizing during trans
45
- // expands to some humongous type that never occurred
46
- // statically -- this humongous type can then overflow,
47
- // leading to an ambiguous result. So report this as an
48
- // overflow bug, since I believe this is the only case
49
- // where ambiguity can result.
50
- let reported = infcx. tcx . sess . delay_span_bug (
51
- rustc_span:: DUMMY_SP ,
52
- & format ! (
53
- "encountered ambiguity selecting `{:?}` during codegen, presuming due to \
54
- overflow or prior type error",
55
- trait_ref
56
- ) ,
57
- ) ;
58
- return Err ( reported) ;
59
- }
60
- Err ( Unimplemented ) => {
61
- // This can trigger when we probe for the source of a `'static` lifetime requirement
62
- // on a trait object: `impl Foo for dyn Trait {}` has an implicit `'static` bound.
63
- // This can also trigger when we have a global bound that is not actually satisfied,
64
- // but was included during typeck due to the trivial_bounds feature.
65
- let guar = infcx. tcx . sess . delay_span_bug (
66
- rustc_span:: DUMMY_SP ,
67
- & format ! (
68
- "Encountered error `Unimplemented` selecting `{:?}` during codegen" ,
69
- trait_ref
70
- ) ,
71
- ) ;
72
- return Err ( guar) ;
73
- }
42
+ Ok ( None ) => return Err ( CodegenObligationError :: Ambiguity ) ,
43
+ Err ( Unimplemented ) => return Err ( CodegenObligationError :: Unimplemented ) ,
74
44
Err ( e) => {
75
45
bug ! ( "Encountered error `{:?}` selecting `{:?}` during codegen" , e, trait_ref)
76
46
}
@@ -85,7 +55,17 @@ pub fn codegen_fulfill_obligation<'tcx>(
85
55
let impl_source = selection. map ( |predicate| {
86
56
fulfill_cx. register_predicate_obligation ( & infcx, predicate) ;
87
57
} ) ;
88
- let impl_source = drain_fulfillment_cx_or_panic ( & infcx, & mut fulfill_cx, impl_source) ;
58
+
59
+ // In principle, we only need to do this so long as `impl_source`
60
+ // contains unbound type parameters. It could be a slight
61
+ // optimization to stop iterating early.
62
+ let errors = fulfill_cx. select_all_or_error ( & infcx) ;
63
+ if !errors. is_empty ( ) {
64
+ return Err ( CodegenObligationError :: FulfillmentError ) ;
65
+ }
66
+
67
+ let impl_source = infcx. resolve_vars_if_possible ( impl_source) ;
68
+ let impl_source = infcx. tcx . erase_regions ( impl_source) ;
89
69
90
70
// Opaque types may have gotten their hidden types constrained, but we can ignore them safely
91
71
// as they will get constrained elsewhere, too.
@@ -95,42 +75,3 @@ pub fn codegen_fulfill_obligation<'tcx>(
95
75
Ok ( & * tcx. arena . alloc ( impl_source) )
96
76
} )
97
77
}
98
-
99
- // # Global Cache
100
-
101
- /// Finishes processes any obligations that remain in the
102
- /// fulfillment context, and then returns the result with all type
103
- /// variables removed and regions erased. Because this is intended
104
- /// for use outside of type inference, if any errors occur,
105
- /// it will panic. It is used during normalization and other cases
106
- /// where processing the obligations in `fulfill_cx` may cause
107
- /// type inference variables that appear in `result` to be
108
- /// unified, and hence we need to process those obligations to get
109
- /// the complete picture of the type.
110
- fn drain_fulfillment_cx_or_panic < ' tcx , T > (
111
- infcx : & InferCtxt < ' _ , ' tcx > ,
112
- fulfill_cx : & mut FulfillmentContext < ' tcx > ,
113
- result : T ,
114
- ) -> T
115
- where
116
- T : TypeFoldable < ' tcx > ,
117
- {
118
- debug ! ( "drain_fulfillment_cx_or_panic()" ) ;
119
-
120
- // In principle, we only need to do this so long as `result`
121
- // contains unbound type parameters. It could be a slight
122
- // optimization to stop iterating early.
123
- let errors = fulfill_cx. select_all_or_error ( infcx) ;
124
- if !errors. is_empty ( ) {
125
- infcx. tcx . sess . delay_span_bug (
126
- rustc_span:: DUMMY_SP ,
127
- & format ! (
128
- "Encountered errors `{:?}` resolving bounds outside of type inference" ,
129
- errors
130
- ) ,
131
- ) ;
132
- }
133
-
134
- let result = infcx. resolve_vars_if_possible ( result) ;
135
- infcx. tcx . erase_regions ( result)
136
- }
0 commit comments