@@ -1330,58 +1330,17 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
13301330
13311331 let suggest_only_tuple_variants =
13321332 matches ! ( source, PathSource :: TupleStruct ( ..) ) || source. is_call ( ) ;
1333- let mut suggestable_variants = if suggest_only_tuple_variants {
1333+ if suggest_only_tuple_variants {
13341334 // Suggest only tuple variants regardless of whether they have fields and do not
13351335 // suggest path with added parenthesis.
1336- variants
1336+ let mut suggestable_variants = variants
13371337 . iter ( )
13381338 . filter ( |( .., kind) | * kind == CtorKind :: Fn )
13391339 . map ( |( variant, ..) | path_names_to_string ( variant) )
1340- . collect :: < Vec < _ > > ( )
1341- } else {
1342- variants
1343- . iter ( )
1344- . filter ( |( _, def_id, kind) | {
1345- // Suggest only variants that have no fields (these can definitely
1346- // be constructed).
1347- let has_fields =
1348- self . r . field_names . get ( & def_id) . map ( |f| f. is_empty ( ) ) . unwrap_or ( false ) ;
1349- match kind {
1350- CtorKind :: Const => true ,
1351- CtorKind :: Fn | CtorKind :: Fictive if has_fields => true ,
1352- _ => false ,
1353- }
1354- } )
1355- . map ( |( variant, _, kind) | ( path_names_to_string ( variant) , kind) )
1356- . map ( |( variant_str, kind) | {
1357- // Add constructor syntax where appropriate.
1358- match kind {
1359- CtorKind :: Const => variant_str,
1360- CtorKind :: Fn => format ! ( "({}())" , variant_str) ,
1361- CtorKind :: Fictive => format ! ( "({} {{}})" , variant_str) ,
1362- }
1363- } )
1364- . collect :: < Vec < _ > > ( )
1365- } ;
1366-
1367- let non_suggestable_variant_count = variants. len ( ) - suggestable_variants. len ( ) ;
1340+ . collect :: < Vec < _ > > ( ) ;
13681341
1369- if !suggestable_variants. is_empty ( ) {
1370- let msg = if non_suggestable_variant_count == 0 && suggestable_variants. len ( ) == 1 {
1371- "try using the enum's variant"
1372- } else {
1373- "try using one of the enum's variants"
1374- } ;
1342+ let non_suggestable_variant_count = variants. len ( ) - suggestable_variants. len ( ) ;
13751343
1376- err. span_suggestions (
1377- span,
1378- msg,
1379- suggestable_variants. drain ( ..) ,
1380- Applicability :: MaybeIncorrect ,
1381- ) ;
1382- }
1383-
1384- if suggest_only_tuple_variants {
13851344 let source_msg = if source. is_call ( ) {
13861345 "to construct"
13871346 } else if matches ! ( source, PathSource :: TupleStruct ( ..) ) {
@@ -1390,6 +1349,21 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
13901349 unreachable ! ( )
13911350 } ;
13921351
1352+ if !suggestable_variants. is_empty ( ) {
1353+ let msg = if non_suggestable_variant_count == 0 && suggestable_variants. len ( ) == 1 {
1354+ format ! ( "try {} the enum's variant" , source_msg)
1355+ } else {
1356+ format ! ( "try {} one of the enum's variants" , source_msg)
1357+ } ;
1358+
1359+ err. span_suggestions (
1360+ span,
1361+ & msg,
1362+ suggestable_variants. drain ( ..) ,
1363+ Applicability :: MaybeIncorrect ,
1364+ ) ;
1365+ }
1366+
13931367 // If the enum has no tuple variants..
13941368 if non_suggestable_variant_count == variants. len ( ) {
13951369 err. help ( & format ! ( "the enum has no tuple variants {}" , source_msg) ) ;
@@ -1408,24 +1382,76 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
14081382 ) ) ;
14091383 }
14101384 } else {
1411- let made_suggestion = non_suggestable_variant_count != variants. len ( ) ;
1412- if made_suggestion {
1413- if non_suggestable_variant_count == 1 {
1414- err. help (
1415- "you might have meant to use the enum's other variant that has fields" ,
1416- ) ;
1417- } else if non_suggestable_variant_count >= 1 {
1418- err. help (
1419- "you might have meant to use one of the enum's other variants that \
1420- have fields",
1421- ) ;
1422- }
1423- } else {
1424- if non_suggestable_variant_count == 1 {
1425- err. help ( "you might have meant to use the enum's variant" ) ;
1426- } else if non_suggestable_variant_count >= 1 {
1427- err. help ( "you might have meant to use one of the enum's variants" ) ;
1385+ let needs_placeholder = |def_id : DefId , kind : CtorKind | {
1386+ let has_no_fields =
1387+ self . r . field_names . get ( & def_id) . map ( |f| f. is_empty ( ) ) . unwrap_or ( false ) ;
1388+ match kind {
1389+ CtorKind :: Const => false ,
1390+ CtorKind :: Fn | CtorKind :: Fictive if has_no_fields => false ,
1391+ _ => true ,
14281392 }
1393+ } ;
1394+
1395+ let mut suggestable_variants = variants
1396+ . iter ( )
1397+ . filter ( |( _, def_id, kind) | !needs_placeholder ( * def_id, * kind) )
1398+ . map ( |( variant, _, kind) | ( path_names_to_string ( variant) , kind) )
1399+ . map ( |( variant, kind) | match kind {
1400+ CtorKind :: Const => variant,
1401+ CtorKind :: Fn => format ! ( "({}())" , variant) ,
1402+ CtorKind :: Fictive => format ! ( "({} {{}})" , variant) ,
1403+ } )
1404+ . collect :: < Vec < _ > > ( ) ;
1405+
1406+ if !suggestable_variants. is_empty ( ) {
1407+ let msg = if suggestable_variants. len ( ) == 1 {
1408+ "you might have meant to use the following enum variant"
1409+ } else {
1410+ "you might have meant to use one of the following enum variants"
1411+ } ;
1412+
1413+ err. span_suggestions (
1414+ span,
1415+ msg,
1416+ suggestable_variants. drain ( ..) ,
1417+ Applicability :: MaybeIncorrect ,
1418+ ) ;
1419+ }
1420+
1421+ let mut suggestable_variants_with_placeholders = variants
1422+ . iter ( )
1423+ . filter ( |( _, def_id, kind) | needs_placeholder ( * def_id, * kind) )
1424+ . map ( |( variant, _, kind) | ( path_names_to_string ( variant) , kind) )
1425+ . filter_map ( |( variant, kind) | match kind {
1426+ CtorKind :: Fn => Some ( format ! ( "({}(/* fields */))" , variant) ) ,
1427+ CtorKind :: Fictive => Some ( format ! ( "({} {{ /* fields */ }})" , variant) ) ,
1428+ _ => None ,
1429+ } )
1430+ . collect :: < Vec < _ > > ( ) ;
1431+
1432+ if !suggestable_variants_with_placeholders. is_empty ( ) {
1433+ let msg = match (
1434+ suggestable_variants. is_empty ( ) ,
1435+ suggestable_variants_with_placeholders. len ( ) ,
1436+ ) {
1437+ ( true , 1 ) => "the following enum variant is available" ,
1438+ ( true , _) => "the following enum variants are available" ,
1439+ ( false , 1 ) => "alternatively, the following enum variant is available" ,
1440+ ( false , _) => "alternatively, the following enum variants are also available" ,
1441+ } ;
1442+
1443+ err. span_suggestions (
1444+ span,
1445+ msg,
1446+ suggestable_variants_with_placeholders. drain ( ..) ,
1447+ Applicability :: HasPlaceholders ,
1448+ ) ;
1449+ }
1450+ } ;
1451+
1452+ if def_id. is_local ( ) {
1453+ if let Some ( span) = self . def_span ( def_id) {
1454+ err. span_note ( span, "the enum is defined here" ) ;
14291455 }
14301456 }
14311457 }
0 commit comments