33// seems likely that they should eventually be merged into more
44// general routines.
55
6- use crate :: infer:: { InferCtxt , TyCtxtInferExt } ;
6+ use crate :: infer:: TyCtxtInferExt ;
77use crate :: traits:: {
88 FulfillmentContext , ImplSource , Obligation , ObligationCause , SelectionContext , TraitEngine ,
99 Unimplemented ,
1010} ;
11- use rustc_errors:: ErrorGuaranteed ;
12- use rustc_middle:: ty:: fold:: TypeFoldable ;
11+ use rustc_middle:: traits:: CodegenObligationError ;
1312use rustc_middle:: ty:: { self , TyCtxt } ;
1413
1514/// Attempts to resolve an obligation to an `ImplSource`. The result is
@@ -23,7 +22,7 @@ use rustc_middle::ty::{self, TyCtxt};
2322pub fn codegen_fulfill_obligation < ' tcx > (
2423 tcx : TyCtxt < ' tcx > ,
2524 ( param_env, trait_ref) : ( ty:: ParamEnv < ' tcx > , ty:: PolyTraitRef < ' tcx > ) ,
26- ) -> Result < & ' tcx ImplSource < ' tcx , ( ) > , ErrorGuaranteed > {
25+ ) -> Result < & ' tcx ImplSource < ' tcx , ( ) > , CodegenObligationError > {
2726 // Remove any references to regions; this helps improve caching.
2827 let trait_ref = tcx. erase_regions ( trait_ref) ;
2928 // We expect the input to be fully normalized.
@@ -40,37 +39,8 @@ pub fn codegen_fulfill_obligation<'tcx>(
4039
4140 let selection = match selcx. select ( & obligation) {
4241 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 ) ,
7444 Err ( e) => {
7545 bug ! ( "Encountered error `{:?}` selecting `{:?}` during codegen" , e, trait_ref)
7646 }
@@ -85,7 +55,17 @@ pub fn codegen_fulfill_obligation<'tcx>(
8555 let impl_source = selection. map ( |predicate| {
8656 fulfill_cx. register_predicate_obligation ( & infcx, predicate) ;
8757 } ) ;
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) ;
8969
9070 // Opaque types may have gotten their hidden types constrained, but we can ignore them safely
9171 // as they will get constrained elsewhere, too.
@@ -95,42 +75,3 @@ pub fn codegen_fulfill_obligation<'tcx>(
9575 Ok ( & * tcx. arena . alloc ( impl_source) )
9676 } )
9777}
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