@@ -2117,55 +2117,38 @@ pub fn type_needs_drop(cx: &ctxt, ty: t) -> bool {
2117
2117
// task can free them all at once later. Currently only things
2118
2118
// that only contain scalars and shared boxes can avoid unwind
2119
2119
// cleanups.
2120
- pub fn type_needs_unwind_cleanup ( cx : & ctxt , ty : t ) -> bool {
2121
- match cx. needs_unwind_cleanup_cache . borrow ( ) . find ( & ty) {
2122
- Some ( & result) => return result,
2123
- None => ( )
2124
- }
2125
-
2126
- let mut tycache = HashSet :: new ( ) ;
2127
- let needs_unwind_cleanup =
2128
- type_needs_unwind_cleanup_ ( cx, ty, & mut tycache) ;
2129
- cx. needs_unwind_cleanup_cache . borrow_mut ( ) . insert ( ty, needs_unwind_cleanup) ;
2130
- needs_unwind_cleanup
2131
- }
2132
-
2133
- fn type_needs_unwind_cleanup_ ( cx : & ctxt , ty : t ,
2134
- tycache : & mut HashSet < t > ) -> bool {
2135
-
2120
+ memoize ! ( cx. needs_unwind_cleanup_cache, ty,
2121
+ fn type_needs_unwind_cleanup_( cx: & ctxt, ty: t, tycache: & mut HashSet <t>) -> bool {
2136
2122
// Prevent infinite recursion
2137
2123
if !tycache. insert( ty) {
2138
2124
return false ;
2139
2125
}
2140
2126
2141
2127
let mut needs_unwind_cleanup = false ;
2142
2128
maybe_walk_ty( ty, |ty| {
2143
- let result = match get ( ty) . sty {
2144
- ty_nil | ty_bot | ty_bool | ty_int( _) | ty_uint( _) | ty_float( _) |
2145
- ty_tup( _) | ty_ptr( _) => {
2146
- true
2147
- }
2148
- ty_enum( did, ref substs) => {
2149
- for v in ( * enum_variants ( cx, did) ) . iter ( ) {
2150
- for aty in v. args . iter ( ) {
2151
- let t = aty. subst ( cx, substs) ;
2152
- needs_unwind_cleanup |=
2153
- type_needs_unwind_cleanup_ ( cx, t, tycache) ;
2154
- }
2155
- }
2156
- !needs_unwind_cleanup
2157
- }
2158
- _ => {
2159
- needs_unwind_cleanup = true ;
2160
- false
2161
- }
2162
- } ;
2129
+ needs_unwind_cleanup |= match get( ty) . sty {
2130
+ ty_nil | ty_bot | ty_bool | ty_int( _) | ty_uint( _) |
2131
+ ty_float( _) | ty_tup( _) | ty_ptr( _) => false ,
2132
+
2133
+ ty_enum( did, ref substs) =>
2134
+ enum_variants( cx, did) . iter( ) . any( |v|
2135
+ v. args. iter( ) . any( |aty| {
2136
+ let t = aty. subst( cx, substs) ;
2137
+ type_needs_unwind_cleanup_( cx, t, tycache)
2138
+ } )
2139
+ ) ,
2163
2140
2164
- result
2141
+ _ => true
2142
+ } ;
2143
+ !needs_unwind_cleanup
2165
2144
} ) ;
2166
-
2167
2145
needs_unwind_cleanup
2168
2146
}
2147
+ )
2148
+
2149
+ pub fn type_needs_unwind_cleanup ( cx : & ctxt , ty : t ) -> bool {
2150
+ type_needs_unwind_cleanup_ ( cx, ty, & mut HashSet :: new ( ) )
2151
+ }
2169
2152
2170
2153
/**
2171
2154
* Type contents is how the type checker reasons about kinds.
@@ -2179,6 +2162,7 @@ fn type_needs_unwind_cleanup_(cx: &ctxt, ty: t,
2179
2162
* easier for me (nmatsakis) to think about what is contained within
2180
2163
* a type than to think about what is *not* contained within a type.
2181
2164
*/
2165
+ #[ deriving( Clone ) ]
2182
2166
pub struct TypeContents {
2183
2167
pub bits : u64
2184
2168
}
@@ -2358,19 +2342,9 @@ pub fn type_interior_is_unsafe(cx: &ctxt, t: ty::t) -> bool {
2358
2342
type_contents ( cx, t) . interior_unsafe ( )
2359
2343
}
2360
2344
2345
+ memoize ! ( cx. tc_cache, type_id( ty) ,
2361
2346
pub fn type_contents( cx: & ctxt, ty: t) -> TypeContents {
2362
- let ty_id = type_id ( ty) ;
2363
-
2364
- match cx. tc_cache . borrow ( ) . find ( & ty_id) {
2365
- Some ( tc) => { return * tc; }
2366
- None => { }
2367
- }
2368
-
2369
- let mut cache = HashMap :: new ( ) ;
2370
- let result = tc_ty ( cx, ty, & mut cache) ;
2371
-
2372
- cx. tc_cache . borrow_mut ( ) . insert ( ty_id, result) ;
2373
- return result;
2347
+ return tc_ty( cx, ty, & mut HashMap :: new( ) ) ;
2374
2348
2375
2349
fn tc_ty( cx: & ctxt,
2376
2350
ty: t,
@@ -2685,6 +2659,7 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
2685
2659
}
2686
2660
}
2687
2661
}
2662
+ )
2688
2663
2689
2664
pub fn type_moves_by_default ( cx : & ctxt , ty : t ) -> bool {
2690
2665
type_contents ( cx, ty) . moves_by_default ( cx)
@@ -4033,28 +4008,23 @@ pub fn impl_or_trait_item(cx: &ctxt, id: ast::DefId) -> ImplOrTraitItem {
4033
4008
4034
4009
/// Returns true if the given ID refers to an associated type and false if it
4035
4010
/// refers to anything else.
4011
+ memoize ! ( cx. associated_types, id,
4036
4012
pub fn is_associated_type( cx: & ctxt, id: ast:: DefId ) -> bool {
4037
- let result = match cx. associated_types . borrow_mut ( ) . find ( & id) {
4038
- Some ( result) => return * result,
4039
- None if id. krate == ast:: LOCAL_CRATE => {
4040
- match cx. impl_or_trait_items . borrow ( ) . find ( & id) {
4041
- Some ( ref item) => {
4042
- match * * item {
4043
- TypeTraitItem ( _) => true ,
4044
- MethodTraitItem ( _) => false ,
4045
- }
4013
+ if id. krate == ast:: LOCAL_CRATE {
4014
+ match cx. impl_or_trait_items. borrow( ) . find( & id) {
4015
+ Some ( ref item) => {
4016
+ match * * item {
4017
+ TypeTraitItem ( _) => true ,
4018
+ MethodTraitItem ( _) => false ,
4046
4019
}
4047
- None => false ,
4048
4020
}
4021
+ None => false ,
4049
4022
}
4050
- None => {
4051
- csearch:: is_associated_type ( & cx. sess . cstore , id)
4052
- }
4053
- } ;
4054
-
4055
- cx. associated_types . borrow_mut ( ) . insert ( id, result) ;
4056
- result
4023
+ } else {
4024
+ csearch:: is_associated_type( & cx. sess. cstore, id)
4025
+ }
4057
4026
}
4027
+ )
4058
4028
4059
4029
/// Returns the parameter index that the given associated type corresponds to.
4060
4030
pub fn associated_type_parameter_index ( cx : & ctxt ,
@@ -4110,13 +4080,9 @@ pub fn trait_item_def_ids(cx: &ctxt, id: ast::DefId)
4110
4080
} )
4111
4081
}
4112
4082
4083
+ memoize ! ( cx. impl_trait_cache, id,
4113
4084
pub fn impl_trait_ref( cx: & ctxt, id: ast:: DefId ) -> Option <Rc <TraitRef >> {
4114
- match cx. impl_trait_cache . borrow ( ) . find ( & id) {
4115
- Some ( ret) => { return ret. clone ( ) ; }
4116
- None => { }
4117
- }
4118
-
4119
- let ret = if id. krate == ast:: LOCAL_CRATE {
4085
+ if id. krate == ast:: LOCAL_CRATE {
4120
4086
debug!( "(impl_trait_ref) searching for trait impl {:?}" , id) ;
4121
4087
match cx. map. find( id. node) {
4122
4088
Some ( ast_map:: NodeItem ( item) ) => {
@@ -4136,11 +4102,9 @@ pub fn impl_trait_ref(cx: &ctxt, id: ast::DefId) -> Option<Rc<TraitRef>> {
4136
4102
}
4137
4103
} else {
4138
4104
csearch:: get_impl_trait( cx, id)
4139
- } ;
4140
-
4141
- cx. impl_trait_cache . borrow_mut ( ) . insert ( id, ret. clone ( ) ) ;
4142
- ret
4105
+ }
4143
4106
}
4107
+ )
4144
4108
4145
4109
pub fn trait_ref_to_def_id ( tcx : & ctxt , tr : & ast:: TraitRef ) -> ast:: DefId {
4146
4110
let def = * tcx. def_map . borrow ( )
@@ -4324,13 +4288,9 @@ pub fn type_is_empty(cx: &ctxt, t: t) -> bool {
4324
4288
}
4325
4289
}
4326
4290
4291
+ memoize ! ( cx. enum_var_cache, id,
4327
4292
pub fn enum_variants( cx: & ctxt, id: ast:: DefId ) -> Rc <Vec <Rc <VariantInfo >>> {
4328
- match cx. enum_var_cache . borrow ( ) . find ( & id) {
4329
- Some ( variants) => return variants. clone ( ) ,
4330
- _ => { /* fallthrough */ }
4331
- }
4332
-
4333
- let result = if ast:: LOCAL_CRATE != id. krate {
4293
+ if ast:: LOCAL_CRATE != id. krate {
4334
4294
Rc :: new( csearch:: get_enum_variants( cx, id) )
4335
4295
} else {
4336
4296
/*
@@ -4385,12 +4345,9 @@ pub fn enum_variants(cx: &ctxt, id: ast::DefId) -> Rc<Vec<Rc<VariantInfo>>> {
4385
4345
}
4386
4346
_ => cx. sess. bug( "enum_variants: id not bound to an enum" )
4387
4347
}
4388
- } ;
4389
-
4390
- cx. enum_var_cache . borrow_mut ( ) . insert ( id, result. clone ( ) ) ;
4391
- result
4348
+ }
4392
4349
}
4393
-
4350
+ )
4394
4351
4395
4352
// Returns information about the enum variant with the given ID:
4396
4353
pub fn enum_variant_with_id ( cx : & ctxt ,
@@ -4415,22 +4372,12 @@ pub fn lookup_item_type(cx: &ctxt,
4415
4372
}
4416
4373
4417
4374
/// Given the did of a trait, returns its canonical trait ref.
4375
+ memoize ! ( cx. trait_defs, did,
4418
4376
pub fn lookup_trait_def( cx: & ctxt, did: ast:: DefId ) -> Rc <ty:: TraitDef > {
4419
- let mut trait_defs = cx. trait_defs . borrow_mut ( ) ;
4420
- match trait_defs. find_copy ( & did) {
4421
- Some ( trait_def) => {
4422
- // The item is in this crate. The caller should have added it to the
4423
- // type cache already
4424
- trait_def
4425
- }
4426
- None => {
4427
- assert ! ( did. krate != ast:: LOCAL_CRATE ) ;
4428
- let trait_def = Rc :: new ( csearch:: get_trait_def ( cx, did) ) ;
4429
- trait_defs. insert ( did, trait_def. clone ( ) ) ;
4430
- trait_def
4431
- }
4432
- }
4377
+ assert!( did. krate != ast:: LOCAL_CRATE ) ;
4378
+ Rc :: new( csearch:: get_trait_def( cx, did) )
4433
4379
}
4380
+ )
4434
4381
4435
4382
/// Given a reference to a trait, returns the bounds declared on the
4436
4383
/// trait, with appropriate substitutions applied.
@@ -4489,13 +4436,9 @@ pub fn lookup_simd(tcx: &ctxt, did: DefId) -> bool {
4489
4436
}
4490
4437
4491
4438
/// Obtain the representation annotation for a struct definition.
4439
+ memoize ! ( tcx. repr_hint_cache, did,
4492
4440
pub fn lookup_repr_hints( tcx: & ctxt, did: DefId ) -> Rc <Vec <attr:: ReprAttr >> {
4493
- match tcx. repr_hint_cache . borrow ( ) . find ( & did) {
4494
- None => { }
4495
- Some ( ref hints) => return ( * hints) . clone ( ) ,
4496
- }
4497
-
4498
- let acc = if did. krate == LOCAL_CRATE {
4441
+ Rc :: new( if did. krate == LOCAL_CRATE {
4499
4442
let mut acc = Vec :: new( ) ;
4500
4443
ty:: each_attr( tcx, did, |meta| {
4501
4444
acc. extend( attr:: find_repr_attrs( tcx. sess. diagnostic( ) ,
@@ -4505,12 +4448,9 @@ pub fn lookup_repr_hints(tcx: &ctxt, did: DefId) -> Rc<Vec<attr::ReprAttr>> {
4505
4448
acc
4506
4449
} else {
4507
4450
csearch:: get_repr_attrs( & tcx. sess. cstore, did)
4508
- } ;
4509
-
4510
- let acc = Rc :: new ( acc) ;
4511
- tcx. repr_hint_cache . borrow_mut ( ) . insert ( did, acc. clone ( ) ) ;
4512
- acc
4451
+ } )
4513
4452
}
4453
+ )
4514
4454
4515
4455
// Look up a field ID, whether or not it's local
4516
4456
// Takes a list of type substs in case the struct is generic
0 commit comments