@@ -52,7 +52,7 @@ use rustc_span::edit_distance::find_best_match_for_name;
5252use rustc_span:: hygiene:: DesugaringKind ;
5353use rustc_span:: source_map:: { Span , Spanned } ;
5454use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
55- use rustc_target:: abi:: FieldIdx ;
55+ use rustc_target:: abi:: { FieldIdx , FIRST_VARIANT } ;
5656use rustc_target:: spec:: abi:: Abi :: RustIntrinsic ;
5757use rustc_trait_selection:: infer:: InferCtxtExt ;
5858use rustc_trait_selection:: traits:: error_reporting:: TypeErrCtxtExt ;
@@ -3128,8 +3128,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
31283128 fields : & [ Ident ] ,
31293129 expr : & ' tcx hir:: Expr < ' tcx > ,
31303130 ) -> Ty < ' tcx > {
3131- use rustc_target:: abi:: OffsetOfIdx :: * ;
3132-
31333131 let container = self . to_ty ( container) . normalized ;
31343132
31353133 let mut field_indices = Vec :: with_capacity ( fields. len ( ) ) ;
@@ -3145,49 +3143,68 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
31453143 let ( ident, _def_scope) =
31463144 self . tcx . adjust_ident_and_get_scope ( field, container_def. did ( ) , block) ;
31473145
3148- if let Some ( ( index, variant) ) = container_def. variants ( )
3146+ let Some ( ( index, variant) ) = container_def. variants ( )
31493147 . iter_enumerated ( )
3150- . find ( |( _, v) | v. ident ( self . tcx ) . normalize_to_macros_2_0 ( ) == ident)
3151- {
3152- let Some ( & subfield) = fields. next ( ) else {
3153- let mut err = type_error_struct ! (
3154- self . tcx( ) . sess,
3155- ident. span,
3156- container,
3157- E0795 ,
3158- "`{ident}` is an enum variant; expected field at end of `offset_of`" ,
3159- ) ;
3160- err. span_label ( field. span , "enum variant" ) ;
3161- err. emit ( ) ;
3162- break ;
3163- } ;
3164- let ( subident, sub_def_scope) =
3165- self . tcx . adjust_ident_and_get_scope ( subfield, variant. def_id , block) ;
3166-
3167- if let Some ( ( subindex, field) ) = variant. fields
3168- . iter_enumerated ( )
3169- . find ( |( _, f) | f. ident ( self . tcx ) . normalize_to_macros_2_0 ( ) == subident)
3170- {
3171- let field_ty = self . field_ty ( expr. span , field, args) ;
3148+ . find ( |( _, v) | v. ident ( self . tcx ) . normalize_to_macros_2_0 ( ) == ident) else {
3149+ let mut err = type_error_struct ! (
3150+ self . tcx( ) . sess,
3151+ ident. span,
3152+ container,
3153+ E0599 ,
3154+ "no variant named `{ident}` found for enum `{container}`" ,
3155+ ) ;
3156+ err. span_label ( field. span , "variant not found" ) ;
3157+ err. emit ( ) ;
3158+ break ;
3159+ } ;
3160+ let Some ( & subfield) = fields. next ( ) else {
3161+ let mut err = type_error_struct ! (
3162+ self . tcx( ) . sess,
3163+ ident. span,
3164+ container,
3165+ E0795 ,
3166+ "`{ident}` is an enum variant; expected field at end of `offset_of`" ,
3167+ ) ;
3168+ err. span_label ( field. span , "enum variant" ) ;
3169+ err. emit ( ) ;
3170+ break ;
3171+ } ;
3172+ let ( subident, sub_def_scope) =
3173+ self . tcx . adjust_ident_and_get_scope ( subfield, variant. def_id , block) ;
31723174
3173- // FIXME: DSTs with static alignment should be allowed
3174- self . require_type_is_sized ( field_ty, expr. span , traits:: MiscObligation ) ;
3175+ let Some ( ( subindex, field) ) = variant. fields
3176+ . iter_enumerated ( )
3177+ . find ( |( _, f) | f. ident ( self . tcx ) . normalize_to_macros_2_0 ( ) == subident) else {
3178+ let mut err = type_error_struct ! (
3179+ self . tcx( ) . sess,
3180+ ident. span,
3181+ container,
3182+ E0609 ,
3183+ "no field named `{subfield}` on enum variant `{container}::{ident}`" ,
3184+ ) ;
3185+ err. span_label ( field. span , "this enum variant..." ) ;
3186+ err. span_label ( subident. span , "...does not have this field" ) ;
3187+ err. emit ( ) ;
3188+ break ;
3189+ } ;
31753190
3176- if field. vis . is_accessible_from ( sub_def_scope, self . tcx ) {
3177- self . tcx . check_stability ( field. did , Some ( expr. hir_id ) , expr. span , None ) ;
3178- } else {
3179- self . private_field_err ( ident, container_def. did ( ) ) . emit ( ) ;
3180- }
3191+ let field_ty = self . field_ty ( expr. span , field, args) ;
31813192
3182- // Save the index of all fields regardless of their visibility in case
3183- // of error recovery.
3184- field_indices. push ( Variant ( index) ) ;
3185- field_indices. push ( Field ( subindex) ) ;
3186- current_container = field_ty;
3193+ // FIXME: DSTs with static alignment should be allowed
3194+ self . require_type_is_sized ( field_ty, expr. span , traits:: MiscObligation ) ;
31873195
3188- continue ;
3189- }
3196+ if field. vis . is_accessible_from ( sub_def_scope, self . tcx ) {
3197+ self . tcx . check_stability ( field. did , Some ( expr. hir_id ) , expr. span , None ) ;
3198+ } else {
3199+ self . private_field_err ( ident, container_def. did ( ) ) . emit ( ) ;
31903200 }
3201+
3202+ // Save the index of all fields regardless of their visibility in case
3203+ // of error recovery.
3204+ field_indices. push ( ( index, subindex) ) ;
3205+ current_container = field_ty;
3206+
3207+ continue ;
31913208 }
31923209 ty:: Adt ( container_def, args) => {
31933210 let block = self . tcx . hir ( ) . local_def_id_to_hir_id ( self . body_id ) ;
@@ -3212,7 +3229,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
32123229
32133230 // Save the index of all fields regardless of their visibility in case
32143231 // of error recovery.
3215- field_indices. push ( Field ( index) ) ;
3232+ field_indices. push ( ( FIRST_VARIANT , index) ) ;
32163233 current_container = field_ty;
32173234
32183235 continue ;
@@ -3226,7 +3243,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
32263243 self . require_type_is_sized ( ty, expr. span , traits:: MiscObligation ) ;
32273244 }
32283245 if let Some ( & field_ty) = tys. get ( index) {
3229- field_indices. push ( Field ( index. into ( ) ) ) ;
3246+ field_indices. push ( ( FIRST_VARIANT , index. into ( ) ) ) ;
32303247 current_container = field_ty;
32313248
32323249 continue ;
0 commit comments