@@ -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 ,
@@ -38,9 +39,9 @@ use rustc_span::edit_distance::find_best_match_for_name;
3839use rustc_span:: symbol:: { kw, Ident , Symbol } ;
3940use rustc_span:: { sym, BytePos , Span , DUMMY_SP } ;
4041use rustc_target:: spec:: abi;
42+ use rustc_trait_selection:: traits:: query:: normalize:: MaxEscapingBoundVarVisitor ;
4143use rustc_trait_selection:: traits:: wf:: object_region_bounds;
4244use rustc_trait_selection:: traits:: { self , NormalizeExt , ObligationCtxt } ;
43- use rustc_type_ir:: fold:: { TypeFoldable , TypeFolder , TypeSuperFoldable } ;
4445
4546use std:: fmt:: Display ;
4647use std:: slice;
@@ -1605,131 +1606,116 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16051606 let cause = ObligationCause :: misc ( span, block. owner . def_id ) ;
16061607
16071608 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+ } ;
16231618
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) ;
16271626
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+ }
16371648
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) ;
16541659
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+ }
16571665
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+ }
16771681
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 ( ) ) ) ,
16851698 ) ;
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- ) ;
17201699
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+ ) ;
17221705
1723- return Ok ( Some ( ( ty, assoc_item) ) ) ;
1724- }
1706+ return Ok ( Some ( ( ty, assoc_item) ) ) ;
1707+ }
17251708
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+ } )
17331719 }
17341720
17351721 fn lookup_assoc_ty (
0 commit comments