@@ -863,6 +863,7 @@ pub struct ty_param_bounds_and_ty {
863
863
/// As `ty_param_bounds_and_ty` but for a trait ref.
864
864
pub struct TraitDef {
865
865
generics : Generics ,
866
+ bounds : BuiltinBounds ,
866
867
trait_ref : @ty:: TraitRef ,
867
868
}
868
869
@@ -2160,17 +2161,19 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
2160
2161
// def-id.
2161
2162
assert_eq ! ( p. def_id. crate , ast:: LOCAL_CRATE ) ;
2162
2163
2163
- type_param_def_to_contents (
2164
- cx, cx. ty_param_defs . get ( & p. def_id . node ) )
2164
+ let tp_def = cx. ty_param_defs . get ( & p. def_id . node ) ;
2165
+ kind_bounds_to_contents ( cx, & tp_def. bounds . builtin_bounds ,
2166
+ tp_def. bounds . trait_bounds )
2165
2167
}
2166
2168
2167
- ty_self( _) => {
2168
- // Currently, self is not bounded, so we must assume the
2169
- // worst. But in the future we should examine the super
2170
- // traits.
2171
- //
2169
+ ty_self( def_id) => {
2172
2170
// FIXME(#4678)---self should just be a ty param
2173
- TC_ALL
2171
+
2172
+ // Self may be bounded if the associated trait has builtin kinds
2173
+ // for supertraits. If so we can use those bounds.
2174
+ let trait_def = lookup_trait_def ( cx, def_id) ;
2175
+ let traits = [ trait_def. trait_ref ] ;
2176
+ kind_bounds_to_contents ( cx, & trait_def. bounds , traits)
2174
2177
}
2175
2178
2176
2179
ty_infer( _) => {
@@ -2314,14 +2317,12 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
2314
2317
st + mt + bt
2315
2318
}
2316
2319
2317
- fn type_param_def_to_contents ( cx : ctxt ,
2318
- type_param_def : & TypeParameterDef ) -> TypeContents
2319
- {
2320
- debug ! ( "type_param_def_to_contents(%s)" , type_param_def. repr( cx) ) ;
2320
+ fn kind_bounds_to_contents ( cx : ctxt , bounds : & BuiltinBounds , traits : & [ @TraitRef ] )
2321
+ -> TypeContents {
2321
2322
let _i = indenter ( ) ;
2322
2323
2323
2324
let mut tc = TC_ALL ;
2324
- for bound in type_param_def . bounds . builtin_bounds . iter ( ) {
2325
+ do each_inherited_builtin_bound ( cx , bounds, traits ) |bound| {
2325
2326
debug ! ( "tc = %s, bound = %?" , tc. to_str( ) , bound) ;
2326
2327
tc = tc - match bound {
2327
2328
BoundStatic => TypeContents :: nonstatic ( cx) ,
@@ -2334,6 +2335,23 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
2334
2335
2335
2336
debug ! ( "result = %s" , tc. to_str( ) ) ;
2336
2337
return tc;
2338
+
2339
+ // Iterates over all builtin bounds on the type parameter def, including
2340
+ // those inherited from traits with builtin-kind-supertraits.
2341
+ fn each_inherited_builtin_bound ( cx : ctxt , bounds : & BuiltinBounds ,
2342
+ traits : & [ @TraitRef ] , f : & fn ( BuiltinBound ) ) {
2343
+ for bound in bounds. iter ( ) {
2344
+ f ( bound) ;
2345
+ }
2346
+
2347
+ do each_bound_trait_and_supertraits ( cx, traits) |trait_ref| {
2348
+ let trait_def = lookup_trait_def ( cx, trait_ref. def_id ) ;
2349
+ for bound in trait_def. bounds . iter ( ) {
2350
+ f ( bound) ;
2351
+ }
2352
+ true
2353
+ } ;
2354
+ }
2337
2355
}
2338
2356
}
2339
2357
@@ -3727,6 +3745,25 @@ pub fn impl_trait_ref(cx: ctxt, id: ast::def_id) -> Option<@TraitRef> {
3727
3745
return ret;
3728
3746
}
3729
3747
3748
+ pub fn trait_ref_to_def_id ( tcx : ctxt , tr : & ast:: trait_ref ) -> ast:: def_id {
3749
+ let def = tcx. def_map . find ( & tr. ref_id ) . expect ( "no def-map entry for trait" ) ;
3750
+ ast_util:: def_id_of_def ( * def)
3751
+ }
3752
+
3753
+ pub fn try_add_builtin_trait ( tcx : ctxt ,
3754
+ trait_def_id : ast:: def_id ,
3755
+ builtin_bounds : & mut BuiltinBounds ) -> bool {
3756
+ //! Checks whether `trait_ref` refers to one of the builtin
3757
+ //! traits, like `Send`, and adds the corresponding
3758
+ //! bound to the set `builtin_bounds` if so. Returns true if `trait_ref`
3759
+ //! is a builtin trait.
3760
+
3761
+ match tcx. lang_items . to_builtin_kind ( trait_def_id) {
3762
+ Some ( bound) => { builtin_bounds. add ( bound) ; true }
3763
+ None => false
3764
+ }
3765
+ }
3766
+
3730
3767
pub fn ty_to_def_id ( ty : t ) -> Option < ast:: def_id > {
3731
3768
match get ( ty) . sty {
3732
3769
ty_trait( id, _, _, _, _) | ty_struct( id, _) | ty_enum( id, _) => Some ( id) ,
0 commit comments