@@ -30,7 +30,7 @@ use middle::def;
30
30
use middle:: lang_items;
31
31
use middle:: subst;
32
32
use middle:: ty:: { ImplContainer , TraitContainer } ;
33
- use middle:: ty:: { self , Ty } ;
33
+ use middle:: ty:: { self , RegionEscape , Ty } ;
34
34
use util:: nodemap:: FnvHashMap ;
35
35
36
36
use std:: cell:: { Cell , RefCell } ;
@@ -108,7 +108,7 @@ fn lookup_item<'a>(item_id: ast::NodeId, data: &'a [u8]) -> rbml::Doc<'a> {
108
108
find_item ( item_id, items)
109
109
}
110
110
111
- #[ derive( PartialEq ) ]
111
+ #[ derive( Debug , PartialEq ) ]
112
112
enum Family {
113
113
ImmStatic , // c
114
114
MutStatic , // b
@@ -390,6 +390,119 @@ pub fn get_trait_def<'tcx>(cdata: Cmd,
390
390
}
391
391
}
392
392
393
+ pub fn get_adt_def < ' tcx > ( intr : & IdentInterner ,
394
+ cdata : Cmd ,
395
+ item_id : ast:: NodeId ,
396
+ tcx : & ty:: ctxt < ' tcx > ) -> ty:: AdtDefMaster < ' tcx >
397
+ {
398
+ fn get_enum_variants < ' tcx > ( intr : & IdentInterner ,
399
+ cdata : Cmd ,
400
+ doc : rbml:: Doc ,
401
+ tcx : & ty:: ctxt < ' tcx > ) -> Vec < ty:: VariantDefData < ' tcx , ' tcx > > {
402
+ let mut disr_val = 0 ;
403
+ reader:: tagged_docs ( doc, tag_items_data_item_variant) . map ( |p| {
404
+ let did = translated_def_id ( cdata, p) ;
405
+ let item = lookup_item ( did. node , cdata. data ( ) ) ;
406
+
407
+ if let Some ( disr) = variant_disr_val ( item) {
408
+ disr_val = disr;
409
+ }
410
+ let disr = disr_val;
411
+ disr_val = disr_val. wrapping_add ( 1 ) ;
412
+
413
+ ty:: VariantDefData {
414
+ did : did,
415
+ name : item_name ( intr, item) ,
416
+ fields : get_variant_fields ( intr, cdata, item, tcx) ,
417
+ disr_val : disr
418
+ }
419
+ } ) . collect ( )
420
+ }
421
+ fn get_variant_fields < ' tcx > ( intr : & IdentInterner ,
422
+ cdata : Cmd ,
423
+ doc : rbml:: Doc ,
424
+ tcx : & ty:: ctxt < ' tcx > ) -> Vec < ty:: FieldDefData < ' tcx , ' tcx > > {
425
+ reader:: tagged_docs ( doc, tag_item_field) . map ( |f| {
426
+ let ff = item_family ( f) ;
427
+ match ff {
428
+ PublicField | InheritedField => { } ,
429
+ _ => tcx. sess . bug ( & format ! ( "expected field, found {:?}" , ff) )
430
+ } ;
431
+ ty:: FieldDefData :: new ( item_def_id ( f, cdata) ,
432
+ item_name ( intr, f) ,
433
+ struct_field_family_to_visibility ( ff) )
434
+ } ) . chain ( reader:: tagged_docs ( doc, tag_item_unnamed_field) . map ( |f| {
435
+ let ff = item_family ( f) ;
436
+ ty:: FieldDefData :: new ( item_def_id ( f, cdata) ,
437
+ special_idents:: unnamed_field. name ,
438
+ struct_field_family_to_visibility ( ff) )
439
+ } ) ) . collect ( )
440
+ }
441
+ fn get_struct_variant < ' tcx > ( intr : & IdentInterner ,
442
+ cdata : Cmd ,
443
+ doc : rbml:: Doc ,
444
+ did : ast:: DefId ,
445
+ tcx : & ty:: ctxt < ' tcx > ) -> ty:: VariantDefData < ' tcx , ' tcx > {
446
+ ty:: VariantDefData {
447
+ did : did,
448
+ name : item_name ( intr, doc) ,
449
+ fields : get_variant_fields ( intr, cdata, doc, tcx) ,
450
+ disr_val : 0
451
+ }
452
+ }
453
+
454
+ let doc = lookup_item ( item_id, cdata. data ( ) ) ;
455
+ let did = ast:: DefId { krate : cdata. cnum , node : item_id } ;
456
+ let ( kind, variants) = match item_family ( doc) {
457
+ Enum => ( ty:: AdtKind :: Enum ,
458
+ get_enum_variants ( intr, cdata, doc, tcx) ) ,
459
+ Struct => ( ty:: AdtKind :: Struct ,
460
+ vec ! [ get_struct_variant( intr, cdata, doc, did, tcx) ] ) ,
461
+ _ => tcx. sess . bug ( "get_adt_def called on a non-ADT" )
462
+ } ;
463
+
464
+ let adt = tcx. intern_adt_def ( did, kind, variants) ;
465
+
466
+ // this needs to be done *after* the variant is interned,
467
+ // to support recursive structures
468
+ for variant in & adt. variants {
469
+ if variant. kind ( ) == ty:: VariantKind :: Tuple &&
470
+ adt. adt_kind ( ) == ty:: AdtKind :: Enum {
471
+ // tuple-like enum variant fields aren't real items - get the types
472
+ // from the ctor.
473
+ debug ! ( "evaluating the ctor-type of {:?}" ,
474
+ variant. name) ;
475
+ let ctor_ty = get_type ( cdata, variant. did . node , tcx) . ty ;
476
+ debug ! ( "evaluating the ctor-type of {:?}.. {:?}" ,
477
+ variant. name,
478
+ ctor_ty) ;
479
+ let field_tys = match ctor_ty. sty {
480
+ ty:: TyBareFn ( _, & ty:: BareFnTy { sig : ty:: Binder ( ty:: FnSig {
481
+ ref inputs, ..
482
+ } ) , ..} ) => {
483
+ // tuple-struct constructors don't have escaping regions
484
+ assert ! ( !inputs. has_escaping_regions( ) ) ;
485
+ inputs
486
+ } ,
487
+ _ => tcx. sess . bug ( "tuple-variant ctor is not an ADT" )
488
+ } ;
489
+ for ( field, & ty) in variant. fields . iter ( ) . zip ( field_tys. iter ( ) ) {
490
+ field. fulfill_ty ( ty) ;
491
+ }
492
+ } else {
493
+ for field in & variant. fields {
494
+ debug ! ( "evaluating the type of {:?}::{:?}" , variant. name, field. name) ;
495
+ let ty = get_type ( cdata, field. did . node , tcx) . ty ;
496
+ field. fulfill_ty ( ty) ;
497
+ debug ! ( "evaluating the type of {:?}::{:?}: {:?}" ,
498
+ variant. name, field. name, ty) ;
499
+ }
500
+ }
501
+ }
502
+
503
+ adt
504
+ }
505
+
393
506
pub fn get_predicates < ' tcx > ( cdata : Cmd ,
394
507
item_id : ast:: NodeId ,
395
508
tcx : & ty:: ctxt < ' tcx > )
@@ -687,55 +800,6 @@ pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &ty::ctxt<'tcx>, id: ast::NodeI
687
800
}
688
801
}
689
802
690
- pub fn get_enum_variants < ' tcx > ( intr : Rc < IdentInterner > , cdata : Cmd , id : ast:: NodeId ,
691
- tcx : & ty:: ctxt < ' tcx > ) -> Vec < Rc < ty:: VariantInfo < ' tcx > > > {
692
- let data = cdata. data ( ) ;
693
- let items = reader:: get_doc ( rbml:: Doc :: new ( data) , tag_items) ;
694
- let item = find_item ( id, items) ;
695
- let mut disr_val = 0 ;
696
- reader:: tagged_docs ( item, tag_items_data_item_variant) . map ( |p| {
697
- let did = translated_def_id ( cdata, p) ;
698
- let item = find_item ( did. node , items) ;
699
- let ctor_ty = item_type ( ast:: DefId { krate : cdata. cnum , node : id} ,
700
- item, tcx, cdata) ;
701
- let name = item_name ( & * intr, item) ;
702
- let ( ctor_ty, arg_tys, arg_names) = match ctor_ty. sty {
703
- ty:: TyBareFn ( _, ref f) =>
704
- ( Some ( ctor_ty) , f. sig . 0 . inputs . clone ( ) , None ) ,
705
- _ => { // Nullary or struct enum variant.
706
- let mut arg_names = Vec :: new ( ) ;
707
- let arg_tys = get_struct_fields ( intr. clone ( ) , cdata, did. node )
708
- . iter ( )
709
- . map ( |field_ty| {
710
- arg_names. push ( field_ty. name ) ;
711
- get_type ( cdata, field_ty. id . node , tcx) . ty
712
- } )
713
- . collect ( ) ;
714
- let arg_names = if arg_names. is_empty ( ) { None } else { Some ( arg_names) } ;
715
-
716
- ( None , arg_tys, arg_names)
717
- }
718
- } ;
719
- match variant_disr_val ( item) {
720
- Some ( val) => { disr_val = val; }
721
- _ => { /* empty */ }
722
- }
723
- let old_disr_val = disr_val;
724
- disr_val = disr_val. wrapping_add ( 1 ) ;
725
- Rc :: new ( ty:: VariantInfo {
726
- args : arg_tys,
727
- arg_names : arg_names,
728
- ctor_ty : ctor_ty,
729
- name : name,
730
- // I'm not even sure if we encode visibility
731
- // for variants -- TEST -- tjc
732
- id : did,
733
- disr_val : old_disr_val,
734
- vis : ast:: Inherited
735
- } )
736
- } ) . collect ( )
737
- }
738
-
739
803
fn get_explicit_self ( item : rbml:: Doc ) -> ty:: ExplicitSelfCategory {
740
804
fn get_mutability ( ch : u8 ) -> ast:: Mutability {
741
805
match ch as char {
@@ -1029,37 +1093,14 @@ fn struct_field_family_to_visibility(family: Family) -> ast::Visibility {
1029
1093
}
1030
1094
}
1031
1095
1032
- pub fn get_struct_fields ( intr : Rc < IdentInterner > , cdata : Cmd , id : ast:: NodeId )
1033
- -> Vec < ty :: FieldTy > {
1096
+ pub fn get_struct_field_names ( intr : & IdentInterner , cdata : Cmd , id : ast:: NodeId )
1097
+ -> Vec < ast :: Name > {
1034
1098
let data = cdata. data ( ) ;
1035
1099
let item = lookup_item ( id, data) ;
1036
- reader:: tagged_docs ( item, tag_item_field) . filter_map ( |an_item| {
1037
- let f = item_family ( an_item) ;
1038
- if f == PublicField || f == InheritedField {
1039
- let name = item_name ( & * intr, an_item) ;
1040
- let did = item_def_id ( an_item, cdata) ;
1041
- let tagdoc = reader:: get_doc ( an_item, tag_item_field_origin) ;
1042
- let origin_id = translated_def_id ( cdata, tagdoc) ;
1043
- Some ( ty:: FieldTy {
1044
- name : name,
1045
- id : did,
1046
- vis : struct_field_family_to_visibility ( f) ,
1047
- origin : origin_id,
1048
- } )
1049
- } else {
1050
- None
1051
- }
1052
- } ) . chain ( reader:: tagged_docs ( item, tag_item_unnamed_field) . map ( |an_item| {
1053
- let did = item_def_id ( an_item, cdata) ;
1054
- let tagdoc = reader:: get_doc ( an_item, tag_item_field_origin) ;
1055
- let f = item_family ( an_item) ;
1056
- let origin_id = translated_def_id ( cdata, tagdoc) ;
1057
- ty:: FieldTy {
1058
- name : special_idents:: unnamed_field. name ,
1059
- id : did,
1060
- vis : struct_field_family_to_visibility ( f) ,
1061
- origin : origin_id,
1062
- }
1100
+ reader:: tagged_docs ( item, tag_item_field) . map ( |an_item| {
1101
+ item_name ( intr, an_item)
1102
+ } ) . chain ( reader:: tagged_docs ( item, tag_item_unnamed_field) . map ( |_| {
1103
+ special_idents:: unnamed_field. name
1063
1104
} ) ) . collect ( )
1064
1105
}
1065
1106
0 commit comments