@@ -15,14 +15,14 @@ use rustc_errors::{struct_span_err, Applicability, ErrorReported, FatalError};
1515use rustc_hir as hir;
1616use rustc_hir:: def:: { CtorOf , DefKind , Namespace , Res } ;
1717use rustc_hir:: def_id:: { DefId , LocalDefId } ;
18- use rustc_hir:: intravisit:: { walk_generics, Visitor as _ } ;
18+ use rustc_hir:: intravisit:: { self , walk_generics, Visitor } ;
1919use rustc_hir:: lang_items:: LangItem ;
2020use rustc_hir:: { Constness , GenericArg , GenericArgs } ;
2121use rustc_middle:: ty:: subst:: { self , InternalSubsts , Subst , SubstsRef } ;
2222use rustc_middle:: ty:: GenericParamDefKind ;
2323use rustc_middle:: ty:: { self , Const , DefIdTree , Ty , TyCtxt , TypeFoldable } ;
2424use rustc_session:: lint:: builtin:: AMBIGUOUS_ASSOCIATED_ITEMS ;
25- use rustc_span:: symbol:: { Ident , Symbol } ;
25+ use rustc_span:: symbol:: { kw , Ident , Symbol } ;
2626use rustc_span:: { Span , DUMMY_SP } ;
2727use rustc_target:: spec:: abi;
2828use rustc_trait_selection:: traits;
@@ -285,8 +285,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
285285 // region with the current anon region binding (in other words,
286286 // whatever & would get replaced with).
287287 debug ! (
288- "create_substs_for_ast_path(def_id={:?}, self_ty={:?}, \
289- generic_args={:?})",
288+ "create_substs_for_ast_path(def_id={:?}, self_ty={:?}, generic_args={:?})" ,
290289 def_id, self_ty, generic_args
291290 ) ;
292291
@@ -316,7 +315,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
316315 infer_args,
317316 ) ;
318317
319- let is_object = self_ty. map_or ( false , |ty| ty == self . tcx ( ) . types . trait_object_dummy_self ) ;
318+ let is_object = self_ty. map_or ( false , |ty| ty == tcx. types . trait_object_dummy_self ) ;
320319 let default_needs_object_self = |param : & ty:: GenericParamDef | {
321320 if let GenericParamDefKind :: Type { has_default, .. } = param. kind {
322321 if is_object && has_default {
@@ -356,14 +355,42 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
356355 ( GenericParamDefKind :: Lifetime , GenericArg :: Lifetime ( lt) ) => {
357356 self . ast_region_to_region ( & lt, Some ( param) ) . into ( )
358357 }
359- ( GenericParamDefKind :: Type { .. } , GenericArg :: Type ( ty) ) => {
360- if let ( hir:: TyKind :: Infer , false ) = ( & ty . kind , self . allow_ty_infer ( ) ) {
358+ ( GenericParamDefKind :: Type { .. } , GenericArg :: Type ( ty) ) => match & ty . kind {
359+ hir:: TyKind :: Infer if ! self . allow_ty_infer ( ) => {
361360 inferred_params. push ( ty. span ) ;
362361 tcx. ty_error ( ) . into ( )
363- } else {
364- self . ast_ty_to_ty ( & ty) . into ( )
365362 }
366- }
363+ hir:: TyKind :: Path ( hir:: QPath :: TypeRelative (
364+ hir:: Ty {
365+ kind :
366+ hir:: TyKind :: Path (
367+ hir:: QPath :: Resolved (
368+ None ,
369+ hir:: Path { res : res @ Res :: SelfTy ( Some ( _) , None ) , .. } ,
370+ ) ,
371+ ..,
372+ ) ,
373+ ..
374+ } ,
375+ segment,
376+ ) ) if Some ( tcx. types . self_param ) == self_ty => {
377+ // Handle `trait A: B<Self::C> { type C; }` to avoid cycle error.
378+ // See `super_predicates_of_skip_self_param` for more information.
379+ self . associated_path_to_ty (
380+ ty. hir_id ,
381+ ty. span ,
382+ tcx. types . self_param ,
383+ * res,
384+ segment,
385+ false ,
386+ true ,
387+ )
388+ . map ( |( ty, _, _) | ty)
389+ . unwrap_or_else ( |_| tcx. ty_error ( ) )
390+ . into ( )
391+ }
392+ _ => self . ast_ty_to_ty ( & ty) . into ( ) ,
393+ } ,
367394 ( GenericParamDefKind :: Const , GenericArg :: Const ( ct) ) => {
368395 ty:: Const :: from_opt_const_arg_anon_const (
369396 tcx,
@@ -527,7 +554,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
527554 ) -> GenericArgCountResult {
528555 let trait_def_id = trait_ref. trait_def_id ( ) . unwrap_or_else ( || FatalError . raise ( ) ) ;
529556
530- debug ! ( "instantiate_poly_trait_ref({:?}, def_id={:?})" , trait_ref, trait_def_id) ;
557+ debug ! (
558+ "instantiate_poly_trait_ref({:?}, def_id={:?}, self_ty={:?})" ,
559+ trait_ref, trait_def_id, self_ty
560+ ) ;
531561
532562 self . prohibit_generics ( trait_ref. path . segments . split_last ( ) . unwrap ( ) . 1 ) ;
533563
@@ -704,9 +734,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
704734 if tpb. path . res != Res :: Def ( DefKind :: Trait , kind_id) {
705735 tcx. sess . span_warn (
706736 span,
707- "default bound relaxed for a type parameter, but \
708- this does nothing because the given bound is not \
709- a default; only `?Sized` is supported",
737+ "default bound relaxed for a type parameter, but this does nothing \
738+ because the given bound is not a default; only `?Sized` is supported",
710739 ) ;
711740 }
712741 }
@@ -741,15 +770,61 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
741770 param_ty : Ty < ' tcx > ,
742771 ast_bounds : & [ hir:: GenericBound < ' _ > ] ,
743772 bounds : & mut Bounds < ' tcx > ,
773+ skip_self_param_evaluation : bool ,
744774 ) {
745775 let mut trait_bounds = Vec :: new ( ) ;
746776 let mut region_bounds = Vec :: new ( ) ;
747777
778+ /// Walk each bound to see if they reference an associated type of `Self` without
779+ /// specifying a trait (using a Resolved path `Self::Foo` instead of fully qualified path
780+ /// `<Self as Bar>::Foo`) and if so, skip them if `skip_self_param_evaluation` is `true`.
781+ /// This way, we avoid cycle errors and are able to resolve the associated type
782+ /// successfully.
783+ struct SelfFinder ( bool ) ;
784+
785+ impl < ' v > Visitor < ' v > for SelfFinder {
786+ type Map = intravisit:: ErasedMap < ' v > ;
787+
788+ fn nested_visit_map ( & mut self ) -> intravisit:: NestedVisitorMap < Self :: Map > {
789+ intravisit:: NestedVisitorMap :: None
790+ }
791+
792+ fn visit_ty ( & mut self , t : & ' v hir:: Ty < ' v > ) {
793+ if let hir:: TyKind :: Path ( hir:: QPath :: TypeRelative (
794+ hir:: Ty {
795+ kind :
796+ hir:: TyKind :: Path (
797+ hir:: QPath :: Resolved (
798+ None ,
799+ hir:: Path { res : Res :: SelfTy ( Some ( _) , None ) , .. } ,
800+ ) ,
801+ ..,
802+ ) ,
803+ ..
804+ } ,
805+ _,
806+ ) ) = t. kind
807+ {
808+ self . 0 = true ;
809+ }
810+ intravisit:: walk_ty ( self , t)
811+ }
812+ }
813+
748814 let constness = self . default_constness_for_trait_bounds ( ) ;
749815 for ast_bound in ast_bounds {
750816 match * ast_bound {
751- hir:: GenericBound :: Trait ( ref b, hir:: TraitBoundModifier :: None ) => {
752- trait_bounds. push ( ( b, constness) )
817+ hir:: GenericBound :: Trait ( ref b, modif @ hir:: TraitBoundModifier :: None ) => {
818+ let mut visitor = SelfFinder ( false ) ;
819+ visitor. visit_poly_trait_ref ( b, modif) ;
820+
821+ let is_self_param = match param_ty. kind {
822+ ty:: Param ( param) if param. name == kw:: SelfUpper => true ,
823+ _ => false ,
824+ } ;
825+ if !( visitor. 0 && skip_self_param_evaluation && is_self_param) {
826+ trait_bounds. push ( ( b, constness) )
827+ }
753828 }
754829 hir:: GenericBound :: Trait ( ref b, hir:: TraitBoundModifier :: MaybeConst ) => {
755830 trait_bounds. push ( ( b, Constness :: NotConst ) )
@@ -794,10 +869,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
794869 ast_bounds : & [ hir:: GenericBound < ' _ > ] ,
795870 sized_by_default : SizedByDefault ,
796871 span : Span ,
872+ skip_self_param_evaluation : bool ,
797873 ) -> Bounds < ' tcx > {
798874 let mut bounds = Bounds :: default ( ) ;
799875
800- self . add_bounds ( param_ty, ast_bounds, & mut bounds) ;
876+ self . add_bounds ( param_ty, ast_bounds, & mut bounds, skip_self_param_evaluation ) ;
801877 bounds. trait_bounds . sort_by_key ( |( t, _, _) | t. def_id ( ) ) ;
802878
803879 bounds. implicitly_sized = if let SizedByDefault :: Yes = sized_by_default {
@@ -969,7 +1045,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
9691045 // Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty`
9701046 // parameter to have a skipped binder.
9711047 let param_ty = tcx. mk_projection ( assoc_ty. def_id , candidate. skip_binder ( ) . substs ) ;
972- self . add_bounds ( param_ty, ast_bounds, bounds) ;
1048+ self . add_bounds ( param_ty, ast_bounds, bounds, false ) ;
9731049 }
9741050 }
9751051 Ok ( ( ) )
@@ -996,7 +1072,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
9961072
9971073 let mut bounds = Bounds :: default ( ) ;
9981074 let mut potential_assoc_types = Vec :: new ( ) ;
999- let dummy_self = self . tcx ( ) . types . trait_object_dummy_self ;
1075+ let dummy_self = tcx. types . trait_object_dummy_self ;
10001076 for trait_bound in trait_bounds. iter ( ) . rev ( ) {
10011077 if let GenericArgCountResult {
10021078 correct :
@@ -1274,15 +1350,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
12741350 err. emit ( ) ;
12751351 }
12761352
1277- // Search for a bound on a type parameter which includes the associated item
1278- // given by `assoc_name`. `ty_param_def_id` is the `DefId` of the type parameter
1279- // This function will fail if there are no suitable bounds or there is
1280- // any ambiguity.
1353+ /// Search for a bound on a type parameter which includes the associated item
1354+ /// given by `assoc_name`. `ty_param_def_id` is the `DefId` of the type parameter
1355+ /// This function will fail if there are no suitable bounds or there is
1356+ /// any ambiguity.
1357+ ///
1358+ /// See `super_predicates_of_skip_self_param` for the behavior when `skip_self_param_evaluation`
1359+ /// is `true`.
12811360 fn find_bound_for_assoc_item (
12821361 & self ,
12831362 ty_param_def_id : LocalDefId ,
12841363 assoc_name : Ident ,
12851364 span : Span ,
1365+ skip_self_param_evaluation : bool ,
12861366 ) -> Result < ty:: PolyTraitRef < ' tcx > , ErrorReported > {
12871367 let tcx = self . tcx ( ) ;
12881368
@@ -1300,9 +1380,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
13001380 let param_name = tcx. hir ( ) . ty_param_name ( param_hir_id) ;
13011381 self . one_bound_for_assoc_type (
13021382 || {
1303- traits:: transitive_bounds (
1383+ traits:: supertraits_maybe_skip_self_param_users (
13041384 tcx,
13051385 predicates. iter ( ) . filter_map ( |( p, _) | p. to_opt_poly_trait_ref ( ) ) ,
1386+ skip_self_param_evaluation,
13061387 )
13071388 } ,
13081389 || param_name. to_string ( ) ,
@@ -1432,12 +1513,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
14321513 Ok ( bound)
14331514 }
14341515
1435- // Create a type from a path to an associated type.
1436- // For a path `A::B::C::D`, `qself_ty` and `qself_def` are the type and def for `A::B::C`
1437- // and item_segment is the path segment for `D`. We return a type and a def for
1438- // the whole path.
1439- // Will fail except for `T::A` and `Self::A`; i.e., if `qself_ty`/`qself_def` are not a type
1440- // parameter or `Self`.
1516+ /// Create a type from a path to an associated type.
1517+ /// For a path `A::B::C::D`, `qself_ty` and `qself_def` are the type and def for `A::B::C`
1518+ /// and `item_segment` is the path segment for `D`. We return a type and a def for
1519+ /// the whole path.
1520+ /// Will fail except for `T::A` and `Self::A`; i.e., if `qself_ty`/`qself_def` are not a type
1521+ /// parameter or `Self`.
1522+ ///
1523+ /// When `dont_recurse` is `true`, and we are evaluation a path rooted in `Self`, we will skip
1524+ /// super-traits that reference `Self` to avoid cycle errors. See
1525+ /// `super_predicates_of_skip_self_param` for more information.
14411526 pub fn associated_path_to_ty (
14421527 & self ,
14431528 hir_ref_id : hir:: HirId ,
@@ -1446,6 +1531,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
14461531 qself_res : Res ,
14471532 assoc_segment : & hir:: PathSegment < ' _ > ,
14481533 permit_variants : bool ,
1534+ dont_recurse : bool ,
14491535 ) -> Result < ( Ty < ' tcx > , DefKind , DefId ) , ErrorReported > {
14501536 let tcx = self . tcx ( ) ;
14511537 let assoc_ident = assoc_segment. ident ;
@@ -1494,10 +1580,15 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
14941580 || None ,
14951581 ) ?
14961582 }
1497- (
1498- & ty:: Param ( _) ,
1499- Res :: SelfTy ( Some ( param_did) , None ) | Res :: Def ( DefKind :: TyParam , param_did) ,
1500- ) => self . find_bound_for_assoc_item ( param_did. expect_local ( ) , assoc_ident, span) ?,
1583+ ( & ty:: Param ( _) , Res :: SelfTy ( Some ( param_did) , None ) ) => self . find_bound_for_assoc_item (
1584+ param_did. expect_local ( ) ,
1585+ assoc_ident,
1586+ span,
1587+ dont_recurse,
1588+ ) ?,
1589+ ( & ty:: Param ( _) , Res :: Def ( DefKind :: TyParam , param_did) ) => {
1590+ self . find_bound_for_assoc_item ( param_did. expect_local ( ) , assoc_ident, span, false ) ?
1591+ }
15011592 _ => {
15021593 if variant_resolution. is_some ( ) {
15031594 // Variant in type position
@@ -2036,9 +2127,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
20362127 } else {
20372128 Res :: Err
20382129 } ;
2039- self . associated_path_to_ty ( ast_ty. hir_id , ast_ty. span , ty, res, segment, false )
2040- . map ( |( ty, _, _) | ty)
2041- . unwrap_or_else ( |_| tcx. ty_error ( ) )
2130+ self . associated_path_to_ty (
2131+ ast_ty. hir_id ,
2132+ ast_ty. span ,
2133+ ty,
2134+ res,
2135+ segment,
2136+ false ,
2137+ false ,
2138+ )
2139+ . map ( |( ty, _, _) | ty)
2140+ . unwrap_or_else ( |_| tcx. ty_error ( ) )
20422141 }
20432142 hir:: TyKind :: Path ( hir:: QPath :: LangItem ( lang_item, span) ) => {
20442143 let def_id = tcx. require_lang_item ( lang_item, Some ( span) ) ;
0 commit comments