Move two large error_reporting fn's to a separate file
This commit is contained in:
parent
0ed75e1f47
commit
d21b0e35e7
3 changed files with 480 additions and 469 deletions
|
@ -55,32 +55,25 @@
|
||||||
//! ported to this system, and which relies on string concatenation at the
|
//! ported to this system, and which relies on string concatenation at the
|
||||||
//! time of error detection.
|
//! time of error detection.
|
||||||
|
|
||||||
use super::InferCtxt;
|
|
||||||
use super::TypeTrace;
|
|
||||||
use super::SubregionOrigin;
|
|
||||||
use super::RegionVariableOrigin;
|
|
||||||
use super::ValuePairs;
|
|
||||||
use super::region_inference::RegionResolutionError;
|
|
||||||
use super::region_inference::ConcreteFailure;
|
|
||||||
use super::region_inference::SubSupConflict;
|
|
||||||
use super::region_inference::GenericBoundFailure;
|
|
||||||
use super::region_inference::GenericKind;
|
|
||||||
|
|
||||||
use hir::map as hir_map;
|
|
||||||
use hir;
|
|
||||||
|
|
||||||
use hir::def_id::DefId;
|
|
||||||
use infer;
|
use infer;
|
||||||
|
use super::{InferCtxt, TypeTrace, SubregionOrigin, RegionVariableOrigin, ValuePairs};
|
||||||
|
use super::region_inference::{RegionResolutionError, ConcreteFailure, SubSupConflict,
|
||||||
|
GenericBoundFailure, GenericKind};
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
|
use hir;
|
||||||
|
use hir::map as hir_map;
|
||||||
|
use hir::def_id::DefId;
|
||||||
use middle::region;
|
use middle::region;
|
||||||
use traits::{ObligationCause, ObligationCauseCode};
|
use traits::{ObligationCause, ObligationCauseCode};
|
||||||
use ty::{self, TyCtxt, TypeFoldable};
|
use ty::{self, TyCtxt, TypeFoldable};
|
||||||
use ty::{Region, Issue32330};
|
use ty::{Region, Issue32330};
|
||||||
use ty::error::TypeError;
|
use ty::error::TypeError;
|
||||||
|
|
||||||
use std::fmt;
|
|
||||||
use syntax_pos::{Pos, Span};
|
use syntax_pos::{Pos, Span};
|
||||||
use errors::DiagnosticBuilder;
|
use errors::DiagnosticBuilder;
|
||||||
|
|
||||||
|
mod note;
|
||||||
|
|
||||||
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||||
pub fn note_and_explain_region(self,
|
pub fn note_and_explain_region(self,
|
||||||
err: &mut DiagnosticBuilder,
|
err: &mut DiagnosticBuilder,
|
||||||
|
@ -584,289 +577,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||||
err.emit();
|
err.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn report_concrete_failure(&self,
|
|
||||||
origin: SubregionOrigin<'tcx>,
|
|
||||||
sub: &'tcx Region,
|
|
||||||
sup: &'tcx Region)
|
|
||||||
-> DiagnosticBuilder<'tcx> {
|
|
||||||
match origin {
|
|
||||||
infer::Subtype(trace) => {
|
|
||||||
let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
|
|
||||||
self.report_and_explain_type_error(trace, &terr)
|
|
||||||
}
|
|
||||||
infer::Reborrow(span) => {
|
|
||||||
let mut err = struct_span_err!(self.tcx.sess, span, E0312,
|
|
||||||
"lifetime of reference outlives \
|
|
||||||
lifetime of borrowed content...");
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"...the reference is valid for ",
|
|
||||||
sub,
|
|
||||||
"...");
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"...but the borrowed content is only valid for ",
|
|
||||||
sup,
|
|
||||||
"");
|
|
||||||
err
|
|
||||||
}
|
|
||||||
infer::ReborrowUpvar(span, ref upvar_id) => {
|
|
||||||
let mut err = struct_span_err!(self.tcx.sess, span, E0313,
|
|
||||||
"lifetime of borrowed pointer outlives \
|
|
||||||
lifetime of captured variable `{}`...",
|
|
||||||
self.tcx.local_var_name_str(upvar_id.var_id));
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"...the borrowed pointer is valid for ",
|
|
||||||
sub,
|
|
||||||
"...");
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
&format!("...but `{}` is only valid for ",
|
|
||||||
self.tcx.local_var_name_str(upvar_id.var_id)),
|
|
||||||
sup,
|
|
||||||
"");
|
|
||||||
err
|
|
||||||
}
|
|
||||||
infer::InfStackClosure(span) => {
|
|
||||||
let mut err = struct_span_err!(self.tcx.sess, span, E0314,
|
|
||||||
"closure outlives stack frame");
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"...the closure must be valid for ",
|
|
||||||
sub,
|
|
||||||
"...");
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"...but the closure's stack frame is only valid for ",
|
|
||||||
sup,
|
|
||||||
"");
|
|
||||||
err
|
|
||||||
}
|
|
||||||
infer::InvokeClosure(span) => {
|
|
||||||
let mut err = struct_span_err!(self.tcx.sess, span, E0315,
|
|
||||||
"cannot invoke closure outside of its lifetime");
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"the closure is only valid for ",
|
|
||||||
sup,
|
|
||||||
"");
|
|
||||||
err
|
|
||||||
}
|
|
||||||
infer::DerefPointer(span) => {
|
|
||||||
let mut err = struct_span_err!(self.tcx.sess, span, E0473,
|
|
||||||
"dereference of reference outside its lifetime");
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"the reference is only valid for ",
|
|
||||||
sup,
|
|
||||||
"");
|
|
||||||
err
|
|
||||||
}
|
|
||||||
infer::FreeVariable(span, id) => {
|
|
||||||
let mut err = struct_span_err!(self.tcx.sess, span, E0474,
|
|
||||||
"captured variable `{}` does not outlive the enclosing closure",
|
|
||||||
self.tcx.local_var_name_str(id));
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"captured variable is valid for ",
|
|
||||||
sup,
|
|
||||||
"");
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"closure is valid for ",
|
|
||||||
sub,
|
|
||||||
"");
|
|
||||||
err
|
|
||||||
}
|
|
||||||
infer::IndexSlice(span) => {
|
|
||||||
let mut err = struct_span_err!(self.tcx.sess, span, E0475,
|
|
||||||
"index of slice outside its lifetime");
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"the slice is only valid for ",
|
|
||||||
sup,
|
|
||||||
"");
|
|
||||||
err
|
|
||||||
}
|
|
||||||
infer::RelateObjectBound(span) => {
|
|
||||||
let mut err = struct_span_err!(self.tcx.sess, span, E0476,
|
|
||||||
"lifetime of the source pointer does not outlive \
|
|
||||||
lifetime bound of the object type");
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"object type is valid for ",
|
|
||||||
sub,
|
|
||||||
"");
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"source pointer is only valid for ",
|
|
||||||
sup,
|
|
||||||
"");
|
|
||||||
err
|
|
||||||
}
|
|
||||||
infer::RelateParamBound(span, ty) => {
|
|
||||||
let mut err = struct_span_err!(self.tcx.sess, span, E0477,
|
|
||||||
"the type `{}` does not fulfill the required lifetime",
|
|
||||||
self.ty_to_string(ty));
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"type must outlive ",
|
|
||||||
sub,
|
|
||||||
"");
|
|
||||||
err
|
|
||||||
}
|
|
||||||
infer::RelateRegionParamBound(span) => {
|
|
||||||
let mut err = struct_span_err!(self.tcx.sess, span, E0478,
|
|
||||||
"lifetime bound not satisfied");
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"lifetime parameter instantiated with ",
|
|
||||||
sup,
|
|
||||||
"");
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"but lifetime parameter must outlive ",
|
|
||||||
sub,
|
|
||||||
"");
|
|
||||||
err
|
|
||||||
}
|
|
||||||
infer::RelateDefaultParamBound(span, ty) => {
|
|
||||||
let mut err = struct_span_err!(self.tcx.sess, span, E0479,
|
|
||||||
"the type `{}` (provided as the value of \
|
|
||||||
a type parameter) is not valid at this point",
|
|
||||||
self.ty_to_string(ty));
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"type must outlive ",
|
|
||||||
sub,
|
|
||||||
"");
|
|
||||||
err
|
|
||||||
}
|
|
||||||
infer::CallRcvr(span) => {
|
|
||||||
let mut err = struct_span_err!(self.tcx.sess, span, E0480,
|
|
||||||
"lifetime of method receiver does not outlive \
|
|
||||||
the method call");
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"the receiver is only valid for ",
|
|
||||||
sup,
|
|
||||||
"");
|
|
||||||
err
|
|
||||||
}
|
|
||||||
infer::CallArg(span) => {
|
|
||||||
let mut err = struct_span_err!(self.tcx.sess, span, E0481,
|
|
||||||
"lifetime of function argument does not outlive \
|
|
||||||
the function call");
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"the function argument is only valid for ",
|
|
||||||
sup,
|
|
||||||
"");
|
|
||||||
err
|
|
||||||
}
|
|
||||||
infer::CallReturn(span) => {
|
|
||||||
let mut err = struct_span_err!(self.tcx.sess, span, E0482,
|
|
||||||
"lifetime of return value does not outlive \
|
|
||||||
the function call");
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"the return value is only valid for ",
|
|
||||||
sup,
|
|
||||||
"");
|
|
||||||
err
|
|
||||||
}
|
|
||||||
infer::Operand(span) => {
|
|
||||||
let mut err = struct_span_err!(self.tcx.sess, span, E0483,
|
|
||||||
"lifetime of operand does not outlive \
|
|
||||||
the operation");
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"the operand is only valid for ",
|
|
||||||
sup,
|
|
||||||
"");
|
|
||||||
err
|
|
||||||
}
|
|
||||||
infer::AddrOf(span) => {
|
|
||||||
let mut err = struct_span_err!(self.tcx.sess, span, E0484,
|
|
||||||
"reference is not valid at the time of borrow");
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"the borrow is only valid for ",
|
|
||||||
sup,
|
|
||||||
"");
|
|
||||||
err
|
|
||||||
}
|
|
||||||
infer::AutoBorrow(span) => {
|
|
||||||
let mut err = struct_span_err!(self.tcx.sess, span, E0485,
|
|
||||||
"automatically reference is not valid \
|
|
||||||
at the time of borrow");
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"the automatic borrow is only valid for ",
|
|
||||||
sup,
|
|
||||||
"");
|
|
||||||
err
|
|
||||||
}
|
|
||||||
infer::ExprTypeIsNotInScope(t, span) => {
|
|
||||||
let mut err = struct_span_err!(self.tcx.sess, span, E0486,
|
|
||||||
"type of expression contains references \
|
|
||||||
that are not valid during the expression: `{}`",
|
|
||||||
self.ty_to_string(t));
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"type is only valid for ",
|
|
||||||
sup,
|
|
||||||
"");
|
|
||||||
err
|
|
||||||
}
|
|
||||||
infer::SafeDestructor(span) => {
|
|
||||||
let mut err = struct_span_err!(self.tcx.sess, span, E0487,
|
|
||||||
"unsafe use of destructor: destructor might be called \
|
|
||||||
while references are dead");
|
|
||||||
// FIXME (22171): terms "super/subregion" are suboptimal
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"superregion: ",
|
|
||||||
sup,
|
|
||||||
"");
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"subregion: ",
|
|
||||||
sub,
|
|
||||||
"");
|
|
||||||
err
|
|
||||||
}
|
|
||||||
infer::BindingTypeIsNotValidAtDecl(span) => {
|
|
||||||
let mut err = struct_span_err!(self.tcx.sess, span, E0488,
|
|
||||||
"lifetime of variable does not enclose its declaration");
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"the variable is only valid for ",
|
|
||||||
sup,
|
|
||||||
"");
|
|
||||||
err
|
|
||||||
}
|
|
||||||
infer::ParameterInScope(_, span) => {
|
|
||||||
let mut err = struct_span_err!(self.tcx.sess, span, E0489,
|
|
||||||
"type/lifetime parameter not in scope here");
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"the parameter is only valid for ",
|
|
||||||
sub,
|
|
||||||
"");
|
|
||||||
err
|
|
||||||
}
|
|
||||||
infer::DataBorrowed(ty, span) => {
|
|
||||||
let mut err = struct_span_err!(self.tcx.sess, span, E0490,
|
|
||||||
"a value of type `{}` is borrowed for too long",
|
|
||||||
self.ty_to_string(ty));
|
|
||||||
self.tcx.note_and_explain_region(&mut err, "the type is valid for ", sub, "");
|
|
||||||
self.tcx.note_and_explain_region(&mut err, "but the borrow lasts for ", sup, "");
|
|
||||||
err
|
|
||||||
}
|
|
||||||
infer::ReferenceOutlivesReferent(ty, span) => {
|
|
||||||
let mut err = struct_span_err!(self.tcx.sess, span, E0491,
|
|
||||||
"in type `{}`, reference has a longer lifetime \
|
|
||||||
than the data it references",
|
|
||||||
self.ty_to_string(ty));
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"the pointer is valid for ",
|
|
||||||
sub,
|
|
||||||
"");
|
|
||||||
self.tcx.note_and_explain_region(&mut err,
|
|
||||||
"but the referenced data is only valid for ",
|
|
||||||
sup,
|
|
||||||
"");
|
|
||||||
err
|
|
||||||
}
|
|
||||||
infer::CompareImplMethodObligation { span,
|
|
||||||
item_name,
|
|
||||||
impl_item_def_id,
|
|
||||||
trait_item_def_id,
|
|
||||||
lint_id } => {
|
|
||||||
self.report_extra_impl_obligation(span,
|
|
||||||
item_name,
|
|
||||||
impl_item_def_id,
|
|
||||||
trait_item_def_id,
|
|
||||||
&format!("`{}: {}`", sup, sub),
|
|
||||||
lint_id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn report_sub_sup_conflict(&self,
|
fn report_sub_sup_conflict(&self,
|
||||||
var_origin: RegionVariableOrigin,
|
var_origin: RegionVariableOrigin,
|
||||||
sub_origin: SubregionOrigin<'tcx>,
|
sub_origin: SubregionOrigin<'tcx>,
|
||||||
|
@ -939,170 +649,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||||
due to conflicting requirements",
|
due to conflicting requirements",
|
||||||
var_description)
|
var_description)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn note_region_origin(&self, err: &mut DiagnosticBuilder, origin: &SubregionOrigin<'tcx>) {
|
|
||||||
match *origin {
|
|
||||||
infer::Subtype(ref trace) => {
|
|
||||||
if let Some((expected, found)) = self.values_str(&trace.values) {
|
|
||||||
// FIXME: do we want a "the" here?
|
|
||||||
err.span_note(
|
|
||||||
trace.cause.span,
|
|
||||||
&format!("...so that {} (expected {}, found {})",
|
|
||||||
trace.cause.as_requirement_str(), expected, found));
|
|
||||||
} else {
|
|
||||||
// FIXME: this really should be handled at some earlier stage. Our
|
|
||||||
// handling of region checking when type errors are present is
|
|
||||||
// *terrible*.
|
|
||||||
|
|
||||||
err.span_note(
|
|
||||||
trace.cause.span,
|
|
||||||
&format!("...so that {}",
|
|
||||||
trace.cause.as_requirement_str()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
infer::Reborrow(span) => {
|
|
||||||
err.span_note(
|
|
||||||
span,
|
|
||||||
"...so that reference does not outlive \
|
|
||||||
borrowed content");
|
|
||||||
}
|
|
||||||
infer::ReborrowUpvar(span, ref upvar_id) => {
|
|
||||||
err.span_note(
|
|
||||||
span,
|
|
||||||
&format!(
|
|
||||||
"...so that closure can access `{}`",
|
|
||||||
self.tcx.local_var_name_str(upvar_id.var_id)
|
|
||||||
.to_string()));
|
|
||||||
}
|
|
||||||
infer::InfStackClosure(span) => {
|
|
||||||
err.span_note(
|
|
||||||
span,
|
|
||||||
"...so that closure does not outlive its stack frame");
|
|
||||||
}
|
|
||||||
infer::InvokeClosure(span) => {
|
|
||||||
err.span_note(
|
|
||||||
span,
|
|
||||||
"...so that closure is not invoked outside its lifetime");
|
|
||||||
}
|
|
||||||
infer::DerefPointer(span) => {
|
|
||||||
err.span_note(
|
|
||||||
span,
|
|
||||||
"...so that pointer is not dereferenced \
|
|
||||||
outside its lifetime");
|
|
||||||
}
|
|
||||||
infer::FreeVariable(span, id) => {
|
|
||||||
err.span_note(
|
|
||||||
span,
|
|
||||||
&format!("...so that captured variable `{}` \
|
|
||||||
does not outlive the enclosing closure",
|
|
||||||
self.tcx.local_var_name_str(id)));
|
|
||||||
}
|
|
||||||
infer::IndexSlice(span) => {
|
|
||||||
err.span_note(
|
|
||||||
span,
|
|
||||||
"...so that slice is not indexed outside the lifetime");
|
|
||||||
}
|
|
||||||
infer::RelateObjectBound(span) => {
|
|
||||||
err.span_note(
|
|
||||||
span,
|
|
||||||
"...so that it can be closed over into an object");
|
|
||||||
}
|
|
||||||
infer::CallRcvr(span) => {
|
|
||||||
err.span_note(
|
|
||||||
span,
|
|
||||||
"...so that method receiver is valid for the method call");
|
|
||||||
}
|
|
||||||
infer::CallArg(span) => {
|
|
||||||
err.span_note(
|
|
||||||
span,
|
|
||||||
"...so that argument is valid for the call");
|
|
||||||
}
|
|
||||||
infer::CallReturn(span) => {
|
|
||||||
err.span_note(
|
|
||||||
span,
|
|
||||||
"...so that return value is valid for the call");
|
|
||||||
}
|
|
||||||
infer::Operand(span) => {
|
|
||||||
err.span_note(
|
|
||||||
span,
|
|
||||||
"...so that operand is valid for operation");
|
|
||||||
}
|
|
||||||
infer::AddrOf(span) => {
|
|
||||||
err.span_note(
|
|
||||||
span,
|
|
||||||
"...so that reference is valid \
|
|
||||||
at the time of borrow");
|
|
||||||
}
|
|
||||||
infer::AutoBorrow(span) => {
|
|
||||||
err.span_note(
|
|
||||||
span,
|
|
||||||
"...so that auto-reference is valid \
|
|
||||||
at the time of borrow");
|
|
||||||
}
|
|
||||||
infer::ExprTypeIsNotInScope(t, span) => {
|
|
||||||
err.span_note(
|
|
||||||
span,
|
|
||||||
&format!("...so type `{}` of expression is valid during the \
|
|
||||||
expression",
|
|
||||||
self.ty_to_string(t)));
|
|
||||||
}
|
|
||||||
infer::BindingTypeIsNotValidAtDecl(span) => {
|
|
||||||
err.span_note(
|
|
||||||
span,
|
|
||||||
"...so that variable is valid at time of its declaration");
|
|
||||||
}
|
|
||||||
infer::ParameterInScope(_, span) => {
|
|
||||||
err.span_note(
|
|
||||||
span,
|
|
||||||
"...so that a type/lifetime parameter is in scope here");
|
|
||||||
}
|
|
||||||
infer::DataBorrowed(ty, span) => {
|
|
||||||
err.span_note(
|
|
||||||
span,
|
|
||||||
&format!("...so that the type `{}` is not borrowed for too long",
|
|
||||||
self.ty_to_string(ty)));
|
|
||||||
}
|
|
||||||
infer::ReferenceOutlivesReferent(ty, span) => {
|
|
||||||
err.span_note(
|
|
||||||
span,
|
|
||||||
&format!("...so that the reference type `{}` \
|
|
||||||
does not outlive the data it points at",
|
|
||||||
self.ty_to_string(ty)));
|
|
||||||
}
|
|
||||||
infer::RelateParamBound(span, t) => {
|
|
||||||
err.span_note(
|
|
||||||
span,
|
|
||||||
&format!("...so that the type `{}` \
|
|
||||||
will meet its required lifetime bounds",
|
|
||||||
self.ty_to_string(t)));
|
|
||||||
}
|
|
||||||
infer::RelateDefaultParamBound(span, t) => {
|
|
||||||
err.span_note(
|
|
||||||
span,
|
|
||||||
&format!("...so that type parameter \
|
|
||||||
instantiated with `{}`, \
|
|
||||||
will meet its declared lifetime bounds",
|
|
||||||
self.ty_to_string(t)));
|
|
||||||
}
|
|
||||||
infer::RelateRegionParamBound(span) => {
|
|
||||||
err.span_note(
|
|
||||||
span,
|
|
||||||
"...so that the declared lifetime parameter bounds \
|
|
||||||
are satisfied");
|
|
||||||
}
|
|
||||||
infer::SafeDestructor(span) => {
|
|
||||||
err.span_note(
|
|
||||||
span,
|
|
||||||
"...so that references are valid when the destructor \
|
|
||||||
runs");
|
|
||||||
}
|
|
||||||
infer::CompareImplMethodObligation { span, .. } => {
|
|
||||||
err.span_note(
|
|
||||||
span,
|
|
||||||
"...so that the definition in impl matches the definition from the trait");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> ObligationCause<'tcx> {
|
impl<'tcx> ObligationCause<'tcx> {
|
465
src/librustc/infer/error_reporting/note.rs
Normal file
465
src/librustc/infer/error_reporting/note.rs
Normal file
|
@ -0,0 +1,465 @@
|
||||||
|
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
use infer::{self, InferCtxt, SubregionOrigin};
|
||||||
|
use ty::Region;
|
||||||
|
use ty::error::TypeError;
|
||||||
|
use errors::DiagnosticBuilder;
|
||||||
|
|
||||||
|
impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||||
|
pub fn note_region_origin(&self, err: &mut DiagnosticBuilder, origin: &SubregionOrigin<'tcx>) {
|
||||||
|
match *origin {
|
||||||
|
infer::Subtype(ref trace) => {
|
||||||
|
if let Some((expected, found)) = self.values_str(&trace.values) {
|
||||||
|
// FIXME: do we want a "the" here?
|
||||||
|
err.span_note(
|
||||||
|
trace.cause.span,
|
||||||
|
&format!("...so that {} (expected {}, found {})",
|
||||||
|
trace.cause.as_requirement_str(), expected, found));
|
||||||
|
} else {
|
||||||
|
// FIXME: this really should be handled at some earlier stage. Our
|
||||||
|
// handling of region checking when type errors are present is
|
||||||
|
// *terrible*.
|
||||||
|
|
||||||
|
err.span_note(
|
||||||
|
trace.cause.span,
|
||||||
|
&format!("...so that {}",
|
||||||
|
trace.cause.as_requirement_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
infer::Reborrow(span) => {
|
||||||
|
err.span_note(
|
||||||
|
span,
|
||||||
|
"...so that reference does not outlive \
|
||||||
|
borrowed content");
|
||||||
|
}
|
||||||
|
infer::ReborrowUpvar(span, ref upvar_id) => {
|
||||||
|
err.span_note(
|
||||||
|
span,
|
||||||
|
&format!(
|
||||||
|
"...so that closure can access `{}`",
|
||||||
|
self.tcx.local_var_name_str(upvar_id.var_id)
|
||||||
|
.to_string()));
|
||||||
|
}
|
||||||
|
infer::InfStackClosure(span) => {
|
||||||
|
err.span_note(
|
||||||
|
span,
|
||||||
|
"...so that closure does not outlive its stack frame");
|
||||||
|
}
|
||||||
|
infer::InvokeClosure(span) => {
|
||||||
|
err.span_note(
|
||||||
|
span,
|
||||||
|
"...so that closure is not invoked outside its lifetime");
|
||||||
|
}
|
||||||
|
infer::DerefPointer(span) => {
|
||||||
|
err.span_note(
|
||||||
|
span,
|
||||||
|
"...so that pointer is not dereferenced \
|
||||||
|
outside its lifetime");
|
||||||
|
}
|
||||||
|
infer::FreeVariable(span, id) => {
|
||||||
|
err.span_note(
|
||||||
|
span,
|
||||||
|
&format!("...so that captured variable `{}` \
|
||||||
|
does not outlive the enclosing closure",
|
||||||
|
self.tcx.local_var_name_str(id)));
|
||||||
|
}
|
||||||
|
infer::IndexSlice(span) => {
|
||||||
|
err.span_note(
|
||||||
|
span,
|
||||||
|
"...so that slice is not indexed outside the lifetime");
|
||||||
|
}
|
||||||
|
infer::RelateObjectBound(span) => {
|
||||||
|
err.span_note(
|
||||||
|
span,
|
||||||
|
"...so that it can be closed over into an object");
|
||||||
|
}
|
||||||
|
infer::CallRcvr(span) => {
|
||||||
|
err.span_note(
|
||||||
|
span,
|
||||||
|
"...so that method receiver is valid for the method call");
|
||||||
|
}
|
||||||
|
infer::CallArg(span) => {
|
||||||
|
err.span_note(
|
||||||
|
span,
|
||||||
|
"...so that argument is valid for the call");
|
||||||
|
}
|
||||||
|
infer::CallReturn(span) => {
|
||||||
|
err.span_note(
|
||||||
|
span,
|
||||||
|
"...so that return value is valid for the call");
|
||||||
|
}
|
||||||
|
infer::Operand(span) => {
|
||||||
|
err.span_note(
|
||||||
|
span,
|
||||||
|
"...so that operand is valid for operation");
|
||||||
|
}
|
||||||
|
infer::AddrOf(span) => {
|
||||||
|
err.span_note(
|
||||||
|
span,
|
||||||
|
"...so that reference is valid \
|
||||||
|
at the time of borrow");
|
||||||
|
}
|
||||||
|
infer::AutoBorrow(span) => {
|
||||||
|
err.span_note(
|
||||||
|
span,
|
||||||
|
"...so that auto-reference is valid \
|
||||||
|
at the time of borrow");
|
||||||
|
}
|
||||||
|
infer::ExprTypeIsNotInScope(t, span) => {
|
||||||
|
err.span_note(
|
||||||
|
span,
|
||||||
|
&format!("...so type `{}` of expression is valid during the \
|
||||||
|
expression",
|
||||||
|
self.ty_to_string(t)));
|
||||||
|
}
|
||||||
|
infer::BindingTypeIsNotValidAtDecl(span) => {
|
||||||
|
err.span_note(
|
||||||
|
span,
|
||||||
|
"...so that variable is valid at time of its declaration");
|
||||||
|
}
|
||||||
|
infer::ParameterInScope(_, span) => {
|
||||||
|
err.span_note(
|
||||||
|
span,
|
||||||
|
"...so that a type/lifetime parameter is in scope here");
|
||||||
|
}
|
||||||
|
infer::DataBorrowed(ty, span) => {
|
||||||
|
err.span_note(
|
||||||
|
span,
|
||||||
|
&format!("...so that the type `{}` is not borrowed for too long",
|
||||||
|
self.ty_to_string(ty)));
|
||||||
|
}
|
||||||
|
infer::ReferenceOutlivesReferent(ty, span) => {
|
||||||
|
err.span_note(
|
||||||
|
span,
|
||||||
|
&format!("...so that the reference type `{}` \
|
||||||
|
does not outlive the data it points at",
|
||||||
|
self.ty_to_string(ty)));
|
||||||
|
}
|
||||||
|
infer::RelateParamBound(span, t) => {
|
||||||
|
err.span_note(
|
||||||
|
span,
|
||||||
|
&format!("...so that the type `{}` \
|
||||||
|
will meet its required lifetime bounds",
|
||||||
|
self.ty_to_string(t)));
|
||||||
|
}
|
||||||
|
infer::RelateDefaultParamBound(span, t) => {
|
||||||
|
err.span_note(
|
||||||
|
span,
|
||||||
|
&format!("...so that type parameter \
|
||||||
|
instantiated with `{}`, \
|
||||||
|
will meet its declared lifetime bounds",
|
||||||
|
self.ty_to_string(t)));
|
||||||
|
}
|
||||||
|
infer::RelateRegionParamBound(span) => {
|
||||||
|
err.span_note(
|
||||||
|
span,
|
||||||
|
"...so that the declared lifetime parameter bounds \
|
||||||
|
are satisfied");
|
||||||
|
}
|
||||||
|
infer::SafeDestructor(span) => {
|
||||||
|
err.span_note(
|
||||||
|
span,
|
||||||
|
"...so that references are valid when the destructor \
|
||||||
|
runs");
|
||||||
|
}
|
||||||
|
infer::CompareImplMethodObligation { span, .. } => {
|
||||||
|
err.span_note(
|
||||||
|
span,
|
||||||
|
"...so that the definition in impl matches the definition from the trait");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn report_concrete_failure(&self,
|
||||||
|
origin: SubregionOrigin<'tcx>,
|
||||||
|
sub: &'tcx Region,
|
||||||
|
sup: &'tcx Region)
|
||||||
|
-> DiagnosticBuilder<'tcx> {
|
||||||
|
match origin {
|
||||||
|
infer::Subtype(trace) => {
|
||||||
|
let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
|
||||||
|
self.report_and_explain_type_error(trace, &terr)
|
||||||
|
}
|
||||||
|
infer::Reborrow(span) => {
|
||||||
|
let mut err = struct_span_err!(self.tcx.sess, span, E0312,
|
||||||
|
"lifetime of reference outlives \
|
||||||
|
lifetime of borrowed content...");
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"...the reference is valid for ",
|
||||||
|
sub,
|
||||||
|
"...");
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"...but the borrowed content is only valid for ",
|
||||||
|
sup,
|
||||||
|
"");
|
||||||
|
err
|
||||||
|
}
|
||||||
|
infer::ReborrowUpvar(span, ref upvar_id) => {
|
||||||
|
let mut err = struct_span_err!(self.tcx.sess, span, E0313,
|
||||||
|
"lifetime of borrowed pointer outlives \
|
||||||
|
lifetime of captured variable `{}`...",
|
||||||
|
self.tcx.local_var_name_str(upvar_id.var_id));
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"...the borrowed pointer is valid for ",
|
||||||
|
sub,
|
||||||
|
"...");
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
&format!("...but `{}` is only valid for ",
|
||||||
|
self.tcx.local_var_name_str(upvar_id.var_id)),
|
||||||
|
sup,
|
||||||
|
"");
|
||||||
|
err
|
||||||
|
}
|
||||||
|
infer::InfStackClosure(span) => {
|
||||||
|
let mut err = struct_span_err!(self.tcx.sess, span, E0314,
|
||||||
|
"closure outlives stack frame");
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"...the closure must be valid for ",
|
||||||
|
sub,
|
||||||
|
"...");
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"...but the closure's stack frame is only valid for ",
|
||||||
|
sup,
|
||||||
|
"");
|
||||||
|
err
|
||||||
|
}
|
||||||
|
infer::InvokeClosure(span) => {
|
||||||
|
let mut err = struct_span_err!(self.tcx.sess, span, E0315,
|
||||||
|
"cannot invoke closure outside of its lifetime");
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"the closure is only valid for ",
|
||||||
|
sup,
|
||||||
|
"");
|
||||||
|
err
|
||||||
|
}
|
||||||
|
infer::DerefPointer(span) => {
|
||||||
|
let mut err = struct_span_err!(self.tcx.sess, span, E0473,
|
||||||
|
"dereference of reference outside its lifetime");
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"the reference is only valid for ",
|
||||||
|
sup,
|
||||||
|
"");
|
||||||
|
err
|
||||||
|
}
|
||||||
|
infer::FreeVariable(span, id) => {
|
||||||
|
let mut err = struct_span_err!(self.tcx.sess, span, E0474,
|
||||||
|
"captured variable `{}` does not outlive the enclosing closure",
|
||||||
|
self.tcx.local_var_name_str(id));
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"captured variable is valid for ",
|
||||||
|
sup,
|
||||||
|
"");
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"closure is valid for ",
|
||||||
|
sub,
|
||||||
|
"");
|
||||||
|
err
|
||||||
|
}
|
||||||
|
infer::IndexSlice(span) => {
|
||||||
|
let mut err = struct_span_err!(self.tcx.sess, span, E0475,
|
||||||
|
"index of slice outside its lifetime");
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"the slice is only valid for ",
|
||||||
|
sup,
|
||||||
|
"");
|
||||||
|
err
|
||||||
|
}
|
||||||
|
infer::RelateObjectBound(span) => {
|
||||||
|
let mut err = struct_span_err!(self.tcx.sess, span, E0476,
|
||||||
|
"lifetime of the source pointer does not outlive \
|
||||||
|
lifetime bound of the object type");
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"object type is valid for ",
|
||||||
|
sub,
|
||||||
|
"");
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"source pointer is only valid for ",
|
||||||
|
sup,
|
||||||
|
"");
|
||||||
|
err
|
||||||
|
}
|
||||||
|
infer::RelateParamBound(span, ty) => {
|
||||||
|
let mut err = struct_span_err!(self.tcx.sess, span, E0477,
|
||||||
|
"the type `{}` does not fulfill the required lifetime",
|
||||||
|
self.ty_to_string(ty));
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"type must outlive ",
|
||||||
|
sub,
|
||||||
|
"");
|
||||||
|
err
|
||||||
|
}
|
||||||
|
infer::RelateRegionParamBound(span) => {
|
||||||
|
let mut err = struct_span_err!(self.tcx.sess, span, E0478,
|
||||||
|
"lifetime bound not satisfied");
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"lifetime parameter instantiated with ",
|
||||||
|
sup,
|
||||||
|
"");
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"but lifetime parameter must outlive ",
|
||||||
|
sub,
|
||||||
|
"");
|
||||||
|
err
|
||||||
|
}
|
||||||
|
infer::RelateDefaultParamBound(span, ty) => {
|
||||||
|
let mut err = struct_span_err!(self.tcx.sess, span, E0479,
|
||||||
|
"the type `{}` (provided as the value of \
|
||||||
|
a type parameter) is not valid at this point",
|
||||||
|
self.ty_to_string(ty));
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"type must outlive ",
|
||||||
|
sub,
|
||||||
|
"");
|
||||||
|
err
|
||||||
|
}
|
||||||
|
infer::CallRcvr(span) => {
|
||||||
|
let mut err = struct_span_err!(self.tcx.sess, span, E0480,
|
||||||
|
"lifetime of method receiver does not outlive \
|
||||||
|
the method call");
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"the receiver is only valid for ",
|
||||||
|
sup,
|
||||||
|
"");
|
||||||
|
err
|
||||||
|
}
|
||||||
|
infer::CallArg(span) => {
|
||||||
|
let mut err = struct_span_err!(self.tcx.sess, span, E0481,
|
||||||
|
"lifetime of function argument does not outlive \
|
||||||
|
the function call");
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"the function argument is only valid for ",
|
||||||
|
sup,
|
||||||
|
"");
|
||||||
|
err
|
||||||
|
}
|
||||||
|
infer::CallReturn(span) => {
|
||||||
|
let mut err = struct_span_err!(self.tcx.sess, span, E0482,
|
||||||
|
"lifetime of return value does not outlive \
|
||||||
|
the function call");
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"the return value is only valid for ",
|
||||||
|
sup,
|
||||||
|
"");
|
||||||
|
err
|
||||||
|
}
|
||||||
|
infer::Operand(span) => {
|
||||||
|
let mut err = struct_span_err!(self.tcx.sess, span, E0483,
|
||||||
|
"lifetime of operand does not outlive \
|
||||||
|
the operation");
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"the operand is only valid for ",
|
||||||
|
sup,
|
||||||
|
"");
|
||||||
|
err
|
||||||
|
}
|
||||||
|
infer::AddrOf(span) => {
|
||||||
|
let mut err = struct_span_err!(self.tcx.sess, span, E0484,
|
||||||
|
"reference is not valid at the time of borrow");
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"the borrow is only valid for ",
|
||||||
|
sup,
|
||||||
|
"");
|
||||||
|
err
|
||||||
|
}
|
||||||
|
infer::AutoBorrow(span) => {
|
||||||
|
let mut err = struct_span_err!(self.tcx.sess, span, E0485,
|
||||||
|
"automatically reference is not valid \
|
||||||
|
at the time of borrow");
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"the automatic borrow is only valid for ",
|
||||||
|
sup,
|
||||||
|
"");
|
||||||
|
err
|
||||||
|
}
|
||||||
|
infer::ExprTypeIsNotInScope(t, span) => {
|
||||||
|
let mut err = struct_span_err!(self.tcx.sess, span, E0486,
|
||||||
|
"type of expression contains references \
|
||||||
|
that are not valid during the expression: `{}`",
|
||||||
|
self.ty_to_string(t));
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"type is only valid for ",
|
||||||
|
sup,
|
||||||
|
"");
|
||||||
|
err
|
||||||
|
}
|
||||||
|
infer::SafeDestructor(span) => {
|
||||||
|
let mut err = struct_span_err!(self.tcx.sess, span, E0487,
|
||||||
|
"unsafe use of destructor: destructor might be called \
|
||||||
|
while references are dead");
|
||||||
|
// FIXME (22171): terms "super/subregion" are suboptimal
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"superregion: ",
|
||||||
|
sup,
|
||||||
|
"");
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"subregion: ",
|
||||||
|
sub,
|
||||||
|
"");
|
||||||
|
err
|
||||||
|
}
|
||||||
|
infer::BindingTypeIsNotValidAtDecl(span) => {
|
||||||
|
let mut err = struct_span_err!(self.tcx.sess, span, E0488,
|
||||||
|
"lifetime of variable does not enclose its declaration");
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"the variable is only valid for ",
|
||||||
|
sup,
|
||||||
|
"");
|
||||||
|
err
|
||||||
|
}
|
||||||
|
infer::ParameterInScope(_, span) => {
|
||||||
|
let mut err = struct_span_err!(self.tcx.sess, span, E0489,
|
||||||
|
"type/lifetime parameter not in scope here");
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"the parameter is only valid for ",
|
||||||
|
sub,
|
||||||
|
"");
|
||||||
|
err
|
||||||
|
}
|
||||||
|
infer::DataBorrowed(ty, span) => {
|
||||||
|
let mut err = struct_span_err!(self.tcx.sess, span, E0490,
|
||||||
|
"a value of type `{}` is borrowed for too long",
|
||||||
|
self.ty_to_string(ty));
|
||||||
|
self.tcx.note_and_explain_region(&mut err, "the type is valid for ", sub, "");
|
||||||
|
self.tcx.note_and_explain_region(&mut err, "but the borrow lasts for ", sup, "");
|
||||||
|
err
|
||||||
|
}
|
||||||
|
infer::ReferenceOutlivesReferent(ty, span) => {
|
||||||
|
let mut err = struct_span_err!(self.tcx.sess, span, E0491,
|
||||||
|
"in type `{}`, reference has a longer lifetime \
|
||||||
|
than the data it references",
|
||||||
|
self.ty_to_string(ty));
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"the pointer is valid for ",
|
||||||
|
sub,
|
||||||
|
"");
|
||||||
|
self.tcx.note_and_explain_region(&mut err,
|
||||||
|
"but the referenced data is only valid for ",
|
||||||
|
sup,
|
||||||
|
"");
|
||||||
|
err
|
||||||
|
}
|
||||||
|
infer::CompareImplMethodObligation {
|
||||||
|
span,
|
||||||
|
item_name,
|
||||||
|
impl_item_def_id,
|
||||||
|
trait_item_def_id,
|
||||||
|
lint_id
|
||||||
|
} => {
|
||||||
|
self.report_extra_impl_obligation(span,
|
||||||
|
item_name,
|
||||||
|
impl_item_def_id,
|
||||||
|
trait_item_def_id,
|
||||||
|
&format!("`{}: {}`", sup, sub),
|
||||||
|
lint_id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -210,7 +210,7 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||||
/// region that each late-bound region was replaced with.
|
/// region that each late-bound region was replaced with.
|
||||||
pub type SkolemizationMap<'tcx> = FxHashMap<ty::BoundRegion, &'tcx ty::Region>;
|
pub type SkolemizationMap<'tcx> = FxHashMap<ty::BoundRegion, &'tcx ty::Region>;
|
||||||
|
|
||||||
/// See `error_reporting.rs` for more details
|
/// See `error_reporting` module for more details
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum ValuePairs<'tcx> {
|
pub enum ValuePairs<'tcx> {
|
||||||
Types(ExpectedFound<Ty<'tcx>>),
|
Types(ExpectedFound<Ty<'tcx>>),
|
||||||
|
@ -221,7 +221,7 @@ pub enum ValuePairs<'tcx> {
|
||||||
/// The trace designates the path through inference that we took to
|
/// The trace designates the path through inference that we took to
|
||||||
/// encounter an error or subtyping constraint.
|
/// encounter an error or subtyping constraint.
|
||||||
///
|
///
|
||||||
/// See `error_reporting.rs` for more details.
|
/// See `error_reporting` module for more details.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct TypeTrace<'tcx> {
|
pub struct TypeTrace<'tcx> {
|
||||||
cause: ObligationCause<'tcx>,
|
cause: ObligationCause<'tcx>,
|
||||||
|
@ -230,7 +230,7 @@ pub struct TypeTrace<'tcx> {
|
||||||
|
|
||||||
/// The origin of a `r1 <= r2` constraint.
|
/// The origin of a `r1 <= r2` constraint.
|
||||||
///
|
///
|
||||||
/// See `error_reporting.rs` for more details
|
/// See `error_reporting` module for more details
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum SubregionOrigin<'tcx> {
|
pub enum SubregionOrigin<'tcx> {
|
||||||
// Arose from a subtyping relation
|
// Arose from a subtyping relation
|
||||||
|
@ -348,7 +348,7 @@ pub enum LateBoundRegionConversionTime {
|
||||||
|
|
||||||
/// Reasons to create a region inference variable
|
/// Reasons to create a region inference variable
|
||||||
///
|
///
|
||||||
/// See `error_reporting.rs` for more details
|
/// See `error_reporting` module for more details
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum RegionVariableOrigin {
|
pub enum RegionVariableOrigin {
|
||||||
// Region variables created for ill-categorized reasons,
|
// Region variables created for ill-categorized reasons,
|
||||||
|
@ -1292,7 +1292,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||||
// this infcx was in use. This is totally hokey but
|
// this infcx was in use. This is totally hokey but
|
||||||
// otherwise we have a hard time separating legit region
|
// otherwise we have a hard time separating legit region
|
||||||
// errors from silly ones.
|
// errors from silly ones.
|
||||||
self.report_region_errors(&errors); // see error_reporting.rs
|
self.report_region_errors(&errors); // see error_reporting module
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue