@@ -168,7 +168,9 @@ fn satisfied_from_param_env<'tcx>(
168168 param_env : ty:: ParamEnv < ' tcx > ,
169169
170170 infcx : & ' a InferCtxt < ' tcx > ,
171+ single_match : Option < Result < ty:: Const < ' tcx > , ( ) > > ,
171172 }
173+
172174 impl < ' a , ' tcx > TypeVisitor < ' tcx > for Visitor < ' a , ' tcx > {
173175 type BreakTy = ( ) ;
174176 fn visit_const ( & mut self , c : ty:: Const < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
@@ -179,7 +181,9 @@ fn satisfied_from_param_env<'tcx>(
179181 && ocx. eq ( & ObligationCause :: dummy ( ) , self . param_env , c, self . ct ) . is_ok ( )
180182 && ocx. select_all_or_error ( ) . is_empty ( )
181183 } ) {
182- ControlFlow :: BREAK
184+ self . single_match =
185+ if self . single_match . is_none ( ) { Some ( Ok ( c) ) } else { Some ( Err ( ( ) ) ) } ;
186+ ControlFlow :: CONTINUE
183187 } else if let ty:: ConstKind :: Expr ( e) = c. kind ( ) {
184188 e. visit_with ( self )
185189 } else {
@@ -195,22 +199,37 @@ fn satisfied_from_param_env<'tcx>(
195199 }
196200 }
197201
202+ let mut single_match: Option < Result < ty:: Const < ' tcx > , ( ) > > = None ;
203+
198204 for pred in param_env. caller_bounds ( ) {
199205 match pred. kind ( ) . skip_binder ( ) {
200206 ty:: PredicateKind :: ConstEvaluatable ( ce) => {
201207 let b_ct = tcx. expand_abstract_consts ( ce) ;
202- let mut v = Visitor { ct, infcx, param_env } ;
203- let result = b_ct. visit_with ( & mut v) ;
204-
205- if let ControlFlow :: Break ( ( ) ) = result {
206- debug ! ( "is_const_evaluatable: yes" ) ;
207- return true ;
208+ let mut v = Visitor { ct, infcx, param_env, single_match : None } ;
209+ let _ = b_ct. visit_with ( & mut v) ;
210+ if let Some ( inner) = v. single_match {
211+ single_match = if single_match. is_none ( ) { Some ( inner) } else { Some ( Err ( ( ) ) ) } ;
208212 }
209213 }
210214 _ => { } // don't care
211215 }
212216 }
213217
218+ if let Some ( c) = single_match {
219+ if let Ok ( c) = c {
220+ let is_ok = infcx
221+ . commit_if_ok ( |_| {
222+ let ocx = ObligationCtxt :: new_in_snapshot ( infcx) ;
223+ assert ! ( ocx. eq( & ObligationCause :: dummy( ) , param_env, c. ty( ) , ct. ty( ) ) . is_ok( ) ) ;
224+ assert ! ( ocx. eq( & ObligationCause :: dummy( ) , param_env, c, ct) . is_ok( ) ) ;
225+ if ocx. select_all_or_error ( ) . is_empty ( ) { Ok ( ( ) ) } else { Err ( ( ) ) }
226+ } )
227+ . is_ok ( ) ;
228+ assert ! ( is_ok) ;
229+ }
230+ return true ;
231+ }
232+
214233 debug ! ( "is_const_evaluatable: no" ) ;
215234 false
216235}
0 commit comments