@@ -29,6 +29,7 @@ use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin};
29
29
use rustc_infer:: infer:: { InferCtxt , InferOk , TyCtxtInferExt } ;
30
30
use rustc_infer:: traits:: ObligationCause ;
31
31
use rustc_middle:: middle:: stability:: AllowUnstable ;
32
+ use rustc_middle:: ty:: visit:: TypeVisitable ;
32
33
use rustc_middle:: ty:: GenericParamDefKind ;
33
34
use rustc_middle:: ty:: {
34
35
self , Const , GenericArgKind , GenericArgsRef , IsSuggestable , Ty , TyCtxt , TypeVisitableExt ,
@@ -38,9 +39,9 @@ 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:: traits:: query:: normalize:: MaxEscapingBoundVarVisitor ;
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;
@@ -1605,131 +1606,116 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
1605
1606
let cause = ObligationCause :: misc ( span, block. owner . def_id ) ;
1606
1607
1607
1608
let mut fulfillment_errors = Vec :: new ( ) ;
1608
- let mut applicable_candidates: Vec < _ > = infcx. probe ( |_| {
1609
- // Regions are not considered during selection.
1610
- let self_ty = self_ty
1611
- . fold_with ( & mut BoundVarEraser { tcx, universe : infcx. create_next_universe ( ) } ) ;
1612
-
1613
- struct BoundVarEraser < ' tcx > {
1614
- tcx : TyCtxt < ' tcx > ,
1615
- universe : ty:: UniverseIndex ,
1616
- }
1617
-
1618
- // FIXME(non_lifetime_binders): Don't assign the same universe to each placeholder.
1619
- impl < ' tcx > TypeFolder < TyCtxt < ' tcx > > for BoundVarEraser < ' tcx > {
1620
- fn interner ( & self ) -> TyCtxt < ' tcx > {
1621
- self . tcx
1622
- }
1609
+ infcx. probe ( |_| {
1610
+ let mut universes = if self_ty. has_escaping_bound_vars ( ) {
1611
+ let mut max_visitor =
1612
+ MaxEscapingBoundVarVisitor { outer_index : ty:: INNERMOST , escaping : 0 } ;
1613
+ self_ty. visit_with ( & mut max_visitor) ;
1614
+ vec ! [ None ; max_visitor. escaping]
1615
+ } else {
1616
+ vec ! [ ]
1617
+ } ;
1623
1618
1624
- fn fold_region ( & mut self , r : ty:: Region < ' tcx > ) -> ty:: Region < ' tcx > {
1625
- if r. is_late_bound ( ) { self . tcx . lifetimes . re_erased } else { r }
1626
- }
1619
+ crate :: traits:: project:: with_replaced_escaping_bound_vars (
1620
+ infcx,
1621
+ & mut universes,
1622
+ self_ty,
1623
+ |self_ty| {
1624
+ let InferOk { value : self_ty, obligations } =
1625
+ infcx. at ( & cause, param_env) . normalize ( self_ty) ;
1627
1626
1628
- fn fold_ty ( & mut self , ty : Ty < ' tcx > ) -> Ty < ' tcx > {
1629
- match * ty. kind ( ) {
1630
- ty:: Bound ( _, bv) => Ty :: new_placeholder (
1631
- self . tcx ,
1632
- ty:: PlaceholderType { universe : self . universe , bound : bv } ,
1633
- ) ,
1634
- _ => ty. super_fold_with ( self ) ,
1635
- }
1636
- }
1627
+ let mut applicable_candidates: Vec < _ > = candidates
1628
+ . iter ( )
1629
+ . copied ( )
1630
+ . filter ( |& ( impl_, _) | {
1631
+ infcx. probe ( |_| {
1632
+ let ocx = ObligationCtxt :: new ( & infcx) ;
1633
+ ocx. register_obligations ( obligations. clone ( ) ) ;
1634
+
1635
+ let impl_args = infcx. fresh_args_for_item ( span, impl_) ;
1636
+ let impl_ty = tcx. type_of ( impl_) . instantiate ( tcx, impl_args) ;
1637
+ let impl_ty = ocx. normalize ( & cause, param_env, impl_ty) ;
1638
+
1639
+ // Check that the self types can be related.
1640
+ // FIXME(inherent_associated_types): Should we use `eq` here? Method probing uses
1641
+ // `sup` for this situtation, too. What for? To constrain inference variables?
1642
+ if ocx
1643
+ . sup ( & ObligationCause :: dummy ( ) , param_env, impl_ty, self_ty)
1644
+ . is_err ( )
1645
+ {
1646
+ return false ;
1647
+ }
1637
1648
1638
- fn fold_const (
1639
- & mut self ,
1640
- ct : ty:: Const < ' tcx > ,
1641
- ) -> <TyCtxt < ' tcx > as rustc_type_ir:: Interner >:: Const {
1642
- assert ! ( !ct. ty( ) . has_escaping_bound_vars( ) ) ;
1643
-
1644
- match ct. kind ( ) {
1645
- ty:: ConstKind :: Bound ( _, bv) => ty:: Const :: new_placeholder (
1646
- self . tcx ,
1647
- ty:: PlaceholderConst { universe : self . universe , bound : bv } ,
1648
- ct. ty ( ) ,
1649
- ) ,
1650
- _ => ct. super_fold_with ( self ) ,
1651
- }
1652
- }
1653
- }
1649
+ // Check whether the impl imposes obligations we have to worry about.
1650
+ let impl_bounds =
1651
+ tcx. predicates_of ( impl_) . instantiate ( tcx, impl_args) ;
1652
+ let impl_bounds = ocx. normalize ( & cause, param_env, impl_bounds) ;
1653
+ let impl_obligations = traits:: predicates_for_generics (
1654
+ |_, _| cause. clone ( ) ,
1655
+ param_env,
1656
+ impl_bounds,
1657
+ ) ;
1658
+ ocx. register_obligations ( impl_obligations) ;
1654
1659
1655
- let InferOk { value : self_ty, obligations } =
1656
- infcx. at ( & cause, param_env) . normalize ( self_ty) ;
1660
+ let mut errors = ocx. select_where_possible ( ) ;
1661
+ if !errors. is_empty ( ) {
1662
+ fulfillment_errors. append ( & mut errors) ;
1663
+ return false ;
1664
+ }
1657
1665
1658
- candidates
1659
- . iter ( )
1660
- . copied ( )
1661
- . filter ( |& ( impl_, _) | {
1662
- infcx. probe ( |_| {
1663
- let ocx = ObligationCtxt :: new ( & infcx) ;
1664
- ocx. register_obligations ( obligations. clone ( ) ) ;
1665
-
1666
- let impl_args = infcx. fresh_args_for_item ( span, impl_) ;
1667
- let impl_ty = tcx. type_of ( impl_) . instantiate ( tcx, impl_args) ;
1668
- let impl_ty = ocx. normalize ( & cause, param_env, impl_ty) ;
1669
-
1670
- // Check that the self types can be related.
1671
- // FIXME(inherent_associated_types): Should we use `eq` here? Method probing uses
1672
- // `sup` for this situtation, too. What for? To constrain inference variables?
1673
- if ocx. sup ( & ObligationCause :: dummy ( ) , param_env, impl_ty, self_ty) . is_err ( )
1674
- {
1675
- return false ;
1676
- }
1666
+ true
1667
+ } )
1668
+ } )
1669
+ . collect ( ) ;
1670
+
1671
+ if applicable_candidates. len ( ) > 1 {
1672
+ return Err ( self . complain_about_ambiguous_inherent_assoc_type (
1673
+ name,
1674
+ applicable_candidates
1675
+ . into_iter ( )
1676
+ . map ( |( _, ( candidate, _) ) | candidate)
1677
+ . collect ( ) ,
1678
+ span,
1679
+ ) ) ;
1680
+ }
1677
1681
1678
- // Check whether the impl imposes obligations we have to worry about.
1679
- let impl_bounds = tcx. predicates_of ( impl_) . instantiate ( tcx, impl_args) ;
1680
- let impl_bounds = ocx. normalize ( & cause, param_env, impl_bounds) ;
1681
- let impl_obligations = traits:: predicates_for_generics (
1682
- |_, _| cause. clone ( ) ,
1683
- param_env,
1684
- impl_bounds,
1682
+ if let Some ( ( impl_, ( assoc_item, def_scope) ) ) = applicable_candidates. pop ( ) {
1683
+ self . check_assoc_ty ( assoc_item, name, def_scope, block, span) ;
1684
+
1685
+ // FIXME(fmease): Currently creating throwaway `parent_args` to please
1686
+ // `create_args_for_associated_item`. Modify the latter instead (or sth. similar) to
1687
+ // not require the parent args logic.
1688
+ let parent_args = ty:: GenericArgs :: identity_for_item ( tcx, impl_) ;
1689
+ let args = self . create_args_for_associated_item (
1690
+ span,
1691
+ assoc_item,
1692
+ segment,
1693
+ parent_args,
1694
+ ) ;
1695
+ let args = tcx. mk_args_from_iter (
1696
+ std:: iter:: once ( ty:: GenericArg :: from ( self_ty) )
1697
+ . chain ( args. into_iter ( ) . skip ( parent_args. len ( ) ) ) ,
1685
1698
) ;
1686
- ocx. register_obligations ( impl_obligations) ;
1687
-
1688
- let mut errors = ocx. select_where_possible ( ) ;
1689
- if !errors. is_empty ( ) {
1690
- fulfillment_errors. append ( & mut errors) ;
1691
- return false ;
1692
- }
1693
-
1694
- true
1695
- } )
1696
- } )
1697
- . collect ( )
1698
- } ) ;
1699
-
1700
- if applicable_candidates. len ( ) > 1 {
1701
- return Err ( self . complain_about_ambiguous_inherent_assoc_type (
1702
- name,
1703
- applicable_candidates. into_iter ( ) . map ( |( _, ( candidate, _) ) | candidate) . collect ( ) ,
1704
- span,
1705
- ) ) ;
1706
- }
1707
-
1708
- if let Some ( ( impl_, ( assoc_item, def_scope) ) ) = applicable_candidates. pop ( ) {
1709
- self . check_assoc_ty ( assoc_item, name, def_scope, block, span) ;
1710
-
1711
- // FIXME(fmease): Currently creating throwaway `parent_args` to please
1712
- // `create_args_for_associated_item`. Modify the latter instead (or sth. similar) to
1713
- // not require the parent args logic.
1714
- let parent_args = ty:: GenericArgs :: identity_for_item ( tcx, impl_) ;
1715
- let args = self . create_args_for_associated_item ( span, assoc_item, segment, parent_args) ;
1716
- let args = tcx. mk_args_from_iter (
1717
- std:: iter:: once ( ty:: GenericArg :: from ( self_ty) )
1718
- . chain ( args. into_iter ( ) . skip ( parent_args. len ( ) ) ) ,
1719
- ) ;
1720
1699
1721
- let ty = Ty :: new_alias ( tcx, ty:: Inherent , ty:: AliasTy :: new ( tcx, assoc_item, args) ) ;
1700
+ let ty = Ty :: new_alias (
1701
+ tcx,
1702
+ ty:: Inherent ,
1703
+ ty:: AliasTy :: new ( tcx, assoc_item, args) ,
1704
+ ) ;
1722
1705
1723
- return Ok ( Some ( ( ty, assoc_item) ) ) ;
1724
- }
1706
+ return Ok ( Some ( ( ty, assoc_item) ) ) ;
1707
+ }
1725
1708
1726
- Err ( self . complain_about_inherent_assoc_type_not_found (
1727
- name,
1728
- self_ty,
1729
- candidates,
1730
- fulfillment_errors,
1731
- span,
1732
- ) )
1709
+ Err ( self . complain_about_inherent_assoc_type_not_found (
1710
+ name,
1711
+ self_ty,
1712
+ candidates,
1713
+ fulfillment_errors,
1714
+ span,
1715
+ ) )
1716
+ } ,
1717
+ )
1718
+ } )
1733
1719
}
1734
1720
1735
1721
fn lookup_assoc_ty (
0 commit comments