@@ -73,6 +73,7 @@ use middle::typeck::infer::region_inference::SubSupConflict;
73
73
use middle:: typeck:: infer:: region_inference:: SupSupConflict ;
74
74
use syntax:: opt_vec:: OptVec ;
75
75
use util:: ppaux:: UserString ;
76
+ use util:: ppaux:: bound_region_to_str;
76
77
use util:: ppaux:: note_and_explain_region;
77
78
78
79
pub trait ErrorReporting {
@@ -110,6 +111,13 @@ pub trait ErrorReporting {
110
111
region2 : Region ) ;
111
112
}
112
113
114
+ trait ErrorReportingHelpers {
115
+ fn report_inference_failure ( @mut self ,
116
+ var_origin : RegionVariableOrigin ) ;
117
+
118
+ fn note_region_origin ( @mut self ,
119
+ origin : SubregionOrigin ) ;
120
+ }
113
121
114
122
impl ErrorReporting for InferCtxt {
115
123
fn report_region_errors ( @mut self ,
@@ -398,30 +406,23 @@ impl ErrorReporting for InferCtxt {
398
406
sub_region : Region ,
399
407
sup_origin : SubregionOrigin ,
400
408
sup_region : Region ) {
401
- self . tcx . sess . span_err (
402
- var_origin. span ( ) ,
403
- format ! ( "cannot infer an appropriate lifetime \
404
- due to conflicting requirements") ) ;
409
+ self . report_inference_failure ( var_origin) ;
405
410
406
411
note_and_explain_region (
407
412
self . tcx ,
408
413
"first, the lifetime cannot outlive " ,
409
414
sup_region,
410
415
"..." ) ;
411
416
412
- self . tcx . sess . span_note (
413
- sup_origin. span ( ) ,
414
- format ! ( "...due to the following expression" ) ) ;
417
+ self . note_region_origin ( sup_origin) ;
415
418
416
419
note_and_explain_region (
417
420
self . tcx ,
418
421
"but, the lifetime must be valid for " ,
419
422
sub_region,
420
423
"..." ) ;
421
424
422
- self . tcx . sess . span_note (
423
- sub_origin. span ( ) ,
424
- format ! ( "...due to the following expression" ) ) ;
425
+ self . note_region_origin ( sub_origin) ;
425
426
}
426
427
427
428
fn report_sup_sup_conflict ( @mut self ,
@@ -430,30 +431,183 @@ impl ErrorReporting for InferCtxt {
430
431
region1 : Region ,
431
432
origin2 : SubregionOrigin ,
432
433
region2 : Region ) {
433
- self . tcx . sess . span_err (
434
- var_origin. span ( ) ,
435
- format ! ( "cannot infer an appropriate lifetime \
436
- due to conflicting requirements") ) ;
434
+ self . report_inference_failure ( var_origin) ;
437
435
438
436
note_and_explain_region (
439
437
self . tcx ,
440
438
"first, the lifetime must be contained by " ,
441
439
region1,
442
440
"..." ) ;
443
441
444
- self . tcx . sess . span_note (
445
- origin1. span ( ) ,
446
- format ! ( "...due to the following expression" ) ) ;
442
+ self . note_region_origin ( origin1) ;
447
443
448
444
note_and_explain_region (
449
445
self . tcx ,
450
446
"but, the lifetime must also be contained by " ,
451
447
region2,
452
448
"..." ) ;
453
449
454
- self . tcx . sess . span_note (
455
- origin2. span ( ) ,
456
- format ! ( "...due to the following expression" ) ) ;
450
+ self . note_region_origin ( origin2) ;
451
+ }
452
+ }
453
+
454
+ impl ErrorReportingHelpers for InferCtxt {
455
+ fn report_inference_failure ( @mut self ,
456
+ var_origin : RegionVariableOrigin ) {
457
+ let var_description = match var_origin {
458
+ infer:: MiscVariable ( _) => ~"",
459
+ infer:: PatternRegion ( _) => ~" for pattern",
460
+ infer:: AddrOfRegion ( _) => ~" for borrow expression",
461
+ infer:: AddrOfSlice ( _) => ~" for slice expression",
462
+ infer:: Autoref ( _) => ~" for autoref",
463
+ infer:: Coercion ( _) => ~" for automatic coercion",
464
+ infer:: BoundRegionInFnCall ( _, br) => {
465
+ format ! ( " for {}in function call" ,
466
+ bound_region_to_str( self . tcx, "region " , true , br) )
467
+ }
468
+ infer:: BoundRegionInFnType ( _, br) => {
469
+ format ! ( " for {}in function type" ,
470
+ bound_region_to_str( self . tcx, "region " , true , br) )
471
+ }
472
+ infer:: BoundRegionInTypeOrImpl ( _) => {
473
+ format ! ( " for region in type/impl" )
474
+ }
475
+ infer:: BoundRegionInCoherence ( * ) => {
476
+ format ! ( " for coherence check" )
477
+ }
478
+ } ;
479
+
480
+ self . tcx . sess . span_err (
481
+ var_origin. span ( ) ,
482
+ format ! ( "cannot infer an appropriate lifetime{} \
483
+ due to conflicting requirements",
484
+ var_description) ) ;
485
+ }
486
+
487
+ fn note_region_origin ( @mut self ,
488
+ origin : SubregionOrigin ) {
489
+ match origin {
490
+ infer:: Subtype ( ref trace) => {
491
+ let desc = match trace. origin {
492
+ infer:: Misc ( _) => {
493
+ format ! ( "types are compatible" )
494
+ }
495
+ infer:: MethodCompatCheck ( _) => {
496
+ format ! ( "method type is compatible with trait" )
497
+ }
498
+ infer:: ExprAssignable ( _) => {
499
+ format ! ( "expression is assignable" )
500
+ }
501
+ infer:: RelateTraitRefs ( _) => {
502
+ format ! ( "traits are compatible" )
503
+ }
504
+ infer:: RelateSelfType ( _) => {
505
+ format ! ( "type matches impl" )
506
+ }
507
+ infer:: MatchExpression ( _) => {
508
+ format ! ( "match arms have compatible types" )
509
+ }
510
+ infer:: IfExpression ( _) => {
511
+ format ! ( "if and else have compatible types" )
512
+ }
513
+ } ;
514
+
515
+ match self . values_str ( & trace. values ) {
516
+ Some ( values_str) => {
517
+ self . tcx . sess . span_note (
518
+ trace. origin . span ( ) ,
519
+ format ! ( "...so that {} ({})" ,
520
+ desc, values_str) ) ;
521
+ }
522
+ None => {
523
+ // Really should avoid printing this error at
524
+ // all, since it is derived, but that would
525
+ // require more refactoring than I feel like
526
+ // doing right now. - nmatsakis
527
+ self . tcx . sess . span_note (
528
+ trace. origin . span ( ) ,
529
+ format ! ( "...so that {}" , desc) ) ;
530
+ }
531
+ }
532
+ }
533
+ infer:: Reborrow ( span) => {
534
+ self . tcx . sess . span_note (
535
+ span,
536
+ "...so that borrowed pointer does not outlive \
537
+ borrowed content") ;
538
+ }
539
+ infer:: InfStackClosure ( span) => {
540
+ self . tcx . sess . span_note (
541
+ span,
542
+ "...so that closure does not outlive its stack frame" ) ;
543
+ }
544
+ infer:: InvokeClosure ( span) => {
545
+ self . tcx . sess . span_note (
546
+ span,
547
+ "...so that closure is not invoked outside its lifetime" ) ;
548
+ }
549
+ infer:: DerefPointer ( span) => {
550
+ self . tcx . sess . span_note (
551
+ span,
552
+ "...so that pointer is not dereferenced \
553
+ outside its lifetime") ;
554
+ }
555
+ infer:: FreeVariable ( span) => {
556
+ self . tcx . sess . span_note (
557
+ span,
558
+ "...so that captured variable does not outlive the \
559
+ enclosing closure") ;
560
+ }
561
+ infer:: IndexSlice ( span) => {
562
+ self . tcx . sess . span_note (
563
+ span,
564
+ "...so that slice is not indexed outside the lifetime" ) ;
565
+ }
566
+ infer:: RelateObjectBound ( span) => {
567
+ self . tcx . sess . span_note (
568
+ span,
569
+ "...so that source pointer does not outlive \
570
+ lifetime bound of the object type") ;
571
+ }
572
+ infer:: CallRcvr ( span) => {
573
+ self . tcx . sess . span_note (
574
+ span,
575
+ "...so that method receiver is valid for the method call" ) ;
576
+ }
577
+ infer:: CallArg ( span) => {
578
+ self . tcx . sess . span_note (
579
+ span,
580
+ "...so that argument is valid for the call" ) ;
581
+ }
582
+ infer:: CallReturn ( span) => {
583
+ self . tcx . sess . span_note (
584
+ span,
585
+ "...so that return value is valid for the call" ) ;
586
+ }
587
+ infer:: AddrOf ( span) => {
588
+ self . tcx . sess . span_note (
589
+ span,
590
+ "...so that borrowed pointer is valid \
591
+ at the time of borrow") ;
592
+ }
593
+ infer:: AutoBorrow ( span) => {
594
+ self . tcx . sess . span_note (
595
+ span,
596
+ "...so that automatically borrowed pointer is valid \
597
+ at the time of borrow") ;
598
+ }
599
+ infer:: BindingTypeIsNotValidAtDecl ( span) => {
600
+ self . tcx . sess . span_note (
601
+ span,
602
+ "...so that variable is valid at time of its declaration" ) ;
603
+ }
604
+ infer:: ReferenceOutlivesReferent ( _, span) => {
605
+ self . tcx . sess . span_note (
606
+ span,
607
+ "...so that the pointer does not outlive the \
608
+ data it points at") ;
609
+ }
610
+ }
457
611
}
458
612
}
459
613
0 commit comments