@@ -1194,13 +1194,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1194
1194
{
1195
1195
self . note_obligation_cause_code ( err,
1196
1196
& obligation. predicate ,
1197
- & obligation. cause . code ) ;
1197
+ & obligation. cause . code ,
1198
+ & mut vec ! [ ] ) ;
1198
1199
}
1199
1200
1200
1201
fn note_obligation_cause_code < T > ( & self ,
1201
1202
err : & mut DiagnosticBuilder ,
1202
1203
predicate : & T ,
1203
- cause_code : & ObligationCauseCode < ' tcx > )
1204
+ cause_code : & ObligationCauseCode < ' tcx > ,
1205
+ obligated_types : & mut Vec < & ty:: TyS < ' tcx > > )
1204
1206
where T : fmt:: Display
1205
1207
{
1206
1208
let tcx = self . tcx ;
@@ -1292,12 +1294,17 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1292
1294
}
1293
1295
ObligationCauseCode :: BuiltinDerivedObligation ( ref data) => {
1294
1296
let parent_trait_ref = self . resolve_type_vars_if_possible ( & data. parent_trait_ref ) ;
1295
- err. note ( & format ! ( "required because it appears within the type `{}`" ,
1296
- parent_trait_ref. 0 . self_ty( ) ) ) ;
1297
+ let ty = parent_trait_ref. 0 . self_ty ( ) ;
1298
+ err. note ( & format ! ( "required because it appears within the type `{}`" , ty) ) ;
1299
+ obligated_types. push ( ty) ;
1300
+
1297
1301
let parent_predicate = parent_trait_ref. to_predicate ( ) ;
1298
- self . note_obligation_cause_code ( err,
1299
- & parent_predicate,
1300
- & data. parent_code ) ;
1302
+ if !self . is_recursive_obligation ( obligated_types, & data. parent_code ) {
1303
+ self . note_obligation_cause_code ( err,
1304
+ & parent_predicate,
1305
+ & data. parent_code ,
1306
+ obligated_types) ;
1307
+ }
1301
1308
}
1302
1309
ObligationCauseCode :: ImplDerivedObligation ( ref data) => {
1303
1310
let parent_trait_ref = self . resolve_type_vars_if_possible ( & data. parent_trait_ref ) ;
@@ -1307,8 +1314,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1307
1314
parent_trait_ref. 0 . self_ty( ) ) ) ;
1308
1315
let parent_predicate = parent_trait_ref. to_predicate ( ) ;
1309
1316
self . note_obligation_cause_code ( err,
1310
- & parent_predicate,
1311
- & data. parent_code ) ;
1317
+ & parent_predicate,
1318
+ & data. parent_code ,
1319
+ obligated_types) ;
1312
1320
}
1313
1321
ObligationCauseCode :: CompareImplMethodObligation { .. } => {
1314
1322
err. note (
@@ -1327,6 +1335,20 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1327
1335
err. help ( & format ! ( "consider adding a `#![recursion_limit=\" {}\" ]` attribute to your crate" ,
1328
1336
suggested_limit) ) ;
1329
1337
}
1338
+
1339
+ fn is_recursive_obligation ( & self ,
1340
+ obligated_types : & mut Vec < & ty:: TyS < ' tcx > > ,
1341
+ cause_code : & ObligationCauseCode < ' tcx > ) -> bool {
1342
+ if let ObligationCauseCode :: BuiltinDerivedObligation ( ref data) = cause_code {
1343
+ let parent_trait_ref = self . resolve_type_vars_if_possible ( & data. parent_trait_ref ) ;
1344
+ for obligated_type in obligated_types {
1345
+ if obligated_type == & parent_trait_ref. 0 . self_ty ( ) {
1346
+ return true ;
1347
+ }
1348
+ }
1349
+ }
1350
+ return false ;
1351
+ }
1330
1352
}
1331
1353
1332
1354
enum ArgKind {
0 commit comments