@@ -27,20 +27,21 @@ use rustc_hir::def_id::{DefId, LocalDefId};
27
27
use rustc_hir:: intravisit:: { walk_generics, Visitor as _} ;
28
28
use rustc_hir:: { GenericArg , GenericArgs , OpaqueTyOrigin } ;
29
29
use rustc_infer:: infer:: { InferCtxt , InferOk , TyCtxtInferExt } ;
30
- use rustc_infer:: traits:: ObligationCause ;
30
+ use rustc_infer:: traits:: { Obligation , ObligationCause } ;
31
31
use rustc_middle:: middle:: stability:: AllowUnstable ;
32
32
use rustc_middle:: ty:: GenericParamDefKind ;
33
33
use rustc_middle:: ty:: {
34
- self , Const , GenericArgKind , GenericArgsRef , IsSuggestable , Ty , TyCtxt , TypeVisitableExt ,
34
+ self , Const , GenericArgKind , GenericArgsRef , IsSuggestable , ParamEnv , Predicate , Ty , TyCtxt ,
35
+ TypeFoldable , TypeVisitableExt ,
35
36
} ;
36
37
use rustc_session:: lint:: builtin:: AMBIGUOUS_ASSOCIATED_ITEMS ;
37
38
use rustc_span:: edit_distance:: find_best_match_for_name;
38
39
use rustc_span:: symbol:: { kw, Ident , Symbol } ;
39
40
use rustc_span:: { sym, BytePos , Span , DUMMY_SP } ;
40
41
use rustc_target:: spec:: abi;
42
+ use rustc_trait_selection:: solve:: eval_ctxt:: canonical:: EagerResolver ;
41
43
use rustc_trait_selection:: traits:: wf:: object_region_bounds;
42
44
use rustc_trait_selection:: traits:: { self , NormalizeExt , ObligationCtxt } ;
43
- use rustc_type_ir:: fold:: { TypeFoldable , TypeFolder , TypeSuperFoldable } ;
44
45
45
46
use std:: fmt:: Display ;
46
47
use std:: slice;
@@ -1608,134 +1609,122 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1608
1609
let param_env = tcx. param_env ( block. owner ) ;
1609
1610
let cause = ObligationCause :: misc ( span, block. owner . def_id ) ;
1610
1611
1611
- let mut fulfillment_errors = Vec :: new ( ) ;
1612
- let mut applicable_candidates: Vec < _ > = infcx. probe ( |_| {
1613
- // Regions are not considered during selection.
1614
- let self_ty = self_ty
1615
- . fold_with ( & mut BoundVarEraser { tcx, universe : infcx. create_next_universe ( ) } ) ;
1616
-
1617
- struct BoundVarEraser < ' tcx > {
1618
- tcx : TyCtxt < ' tcx > ,
1619
- universe : ty:: UniverseIndex ,
1620
- }
1621
-
1622
- // FIXME(non_lifetime_binders): Don't assign the same universe to each placeholder.
1623
- impl < ' tcx > TypeFolder < TyCtxt < ' tcx > > for BoundVarEraser < ' tcx > {
1624
- fn interner ( & self ) -> TyCtxt < ' tcx > {
1625
- self . tcx
1626
- }
1612
+ let mut universes = if self_ty. has_escaping_bound_vars ( ) {
1613
+ vec ! [ None ; self_ty. outer_exclusive_binder( ) . as_usize( ) ]
1614
+ } else {
1615
+ vec ! [ ]
1616
+ } ;
1627
1617
1628
- fn fold_region ( & mut self , r : ty:: Region < ' tcx > ) -> ty:: Region < ' tcx > {
1629
- // FIXME(@lcnr): This is broken, erasing bound regions
1630
- // impacts selection as it results in different types.
1631
- if r. is_bound ( ) { self . tcx . lifetimes . re_erased } else { r }
1632
- }
1618
+ crate :: traits:: project:: with_replaced_escaping_bound_vars (
1619
+ infcx,
1620
+ & mut universes,
1621
+ self_ty,
1622
+ |self_ty| {
1623
+ let tcx = self . tcx ( ) ;
1624
+ let InferOk { value : self_ty, obligations } =
1625
+ infcx. at ( & cause, param_env) . normalize ( self_ty) ;
1626
+
1627
+ let ( impl_, ( assoc_item, def_scope) ) = self . select_inherent_assoc_type_candidates (
1628
+ infcx,
1629
+ name,
1630
+ span,
1631
+ self_ty,
1632
+ cause,
1633
+ param_env,
1634
+ obligations,
1635
+ candidates,
1636
+ ) ?;
1637
+
1638
+ self . check_assoc_ty ( assoc_item, name, def_scope, block, span) ;
1639
+
1640
+ // FIXME(fmease): Currently creating throwaway `parent_args` to please
1641
+ // `create_args_for_associated_item`. Modify the latter instead (or sth. similar) to
1642
+ // not require the parent args logic.
1643
+ let parent_args = ty:: GenericArgs :: identity_for_item ( tcx, impl_) ;
1644
+ let args =
1645
+ self . create_args_for_associated_item ( span, assoc_item, segment, parent_args) ;
1646
+ let args = tcx. mk_args_from_iter (
1647
+ std:: iter:: once ( ty:: GenericArg :: from ( self_ty) )
1648
+ . chain ( args. into_iter ( ) . skip ( parent_args. len ( ) ) ) ,
1649
+ ) ;
1633
1650
1634
- fn fold_ty ( & mut self , ty : Ty < ' tcx > ) -> Ty < ' tcx > {
1635
- match * ty. kind ( ) {
1636
- ty:: Bound ( _, bv) => Ty :: new_placeholder (
1637
- self . tcx ,
1638
- ty:: PlaceholderType { universe : self . universe , bound : bv } ,
1639
- ) ,
1640
- _ => ty. super_fold_with ( self ) ,
1641
- }
1642
- }
1651
+ let ty = Ty :: new_alias ( tcx, ty:: Inherent , ty:: AliasTy :: new ( tcx, assoc_item, args) ) ;
1652
+ let ty = ty. fold_with ( & mut EagerResolver { infcx } ) ;
1643
1653
1644
- fn fold_const (
1645
- & mut self ,
1646
- ct : ty:: Const < ' tcx > ,
1647
- ) -> <TyCtxt < ' tcx > as rustc_type_ir:: Interner >:: Const {
1648
- assert ! ( !ct. ty( ) . has_escaping_bound_vars( ) ) ;
1649
-
1650
- match ct. kind ( ) {
1651
- ty:: ConstKind :: Bound ( _, bv) => ty:: Const :: new_placeholder (
1652
- self . tcx ,
1653
- ty:: PlaceholderConst { universe : self . universe , bound : bv } ,
1654
- ct. ty ( ) ,
1655
- ) ,
1656
- _ => ct. super_fold_with ( self ) ,
1657
- }
1658
- }
1659
- }
1654
+ Ok ( Some ( ( ty, assoc_item) ) )
1655
+ } ,
1656
+ )
1657
+ }
1660
1658
1661
- let InferOk { value : self_ty, obligations } =
1662
- infcx. at ( & cause, param_env) . normalize ( self_ty) ;
1659
+ fn select_inherent_assoc_type_candidates (
1660
+ & self ,
1661
+ infcx : & InferCtxt < ' tcx > ,
1662
+ name : Ident ,
1663
+ span : Span ,
1664
+ self_ty : Ty < ' tcx > ,
1665
+ cause : ObligationCause < ' tcx > ,
1666
+ param_env : ParamEnv < ' tcx > ,
1667
+ obligations : Vec < Obligation < ' tcx , Predicate < ' tcx > > > ,
1668
+ candidates : Vec < ( DefId , ( DefId , DefId ) ) > ,
1669
+ ) -> Result < ( DefId , ( DefId , DefId ) ) , ErrorGuaranteed > {
1670
+ let tcx = self . tcx ( ) ;
1671
+ let mut fulfillment_errors = Vec :: new ( ) ;
1663
1672
1664
- candidates
1665
- . iter ( )
1666
- . copied ( )
1667
- . filter ( |& ( impl_, _) | {
1668
- infcx. probe ( |_| {
1669
- let ocx = ObligationCtxt :: new ( infcx) ;
1670
- ocx. register_obligations ( obligations. clone ( ) ) ;
1671
-
1672
- let impl_args = infcx. fresh_args_for_item ( span, impl_) ;
1673
- let impl_ty = tcx. type_of ( impl_) . instantiate ( tcx, impl_args) ;
1674
- let impl_ty = ocx. normalize ( & cause, param_env, impl_ty) ;
1675
-
1676
- // Check that the self types can be related.
1677
- // FIXME(inherent_associated_types): Should we use `eq` here? Method probing uses
1678
- // `sup` for this situtation, too. What for? To constrain inference variables?
1679
- if ocx. sup ( & ObligationCause :: dummy ( ) , param_env, impl_ty, self_ty) . is_err ( )
1680
- {
1681
- return false ;
1682
- }
1673
+ let applicable_candidates: Vec < _ > = candidates
1674
+ . iter ( )
1675
+ . copied ( )
1676
+ . filter ( |& ( impl_, _) | {
1677
+ infcx. probe ( |_| {
1678
+ let ocx = ObligationCtxt :: new ( infcx) ;
1679
+ ocx. register_obligations ( obligations. clone ( ) ) ;
1680
+
1681
+ let impl_args = infcx. fresh_args_for_item ( span, impl_) ;
1682
+ let impl_ty = tcx. type_of ( impl_) . instantiate ( tcx, impl_args) ;
1683
+ let impl_ty = ocx. normalize ( & cause, param_env, impl_ty) ;
1684
+
1685
+ // Check that the self types can be related.
1686
+ if ocx. eq ( & ObligationCause :: dummy ( ) , param_env, impl_ty, self_ty) . is_err ( ) {
1687
+ return false ;
1688
+ }
1683
1689
1684
- // Check whether the impl imposes obligations we have to worry about.
1685
- let impl_bounds = tcx. predicates_of ( impl_) . instantiate ( tcx, impl_args) ;
1686
- let impl_bounds = ocx. normalize ( & cause, param_env, impl_bounds) ;
1687
- let impl_obligations = traits:: predicates_for_generics (
1688
- |_, _| cause. clone ( ) ,
1689
- param_env,
1690
- impl_bounds,
1691
- ) ;
1692
- ocx. register_obligations ( impl_obligations) ;
1690
+ // Check whether the impl imposes obligations we have to worry about.
1691
+ let impl_bounds = tcx. predicates_of ( impl_) . instantiate ( tcx, impl_args) ;
1692
+ let impl_bounds = ocx. normalize ( & cause, param_env, impl_bounds) ;
1693
+ let impl_obligations = traits:: predicates_for_generics (
1694
+ |_, _| cause. clone ( ) ,
1695
+ param_env,
1696
+ impl_bounds,
1697
+ ) ;
1698
+ ocx. register_obligations ( impl_obligations) ;
1693
1699
1694
- let mut errors = ocx. select_where_possible ( ) ;
1695
- if !errors. is_empty ( ) {
1696
- fulfillment_errors. append ( & mut errors) ;
1697
- return false ;
1698
- }
1700
+ let mut errors = ocx. select_where_possible ( ) ;
1701
+ if !errors. is_empty ( ) {
1702
+ fulfillment_errors. append ( & mut errors) ;
1703
+ return false ;
1704
+ }
1699
1705
1700
- true
1701
- } )
1706
+ true
1702
1707
} )
1703
- . collect ( )
1704
- } ) ;
1708
+ } )
1709
+ . collect ( ) ;
1705
1710
1706
- if applicable_candidates. len ( ) > 1 {
1707
- return Err ( self . complain_about_ambiguous_inherent_assoc_type (
1711
+ match & applicable_candidates[ .. ] {
1712
+ & [ ] => Err ( self . complain_about_inherent_assoc_type_not_found (
1708
1713
name,
1709
- applicable_candidates. into_iter ( ) . map ( |( _, ( candidate, _) ) | candidate) . collect ( ) ,
1714
+ self_ty,
1715
+ candidates,
1716
+ fulfillment_errors,
1710
1717
span,
1711
- ) ) ;
1712
- }
1713
-
1714
- if let Some ( ( impl_, ( assoc_item, def_scope) ) ) = applicable_candidates. pop ( ) {
1715
- self . check_assoc_ty ( assoc_item, name, def_scope, block, span) ;
1716
-
1717
- // FIXME(fmease): Currently creating throwaway `parent_args` to please
1718
- // `create_args_for_associated_item`. Modify the latter instead (or sth. similar) to
1719
- // not require the parent args logic.
1720
- let parent_args = ty:: GenericArgs :: identity_for_item ( tcx, impl_) ;
1721
- let args = self . create_args_for_associated_item ( span, assoc_item, segment, parent_args) ;
1722
- let args = tcx. mk_args_from_iter (
1723
- std:: iter:: once ( ty:: GenericArg :: from ( self_ty) )
1724
- . chain ( args. into_iter ( ) . skip ( parent_args. len ( ) ) ) ,
1725
- ) ;
1718
+ ) ) ,
1726
1719
1727
- let ty = Ty :: new_alias ( tcx , ty :: Inherent , ty :: AliasTy :: new ( tcx , assoc_item , args ) ) ;
1720
+ & [ applicable_candidate ] => Ok ( applicable_candidate ) ,
1728
1721
1729
- return Ok ( Some ( ( ty, assoc_item) ) ) ;
1722
+ & [ _, ..] => Err ( self . complain_about_ambiguous_inherent_assoc_type (
1723
+ name,
1724
+ applicable_candidates. into_iter ( ) . map ( |( _, ( candidate, _) ) | candidate) . collect ( ) ,
1725
+ span,
1726
+ ) ) ,
1730
1727
}
1731
-
1732
- Err ( self . complain_about_inherent_assoc_type_not_found (
1733
- name,
1734
- self_ty,
1735
- candidates,
1736
- fulfillment_errors,
1737
- span,
1738
- ) )
1739
1728
}
1740
1729
1741
1730
fn lookup_assoc_ty (
0 commit comments