@@ -2063,20 +2063,8 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
2063
2063
TC_MANAGED + statically_sized ( nonowned ( tc_mt ( cx, mt, cache) ) )
2064
2064
}
2065
2065
2066
- ty_trait( _, _, UniqTraitStore , _, _bounds) => {
2067
- // FIXME(#3569): Make this conditional on the trait's bounds.
2068
- TC_NONCOPY_TRAIT + TC_OWNED_POINTER
2069
- }
2070
-
2071
- ty_trait( _, _, BoxTraitStore , mutbl, _bounds) => {
2072
- match mutbl {
2073
- ast:: m_mutbl => TC_MANAGED + TC_MUTABLE ,
2074
- _ => TC_MANAGED
2075
- }
2076
- }
2077
-
2078
- ty_trait( _, _, RegionTraitStore ( r) , mutbl, _bounds) => {
2079
- borrowed_contents ( r, mutbl)
2066
+ ty_trait( _, _, store, mutbl, bounds) => {
2067
+ trait_contents ( store, mutbl, bounds)
2080
2068
}
2081
2069
2082
2070
ty_rptr( r, mt) => {
@@ -2261,23 +2249,59 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
2261
2249
}
2262
2250
2263
2251
fn closure_contents ( cty : & ClosureTy ) -> TypeContents {
2252
+ // Closure contents are just like trait contents, but with potentially
2253
+ // even more stuff.
2264
2254
let st = match cty. sigil {
2265
- ast:: BorrowedSigil => TC_BORROWED_POINTER ,
2266
- ast :: ManagedSigil => TC_MANAGED ,
2267
- ast :: OwnedSigil => if cty . bounds . contains_elem ( BoundCopy ) {
2268
- TC_OWNED_POINTER
2269
- } else {
2270
- TC_OWNED_POINTER + TC_NONCOPY_TRAIT
2271
- }
2255
+ ast:: BorrowedSigil =>
2256
+ trait_contents ( RegionTraitStore ( cty . region ) , m_imm , cty . bounds )
2257
+ + TC_BORROWED_POINTER , // might be an env packet even if static
2258
+ ast :: ManagedSigil =>
2259
+ trait_contents ( BoxTraitStore , m_imm , cty . bounds ) ,
2260
+ ast :: OwnedSigil =>
2261
+ trait_contents ( UniqTraitStore , m_imm , cty . bounds ) ,
2272
2262
} ;
2263
+ // FIXME(#3569): This borrowed_contents call should be taken care of in
2264
+ // trait_contents, after ~Traits and @Traits can have region bounds too.
2265
+ // This one here is redundant for &fns but important for ~fns and @fns.
2273
2266
let rt = borrowed_contents ( cty. region , m_imm) ;
2267
+ // This also prohibits "@once fn" from being copied, which allows it to
2268
+ // be called. Neither way really makes much sense.
2274
2269
let ot = match cty. onceness {
2275
2270
ast:: Once => TC_ONCE_CLOSURE ,
2276
2271
ast:: Many => TC_NONE
2277
2272
} ;
2278
2273
st + rt + ot
2279
2274
}
2280
2275
2276
+ fn trait_contents ( store : TraitStore , mutbl : ast:: mutability ,
2277
+ bounds : BuiltinBounds ) -> TypeContents {
2278
+ let st = match store {
2279
+ UniqTraitStore => TC_OWNED_POINTER ,
2280
+ BoxTraitStore => TC_MANAGED ,
2281
+ RegionTraitStore ( r) => borrowed_contents ( r, mutbl) ,
2282
+ } ;
2283
+ let mt = match mutbl { ast:: m_mutbl => TC_MUTABLE , _ => TC_NONE } ;
2284
+ // We get additional "special type contents" for each bound that *isn't*
2285
+ // on the trait. So iterate over the inverse of the bounds that are set.
2286
+ // This is like with typarams below, but less "pessimistic" and also
2287
+ // dependent on the trait store.
2288
+ let mut bt = TC_NONE ;
2289
+ for ( AllBuiltinBounds ( ) - bounds) . each |bound| {
2290
+ bt = bt + match bound {
2291
+ BoundCopy if store == UniqTraitStore
2292
+ => TC_NONCOPY_TRAIT ,
2293
+ BoundCopy => TC_NONE , // @Trait/&Trait are copyable either way
2294
+ BoundStatic if bounds. contains_elem ( BoundOwned )
2295
+ => TC_NONE , // Owned bound implies static bound.
2296
+ BoundStatic => TC_BORROWED_POINTER , // Useful for "@Trait:'static"
2297
+ BoundOwned => TC_NON_OWNED ,
2298
+ BoundConst => TC_MUTABLE ,
2299
+ BoundSized => TC_NONE , // don't care if interior is sized
2300
+ } ;
2301
+ }
2302
+ st + mt + bt
2303
+ }
2304
+
2281
2305
fn type_param_def_to_contents ( cx : ctxt ,
2282
2306
type_param_def : & TypeParameterDef ) -> TypeContents
2283
2307
{
@@ -4497,7 +4521,9 @@ pub fn visitor_object_ty(tcx: ctxt) -> (@TraitRef, t) {
4497
4521
} ;
4498
4522
let trait_lang_item = tcx. lang_items. ty_visitor( ) ;
4499
4523
let trait_ref = @TraitRef { def_id : trait_lang_item, substs : substs } ;
4524
+ let mut static_trait_bound = EmptyBuiltinBounds ( ) ;
4525
+ static_trait_bound. add( BoundStatic ) ;
4500
4526
( trait_ref,
4501
4527
mk_trait( tcx, trait_ref. def_id, copy trait_ref. substs,
4502
- BoxTraitStore , ast:: m_imm, EmptyBuiltinBounds ( ) ) )
4528
+ BoxTraitStore , ast:: m_imm, static_trait_bound ) )
4503
4529
}
0 commit comments