@@ -44,6 +44,7 @@ pub use self::object_safety::object_safety_violations;
44
44
pub use self :: object_safety:: ObjectSafetyViolation ;
45
45
pub use self :: object_safety:: MethodViolationCode ;
46
46
pub use self :: object_safety:: is_vtable_safe_method;
47
+ pub use self :: select:: EvaluationCache ;
47
48
pub use self :: select:: SelectionContext ;
48
49
pub use self :: select:: SelectionCache ;
49
50
pub use self :: select:: { MethodMatchResult , MethodMatched , MethodAmbiguous , MethodDidNotMatch } ;
@@ -339,32 +340,53 @@ pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
339
340
ty,
340
341
bound) ;
341
342
342
- let mut fulfill_cx = FulfillmentContext :: new ( false ) ;
343
-
344
- // We can use a dummy node-id here because we won't pay any mind
345
- // to region obligations that arise (there shouldn't really be any
346
- // anyhow).
347
343
let cause = ObligationCause :: misc ( span, ast:: DUMMY_NODE_ID ) ;
348
-
349
- fulfill_cx. register_builtin_bound ( infcx, ty, bound, cause) ;
350
-
351
- // Note: we only assume something is `Copy` if we can
352
- // *definitively* show that it implements `Copy`. Otherwise,
353
- // assume it is move; linear is always ok.
354
- match fulfill_cx. select_all_or_error ( infcx) {
355
- Ok ( ( ) ) => {
356
- debug ! ( "type_known_to_meet_builtin_bound: ty={:?} bound={:?} success" ,
357
- ty,
358
- bound) ;
359
- true
360
- }
361
- Err ( e) => {
362
- debug ! ( "type_known_to_meet_builtin_bound: ty={:?} bound={:?} errors={:?}" ,
363
- ty,
364
- bound,
365
- e) ;
366
- false
344
+ let obligation =
345
+ util:: predicate_for_builtin_bound ( infcx. tcx , cause, bound, 0 , ty) ;
346
+ let obligation = match obligation {
347
+ Ok ( o) => o,
348
+ Err ( ..) => return false
349
+ } ;
350
+ let result = SelectionContext :: new ( infcx)
351
+ . evaluate_obligation_conservatively ( & obligation) ;
352
+ debug ! ( "type_known_to_meet_builtin_bound: ty={:?} bound={:?} => {:?}" ,
353
+ ty, bound, result) ;
354
+
355
+ if result && ( ty. has_infer_types ( ) || ty. has_closure_types ( ) ) {
356
+ // Because of inference "guessing", selection can sometimes claim
357
+ // to succeed while the success requires a guess. To ensure
358
+ // this function's result remains infallible, we must confirm
359
+ // that guess. While imperfect, I believe this is sound.
360
+
361
+ let mut fulfill_cx = FulfillmentContext :: new ( false ) ;
362
+
363
+ // We can use a dummy node-id here because we won't pay any mind
364
+ // to region obligations that arise (there shouldn't really be any
365
+ // anyhow).
366
+ let cause = ObligationCause :: misc ( span, ast:: DUMMY_NODE_ID ) ;
367
+
368
+ fulfill_cx. register_builtin_bound ( infcx, ty, bound, cause) ;
369
+
370
+ // Note: we only assume something is `Copy` if we can
371
+ // *definitively* show that it implements `Copy`. Otherwise,
372
+ // assume it is move; linear is always ok.
373
+ match fulfill_cx. select_all_or_error ( infcx) {
374
+ Ok ( ( ) ) => {
375
+ debug ! ( "type_known_to_meet_builtin_bound: ty={:?} bound={:?} success" ,
376
+ ty,
377
+ bound) ;
378
+ true
379
+ }
380
+ Err ( e) => {
381
+ debug ! ( "type_known_to_meet_builtin_bound: ty={:?} bound={:?} errors={:?}" ,
382
+ ty,
383
+ bound,
384
+ e) ;
385
+ false
386
+ }
367
387
}
388
+ } else {
389
+ result
368
390
}
369
391
}
370
392
0 commit comments