@@ -21,10 +21,9 @@ use rustc_hir::Item;
21
21
use rustc_hir:: Node ;
22
22
use rustc_middle:: thir:: abstract_const:: NotConstEvaluatable ;
23
23
use rustc_middle:: ty:: error:: ExpectedFound ;
24
- use rustc_middle:: ty:: fast_reject:: { self , SimplifyParams , StripReferences } ;
25
24
use rustc_middle:: ty:: fold:: TypeFolder ;
26
25
use rustc_middle:: ty:: {
27
- self , AdtKind , SubtypePredicate , ToPolyTraitRef , ToPredicate , Ty , TyCtxt , TypeFoldable ,
26
+ self , SubtypePredicate , ToPolyTraitRef , ToPredicate , Ty , TyCtxt , TypeFoldable ,
28
27
} ;
29
28
use rustc_session:: DiagnosticMessageId ;
30
29
use rustc_span:: symbol:: { kw, sym} ;
@@ -44,9 +43,7 @@ pub use rustc_infer::traits::error_reporting::*;
44
43
#[ derive( Debug , Copy , Clone , PartialEq , Eq , PartialOrd , Ord ) ]
45
44
pub enum CandidateSimilarity {
46
45
Exact ,
47
- Simplified ,
48
46
Fuzzy ,
49
- Unknown ,
50
47
}
51
48
52
49
#[ derive( Debug , Clone , Copy ) ]
@@ -1099,7 +1096,7 @@ trait InferCtxtPrivExt<'hir, 'tcx> {
1099
1096
error : & MismatchedProjectionTypes < ' tcx > ,
1100
1097
) ;
1101
1098
1102
- fn fuzzy_match_tys ( & self , a : Ty < ' tcx > , b : Ty < ' tcx > , strip_references : StripReferences ) -> bool ;
1099
+ fn fuzzy_match_tys ( & self , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> bool ;
1103
1100
1104
1101
fn describe_generator ( & self , body_id : hir:: BodyId ) -> Option < & ' static str > ;
1105
1102
@@ -1404,7 +1401,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
1404
1401
} ) ;
1405
1402
}
1406
1403
1407
- fn fuzzy_match_tys ( & self , a : Ty < ' tcx > , b : Ty < ' tcx > , strip_references : StripReferences ) -> bool {
1404
+ fn fuzzy_match_tys ( & self , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> bool {
1408
1405
/// returns the fuzzy category of a given type, or None
1409
1406
/// if the type can be equated to any type.
1410
1407
fn type_category ( t : Ty < ' _ > ) -> Option < u32 > {
@@ -1424,19 +1421,15 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
1424
1421
ty:: Param ( ..) => Some ( 12 ) ,
1425
1422
ty:: Opaque ( ..) => Some ( 13 ) ,
1426
1423
ty:: Never => Some ( 14 ) ,
1427
- ty:: Adt ( adt, ..) => match adt. adt_kind ( ) {
1428
- AdtKind :: Struct => Some ( 15 ) ,
1429
- AdtKind :: Union => Some ( 16 ) ,
1430
- AdtKind :: Enum => Some ( 17 ) ,
1431
- } ,
1432
- ty:: Generator ( ..) => Some ( 18 ) ,
1433
- ty:: Foreign ( ..) => Some ( 19 ) ,
1434
- ty:: GeneratorWitness ( ..) => Some ( 20 ) ,
1424
+ ty:: Adt ( ..) => Some ( 15 ) ,
1425
+ ty:: Generator ( ..) => Some ( 16 ) ,
1426
+ ty:: Foreign ( ..) => Some ( 17 ) ,
1427
+ ty:: GeneratorWitness ( ..) => Some ( 18 ) ,
1435
1428
ty:: Placeholder ( ..) | ty:: Bound ( ..) | ty:: Infer ( ..) | ty:: Error ( _) => None ,
1436
1429
}
1437
1430
}
1438
1431
1439
- let strip_reference = |mut t : Ty < ' tcx > | -> Ty < ' tcx > {
1432
+ let strip_references = |mut t : Ty < ' tcx > | -> Ty < ' tcx > {
1440
1433
loop {
1441
1434
match t. kind ( ) {
1442
1435
ty:: Ref ( _, inner, _) | ty:: RawPtr ( ty:: TypeAndMut { ty : inner, .. } ) => {
@@ -1447,16 +1440,14 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
1447
1440
}
1448
1441
} ;
1449
1442
1450
- let ( a, b) = if strip_references == StripReferences :: Yes {
1451
- ( strip_reference ( a) , strip_reference ( b) )
1452
- } else {
1453
- ( a, b)
1454
- } ;
1455
-
1456
1443
match ( type_category ( a) , type_category ( b) ) {
1457
1444
( Some ( cat_a) , Some ( cat_b) ) => match ( a. kind ( ) , b. kind ( ) ) {
1458
- ( & ty:: Adt ( def_a, _) , & ty:: Adt ( def_b, _) ) => def_a == def_b,
1459
- _ => cat_a == cat_b,
1445
+ ( ty:: Adt ( def_a, _) , ty:: Adt ( def_b, _) ) => def_a == def_b,
1446
+ _ if cat_a == cat_b => true ,
1447
+ ( ty:: Ref ( ..) , _) | ( _, ty:: Ref ( ..) ) => {
1448
+ self . fuzzy_match_tys ( strip_references ( a) , strip_references ( b) )
1449
+ }
1450
+ _ => false ,
1460
1451
} ,
1461
1452
// infer and error can be equated to all types
1462
1453
_ => true ,
@@ -1476,87 +1467,33 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
1476
1467
& self ,
1477
1468
trait_ref : ty:: PolyTraitRef < ' tcx > ,
1478
1469
) -> Vec < ImplCandidate < ' tcx > > {
1479
- // We simplify params and strip references here.
1480
- //
1481
- // This both removes a lot of unhelpful suggestions, e.g.
1482
- // when searching for `&Foo: Trait` it doesn't suggestion `impl Trait for &Bar`,
1483
- // while also suggesting impls for `&Foo` when we're looking for `Foo: Trait`.
1484
- //
1485
- // The second thing isn't necessarily always a good thing, but
1486
- // any other simple setup results in a far worse output, so 🤷
1487
- let simp = fast_reject:: simplify_type (
1488
- self . tcx ,
1489
- trait_ref. skip_binder ( ) . self_ty ( ) ,
1490
- SimplifyParams :: Yes ,
1491
- StripReferences :: Yes ,
1492
- ) ;
1493
- let all_impls = self . tcx . all_impls ( trait_ref. def_id ( ) ) ;
1494
-
1495
- match simp {
1496
- Some ( simp) => {
1497
- all_impls
1498
- . filter_map ( |def_id| {
1499
- if self . tcx . impl_polarity ( def_id) == ty:: ImplPolarity :: Negative {
1500
- return None ;
1501
- }
1470
+ self . tcx
1471
+ . all_impls ( trait_ref. def_id ( ) )
1472
+ . filter_map ( |def_id| {
1473
+ if self . tcx . impl_polarity ( def_id) == ty:: ImplPolarity :: Negative {
1474
+ return None ;
1475
+ }
1502
1476
1503
- let imp = self . tcx . impl_trait_ref ( def_id) . unwrap ( ) ;
1477
+ let imp = self . tcx . impl_trait_ref ( def_id) . unwrap ( ) ;
1504
1478
1505
- // Check for exact match.
1506
- if trait_ref. skip_binder ( ) . self_ty ( ) == imp. self_ty ( ) {
1507
- return Some ( ImplCandidate {
1508
- trait_ref : imp,
1509
- similarity : CandidateSimilarity :: Exact ,
1510
- } ) ;
1511
- }
1512
-
1513
- // Check for match between simplified types.
1514
- let imp_simp = fast_reject:: simplify_type (
1515
- self . tcx ,
1516
- imp. self_ty ( ) ,
1517
- SimplifyParams :: Yes ,
1518
- StripReferences :: Yes ,
1519
- ) ;
1520
- if let Some ( imp_simp) = imp_simp {
1521
- if simp == imp_simp {
1522
- return Some ( ImplCandidate {
1523
- trait_ref : imp,
1524
- similarity : CandidateSimilarity :: Simplified ,
1525
- } ) ;
1526
- }
1527
- }
1479
+ // Check for exact match.
1480
+ if trait_ref. skip_binder ( ) . self_ty ( ) == imp. self_ty ( ) {
1481
+ return Some ( ImplCandidate {
1482
+ trait_ref : imp,
1483
+ similarity : CandidateSimilarity :: Exact ,
1484
+ } ) ;
1485
+ }
1528
1486
1529
- // Check for fuzzy match.
1530
- // Pass `StripReferences::Yes` because although we do want to
1531
- // be fuzzier than `simplify_type`, we don't want to be
1532
- // *too* fuzzy.
1533
- if self . fuzzy_match_tys (
1534
- trait_ref. skip_binder ( ) . self_ty ( ) ,
1535
- imp. self_ty ( ) ,
1536
- StripReferences :: Yes ,
1537
- ) {
1538
- return Some ( ImplCandidate {
1539
- trait_ref : imp,
1540
- similarity : CandidateSimilarity :: Fuzzy ,
1541
- } ) ;
1542
- }
1487
+ if self . fuzzy_match_tys ( trait_ref. skip_binder ( ) . self_ty ( ) , imp. self_ty ( ) ) {
1488
+ return Some ( ImplCandidate {
1489
+ trait_ref : imp,
1490
+ similarity : CandidateSimilarity :: Fuzzy ,
1491
+ } ) ;
1492
+ }
1543
1493
1544
- None
1545
- } )
1546
- . collect ( )
1547
- }
1548
- None => all_impls
1549
- . filter_map ( |def_id| {
1550
- if self . tcx . impl_polarity ( def_id) == ty:: ImplPolarity :: Negative {
1551
- return None ;
1552
- }
1553
- self . tcx . impl_trait_ref ( def_id) . map ( |trait_ref| ImplCandidate {
1554
- trait_ref,
1555
- similarity : CandidateSimilarity :: Unknown ,
1556
- } )
1557
- } )
1558
- . collect ( ) ,
1559
- }
1494
+ None
1495
+ } )
1496
+ . collect ( )
1560
1497
}
1561
1498
1562
1499
fn report_similar_impl_candidates (
0 commit comments