@@ -1224,13 +1224,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1224
1224
{
1225
1225
self . note_obligation_cause_code ( err,
1226
1226
& obligation. predicate ,
1227
- & obligation. cause . code ) ;
1227
+ & obligation. cause . code ,
1228
+ & mut vec ! [ ] ) ;
1228
1229
}
1229
1230
1230
1231
fn note_obligation_cause_code < T > ( & self ,
1231
1232
err : & mut DiagnosticBuilder ,
1232
1233
predicate : & T ,
1233
- cause_code : & ObligationCauseCode < ' tcx > )
1234
+ cause_code : & ObligationCauseCode < ' tcx > ,
1235
+ obligated_types : & mut Vec < & ty:: TyS < ' tcx > > )
1234
1236
where T : fmt:: Display
1235
1237
{
1236
1238
let tcx = self . tcx ;
@@ -1326,12 +1328,17 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1326
1328
}
1327
1329
ObligationCauseCode :: BuiltinDerivedObligation ( ref data) => {
1328
1330
let parent_trait_ref = self . resolve_type_vars_if_possible ( & data. parent_trait_ref ) ;
1329
- err. note ( & format ! ( "required because it appears within the type `{}`" ,
1330
- parent_trait_ref. 0 . self_ty( ) ) ) ;
1331
+ let ty = parent_trait_ref. 0 . self_ty ( ) ;
1332
+ err. note ( & format ! ( "required because it appears within the type `{}`" , ty) ) ;
1333
+ obligated_types. push ( ty) ;
1334
+
1331
1335
let parent_predicate = parent_trait_ref. to_predicate ( ) ;
1332
- self . note_obligation_cause_code ( err,
1333
- & parent_predicate,
1334
- & data. parent_code ) ;
1336
+ if !self . is_recursive_obligation ( obligated_types, & data. parent_code ) {
1337
+ self . note_obligation_cause_code ( err,
1338
+ & parent_predicate,
1339
+ & data. parent_code ,
1340
+ obligated_types) ;
1341
+ }
1335
1342
}
1336
1343
ObligationCauseCode :: ImplDerivedObligation ( ref data) => {
1337
1344
let parent_trait_ref = self . resolve_type_vars_if_possible ( & data. parent_trait_ref ) ;
@@ -1341,8 +1348,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1341
1348
parent_trait_ref. 0 . self_ty( ) ) ) ;
1342
1349
let parent_predicate = parent_trait_ref. to_predicate ( ) ;
1343
1350
self . note_obligation_cause_code ( err,
1344
- & parent_predicate,
1345
- & data. parent_code ) ;
1351
+ & parent_predicate,
1352
+ & data. parent_code ,
1353
+ obligated_types) ;
1346
1354
}
1347
1355
ObligationCauseCode :: CompareImplMethodObligation { .. } => {
1348
1356
err. note (
@@ -1361,6 +1369,20 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1361
1369
err. help ( & format ! ( "consider adding a `#![recursion_limit=\" {}\" ]` attribute to your crate" ,
1362
1370
suggested_limit) ) ;
1363
1371
}
1372
+
1373
+ fn is_recursive_obligation ( & self ,
1374
+ obligated_types : & mut Vec < & ty:: TyS < ' tcx > > ,
1375
+ cause_code : & ObligationCauseCode < ' tcx > ) -> bool {
1376
+ if let ObligationCauseCode :: BuiltinDerivedObligation ( ref data) = cause_code {
1377
+ let parent_trait_ref = self . resolve_type_vars_if_possible ( & data. parent_trait_ref ) ;
1378
+ for obligated_type in obligated_types {
1379
+ if obligated_type == & parent_trait_ref. 0 . self_ty ( ) {
1380
+ return true ;
1381
+ }
1382
+ }
1383
+ }
1384
+ return false ;
1385
+ }
1364
1386
}
1365
1387
1366
1388
enum ArgKind {
0 commit comments