@@ -28,7 +28,6 @@ use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
2828use rustc_middle:: ty:: subst:: Subst ;
2929use rustc_middle:: ty:: { self , ToPolyTraitRef , ToPredicate , Ty , TyCtxt , WithConstness } ;
3030use rustc_span:: symbol:: sym;
31- use rustc_span:: DUMMY_SP ;
3231
3332pub use rustc_middle:: traits:: Reveal ;
3433
@@ -1409,6 +1408,7 @@ fn confirm_param_env_candidate<'cx, 'tcx>(
14091408 match infcx. at ( cause, param_env) . eq ( cache_trait_ref, obligation_trait_ref) {
14101409 Ok ( InferOk { value : _, obligations } ) => {
14111410 nested_obligations. extend ( obligations) ;
1411+ assoc_ty_own_obligations ( selcx, obligation, & mut nested_obligations) ;
14121412 Progress { ty : cache_entry. ty , obligations : nested_obligations }
14131413 }
14141414 Err ( e) => {
@@ -1430,7 +1430,7 @@ fn confirm_impl_candidate<'cx, 'tcx>(
14301430) -> Progress < ' tcx > {
14311431 let tcx = selcx. tcx ( ) ;
14321432
1433- let ImplSourceUserDefinedData { impl_def_id, substs, nested } = impl_impl_source;
1433+ let ImplSourceUserDefinedData { impl_def_id, substs, mut nested } = impl_impl_source;
14341434 let assoc_item_id = obligation. predicate . item_def_id ;
14351435 let trait_def_id = tcx. trait_id_of_impl ( impl_def_id) . unwrap ( ) ;
14361436
@@ -1463,15 +1463,48 @@ fn confirm_impl_candidate<'cx, 'tcx>(
14631463 let ty = tcx. type_of ( assoc_ty. item . def_id ) ;
14641464 if substs. len ( ) != tcx. generics_of ( assoc_ty. item . def_id ) . count ( ) {
14651465 let err = tcx. ty_error_with_message (
1466- DUMMY_SP ,
1466+ obligation . cause . span ,
14671467 "impl item and trait item have different parameter counts" ,
14681468 ) ;
14691469 Progress { ty : err, obligations : nested }
14701470 } else {
1471+ assoc_ty_own_obligations ( selcx, obligation, & mut nested) ;
14711472 Progress { ty : ty. subst ( tcx, substs) , obligations : nested }
14721473 }
14731474}
14741475
1476+ // Get obligations corresponding to the predicates from the where-clause of the
1477+ // associated type itself.
1478+ // Note: `feature(generic_associated_types)` is required to write such
1479+ // predicates, even for non-generic associcated types.
1480+ fn assoc_ty_own_obligations < ' cx , ' tcx > (
1481+ selcx : & mut SelectionContext < ' cx , ' tcx > ,
1482+ obligation : & ProjectionTyObligation < ' tcx > ,
1483+ nested : & mut Vec < PredicateObligation < ' tcx > > ,
1484+ ) {
1485+ let tcx = selcx. tcx ( ) ;
1486+ for predicate in tcx
1487+ . predicates_of ( obligation. predicate . item_def_id )
1488+ . instantiate_own ( tcx, obligation. predicate . substs )
1489+ . predicates
1490+ {
1491+ let normalized = normalize_with_depth_to (
1492+ selcx,
1493+ obligation. param_env ,
1494+ obligation. cause . clone ( ) ,
1495+ obligation. recursion_depth + 1 ,
1496+ & predicate,
1497+ nested,
1498+ ) ;
1499+ nested. push ( Obligation :: with_depth (
1500+ obligation. cause . clone ( ) ,
1501+ obligation. recursion_depth + 1 ,
1502+ obligation. param_env ,
1503+ normalized,
1504+ ) ) ;
1505+ }
1506+ }
1507+
14751508/// Locate the definition of an associated type in the specialization hierarchy,
14761509/// starting from the given impl.
14771510///
0 commit comments