@@ -604,26 +604,55 @@ pub(crate) fn adt_datum_query(
604604 debug ! ( "adt_datum {:?}" , adt_id) ;
605605 let chalk_ir:: AdtId ( adt_id) = adt_id;
606606 let generic_params = generics ( db. upcast ( ) , adt_id. into ( ) ) ;
607- let upstream = adt_id. module ( db. upcast ( ) ) . krate ( ) != krate;
608- let where_clauses = {
609- let generic_params = generics ( db. upcast ( ) , adt_id. into ( ) ) ;
610- let bound_vars = generic_params. bound_vars_subst ( db, DebruijnIndex :: INNERMOST ) ;
611- convert_where_clauses ( db, adt_id. into ( ) , & bound_vars)
612- } ;
607+ let bound_vars_subst = generic_params. bound_vars_subst ( db, DebruijnIndex :: INNERMOST ) ;
608+ let where_clauses = convert_where_clauses ( db, adt_id. into ( ) , & bound_vars_subst) ;
609+
610+ let phantom_data_id = db
611+ . lang_item ( krate, SmolStr :: new_inline ( "phantom_data" ) )
612+ . and_then ( |item| item. as_struct ( ) )
613+ . map ( |item| item. into ( ) ) ;
613614 let flags = rust_ir:: AdtFlags {
614- upstream,
615- // FIXME set fundamental and phantom_data flags correctly
615+ upstream : adt_id . module ( db . upcast ( ) ) . krate ( ) != krate ,
616+ // FIXME set fundamental flags correctly
616617 fundamental : false ,
617- phantom_data : false ,
618+ phantom_data : phantom_data_id == Some ( adt_id) ,
619+ } ;
620+
621+ let variant_id_to_fields = |id| {
622+ let field_types = db. field_types ( id) ;
623+ let fields = id
624+ . variant_data ( db. upcast ( ) )
625+ . fields ( )
626+ . iter ( )
627+ . map ( |( idx, _) | field_types[ idx] . clone ( ) . substitute ( Interner , & bound_vars_subst) )
628+ . collect ( ) ;
629+ rust_ir:: AdtVariantDatum { fields }
618630 } ;
619- // FIXME provide enum variants properly (for auto traits)
620- let variant = rust_ir:: AdtVariantDatum {
621- fields : Vec :: new ( ) , // FIXME add fields (only relevant for auto traits),
631+
632+ let ( kind, variants) = match adt_id {
633+ hir_def:: AdtId :: StructId ( id) => {
634+ ( rust_ir:: AdtKind :: Struct , vec ! [ variant_id_to_fields( id. into( ) ) ] )
635+ }
636+ hir_def:: AdtId :: EnumId ( id) => {
637+ let variants = db
638+ . enum_data ( id)
639+ . variants
640+ . iter ( )
641+ . map ( |( local_id, _) | {
642+ let variant_id = hir_def:: EnumVariantId { parent : id, local_id } ;
643+ variant_id_to_fields ( variant_id. into ( ) )
644+ } )
645+ . collect ( ) ;
646+ ( rust_ir:: AdtKind :: Enum , variants)
647+ }
648+ hir_def:: AdtId :: UnionId ( id) => {
649+ ( rust_ir:: AdtKind :: Union , vec ! [ variant_id_to_fields( id. into( ) ) ] )
650+ }
622651 } ;
623- let struct_datum_bound = rust_ir:: AdtDatumBound { variants : vec ! [ variant] , where_clauses } ;
652+
653+ let struct_datum_bound = rust_ir:: AdtDatumBound { variants, where_clauses } ;
624654 let struct_datum = AdtDatum {
625- // FIXME set ADT kind
626- kind : rust_ir:: AdtKind :: Struct ,
655+ kind,
627656 id : chalk_ir:: AdtId ( adt_id) ,
628657 binders : make_binders ( db, & generic_params, struct_datum_bound) ,
629658 flags,
0 commit comments