@@ -9,7 +9,7 @@ use rustc_hir::HirIdMap;
9
9
use rustc_infer:: infer;
10
10
use rustc_infer:: infer:: { InferCtxt , InferOk , TyCtxtInferExt } ;
11
11
use rustc_middle:: ty:: fold:: TypeFoldable ;
12
- use rustc_middle:: ty:: { self , OpaqueTypeKey , Ty , TyCtxt } ;
12
+ use rustc_middle:: ty:: { self , OpaqueTypeKey , ToPredicate , Ty , TyCtxt } ;
13
13
use rustc_span:: { self , Span } ;
14
14
use rustc_trait_selection:: infer:: InferCtxtExt as _;
15
15
use rustc_trait_selection:: opaque_types:: OpaqueTypeDecl ;
@@ -68,6 +68,9 @@ pub struct Inherited<'a, 'tcx> {
68
68
/// opaque type.
69
69
pub ( super ) opaque_types_vars : RefCell < FxHashMap < Ty < ' tcx > , Ty < ' tcx > > > ,
70
70
71
+ /// Reports whether this is in a const context.
72
+ pub ( super ) constness : hir:: Constness ,
73
+
71
74
pub ( super ) body_id : Option < hir:: BodyId > ,
72
75
}
73
76
@@ -109,6 +112,12 @@ impl<'tcx> InheritedBuilder<'tcx> {
109
112
110
113
impl Inherited < ' a , ' tcx > {
111
114
pub ( super ) fn new ( infcx : InferCtxt < ' a , ' tcx > , def_id : LocalDefId ) -> Self {
115
+ let tcx = infcx. tcx ;
116
+ let item_id = tcx. hir ( ) . local_def_id_to_hir_id ( def_id) ;
117
+ Self :: with_constness ( infcx, def_id, tcx. hir ( ) . get ( item_id) . constness ( ) )
118
+ }
119
+
120
+ pub ( super ) fn with_constness ( infcx : InferCtxt < ' a , ' tcx > , def_id : LocalDefId , constness : hir:: Constness ) -> Self {
112
121
let tcx = infcx. tcx ;
113
122
let item_id = tcx. hir ( ) . local_def_id_to_hir_id ( def_id) ;
114
123
let body_id = tcx. hir ( ) . maybe_body_owned_by ( item_id) ;
@@ -126,12 +135,29 @@ impl Inherited<'a, 'tcx> {
126
135
deferred_generator_interiors : RefCell :: new ( Vec :: new ( ) ) ,
127
136
opaque_types : RefCell :: new ( Default :: default ( ) ) ,
128
137
opaque_types_vars : RefCell :: new ( Default :: default ( ) ) ,
138
+ constness,
129
139
body_id,
130
140
}
131
141
}
132
142
133
- pub ( super ) fn register_predicate ( & self , obligation : traits:: PredicateObligation < ' tcx > ) {
143
+ #[ instrument( level = "debug" , skip( self ) ) ]
144
+ fn transform_predicate ( & self , p : & mut ty:: Predicate < ' tcx > ) {
145
+ // Don't transform non-const bounds into const bounds,
146
+ // but transform const bounds to non-const when we are
147
+ // not in a const context.
148
+ if let hir:: Constness :: NotConst = self . constness {
149
+ let kind = p. kind ( ) ;
150
+ if let ty:: PredicateKind :: Trait ( pred) = kind. as_ref ( ) . skip_binder ( ) {
151
+ let mut pred = * pred;
152
+ pred. constness = hir:: Constness :: NotConst ;
153
+ * p = kind. rebind ( ty:: PredicateKind :: Trait ( pred) ) . to_predicate ( self . tcx ) ;
154
+ }
155
+ }
156
+ }
157
+
158
+ pub ( super ) fn register_predicate ( & self , mut obligation : traits:: PredicateObligation < ' tcx > ) {
134
159
debug ! ( "register_predicate({:?})" , obligation) ;
160
+ self . transform_predicate ( & mut obligation. predicate ) ;
135
161
if obligation. has_escaping_bound_vars ( ) {
136
162
span_bug ! ( obligation. cause. span, "escaping bound vars in predicate {:?}" , obligation) ;
137
163
}
0 commit comments