@@ -20,9 +20,11 @@ use ty::{Disr, ParameterEnvironment};
2020use ty:: fold:: TypeVisitor ;
2121use ty:: layout:: { Layout , LayoutError } ;
2222use ty:: TypeVariants :: * ;
23+ use util:: nodemap:: FnvHashMap ;
2324
2425use rustc_const_math:: { ConstInt , ConstIsize , ConstUsize } ;
2526
27+ use std:: cell:: RefCell ;
2628use std:: cmp;
2729use std:: hash:: { Hash , Hasher } ;
2830use std:: collections:: hash_map:: DefaultHasher ;
@@ -579,11 +581,24 @@ impl<'a, 'gcx, 'tcx, H: Hasher> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tc
579581impl < ' a , ' tcx > ty:: TyS < ' tcx > {
580582 fn impls_bound ( & ' tcx self , tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
581583 param_env : & ParameterEnvironment < ' tcx > ,
582- bound : ty:: BuiltinBound , span : Span ) -> bool
584+ bound : ty:: BuiltinBound ,
585+ cache : & RefCell < FnvHashMap < Ty < ' tcx > , bool > > ,
586+ span : Span ) -> bool
583587 {
584- tcx. infer_ctxt ( None , Some ( param_env. clone ( ) ) , Reveal :: ExactMatch ) . enter ( |infcx| {
585- traits:: type_known_to_meet_builtin_bound ( & infcx, self , bound, span)
586- } )
588+ if self . has_param_types ( ) || self . has_self_ty ( ) {
589+ if let Some ( result) = cache. borrow ( ) . get ( self ) {
590+ return * result;
591+ }
592+ }
593+ let result =
594+ tcx. infer_ctxt ( None , Some ( param_env. clone ( ) ) , Reveal :: ExactMatch )
595+ . enter ( |infcx| {
596+ traits:: type_known_to_meet_builtin_bound ( & infcx, self , bound, span)
597+ } ) ;
598+ if self . has_param_types ( ) || self . has_self_ty ( ) {
599+ cache. borrow_mut ( ) . insert ( self , result) ;
600+ }
601+ return result;
587602 }
588603
589604 // FIXME (@jroesch): I made this public to use it, not sure if should be private
@@ -610,7 +625,9 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
610625 TyArray ( ..) | TySlice ( ..) | TyTrait ( ..) | TyTuple ( ..) |
611626 TyClosure ( ..) | TyAdt ( ..) | TyAnon ( ..) |
612627 TyProjection ( ..) | TyParam ( ..) | TyInfer ( ..) | TyError => None
613- } . unwrap_or_else ( || !self . impls_bound ( tcx, param_env, ty:: BoundCopy , span) ) ;
628+ } . unwrap_or_else ( || {
629+ !self . impls_bound ( tcx, param_env, ty:: BoundCopy , & param_env. is_copy_cache , span)
630+ } ) ;
614631
615632 if !self . has_param_types ( ) && !self . has_self_ty ( ) {
616633 self . flags . set ( self . flags . get ( ) | if result {
@@ -650,7 +667,9 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
650667
651668 TyAdt ( ..) | TyProjection ( ..) | TyParam ( ..) |
652669 TyInfer ( ..) | TyAnon ( ..) | TyError => None
653- } . unwrap_or_else ( || self . impls_bound ( tcx, param_env, ty:: BoundSized , span) ) ;
670+ } . unwrap_or_else ( || {
671+ self . impls_bound ( tcx, param_env, ty:: BoundSized , & param_env. is_sized_cache , span)
672+ } ) ;
654673
655674 if !self . has_param_types ( ) && !self . has_self_ty ( ) {
656675 self . flags . set ( self . flags . get ( ) | if result {
0 commit comments