@@ -130,6 +130,9 @@ pub struct SelectionContext<'cx, 'tcx> {
130130 /// and a negative impl
131131 allow_negative_impls : bool ,
132132
133+ /// Do we only want const impls when we have a const trait predicate?
134+ const_impls_required : bool ,
135+
133136 /// The mode that trait queries run in, which informs our error handling
134137 /// policy. In essence, canonicalized queries need their errors propagated
135138 /// rather than immediately reported because we do not have accurate spans.
@@ -221,6 +224,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
221224 intercrate : false ,
222225 intercrate_ambiguity_causes : None ,
223226 allow_negative_impls : false ,
227+ const_impls_required : false ,
224228 query_mode : TraitQueryMode :: Standard ,
225229 }
226230 }
@@ -232,6 +236,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
232236 intercrate : true ,
233237 intercrate_ambiguity_causes : None ,
234238 allow_negative_impls : false ,
239+ const_impls_required : false ,
235240 query_mode : TraitQueryMode :: Standard ,
236241 }
237242 }
@@ -247,6 +252,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
247252 intercrate : false ,
248253 intercrate_ambiguity_causes : None ,
249254 allow_negative_impls,
255+ const_impls_required : false ,
250256 query_mode : TraitQueryMode :: Standard ,
251257 }
252258 }
@@ -262,10 +268,26 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
262268 intercrate : false ,
263269 intercrate_ambiguity_causes : None ,
264270 allow_negative_impls : false ,
271+ const_impls_required : false ,
265272 query_mode,
266273 }
267274 }
268275
276+ pub fn with_constness (
277+ infcx : & ' cx InferCtxt < ' cx , ' tcx > ,
278+ constness : hir:: Constness ,
279+ ) -> SelectionContext < ' cx , ' tcx > {
280+ SelectionContext {
281+ infcx,
282+ freshener : infcx. freshener_keep_static ( ) ,
283+ intercrate : false ,
284+ intercrate_ambiguity_causes : None ,
285+ allow_negative_impls : false ,
286+ const_impls_required : matches ! ( constness, hir:: Constness :: Const ) ,
287+ query_mode : TraitQueryMode :: Standard ,
288+ }
289+ }
290+
269291 /// Enables tracking of intercrate ambiguity causes. These are
270292 /// used in coherence to give improved diagnostics. We don't do
271293 /// this until we detect a coherence error because it can lead to
@@ -1024,26 +1046,29 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
10241046 ) -> SelectionResult < ' tcx , SelectionCandidate < ' tcx > > {
10251047 let tcx = self . tcx ( ) ;
10261048 // Respect const trait obligations
1027- if let hir:: Constness :: Const = obligation. predicate . skip_binder ( ) . constness {
1028- if Some ( obligation. predicate . skip_binder ( ) . trait_ref . def_id )
1029- != tcx. lang_items ( ) . sized_trait ( )
1030- // const Sized bounds are skipped
1031- {
1032- match candidate {
1033- // const impl
1034- ImplCandidate ( def_id)
1035- if tcx. impl_constness ( def_id) == hir:: Constness :: Const => { }
1036- // const param
1037- ParamCandidate ( ty:: ConstnessAnd {
1038- constness : hir:: Constness :: Const , ..
1039- } ) => { }
1040- // auto trait impl
1041- AutoImplCandidate ( ..) => { }
1042- // FIXME check if this is right, but this would allow Sized impls
1043- // BuiltinCandidate { .. } => {}
1044- _ => {
1045- // reject all other types of candidates
1046- return Err ( Unimplemented ) ;
1049+ if self . const_impls_required {
1050+ if let hir:: Constness :: Const = obligation. predicate . skip_binder ( ) . constness {
1051+ if Some ( obligation. predicate . skip_binder ( ) . trait_ref . def_id )
1052+ != tcx. lang_items ( ) . sized_trait ( )
1053+ // const Sized bounds are skipped
1054+ {
1055+ match candidate {
1056+ // const impl
1057+ ImplCandidate ( def_id)
1058+ if tcx. impl_constness ( def_id) == hir:: Constness :: Const => { }
1059+ // const param
1060+ ParamCandidate ( ty:: ConstnessAnd {
1061+ constness : hir:: Constness :: Const ,
1062+ ..
1063+ } ) => { }
1064+ // auto trait impl
1065+ AutoImplCandidate ( ..) => { }
1066+ // FIXME check if this is right, but this would allow Sized impls
1067+ // BuiltinCandidate { .. } => {}
1068+ _ => {
1069+ // reject all other types of candidates
1070+ return Err ( Unimplemented ) ;
1071+ }
10471072 }
10481073 }
10491074 }
0 commit comments