@@ -132,18 +132,52 @@ fn extract_default_variant<'a>(
132
132
let variant = match default_variants. as_slice ( ) {
133
133
[ variant] => variant,
134
134
[ ] => {
135
- cx. struct_span_err ( trait_span, "no default declared" )
136
- . help ( "make a unit variant default by placing `#[default]` above it" )
137
- . emit ( ) ;
135
+ let possible_defaults = enum_def
136
+ . variants
137
+ . iter ( )
138
+ . filter ( |variant| matches ! ( variant. data, VariantData :: Unit ( ..) ) )
139
+ . filter ( |variant| !cx. sess . contains_name ( & variant. attrs , sym:: non_exhaustive) ) ;
140
+
141
+ let mut diag = cx. struct_span_err ( trait_span, "no default declared" ) ;
142
+ diag. help ( "make a unit variant default by placing `#[default]` above it" ) ;
143
+ for variant in possible_defaults {
144
+ // Suggest making each unit variant default.
145
+ diag. tool_only_span_suggestion (
146
+ variant. span ,
147
+ & format ! ( "make `{}` default" , variant. ident) ,
148
+ format ! ( "#[default] {}" , variant. ident) ,
149
+ Applicability :: MaybeIncorrect ,
150
+ ) ;
151
+ }
152
+ diag. emit ( ) ;
138
153
139
154
return Err ( ( ) ) ;
140
155
}
141
156
[ first, rest @ ..] => {
142
- cx. struct_span_err ( trait_span, "multiple declared defaults" )
143
- . span_label ( first. span , "first default" )
144
- . span_labels ( rest. iter ( ) . map ( |variant| variant. span ) , "additional default" )
145
- . note ( "only one variant can be default" )
146
- . emit ( ) ;
157
+ let mut diag = cx. struct_span_err ( trait_span, "multiple declared defaults" ) ;
158
+ diag. span_label ( first. span , "first default" ) ;
159
+ diag. span_labels ( rest. iter ( ) . map ( |variant| variant. span ) , "additional default" ) ;
160
+ diag. note ( "only one variant can be default" ) ;
161
+ for variant in & default_variants {
162
+ // Suggest making each variant already tagged default.
163
+ let suggestion = default_variants
164
+ . iter ( )
165
+ . filter_map ( |v| {
166
+ if v. ident == variant. ident {
167
+ None
168
+ } else {
169
+ Some ( ( cx. sess . find_by_name ( & v. attrs , kw:: Default ) ?. span , String :: new ( ) ) )
170
+ }
171
+ } )
172
+ . collect ( ) ;
173
+
174
+ diag. tool_only_multipart_suggestion (
175
+ & format ! ( "make `{}` default" , variant. ident) ,
176
+ suggestion,
177
+ Applicability :: MaybeIncorrect ,
178
+ ) ;
179
+ }
180
+ diag. emit ( ) ;
147
181
148
182
return Err ( ( ) ) ;
149
183
}
0 commit comments