@@ -1303,15 +1303,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
13031303 _ => { }
13041304 }
13051305
1306+ /// This is a bare signal of what kind of type we're dealing with. `ty::TyKind` tracks
1307+ /// extra information about each type, but we only care about the category.
13061308 #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
1307- enum TyKind {
1309+ enum TyCategory {
13081310 Closure ,
13091311 Opaque ,
13101312 Generator ,
13111313 Foreign ,
13121314 }
13131315
1314- impl TyKind {
1316+ impl TyCategory {
13151317 fn descr ( & self ) -> & ' static str {
13161318 match self {
13171319 Self :: Closure => "closure" ,
@@ -1334,8 +1336,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
13341336
13351337 struct OpaqueTypesVisitor < ' tcx > {
13361338 types : FxHashMap < TyKind , FxHashSet < Span > > ,
1337- expected : FxHashMap < TyKind , FxHashSet < Span > > ,
1338- found : FxHashMap < TyKind , FxHashSet < Span > > ,
1339+ expected : FxHashMap < TyCategory , FxHashSet < Span > > ,
1340+ found : FxHashMap < TyCategory , FxHashSet < Span > > ,
13391341 ignore_span : Span ,
13401342 tcx : TyCtxt < ' tcx > ,
13411343 }
@@ -1354,6 +1356,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
13541356 ignore_span,
13551357 tcx,
13561358 } ;
1359+ // The visitor puts all the relevant encountered types in `self.types`, but in
1360+ // here we want to visit two separate types with no relation to each other, so we
1361+ // move the results from `types` to `expected` or `found` as appropriate.
13571362 expected. visit_with ( & mut types_visitor) ;
13581363 std:: mem:: swap ( & mut types_visitor. expected , & mut types_visitor. types ) ;
13591364 found. visit_with ( & mut types_visitor) ;
@@ -1362,28 +1367,37 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
13621367 }
13631368
13641369 fn report ( & self , err : & mut DiagnosticBuilder < ' _ > ) {
1365- for ( target, types) in & [ ( "expected" , & self . expected ) , ( "found" , & self . found ) ] {
1366- for ( key, values) in types. iter ( ) {
1367- let count = values. len ( ) ;
1368- for sp in values {
1369- err. span_label (
1370- * sp,
1371- format ! (
1372- "{}{}{} {}{}" ,
1373- if sp. is_desugaring( DesugaringKind :: Async ) {
1374- "the `Output` of this `async fn`'s "
1375- } else if count == 1 {
1376- "the "
1377- } else {
1378- ""
1379- } ,
1380- if count > 1 { "one of the " } else { "" } ,
1381- target,
1382- key. descr( ) ,
1383- pluralize!( count) ,
1384- ) ,
1385- ) ;
1386- }
1370+ self . add_labels_for_types ( err, "expected" , & self . expected ) ;
1371+ self . add_labels_for_types ( err, "found" , & self . found ) ;
1372+ }
1373+
1374+ fn add_labels_for_types (
1375+ & self ,
1376+ err : & mut DiagnosticBuilder < ' _ > ,
1377+ target : & str ,
1378+ types : & FxHashMap < TyKind , FxHashSet < Span > > ,
1379+ ) {
1380+ for ( key, values) in types. iter ( ) {
1381+ let count = values. len ( ) ;
1382+ let kind = key. descr ( ) ;
1383+ for sp in values {
1384+ err. span_label (
1385+ * sp,
1386+ format ! (
1387+ "{}{}{} {}{}" ,
1388+ if sp. is_desugaring( DesugaringKind :: Async ) {
1389+ "the `Output` of this `async fn`'s "
1390+ } else if count == 1 {
1391+ "the "
1392+ } else {
1393+ ""
1394+ } ,
1395+ if count > 1 { "one of the " } else { "" } ,
1396+ target,
1397+ key,
1398+ pluralize!( count) ,
1399+ ) ,
1400+ ) ;
13871401 }
13881402 }
13891403 }
0 commit comments