@@ -720,26 +720,55 @@ pub(crate) fn adt_datum_query(
720720 debug ! ( "adt_datum {:?}" , adt_id) ;
721721 let chalk_ir:: AdtId ( adt_id) = adt_id;
722722 let generic_params = generics ( db. upcast ( ) , adt_id. into ( ) ) ;
723- let upstream = adt_id. module ( db. upcast ( ) ) . krate ( ) != krate;
724- let where_clauses = {
725- let generic_params = generics ( db. upcast ( ) , adt_id. into ( ) ) ;
726- let bound_vars = generic_params. bound_vars_subst ( db, DebruijnIndex :: INNERMOST ) ;
727- convert_where_clauses ( db, adt_id. into ( ) , & bound_vars)
728- } ;
723+ let bound_vars_subst = generic_params. bound_vars_subst ( db, DebruijnIndex :: INNERMOST ) ;
724+ let where_clauses = convert_where_clauses ( db, adt_id. into ( ) , & bound_vars_subst) ;
725+
726+ let phantom_data_id = db
727+ . lang_item ( krate, SmolStr :: new_inline ( "phantom_data" ) )
728+ . and_then ( |item| item. as_struct ( ) )
729+ . map ( |item| item. into ( ) ) ;
729730 let flags = rust_ir:: AdtFlags {
730- upstream,
731- // FIXME set fundamental and phantom_data flags correctly
731+ upstream : adt_id . module ( db . upcast ( ) ) . krate ( ) != krate ,
732+ // FIXME set fundamental flags correctly
732733 fundamental : false ,
733- phantom_data : false ,
734+ phantom_data : phantom_data_id == Some ( adt_id) ,
735+ } ;
736+
737+ let variant_id_to_fields = |id| {
738+ let field_types = db. field_types ( id) ;
739+ let fields = id
740+ . variant_data ( db. upcast ( ) )
741+ . fields ( )
742+ . iter ( )
743+ . map ( |( idx, _) | field_types[ idx] . clone ( ) . substitute ( Interner , & bound_vars_subst) )
744+ . collect ( ) ;
745+ rust_ir:: AdtVariantDatum { fields }
734746 } ;
735- // FIXME provide enum variants properly (for auto traits)
736- let variant = rust_ir:: AdtVariantDatum {
737- fields : Vec :: new ( ) , // FIXME add fields (only relevant for auto traits),
747+
748+ let ( kind, variants) = match adt_id {
749+ hir_def:: AdtId :: StructId ( id) => {
750+ ( rust_ir:: AdtKind :: Struct , vec ! [ variant_id_to_fields( id. into( ) ) ] )
751+ }
752+ hir_def:: AdtId :: EnumId ( id) => {
753+ let variants = db
754+ . enum_data ( id)
755+ . variants
756+ . iter ( )
757+ . map ( |( local_id, _) | {
758+ let variant_id = hir_def:: EnumVariantId { parent : id, local_id } ;
759+ variant_id_to_fields ( variant_id. into ( ) )
760+ } )
761+ . collect ( ) ;
762+ ( rust_ir:: AdtKind :: Enum , variants)
763+ }
764+ hir_def:: AdtId :: UnionId ( id) => {
765+ ( rust_ir:: AdtKind :: Union , vec ! [ variant_id_to_fields( id. into( ) ) ] )
766+ }
738767 } ;
739- let struct_datum_bound = rust_ir:: AdtDatumBound { variants : vec ! [ variant] , where_clauses } ;
768+
769+ let struct_datum_bound = rust_ir:: AdtDatumBound { variants, where_clauses } ;
740770 let struct_datum = AdtDatum {
741- // FIXME set ADT kind
742- kind : rust_ir:: AdtKind :: Struct ,
771+ kind,
743772 id : chalk_ir:: AdtId ( adt_id) ,
744773 binders : make_binders ( db, & generic_params, struct_datum_bound) ,
745774 flags,
0 commit comments