1
1
// This file was taken from the compiler:
2
- // https://raw.githubusercontent.com/rust-lang/rust/949b98cab8a186b98bf87e64374b8d0848c55271 /compiler/rustc_trait_selection/src/traits/codegen.rs
2
+ // https://raw.githubusercontent.com/rust-lang/rust/03d488b48af9f66b91e9400387f781b82411fa82 /compiler/rustc_trait_selection/src/traits/codegen.rs
3
3
// This file is licensed under Apache 2.0
4
- // (https://github.com/rust-lang/rust/blob/949b98cab8a186b98bf87e64374b8d0848c55271 /LICENSE-APACHE)
4
+ // (https://github.com/rust-lang/rust/blob/03d488b48af9f66b91e9400387f781b82411fa82 /LICENSE-APACHE)
5
5
// and MIT
6
- // (https://github.com/rust-lang/rust/blob/949b98cab8a186b98bf87e64374b8d0848c55271 /LICENSE-MIT).
6
+ // (https://github.com/rust-lang/rust/blob/03d488b48af9f66b91e9400387f781b82411fa82 /LICENSE-MIT).
7
7
8
8
// Changes:
9
9
// + Fix compilation errors.
10
10
// + Remove all diagnostics (this is the main motivation for duplication).
11
- // + `ErrorGuaranteed` changed to `()` (private constructor).
11
+ // + Remove all `instrument`ation.
12
+ // + Replace `crate::*` imports with `prusti_rustc_interface::*` imports.
12
13
13
14
14
15
// This file contains various trait resolution methods used by codegen.
17
18
// general routines.
18
19
19
20
use log:: debug;
20
- use prusti_rustc_interface:: trait_selection:: infer:: { InferCtxt , TyCtxtInferExt } ;
21
+ use prusti_rustc_interface:: trait_selection:: infer:: { TyCtxtInferExt } ;
21
22
use prusti_rustc_interface:: trait_selection:: traits:: {
22
23
FulfillmentContext , ImplSource , Obligation , ObligationCause , SelectionContext , TraitEngine ,
23
24
Unimplemented ,
24
25
} ;
25
- use prusti_rustc_interface:: middle:: ty :: fold :: TypeFoldable ;
26
+ use prusti_rustc_interface:: middle:: traits :: CodegenObligationError ;
26
27
use prusti_rustc_interface:: middle:: ty:: { self , TyCtxt } ;
27
28
28
29
/// Attempts to resolve an obligation to an `ImplSource`. The result is
@@ -32,10 +33,10 @@ use prusti_rustc_interface::middle::ty::{self, TyCtxt};
32
33
/// obligations *could be* resolved if we wanted to.
33
34
///
34
35
/// This also expects that `trait_ref` is fully normalized.
35
- pub fn codegen_fulfill_obligation < ' tcx > (
36
+ pub ( super ) fn codegen_fulfill_obligation < ' tcx > (
36
37
tcx : TyCtxt < ' tcx > ,
37
38
( param_env, trait_ref) : ( ty:: ParamEnv < ' tcx > , ty:: PolyTraitRef < ' tcx > ) ,
38
- ) -> Result < & ' tcx ImplSource < ' tcx , ( ) > , ( ) > {
39
+ ) -> Result < & ' tcx ImplSource < ' tcx , ( ) > , CodegenObligationError > {
39
40
// Remove any references to regions; this helps improve caching.
40
41
let trait_ref = tcx. erase_regions ( trait_ref) ;
41
42
// We expect the input to be fully normalized.
@@ -57,37 +58,8 @@ pub fn codegen_fulfill_obligation<'tcx>(
57
58
58
59
let selection = match selcx. select ( & obligation) {
59
60
Ok ( Some ( selection) ) => selection,
60
- Ok ( None ) => {
61
- // // Ambiguity can happen when monomorphizing during trans
62
- // // expands to some humongo type that never occurred
63
- // // statically -- this humongo type can then overflow,
64
- // // leading to an ambiguous result. So report this as an
65
- // // overflow bug, since I believe this is the only case
66
- // // where ambiguity can result.
67
- // let reported = infcx.tcx.sess.delay_span_bug(
68
- // prusti_rustc_interface::span::DUMMY_SP,
69
- // &format!(
70
- // "encountered ambiguity selecting `{:?}` during codegen, presuming due to \
71
- // overflow or prior type error",
72
- // trait_ref
73
- // ),
74
- // );
75
- return Err ( ( ) ) ;
76
- }
77
- Err ( Unimplemented ) => {
78
- // // This can trigger when we probe for the source of a `'static` lifetime requirement
79
- // // on a trait object: `impl Foo for dyn Trait {}` has an implicit `'static` bound.
80
- // // This can also trigger when we have a global bound that is not actually satisfied,
81
- // // but was included during typeck due to the trivial_bounds feature.
82
- // let guar = infcx.tcx.sess.delay_span_bug(
83
- // prusti_rustc_interface::span::DUMMY_SP,
84
- // &format!(
85
- // "Encountered error `Unimplemented` selecting `{:?}` during codegen",
86
- // trait_ref
87
- // ),
88
- // );
89
- return Err ( ( ) ) ;
90
- }
61
+ Ok ( None ) => return Err ( CodegenObligationError :: Ambiguity ) ,
62
+ Err ( Unimplemented ) => return Err ( CodegenObligationError :: Unimplemented ) ,
91
63
Err ( e) => {
92
64
panic ! ( "Encountered error `{:?}` selecting `{:?}` during codegen" , e, trait_ref)
93
65
}
@@ -103,52 +75,23 @@ pub fn codegen_fulfill_obligation<'tcx>(
103
75
debug ! ( "fulfill_obligation: register_predicate_obligation {:?}" , predicate) ;
104
76
fulfill_cx. register_predicate_obligation ( & infcx, predicate) ;
105
77
} ) ;
106
- let impl_source = drain_fulfillment_cx_or_panic ( & infcx, & mut fulfill_cx, impl_source) ;
78
+
79
+ // In principle, we only need to do this so long as `impl_source`
80
+ // contains unbound type parameters. It could be a slight
81
+ // optimization to stop iterating early.
82
+ let errors = fulfill_cx. select_all_or_error ( & infcx) ;
83
+ if !errors. is_empty ( ) {
84
+ return Err ( CodegenObligationError :: FulfillmentError ) ;
85
+ }
86
+
87
+ let impl_source = infcx. resolve_vars_if_possible ( impl_source) ;
88
+ let impl_source = infcx. tcx . erase_regions ( impl_source) ;
107
89
108
90
// Opaque types may have gotten their hidden types constrained, but we can ignore them safely
109
91
// as they will get constrained elsewhere, too.
110
92
let _opaque_types = infcx. inner . borrow_mut ( ) . opaque_type_storage . take_opaque_types ( ) ;
111
93
112
- debug ! ( "Cache miss: {:?} => {:?}" , trait_ref , impl_source ) ;
94
+ debug ! ( "Cache miss: {trait_ref :?} => {impl_source :?}" ) ;
113
95
Ok ( & * tcx. arena . alloc ( impl_source) )
114
96
} )
115
97
}
116
-
117
- // # Global Cache
118
-
119
- /// Finishes processes any obligations that remain in the
120
- /// fulfillment context, and then returns the result with all type
121
- /// variables removed and regions erased. Because this is intended
122
- /// for use outside of type inference, if any errors occur,
123
- /// it will panic. It is used during normalization and other cases
124
- /// where processing the obligations in `fulfill_cx` may cause
125
- /// type inference variables that appear in `result` to be
126
- /// unified, and hence we need to process those obligations to get
127
- /// the complete picture of the type.
128
- fn drain_fulfillment_cx_or_panic < ' tcx , T > (
129
- infcx : & InferCtxt < ' _ , ' tcx > ,
130
- fulfill_cx : & mut FulfillmentContext < ' tcx > ,
131
- result : T ,
132
- ) -> T
133
- where
134
- T : TypeFoldable < ' tcx > ,
135
- {
136
- debug ! ( "drain_fulfillment_cx_or_panic()" ) ;
137
-
138
- // In principle, we only need to do this so long as `result`
139
- // contains unbound type parameters. It could be a slight
140
- // optimization to stop iterating early.
141
- let errors = fulfill_cx. select_all_or_error ( infcx) ;
142
- if !errors. is_empty ( ) {
143
- // infcx.tcx.sess.delay_span_bug(
144
- // prusti_rustc_interface::span::DUMMY_SP,
145
- // &format!(
146
- // "Encountered errors `{:?}` resolving bounds outside of type inference",
147
- // errors
148
- // ),
149
- // );
150
- }
151
-
152
- let result = infcx. resolve_vars_if_possible ( result) ;
153
- infcx. tcx . erase_regions ( result)
154
- }
0 commit comments