@@ -29,6 +29,7 @@ use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin};
2929use rustc_infer:: infer:: { InferCtxt , InferOk , TyCtxtInferExt } ;
3030use rustc_infer:: traits:: ObligationCause ;
3131use rustc_middle:: middle:: stability:: AllowUnstable ;
32+ use rustc_middle:: ty:: visit:: TypeVisitable ;
3233use rustc_middle:: ty:: GenericParamDefKind ;
3334use rustc_middle:: ty:: {
3435 self , Const , GenericArgKind , GenericArgsRef , IsSuggestable , Ty , TyCtxt , TypeVisitableExt ,
@@ -40,7 +41,6 @@ use rustc_span::{sym, BytePos, Span, DUMMY_SP};
4041use rustc_target:: spec:: abi;
4142use rustc_trait_selection:: traits:: wf:: object_region_bounds;
4243use rustc_trait_selection:: traits:: { self , NormalizeExt , ObligationCtxt } ;
43- use rustc_type_ir:: fold:: { TypeFoldable , TypeFolder , TypeSuperFoldable } ;
4444
4545use std:: fmt:: Display ;
4646use std:: slice;
@@ -1609,130 +1609,111 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16091609 let cause = ObligationCause :: misc ( span, block. owner . def_id ) ;
16101610
16111611 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+ infcx. probe ( |_| {
1613+ let mut universes = if self_ty. has_escaping_bound_vars ( ) {
1614+ vec ! [ None ; self_ty. outer_exclusive_binder( ) . as_usize( ) ]
1615+ } else {
1616+ vec ! [ ]
1617+ } ;
16271618
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- }
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) ;
16331626
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- }
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+ if ocx
1641+ . eq ( & ObligationCause :: dummy ( ) , param_env, impl_ty, self_ty)
1642+ . is_err ( )
1643+ {
1644+ return false ;
1645+ }
16431646
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- }
1647+ // Check whether the impl imposes obligations we have to worry about.
1648+ let impl_bounds =
1649+ tcx. predicates_of ( impl_) . instantiate ( tcx, impl_args) ;
1650+ let impl_bounds = ocx. normalize ( & cause, param_env, impl_bounds) ;
1651+ let impl_obligations = traits:: predicates_for_generics (
1652+ |_, _| cause. clone ( ) ,
1653+ param_env,
1654+ impl_bounds,
1655+ ) ;
1656+ ocx. register_obligations ( impl_obligations) ;
16601657
1661- let InferOk { value : self_ty, obligations } =
1662- infcx. at ( & cause, param_env) . normalize ( self_ty) ;
1658+ let mut errors = ocx. select_where_possible ( ) ;
1659+ if !errors. is_empty ( ) {
1660+ fulfillment_errors. append ( & mut errors) ;
1661+ return false ;
1662+ }
16631663
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- if ocx. eq ( & ObligationCause :: dummy ( ) , param_env, impl_ty, self_ty) . is_err ( ) {
1678- return false ;
1679- }
1664+ true
1665+ } )
1666+ } )
1667+ . collect ( ) ;
1668+
1669+ if applicable_candidates. len ( ) > 1 {
1670+ return Err ( self . complain_about_ambiguous_inherent_assoc_type (
1671+ name,
1672+ applicable_candidates
1673+ . into_iter ( )
1674+ . map ( |( _, ( candidate, _) ) | candidate)
1675+ . collect ( ) ,
1676+ span,
1677+ ) ) ;
1678+ }
16801679
1681- // Check whether the impl imposes obligations we have to worry about.
1682- let impl_bounds = tcx. predicates_of ( impl_) . instantiate ( tcx, impl_args) ;
1683- let impl_bounds = ocx. normalize ( & cause, param_env, impl_bounds) ;
1684- let impl_obligations = traits:: predicates_for_generics (
1685- |_, _| cause. clone ( ) ,
1686- param_env,
1687- impl_bounds,
1680+ if let Some ( ( impl_, ( assoc_item, def_scope) ) ) = applicable_candidates. pop ( ) {
1681+ self . check_assoc_ty ( assoc_item, name, def_scope, block, span) ;
1682+
1683+ // FIXME(fmease): Currently creating throwaway `parent_args` to please
1684+ // `create_args_for_associated_item`. Modify the latter instead (or sth. similar) to
1685+ // not require the parent args logic.
1686+ let parent_args = ty:: GenericArgs :: identity_for_item ( tcx, impl_) ;
1687+ let args = self . create_args_for_associated_item (
1688+ span,
1689+ assoc_item,
1690+ segment,
1691+ parent_args,
1692+ ) ;
1693+ let args = tcx. mk_args_from_iter (
1694+ std:: iter:: once ( ty:: GenericArg :: from ( self_ty) )
1695+ . chain ( args. into_iter ( ) . skip ( parent_args. len ( ) ) ) ,
16881696 ) ;
1689- ocx. register_obligations ( impl_obligations) ;
1690-
1691- let mut errors = ocx. select_where_possible ( ) ;
1692- if !errors. is_empty ( ) {
1693- fulfillment_errors. append ( & mut errors) ;
1694- return false ;
1695- }
1696-
1697- true
1698- } )
1699- } )
1700- . collect ( )
1701- } ) ;
1702-
1703- if applicable_candidates. len ( ) > 1 {
1704- return Err ( self . complain_about_ambiguous_inherent_assoc_type (
1705- name,
1706- applicable_candidates. into_iter ( ) . map ( |( _, ( candidate, _) ) | candidate) . collect ( ) ,
1707- span,
1708- ) ) ;
1709- }
1710-
1711- if let Some ( ( impl_, ( assoc_item, def_scope) ) ) = applicable_candidates. pop ( ) {
1712- self . check_assoc_ty ( assoc_item, name, def_scope, block, span) ;
1713-
1714- // FIXME(fmease): Currently creating throwaway `parent_args` to please
1715- // `create_args_for_associated_item`. Modify the latter instead (or sth. similar) to
1716- // not require the parent args logic.
1717- let parent_args = ty:: GenericArgs :: identity_for_item ( tcx, impl_) ;
1718- let args = self . create_args_for_associated_item ( span, assoc_item, segment, parent_args) ;
1719- let args = tcx. mk_args_from_iter (
1720- std:: iter:: once ( ty:: GenericArg :: from ( self_ty) )
1721- . chain ( args. into_iter ( ) . skip ( parent_args. len ( ) ) ) ,
1722- ) ;
17231697
1724- let ty = Ty :: new_alias ( tcx, ty:: Inherent , ty:: AliasTy :: new ( tcx, assoc_item, args) ) ;
1698+ let ty = Ty :: new_alias (
1699+ tcx,
1700+ ty:: Inherent ,
1701+ ty:: AliasTy :: new ( tcx, assoc_item, args) ,
1702+ ) ;
17251703
1726- return Ok ( Some ( ( ty, assoc_item) ) ) ;
1727- }
1704+ return Ok ( Some ( ( ty, assoc_item) ) ) ;
1705+ }
17281706
1729- Err ( self . complain_about_inherent_assoc_type_not_found (
1730- name,
1731- self_ty,
1732- candidates,
1733- fulfillment_errors,
1734- span,
1735- ) )
1707+ Err ( self . complain_about_inherent_assoc_type_not_found (
1708+ name,
1709+ self_ty,
1710+ candidates,
1711+ fulfillment_errors,
1712+ span,
1713+ ) )
1714+ } ,
1715+ )
1716+ } )
17361717 }
17371718
17381719 fn lookup_assoc_ty (
0 commit comments