+++ /dev/null
-//! Error Reporting for Anonymous Region Lifetime Errors
-//! where both the regions are anonymous.
-
-use crate::infer::error_reporting::nice_region_error::NiceRegionError;
-use crate::infer::lexical_region_resolve::RegionResolutionError::SubSupConflict;
-use crate::infer::SubregionOrigin;
-use rustc_errors::ErrorReported;
-use rustc_hir::{Expr, ExprKind::Closure, Node};
-use rustc_middle::ty::RegionKind;
-
-impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
- /// Print the error message for lifetime errors when binding escapes a closure.
- ///
- /// Consider a case where we have
- ///
- /// ```no_run
- /// fn with_int<F>(f: F) where F: FnOnce(&isize) {
- /// let x = 3;
- /// f(&x);
- /// }
- /// fn main() {
- /// let mut x = None;
- /// with_int(|y| x = Some(y));
- /// }
- /// ```
- ///
- /// the output will be
- ///
- /// ```text
- /// let mut x = None;
- /// ----- borrowed data cannot be stored into here...
- /// with_int(|y| x = Some(y));
- /// --- ^ cannot be stored outside of its closure
- /// |
- /// ...because it cannot outlive this closure
- /// ```
- pub(super) fn try_report_outlives_closure(&self) -> Option<ErrorReported> {
- if let Some(SubSupConflict(_, origin, ref sub_origin, _, ref sup_origin, sup_region)) =
- self.error
- {
- // #45983: when trying to assign the contents of an argument to a binding outside of a
- // closure, provide a specific message pointing this out.
- if let (
- &SubregionOrigin::BindingTypeIsNotValidAtDecl(ref external_span),
- &RegionKind::ReFree(ref free_region),
- ) = (&sub_origin, sup_region)
- {
- let hir = &self.tcx().hir();
- if let Some(def_id) = free_region.scope.as_local() {
- let hir_id = hir.as_local_hir_id(def_id);
- if let Node::Expr(Expr { kind: Closure(_, _, _, closure_span, None), .. }) =
- hir.get(hir_id)
- {
- let sup_sp = sup_origin.span();
- let origin_sp = origin.span();
- let mut err = self.tcx().sess.struct_span_err(
- sup_sp,
- "borrowed data cannot be stored outside of its closure",
- );
- err.span_label(sup_sp, "cannot be stored outside of its closure");
- if origin_sp == sup_sp || origin_sp.contains(sup_sp) {
- // // sup_sp == origin.span():
- //
- // let mut x = None;
- // ----- borrowed data cannot be stored into here...
- // with_int(|y| x = Some(y));
- // --- ^ cannot be stored outside of its closure
- // |
- // ...because it cannot outlive this closure
- //
- // // origin.contains(&sup_sp):
- //
- // let mut f: Option<&u32> = None;
- // ----- borrowed data cannot be stored into here...
- // closure_expecting_bound(|x: &'x u32| {
- // ------------ ... because it cannot outlive this closure
- // f = Some(x);
- // ^ cannot be stored outside of its closure
- err.span_label(
- *external_span,
- "borrowed data cannot be stored into here...",
- );
- err.span_label(
- *closure_span,
- "...because it cannot outlive this closure",
- );
- } else {
- // FIXME: the wording for this case could be much improved
- //
- // let mut lines_to_use: Vec<&CrateId> = Vec::new();
- // - cannot infer an appropriate lifetime...
- // let push_id = |installed_id: &CrateId| {
- // ------- ------------------------ borrowed data cannot outlive this closure
- // |
- // ...so that variable is valid at time of its declaration
- // lines_to_use.push(installed_id);
- // ^^^^^^^^^^^^ cannot be stored outside of its closure
- err.span_label(origin_sp, "cannot infer an appropriate lifetime...");
- err.span_label(
- *external_span,
- "...so that variable is valid at time of its \
- declaration",
- );
- err.span_label(
- *closure_span,
- "borrowed data cannot outlive this closure",
- );
- }
- err.emit();
- return Some(ErrorReported);
- }
- }
- }
- }
- None
- }
-}
let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id);
err.span_note(span, &format!("...so that closure can access `{}`", var_name));
}
- 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::ClosureCapture(span, id) => {
- err.span_note(
- span,
- &format!(
- "...so that captured variable `{}` does not outlive the \
- enclosing closure",
- self.tcx.hir().name(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,
),
);
}
- 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,
);
err
}
- infer::InfStackClosure(span) => {
- let mut err =
- struct_span_err!(self.tcx.sess, span, E0314, "closure outlives stack frame");
- note_and_explain_region(
- self.tcx,
- region_scope_tree,
- &mut err,
- "...the closure must be valid for ",
- sub,
- "...",
- );
- note_and_explain_region(
- self.tcx,
- region_scope_tree,
- &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"
- );
- note_and_explain_region(
- self.tcx,
- region_scope_tree,
- &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"
- );
- note_and_explain_region(
- self.tcx,
- region_scope_tree,
- &mut err,
- "the reference is only valid for ",
- sup,
- "",
- );
- err
- }
- infer::ClosureCapture(span, id) => {
- let mut err = struct_span_err!(
- self.tcx.sess,
- span,
- E0474,
- "captured variable `{}` does not outlive the \
- enclosing closure",
- self.tcx.hir().name(id)
- );
- note_and_explain_region(
- self.tcx,
- region_scope_tree,
- &mut err,
- "captured variable is valid for ",
- sup,
- "",
- );
- note_and_explain_region(
- self.tcx,
- region_scope_tree,
- &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"
- );
- note_and_explain_region(
- self.tcx,
- region_scope_tree,
- &mut err,
- "the slice is only valid for ",
- sup,
- "",
- );
- err
- }
infer::RelateObjectBound(span) => {
let mut err = struct_span_err!(
self.tcx.sess,
);
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)
- );
- note_and_explain_region(
- self.tcx,
- region_scope_tree,
- &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"
- );
- note_and_explain_region(
- self.tcx,
- region_scope_tree,
- &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"
- );
- note_and_explain_region(
- self.tcx,
- region_scope_tree,
- &mut err,
- "the function argument is only valid for ",
- sup,
- "",
- );
- err
- }
infer::CallReturn(span) => {
let mut err = struct_span_err!(
self.tcx.sess,
);
err
}
- infer::Operand(span) => {
- let mut err = struct_span_err!(
- self.tcx.sess,
- span,
- E0483,
- "lifetime of operand does not outlive the \
- operation"
- );
- note_and_explain_region(
- self.tcx,
- region_scope_tree,
- &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"
- );
- note_and_explain_region(
- self.tcx,
- region_scope_tree,
- &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"
- );
- note_and_explain_region(
- self.tcx,
- region_scope_tree,
- &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)
- );
- note_and_explain_region(
- self.tcx,
- region_scope_tree,
- &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
- note_and_explain_region(
- self.tcx,
- region_scope_tree,
- &mut err,
- "superregion: ",
- sup,
- "",
- );
- note_and_explain_region(
- self.tcx,
- region_scope_tree,
- &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"
- );
- note_and_explain_region(
- self.tcx,
- region_scope_tree,
- &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"
- );
- note_and_explain_region(
- self.tcx,
- region_scope_tree,
- &mut err,
- "the parameter is only valid for ",
- sub,
- "",
- );
- err
- }
infer::DataBorrowed(ty, span) => {
let mut err = struct_span_err!(
self.tcx.sess,
/// Arose from a subtyping relation
Subtype(Box<TypeTrace<'tcx>>),
- /// Stack-allocated closures cannot outlive innermost loop
- /// or function so as to ensure we only require finite stack
- InfStackClosure(Span),
-
- /// Invocation of closure must be within its lifetime
- InvokeClosure(Span),
-
- /// Dereference of reference must be within its lifetime
- DerefPointer(Span),
-
- /// Closure bound must not outlive captured variables
- ClosureCapture(Span, hir::HirId),
-
- /// Index into slice must be within its lifetime
- IndexSlice(Span),
-
/// When casting `&'a T` to an `&'b Trait` object,
/// relating `'a` to `'b`
RelateObjectBound(Span),
/// that must outlive some other region.
RelateRegionParamBound(Span),
- /// A bound placed on type parameters that states that must outlive
- /// the moment of their instantiation.
- RelateDefaultParamBound(Span, Ty<'tcx>),
-
/// Creating a pointer `b` to contents of another reference
Reborrow(Span),
/// (&'a &'b T) where a >= b
ReferenceOutlivesReferent(Ty<'tcx>, Span),
- /// Type or region parameters must be in scope.
- ParameterInScope(ParameterOrigin, Span),
-
- /// The type T of an expression E must outlive the lifetime for E.
- ExprTypeIsNotInScope(Ty<'tcx>, Span),
-
- /// A `ref b` whose region does not enclose the decl site
- BindingTypeIsNotValidAtDecl(Span),
-
- /// Regions appearing in a method receiver must outlive method call
- CallRcvr(Span),
-
- /// Regions appearing in a function argument must outlive func call
- CallArg(Span),
-
/// Region in return type of invoked fn must enclose call
CallReturn(Span),
- /// Operands must be in scope
- Operand(Span),
-
- /// Region resulting from a `&` expr must enclose the `&` expr
- AddrOf(Span),
-
- /// An auto-borrow that does not enclose the expr where it occurs
- AutoBorrow(Span),
-
- /// Region constraint arriving from destructor safety
- SafeDestructor(Span),
-
/// Comparing the signature and requirements of an impl method against
/// the containing trait.
CompareImplMethodObligation {
pub fn span(&self) -> Span {
match *self {
Subtype(ref a) => a.span(),
- InfStackClosure(a) => a,
- InvokeClosure(a) => a,
- DerefPointer(a) => a,
- ClosureCapture(a, _) => a,
- IndexSlice(a) => a,
RelateObjectBound(a) => a,
RelateParamBound(a, _) => a,
RelateRegionParamBound(a) => a,
- RelateDefaultParamBound(a, _) => a,
Reborrow(a) => a,
ReborrowUpvar(a, _) => a,
DataBorrowed(_, a) => a,
ReferenceOutlivesReferent(_, a) => a,
- ParameterInScope(_, a) => a,
- ExprTypeIsNotInScope(_, a) => a,
- BindingTypeIsNotValidAtDecl(a) => a,
- CallRcvr(a) => a,
- CallArg(a) => a,
CallReturn(a) => a,
- Operand(a) => a,
- AddrOf(a) => a,
- AutoBorrow(a) => a,
- SafeDestructor(a) => a,
CompareImplMethodObligation { span, .. } => span,
}
}