@@ -398,28 +398,39 @@ pub fn ensure_supertraits(ccx: &CrateCtxt,
398
398
sp : codemap:: span ,
399
399
rp : Option < ty:: region_variance > ,
400
400
ast_trait_refs : & [ ast:: trait_ref ] ,
401
- generics : & ast:: Generics )
401
+ generics : & ast:: Generics ) -> ty :: BuiltinBounds
402
402
{
403
403
let tcx = ccx. tcx ;
404
- if tcx. supertraits . contains_key ( & local_def ( id) ) { return ; }
404
+
405
+ // Called only the first time trait_def_of_item is called.
406
+ // Supertraits are ensured at the same time.
407
+ assert ! ( !tcx. supertraits. contains_key( & local_def( id) ) ) ;
405
408
406
409
let self_ty = ty:: mk_self ( ccx. tcx , local_def ( id) ) ;
407
410
let mut ty_trait_refs: ~[ @ty:: TraitRef ] = ~[ ] ;
411
+ let mut bounds = ty:: EmptyBuiltinBounds ( ) ;
408
412
for ast_trait_ref in ast_trait_refs. iter ( ) {
413
+ let trait_def_id = ty:: trait_ref_to_def_id ( ccx. tcx , ast_trait_ref) ;
414
+ // FIXME(#8559): Need to instantiate the trait_ref whether or not it's a
415
+ // builtin trait, so that the trait's node id appears in the tcx trait_ref
416
+ // map. This is only needed for metadata; see the similar fixme in encoder.rs.
409
417
let trait_ref = instantiate_trait_ref ( ccx, ast_trait_ref, rp,
410
418
generics, self_ty) ;
411
-
412
- // FIXME(#5527) Could have same trait multiple times
413
- if ty_trait_refs. iter ( ) . any ( |other_trait| other_trait. def_id == trait_ref. def_id ) {
414
- // This means a trait inherited from the same supertrait more
415
- // than once.
416
- tcx. sess . span_err ( sp, "Duplicate supertrait in trait declaration" ) ;
417
- break ;
418
- } else {
419
- ty_trait_refs. push ( trait_ref) ;
419
+ if !ty:: try_add_builtin_trait ( ccx. tcx , trait_def_id, & mut bounds) {
420
+
421
+ // FIXME(#5527) Could have same trait multiple times
422
+ if ty_trait_refs. iter ( ) . any ( |other_trait| other_trait. def_id == trait_ref. def_id ) {
423
+ // This means a trait inherited from the same supertrait more
424
+ // than once.
425
+ tcx. sess . span_err ( sp, "Duplicate supertrait in trait declaration" ) ;
426
+ break ;
427
+ } else {
428
+ ty_trait_refs. push ( trait_ref) ;
429
+ }
420
430
}
421
431
}
422
432
tcx. supertraits . insert ( local_def ( id) , @ty_trait_refs) ;
433
+ bounds
423
434
}
424
435
425
436
/**
@@ -870,20 +881,19 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::item) {
870
881
parent_visibility) ;
871
882
for t in opt_trait_ref. iter ( ) {
872
883
// Prevent the builtin kind traits from being manually implemented.
873
- if ty:: trait_ref_is_builtin_kind ( ccx. tcx , t) {
874
- ccx. tcx . sess . span_err ( it. span ,
884
+ let trait_def_id = ty:: trait_ref_to_def_id ( tcx, t) ;
885
+ if tcx. lang_items . to_builtin_kind ( trait_def_id) . is_some ( ) {
886
+ tcx. sess . span_err ( it. span ,
875
887
"cannot provide an explicit implementation \
876
888
for a builtin kind") ;
877
889
}
878
890
879
891
check_methods_against_trait ( ccx, generics, rp, selfty, t, cms) ;
880
892
}
881
893
}
882
- ast:: item_trait( ref generics, ref supertraits, ref trait_methods) => {
883
- let trait_def = trait_def_of_item ( ccx, it) ;
884
- tcx. trait_defs . insert ( local_def ( it. id ) , trait_def) ;
894
+ ast:: item_trait( ref generics, _, ref trait_methods) => {
895
+ let _trait_def = trait_def_of_item ( ccx, it) ;
885
896
ensure_trait_methods ( ccx, it. id ) ;
886
- ensure_supertraits ( ccx, it. id , it. span , rp, * supertraits, generics) ;
887
897
888
898
let ( _, provided_methods) =
889
899
split_trait_methods ( * trait_methods) ;
@@ -1039,13 +1049,16 @@ pub fn trait_def_of_item(ccx: &CrateCtxt, it: &ast::item) -> @ty::TraitDef {
1039
1049
}
1040
1050
let rp = tcx. region_paramd_items . find ( & it. id ) . map_move ( |x| * x) ;
1041
1051
match it. node {
1042
- ast:: item_trait( ref generics, _ , _) => {
1052
+ ast:: item_trait( ref generics, ref supertraits , _) => {
1043
1053
let self_ty = ty:: mk_self ( tcx, def_id) ;
1044
1054
let ( ty_generics, substs) = mk_item_substs ( ccx, generics, rp,
1045
1055
Some ( self_ty) ) ;
1056
+ let bounds = ensure_supertraits ( ccx, it. id , it. span , rp,
1057
+ * supertraits, generics) ;
1046
1058
let trait_ref = @ty:: TraitRef { def_id : def_id,
1047
1059
substs : substs} ;
1048
1060
let trait_def = @ty:: TraitDef { generics : ty_generics,
1061
+ bounds : bounds,
1049
1062
trait_ref : trait_ref} ;
1050
1063
tcx. trait_defs . insert ( def_id, trait_def) ;
1051
1064
return trait_def;
@@ -1225,7 +1238,7 @@ pub fn ty_generics(ccx: &CrateCtxt,
1225
1238
TraitTyParamBound ( ref b) => {
1226
1239
let ty = ty:: mk_param ( ccx. tcx , param_ty. idx , param_ty. def_id ) ;
1227
1240
let trait_ref = instantiate_trait_ref ( ccx, b, rp, generics, ty) ;
1228
- if !astconv :: try_add_builtin_trait (
1241
+ if !ty :: try_add_builtin_trait (
1229
1242
ccx. tcx , trait_ref. def_id ,
1230
1243
& mut param_bounds. builtin_bounds )
1231
1244
{
0 commit comments