@@ -21,10 +21,9 @@ use rustc_hir::Item;
2121use rustc_hir:: Node ;
2222use rustc_middle:: thir:: abstract_const:: NotConstEvaluatable ;
2323use rustc_middle:: ty:: error:: ExpectedFound ;
24- use rustc_middle:: ty:: fast_reject:: { self , SimplifyParams , StripReferences } ;
2524use rustc_middle:: ty:: fold:: TypeFolder ;
2625use rustc_middle:: ty:: {
27- self , AdtKind , SubtypePredicate , ToPolyTraitRef , ToPredicate , Ty , TyCtxt , TypeFoldable ,
26+ self , SubtypePredicate , ToPolyTraitRef , ToPredicate , Ty , TyCtxt , TypeFoldable ,
2827} ;
2928use rustc_session:: DiagnosticMessageId ;
3029use rustc_span:: symbol:: { kw, sym} ;
@@ -44,9 +43,7 @@ pub use rustc_infer::traits::error_reporting::*;
4443#[ derive( Debug , Copy , Clone , PartialEq , Eq , PartialOrd , Ord ) ]
4544pub enum CandidateSimilarity {
4645 Exact ,
47- Simplified ,
4846 Fuzzy ,
49- Unknown ,
5047}
5148
5249#[ derive( Debug , Clone , Copy ) ]
@@ -1099,7 +1096,7 @@ trait InferCtxtPrivExt<'hir, 'tcx> {
10991096 error : & MismatchedProjectionTypes < ' tcx > ,
11001097 ) ;
11011098
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 ;
11031100
11041101 fn describe_generator ( & self , body_id : hir:: BodyId ) -> Option < & ' static str > ;
11051102
@@ -1404,7 +1401,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
14041401 } ) ;
14051402 }
14061403
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 {
14081405 /// returns the fuzzy category of a given type, or None
14091406 /// if the type can be equated to any type.
14101407 fn type_category ( t : Ty < ' _ > ) -> Option < u32 > {
@@ -1424,19 +1421,15 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
14241421 ty:: Param ( ..) => Some ( 12 ) ,
14251422 ty:: Opaque ( ..) => Some ( 13 ) ,
14261423 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 ) ,
14351428 ty:: Placeholder ( ..) | ty:: Bound ( ..) | ty:: Infer ( ..) | ty:: Error ( _) => None ,
14361429 }
14371430 }
14381431
1439- let strip_reference = |mut t : Ty < ' tcx > | -> Ty < ' tcx > {
1432+ let strip_references = |mut t : Ty < ' tcx > | -> Ty < ' tcx > {
14401433 loop {
14411434 match t. kind ( ) {
14421435 ty:: Ref ( _, inner, _) | ty:: RawPtr ( ty:: TypeAndMut { ty : inner, .. } ) => {
@@ -1447,16 +1440,14 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
14471440 }
14481441 } ;
14491442
1450- let ( a, b) = if strip_references == StripReferences :: Yes {
1451- ( strip_reference ( a) , strip_reference ( b) )
1452- } else {
1453- ( a, b)
1454- } ;
1455-
14561443 match ( type_category ( a) , type_category ( b) ) {
14571444 ( 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 ,
14601451 } ,
14611452 // infer and error can be equated to all types
14621453 _ => true ,
@@ -1476,87 +1467,33 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
14761467 & self ,
14771468 trait_ref : ty:: PolyTraitRef < ' tcx > ,
14781469 ) -> 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+ }
15021476
1503- let imp = self . tcx . impl_trait_ref ( def_id) . unwrap ( ) ;
1477+ let imp = self . tcx . impl_trait_ref ( def_id) . unwrap ( ) ;
15041478
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+ }
15281486
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+ }
15431493
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 ( )
15601497 }
15611498
15621499 fn report_similar_impl_candidates (
0 commit comments