@@ -27,21 +27,39 @@ pub(crate) fn expand_deriving_from(
27
27
cx. dcx ( ) . bug ( "derive(From) used on something else than an item" ) ;
28
28
} ;
29
29
30
- // #[derive(From)] is currently usable only on structs with exactly one field.
31
- let field = if let ItemKind :: Struct ( _, _, data) = & item. kind
32
- && let [ field] = data. fields ( )
33
- {
34
- Some ( field. clone ( ) )
35
- } else {
36
- None
30
+ let err_span = || {
31
+ let item_span = item. kind . ident ( ) . map ( |ident| ident. span ) . unwrap_or ( item. span ) ;
32
+ MultiSpan :: from_spans ( vec ! [ span, item_span] )
37
33
} ;
38
34
39
- let from_type = match & field {
40
- Some ( field) => Ty :: AstTy ( field. ty . clone ( ) ) ,
41
- // We don't have a type to put into From<...> if we don't have a single field, so just put
42
- // unit there.
43
- None => Ty :: Unit ,
35
+ // `#[derive(From)]` is currently usable only on structs with exactly one field.
36
+ let field = match & item. kind {
37
+ ItemKind :: Struct ( _, _, data) => {
38
+ if let [ field] = data. fields ( ) {
39
+ Ok ( field. clone ( ) )
40
+ } else {
41
+ let guar = cx. dcx ( ) . emit_err ( errors:: DeriveFromWrongFieldCount {
42
+ span : err_span ( ) ,
43
+ multiple_fields : data. fields ( ) . len ( ) > 1 ,
44
+ } ) ;
45
+ Err ( guar)
46
+ }
47
+ }
48
+ ItemKind :: Enum ( _, _, _) | ItemKind :: Union ( _, _, _) => {
49
+ let guar = cx. dcx ( ) . emit_err ( errors:: DeriveFromWrongTarget {
50
+ span : err_span ( ) ,
51
+ kind : & format ! ( "{} {}" , item. kind. article( ) , item. kind. descr( ) ) ,
52
+ } ) ;
53
+ Err ( guar)
54
+ }
55
+ _ => cx. dcx ( ) . bug ( "Invalid derive(From) ADT input" ) ,
44
56
} ;
57
+
58
+ let from_type = Ty :: AstTy ( match field {
59
+ Ok ( ref field) => field. ty . clone ( ) ,
60
+ Err ( guar) => cx. ty ( span, ast:: TyKind :: Err ( guar) ) ,
61
+ } ) ;
62
+
45
63
let path =
46
64
Path :: new_ ( pathvec_std ! ( convert:: From ) , vec ! [ Box :: new( from_type. clone( ) ) ] , PathKind :: Std ) ;
47
65
@@ -71,34 +89,17 @@ pub(crate) fn expand_deriving_from(
71
89
attributes: thin_vec![ cx. attr_word( sym:: inline, span) ] ,
72
90
fieldless_variants_strategy: FieldlessVariantsStrategy :: Default ,
73
91
combine_substructure: combine_substructure( Box :: new( |cx, span, substructure| {
74
- let Some ( field) = & field else {
75
- let item_span = item. kind. ident( ) . map( |ident| ident. span) . unwrap_or( item. span) ;
76
- let err_span = MultiSpan :: from_spans( vec![ span, item_span] ) ;
77
- let error = match & item. kind {
78
- ItemKind :: Struct ( _, _, data) => {
79
- cx. dcx( ) . emit_err( errors:: DeriveFromWrongFieldCount {
80
- span: err_span,
81
- multiple_fields: data. fields( ) . len( ) > 1 ,
82
- } )
83
- }
84
- ItemKind :: Enum ( _, _, _) | ItemKind :: Union ( _, _, _) => {
85
- cx. dcx( ) . emit_err( errors:: DeriveFromWrongTarget {
86
- span: err_span,
87
- kind: & format!( "{} {}" , item. kind. article( ) , item. kind. descr( ) ) ,
88
- } )
89
- }
90
- _ => cx. dcx( ) . bug( "Invalid derive(From) ADT input" ) ,
91
- } ;
92
-
93
- return BlockOrExpr :: new_expr( DummyResult :: raw_expr( span, Some ( error) ) ) ;
92
+ let field = match field {
93
+ Ok ( ref field) => field,
94
+ Err ( guar) => {
95
+ return BlockOrExpr :: new_expr( DummyResult :: raw_expr( span, Some ( guar) ) ) ;
96
+ }
94
97
} ;
95
98
96
99
let self_kw = Ident :: new( kw:: SelfUpper , span) ;
97
100
let expr: Box <ast:: Expr > = match substructure. fields {
98
101
SubstructureFields :: StaticStruct ( variant, _) => match variant {
99
- // Self {
100
- // field: value
101
- // }
102
+ // Self { field: value }
102
103
VariantData :: Struct { .. } => cx. expr_struct_ident(
103
104
span,
104
105
self_kw,
0 commit comments