11use rustc_ast as ast;
2- use rustc_ast:: { FieldDef , Item , ItemKind , VariantData } ;
2+ use rustc_ast:: { ItemKind , VariantData } ;
33use rustc_expand:: base:: { Annotatable , ExtCtxt } ;
4- use rustc_span:: { Ident , Span , kw , sym } ;
4+ use rustc_span:: { kw , sym , Ident , Span } ;
55use thin_vec:: thin_vec;
66
77use crate :: deriving:: generic:: ty:: { Bounds , Path , PathKind , Ty } ;
88use crate :: deriving:: generic:: {
9- BlockOrExpr , FieldlessVariantsStrategy , MethodDef , SubstructureFields , TraitDef ,
10- combine_substructure ,
9+ combine_substructure , BlockOrExpr , FieldlessVariantsStrategy , MethodDef , SubstructureFields ,
10+ TraitDef ,
1111} ;
1212use crate :: deriving:: pathvec_std;
1313use crate :: errors;
@@ -22,12 +22,23 @@ pub(crate) fn expand_deriving_from(
2222 push : & mut dyn FnMut ( Annotatable ) ,
2323 is_const : bool ,
2424) {
25- let mut visitor = ExtractNonSingleFieldStruct { cx, field : None } ;
26- item. visit_with ( & mut visitor) ;
25+ let field = match & item {
26+ Annotatable :: Item ( item) => match & item. kind {
27+ ItemKind :: Struct ( _, _, data) => match data. fields ( ) {
28+ [ field] => Some ( field. clone ( ) ) ,
29+ _ => None ,
30+ } ,
31+ _ => None ,
32+ } ,
33+ _ => None ,
34+ } ;
2735
2836 // Make sure that the derive is only invoked on single-field [tuple] structs.
2937 // From this point below, we know that there is exactly one field.
30- let Some ( field) = visitor. field else { return } ;
38+ let Some ( field) = field else {
39+ cx. dcx ( ) . emit_err ( errors:: DeriveFromWrongTarget { span } ) ;
40+ return ;
41+ } ;
3142
3243 let path = Path :: new_ (
3344 pathvec_std ! ( convert:: From ) ,
@@ -98,23 +109,3 @@ pub(crate) fn expand_deriving_from(
98109
99110 from_trait_def. expand ( cx, mitem, item, push) ;
100111}
101-
102- struct ExtractNonSingleFieldStruct < ' a , ' b > {
103- cx : & ' a ExtCtxt < ' b > ,
104- field : Option < FieldDef > ,
105- }
106-
107- impl < ' a , ' b > rustc_ast:: visit:: Visitor < ' a > for ExtractNonSingleFieldStruct < ' a , ' b > {
108- fn visit_item ( & mut self , item : & ' a Item ) -> Self :: Result {
109- match & item. kind {
110- ItemKind :: Struct ( _, _, data) => match data. fields ( ) {
111- [ field] => self . field = Some ( field. clone ( ) ) ,
112- _ => { }
113- } ,
114- _ => { }
115- } ;
116- if self . field . is_none ( ) {
117- self . cx . dcx ( ) . emit_err ( errors:: DeriveFromWrongTarget { span : item. span } ) ;
118- }
119- }
120- }
0 commit comments