@@ -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 ) ]
@@ -1158,7 +1155,7 @@ trait InferCtxtPrivExt<'hir, 'tcx> {
11581155 error : & MismatchedProjectionTypes < ' tcx > ,
11591156 ) ;
11601157
1161- fn fuzzy_match_tys ( & self , a : Ty < ' tcx > , b : Ty < ' tcx > , strip_references : StripReferences ) -> bool ;
1158+ fn fuzzy_match_tys ( & self , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> bool ;
11621159
11631160 fn describe_generator ( & self , body_id : hir:: BodyId ) -> Option < & ' static str > ;
11641161
@@ -1461,7 +1458,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
14611458 } ) ;
14621459 }
14631460
1464- fn fuzzy_match_tys ( & self , a : Ty < ' tcx > , b : Ty < ' tcx > , strip_references : StripReferences ) -> bool {
1461+ fn fuzzy_match_tys ( & self , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> bool {
14651462 /// returns the fuzzy category of a given type, or None
14661463 /// if the type can be equated to any type.
14671464 fn type_category ( t : Ty < ' _ > ) -> Option < u32 > {
@@ -1481,19 +1478,15 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
14811478 ty:: Param ( ..) => Some ( 12 ) ,
14821479 ty:: Opaque ( ..) => Some ( 13 ) ,
14831480 ty:: Never => Some ( 14 ) ,
1484- ty:: Adt ( adt, ..) => match adt. adt_kind ( ) {
1485- AdtKind :: Struct => Some ( 15 ) ,
1486- AdtKind :: Union => Some ( 16 ) ,
1487- AdtKind :: Enum => Some ( 17 ) ,
1488- } ,
1489- ty:: Generator ( ..) => Some ( 18 ) ,
1490- ty:: Foreign ( ..) => Some ( 19 ) ,
1491- ty:: GeneratorWitness ( ..) => Some ( 20 ) ,
1481+ ty:: Adt ( ..) => Some ( 15 ) ,
1482+ ty:: Generator ( ..) => Some ( 16 ) ,
1483+ ty:: Foreign ( ..) => Some ( 17 ) ,
1484+ ty:: GeneratorWitness ( ..) => Some ( 18 ) ,
14921485 ty:: Placeholder ( ..) | ty:: Bound ( ..) | ty:: Infer ( ..) | ty:: Error ( _) => None ,
14931486 }
14941487 }
14951488
1496- let strip_reference = |mut t : Ty < ' tcx > | -> Ty < ' tcx > {
1489+ let strip_references = |mut t : Ty < ' tcx > | -> Ty < ' tcx > {
14971490 loop {
14981491 match t. kind ( ) {
14991492 ty:: Ref ( _, inner, _) | ty:: RawPtr ( ty:: TypeAndMut { ty : inner, .. } ) => {
@@ -1504,16 +1497,14 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
15041497 }
15051498 } ;
15061499
1507- let ( a, b) = if strip_references == StripReferences :: Yes {
1508- ( strip_reference ( a) , strip_reference ( b) )
1509- } else {
1510- ( a, b)
1511- } ;
1512-
15131500 match ( type_category ( a) , type_category ( b) ) {
15141501 ( Some ( cat_a) , Some ( cat_b) ) => match ( a. kind ( ) , b. kind ( ) ) {
1515- ( & ty:: Adt ( def_a, _) , & ty:: Adt ( def_b, _) ) => def_a == def_b,
1516- _ => cat_a == cat_b,
1502+ ( ty:: Adt ( def_a, _) , ty:: Adt ( def_b, _) ) => def_a == def_b,
1503+ _ if cat_a == cat_b => true ,
1504+ ( ty:: Ref ( ..) , _) | ( _, ty:: Ref ( ..) ) => {
1505+ self . fuzzy_match_tys ( strip_references ( a) , strip_references ( b) )
1506+ }
1507+ _ => false ,
15171508 } ,
15181509 // infer and error can be equated to all types
15191510 _ => true ,
@@ -1533,87 +1524,33 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
15331524 & self ,
15341525 trait_ref : ty:: PolyTraitRef < ' tcx > ,
15351526 ) -> Vec < ImplCandidate < ' tcx > > {
1536- // We simplify params and strip references here.
1537- //
1538- // This both removes a lot of unhelpful suggestions, e.g.
1539- // when searching for `&Foo: Trait` it doesn't suggestion `impl Trait for &Bar`,
1540- // while also suggesting impls for `&Foo` when we're looking for `Foo: Trait`.
1541- //
1542- // The second thing isn't necessarily always a good thing, but
1543- // any other simple setup results in a far worse output, so 🤷
1544- let simp = fast_reject:: simplify_type (
1545- self . tcx ,
1546- trait_ref. skip_binder ( ) . self_ty ( ) ,
1547- SimplifyParams :: Yes ,
1548- StripReferences :: Yes ,
1549- ) ;
1550- let all_impls = self . tcx . all_impls ( trait_ref. def_id ( ) ) ;
1551-
1552- match simp {
1553- Some ( simp) => {
1554- all_impls
1555- . filter_map ( |def_id| {
1556- if self . tcx . impl_polarity ( def_id) == ty:: ImplPolarity :: Negative {
1557- return None ;
1558- }
1527+ self . tcx
1528+ . all_impls ( trait_ref. def_id ( ) )
1529+ . filter_map ( |def_id| {
1530+ if self . tcx . impl_polarity ( def_id) == ty:: ImplPolarity :: Negative {
1531+ return None ;
1532+ }
15591533
1560- let imp = self . tcx . impl_trait_ref ( def_id) . unwrap ( ) ;
1534+ let imp = self . tcx . impl_trait_ref ( def_id) . unwrap ( ) ;
15611535
1562- // Check for exact match.
1563- if trait_ref. skip_binder ( ) . self_ty ( ) == imp. self_ty ( ) {
1564- return Some ( ImplCandidate {
1565- trait_ref : imp,
1566- similarity : CandidateSimilarity :: Exact ,
1567- } ) ;
1568- }
1569-
1570- // Check for match between simplified types.
1571- let imp_simp = fast_reject:: simplify_type (
1572- self . tcx ,
1573- imp. self_ty ( ) ,
1574- SimplifyParams :: Yes ,
1575- StripReferences :: Yes ,
1576- ) ;
1577- if let Some ( imp_simp) = imp_simp {
1578- if simp == imp_simp {
1579- return Some ( ImplCandidate {
1580- trait_ref : imp,
1581- similarity : CandidateSimilarity :: Simplified ,
1582- } ) ;
1583- }
1584- }
1536+ // Check for exact match.
1537+ if trait_ref. skip_binder ( ) . self_ty ( ) == imp. self_ty ( ) {
1538+ return Some ( ImplCandidate {
1539+ trait_ref : imp,
1540+ similarity : CandidateSimilarity :: Exact ,
1541+ } ) ;
1542+ }
15851543
1586- // Check for fuzzy match.
1587- // Pass `StripReferences::Yes` because although we do want to
1588- // be fuzzier than `simplify_type`, we don't want to be
1589- // *too* fuzzy.
1590- if self . fuzzy_match_tys (
1591- trait_ref. skip_binder ( ) . self_ty ( ) ,
1592- imp. self_ty ( ) ,
1593- StripReferences :: Yes ,
1594- ) {
1595- return Some ( ImplCandidate {
1596- trait_ref : imp,
1597- similarity : CandidateSimilarity :: Fuzzy ,
1598- } ) ;
1599- }
1544+ if self . fuzzy_match_tys ( trait_ref. skip_binder ( ) . self_ty ( ) , imp. self_ty ( ) ) {
1545+ return Some ( ImplCandidate {
1546+ trait_ref : imp,
1547+ similarity : CandidateSimilarity :: Fuzzy ,
1548+ } ) ;
1549+ }
16001550
1601- None
1602- } )
1603- . collect ( )
1604- }
1605- None => all_impls
1606- . filter_map ( |def_id| {
1607- if self . tcx . impl_polarity ( def_id) == ty:: ImplPolarity :: Negative {
1608- return None ;
1609- }
1610- self . tcx . impl_trait_ref ( def_id) . map ( |trait_ref| ImplCandidate {
1611- trait_ref,
1612- similarity : CandidateSimilarity :: Unknown ,
1613- } )
1614- } )
1615- . collect ( ) ,
1616- }
1551+ None
1552+ } )
1553+ . collect ( )
16171554 }
16181555
16191556 fn report_similar_impl_candidates (
0 commit comments