Skip to content

Commit 98458e4

Browse files
committed
---
yaml --- r: 95967 b: refs/heads/dist-snap c: f57a28b h: refs/heads/master i: 95965: 276f991 95963: 3589094 95959: be85e12 95951: 8e7cb90 95935: e99de74 v: v3
1 parent 8477c48 commit 98458e4

File tree

2 files changed

+175
-21
lines changed

2 files changed

+175
-21
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ refs/heads/try: c274a6888410ce3e357e014568b43310ed787d36
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c
9-
refs/heads/dist-snap: 168ac5290e9d4a787e020735f96fa789060a8f76
9+
refs/heads/dist-snap: f57a28b2dbb1823b88b5db270145a4f324820390
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503
1212
refs/heads/try3: 9387340aab40a73e8424c48fd42f0c521a4875c0

branches/dist-snap/src/librustc/middle/typeck/infer/error_reporting.rs

Lines changed: 174 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ use middle::typeck::infer::region_inference::SubSupConflict;
7373
use middle::typeck::infer::region_inference::SupSupConflict;
7474
use syntax::opt_vec::OptVec;
7575
use util::ppaux::UserString;
76+
use util::ppaux::bound_region_to_str;
7677
use util::ppaux::note_and_explain_region;
7778

7879
pub trait ErrorReporting {
@@ -110,6 +111,13 @@ pub trait ErrorReporting {
110111
region2: Region);
111112
}
112113

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+
}
113121

114122
impl ErrorReporting for InferCtxt {
115123
fn report_region_errors(@mut self,
@@ -398,30 +406,23 @@ impl ErrorReporting for InferCtxt {
398406
sub_region: Region,
399407
sup_origin: SubregionOrigin,
400408
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);
405410

406411
note_and_explain_region(
407412
self.tcx,
408413
"first, the lifetime cannot outlive ",
409414
sup_region,
410415
"...");
411416

412-
self.tcx.sess.span_note(
413-
sup_origin.span(),
414-
format!("...due to the following expression"));
417+
self.note_region_origin(sup_origin);
415418

416419
note_and_explain_region(
417420
self.tcx,
418421
"but, the lifetime must be valid for ",
419422
sub_region,
420423
"...");
421424

422-
self.tcx.sess.span_note(
423-
sub_origin.span(),
424-
format!("...due to the following expression"));
425+
self.note_region_origin(sub_origin);
425426
}
426427

427428
fn report_sup_sup_conflict(@mut self,
@@ -430,30 +431,183 @@ impl ErrorReporting for InferCtxt {
430431
region1: Region,
431432
origin2: SubregionOrigin,
432433
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);
437435

438436
note_and_explain_region(
439437
self.tcx,
440438
"first, the lifetime must be contained by ",
441439
region1,
442440
"...");
443441

444-
self.tcx.sess.span_note(
445-
origin1.span(),
446-
format!("...due to the following expression"));
442+
self.note_region_origin(origin1);
447443

448444
note_and_explain_region(
449445
self.tcx,
450446
"but, the lifetime must also be contained by ",
451447
region2,
452448
"...");
453449

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+
}
457611
}
458612
}
459613

0 commit comments

Comments
 (0)