@@ -32,7 +32,6 @@ use rustc_data_structures::sync::Lrc;
32
32
use rustc_errors:: ErrorReported ;
33
33
use rustc_hir as hir;
34
34
use rustc_hir:: def_id:: DefId ;
35
- use rustc_hir:: Constness ;
36
35
use rustc_infer:: infer:: LateBoundRegionConversionTime ;
37
36
use rustc_middle:: dep_graph:: { DepKind , DepNodeIndex } ;
38
37
use rustc_middle:: mir:: abstract_const:: NotConstEvaluatable ;
@@ -130,8 +129,8 @@ pub struct SelectionContext<'cx, 'tcx> {
130
129
/// and a negative impl
131
130
allow_negative_impls : bool ,
132
131
133
- /// Do we only want const impls when we have a const trait predicate ?
134
- const_impls_required : bool ,
132
+ /// Are we in a const context that needs `~const` bounds to be const ?
133
+ is_in_const_context : bool ,
135
134
136
135
/// The mode that trait queries run in, which informs our error handling
137
136
/// policy. In essence, canonicalized queries need their errors propagated
@@ -224,7 +223,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
224
223
intercrate : false ,
225
224
intercrate_ambiguity_causes : None ,
226
225
allow_negative_impls : false ,
227
- const_impls_required : false ,
226
+ is_in_const_context : false ,
228
227
query_mode : TraitQueryMode :: Standard ,
229
228
}
230
229
}
@@ -236,7 +235,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
236
235
intercrate : true ,
237
236
intercrate_ambiguity_causes : None ,
238
237
allow_negative_impls : false ,
239
- const_impls_required : false ,
238
+ is_in_const_context : false ,
240
239
query_mode : TraitQueryMode :: Standard ,
241
240
}
242
241
}
@@ -252,7 +251,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
252
251
intercrate : false ,
253
252
intercrate_ambiguity_causes : None ,
254
253
allow_negative_impls,
255
- const_impls_required : false ,
254
+ is_in_const_context : false ,
256
255
query_mode : TraitQueryMode :: Standard ,
257
256
}
258
257
}
@@ -268,7 +267,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
268
267
intercrate : false ,
269
268
intercrate_ambiguity_causes : None ,
270
269
allow_negative_impls : false ,
271
- const_impls_required : false ,
270
+ is_in_const_context : false ,
272
271
query_mode,
273
272
}
274
273
}
@@ -283,7 +282,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
283
282
intercrate : false ,
284
283
intercrate_ambiguity_causes : None ,
285
284
allow_negative_impls : false ,
286
- const_impls_required : matches ! ( constness, hir:: Constness :: Const ) ,
285
+ is_in_const_context : matches ! ( constness, hir:: Constness :: Const ) ,
287
286
query_mode : TraitQueryMode :: Standard ,
288
287
}
289
288
}
@@ -316,14 +315,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
316
315
self . infcx . tcx
317
316
}
318
317
318
+ /// Returns `true` if the trait predicate is considerd `const` to this selection context.
319
+ pub fn is_trait_predicate_const ( & self , pred : ty:: TraitPredicate < ' _ > ) -> bool {
320
+ match pred. constness {
321
+ ty:: BoundConstness :: ConstIfConst if self . is_in_const_context => true ,
322
+ _ => false
323
+ }
324
+ }
325
+
319
326
/// Returns `true` if the predicate is considered `const` to
320
327
/// this selection context.
321
328
pub fn is_predicate_const ( & self , pred : ty:: Predicate < ' _ > ) -> bool {
322
329
match pred. kind ( ) . skip_binder ( ) {
323
- ty:: PredicateKind :: Trait ( ty:: TraitPredicate {
324
- constness : hir:: Constness :: Const ,
325
- ..
326
- } ) if self . const_impls_required => true ,
330
+ ty:: PredicateKind :: Trait ( pred) => self . is_trait_predicate_const ( pred) ,
327
331
_ => false ,
328
332
}
329
333
}
@@ -1074,8 +1078,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1074
1078
) -> SelectionResult < ' tcx , SelectionCandidate < ' tcx > > {
1075
1079
let tcx = self . tcx ( ) ;
1076
1080
// Respect const trait obligations
1077
- if self . const_impls_required {
1078
- if let hir:: Constness :: Const = obligation. predicate . skip_binder ( ) . constness {
1081
+ if self . is_trait_predicate_const ( obligation. predicate . skip_binder ( ) ) {
1079
1082
if Some ( obligation. predicate . skip_binder ( ) . trait_ref . def_id )
1080
1083
!= tcx. lang_items ( ) . sized_trait ( )
1081
1084
// const Sized bounds are skipped
@@ -1086,7 +1089,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1086
1089
if tcx. impl_constness ( def_id) == hir:: Constness :: Const => { }
1087
1090
// const param
1088
1091
ParamCandidate ( ty:: ConstnessAnd {
1089
- constness : hir :: Constness :: Const ,
1092
+ constness : ty :: BoundConstness :: ConstIfConst ,
1090
1093
..
1091
1094
} ) => { }
1092
1095
// auto trait impl
@@ -1100,7 +1103,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1100
1103
}
1101
1104
}
1102
1105
}
1103
- }
1104
1106
}
1105
1107
// Treat negative impls as unimplemented, and reservation impls as ambiguity.
1106
1108
if let ImplCandidate ( def_id) = candidate {
@@ -1495,7 +1497,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1495
1497
// probably best characterized as a "hack", since we might prefer to just do our
1496
1498
// best to *not* create essentially duplicate candidates in the first place.
1497
1499
other. value . bound_vars ( ) . len ( ) <= victim. value . bound_vars ( ) . len ( )
1498
- } else if other. value == victim. value && victim. constness == Constness :: NotConst {
1500
+ } else if other. value == victim. value && victim. constness == ty :: BoundConstness :: NotConst {
1499
1501
// Drop otherwise equivalent non-const candidates in favor of const candidates.
1500
1502
true
1501
1503
} else {
0 commit comments