diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index e653f645881..5c2bafd5ae8 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -79,98 +79,95 @@ pub use need_type_info::TypeAnnotationNeeded; pub mod nice_region_error; -impl<'tcx> TyCtxt<'tcx> { - pub fn note_and_explain_region( - self, - region_scope_tree: ®ion::ScopeTree, - err: &mut DiagnosticBuilder<'_>, - prefix: &str, - region: ty::Region<'tcx>, - suffix: &str, - ) { - let (description, span) = match *region { - ty::ReScope(scope) => { - let new_string; - let unknown_scope = || { - format!("{}unknown scope: {:?}{}. Please report a bug.", prefix, scope, suffix) - }; - let span = scope.span(self, region_scope_tree); - let tag = match self.hir().find(scope.hir_id(region_scope_tree)) { - Some(Node::Block(_)) => "block", - Some(Node::Expr(expr)) => match expr.kind { - hir::ExprKind::Call(..) => "call", - hir::ExprKind::MethodCall(..) => "method call", - hir::ExprKind::Match(.., hir::MatchSource::IfLetDesugar { .. }) => "if let", - hir::ExprKind::Match(.., hir::MatchSource::WhileLetDesugar) => "while let", - hir::ExprKind::Match(.., hir::MatchSource::ForLoopDesugar) => "for", - hir::ExprKind::Match(..) => "match", - _ => "expression", - }, - Some(Node::Stmt(_)) => "statement", - Some(Node::Item(it)) => item_scope_tag(&it), - Some(Node::TraitItem(it)) => trait_item_scope_tag(&it), - Some(Node::ImplItem(it)) => impl_item_scope_tag(&it), - Some(_) | None => { - err.span_note(span, &unknown_scope()); - return; - } - }; - let scope_decorated_tag = match scope.data { - region::ScopeData::Node => tag, - region::ScopeData::CallSite => "scope of call-site for function", - region::ScopeData::Arguments => "scope of function body", - region::ScopeData::Destruction => { - new_string = format!("destruction scope surrounding {}", tag); - &new_string[..] - } - region::ScopeData::Remainder(first_statement_index) => { - new_string = format!( - "block suffix following statement {}", - first_statement_index.index() - ); - &new_string[..] - } - }; - explain_span(self, scope_decorated_tag, span) - } +pub(super) fn note_and_explain_region( + tcx: TyCtxt<'tcx>, + region_scope_tree: ®ion::ScopeTree, + err: &mut DiagnosticBuilder<'_>, + prefix: &str, + region: ty::Region<'tcx>, + suffix: &str, +) { + let (description, span) = match *region { + ty::ReScope(scope) => { + let new_string; + let unknown_scope = + || format!("{}unknown scope: {:?}{}. Please report a bug.", prefix, scope, suffix); + let span = scope.span(tcx, region_scope_tree); + let tag = match tcx.hir().find(scope.hir_id(region_scope_tree)) { + Some(Node::Block(_)) => "block", + Some(Node::Expr(expr)) => match expr.kind { + hir::ExprKind::Call(..) => "call", + hir::ExprKind::MethodCall(..) => "method call", + hir::ExprKind::Match(.., hir::MatchSource::IfLetDesugar { .. }) => "if let", + hir::ExprKind::Match(.., hir::MatchSource::WhileLetDesugar) => "while let", + hir::ExprKind::Match(.., hir::MatchSource::ForLoopDesugar) => "for", + hir::ExprKind::Match(..) => "match", + _ => "expression", + }, + Some(Node::Stmt(_)) => "statement", + Some(Node::Item(it)) => item_scope_tag(&it), + Some(Node::TraitItem(it)) => trait_item_scope_tag(&it), + Some(Node::ImplItem(it)) => impl_item_scope_tag(&it), + Some(_) | None => { + err.span_note(span, &unknown_scope()); + return; + } + }; + let scope_decorated_tag = match scope.data { + region::ScopeData::Node => tag, + region::ScopeData::CallSite => "scope of call-site for function", + region::ScopeData::Arguments => "scope of function body", + region::ScopeData::Destruction => { + new_string = format!("destruction scope surrounding {}", tag); + &new_string[..] + } + region::ScopeData::Remainder(first_statement_index) => { + new_string = format!( + "block suffix following statement {}", + first_statement_index.index() + ); + &new_string[..] + } + }; + explain_span(tcx, scope_decorated_tag, span) + } - ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic => { - msg_span_from_free_region(self, region) - } + ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic => { + msg_span_from_free_region(tcx, region) + } - ty::ReEmpty => ("the empty lifetime".to_owned(), None), + ty::ReEmpty => ("the empty lifetime".to_owned(), None), - ty::RePlaceholder(_) => (format!("any other region"), None), + ty::RePlaceholder(_) => (format!("any other region"), None), - // FIXME(#13998) RePlaceholder should probably print like - // ReFree rather than dumping Debug output on the user. - // - // We shouldn't really be having unification failures with ReVar - // and ReLateBound though. - ty::ReVar(_) | ty::ReLateBound(..) | ty::ReErased => { - (format!("lifetime {:?}", region), None) - } + // FIXME(#13998) RePlaceholder should probably print like + // ReFree rather than dumping Debug output on the user. + // + // We shouldn't really be having unification failures with ReVar + // and ReLateBound though. + ty::ReVar(_) | ty::ReLateBound(..) | ty::ReErased => { + (format!("lifetime {:?}", region), None) + } - // We shouldn't encounter an error message with ReClosureBound. - ty::ReClosureBound(..) => { - bug!("encountered unexpected ReClosureBound: {:?}", region,); - } - }; + // We shouldn't encounter an error message with ReClosureBound. + ty::ReClosureBound(..) => { + bug!("encountered unexpected ReClosureBound: {:?}", region,); + } + }; - emit_msg_span(err, prefix, description, span, suffix); - } + emit_msg_span(err, prefix, description, span, suffix); +} - pub fn note_and_explain_free_region( - self, - err: &mut DiagnosticBuilder<'_>, - prefix: &str, - region: ty::Region<'tcx>, - suffix: &str, - ) { - let (description, span) = msg_span_from_free_region(self, region); +pub(super) fn note_and_explain_free_region( + tcx: TyCtxt<'tcx>, + err: &mut DiagnosticBuilder<'_>, + prefix: &str, + region: ty::Region<'tcx>, + suffix: &str, +) { + let (description, span) = msg_span_from_free_region(tcx, region); - emit_msg_span(err, prefix, description, span, suffix); - } + emit_msg_span(err, prefix, description, span, suffix); } fn msg_span_from_free_region( @@ -1719,7 +1716,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { "consider adding an explicit lifetime bound for `{}`", bound_kind )); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, &format!("{} must be valid for ", labeled_user_string), @@ -1747,7 +1745,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ) { let mut err = self.report_inference_failure(var_origin); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "first, the lifetime cannot outlive ", @@ -1771,7 +1770,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { (self.values_str(&sup_trace.values), self.values_str(&sub_trace.values)) { if sub_expected == sup_expected && sub_found == sup_found { - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "...but the lifetime must also be valid for ", @@ -1794,7 +1794,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.note_region_origin(&mut err, &sup_origin); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "but, the lifetime must be valid for ", diff --git a/src/librustc/infer/error_reporting/note.rs b/src/librustc/infer/error_reporting/note.rs index 979bcca619c..7919274c373 100644 --- a/src/librustc/infer/error_reporting/note.rs +++ b/src/librustc/infer/error_reporting/note.rs @@ -1,3 +1,4 @@ +use crate::infer::error_reporting::note_and_explain_region; use crate::infer::{self, InferCtxt, SubregionOrigin}; use crate::middle::region; use crate::ty::error::TypeError; @@ -167,8 +168,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { infer::Subtype(box trace) => { let terr = TypeError::RegionsDoesNotOutlive(sup, sub); let mut err = self.report_and_explain_type_error(trace, &terr); - self.tcx.note_and_explain_region(region_scope_tree, &mut err, "", sup, "..."); - self.tcx.note_and_explain_region( + note_and_explain_region(self.tcx, region_scope_tree, &mut err, "", sup, "..."); + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "...does not necessarily outlive ", @@ -185,14 +187,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { "lifetime of reference outlives lifetime of \ borrowed content..." ); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "...the reference is valid for ", sub, "...", ); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "...but the borrowed content is only valid for ", @@ -211,14 +215,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { of captured variable `{}`...", var_name ); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "...the borrowed pointer is valid for ", sub, "...", ); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, &format!("...but `{}` is only valid for ", var_name), @@ -230,14 +236,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { infer::InfStackClosure(span) => { let mut err = struct_span_err!(self.tcx.sess, span, E0314, "closure outlives stack frame"); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "...the closure must be valid for ", sub, "...", ); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "...but the closure's stack frame is only valid \ @@ -254,7 +262,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { E0315, "cannot invoke closure outside of its lifetime" ); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "the closure is only valid for ", @@ -270,7 +279,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { E0473, "dereference of reference outside its lifetime" ); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "the reference is only valid for ", @@ -288,14 +298,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { enclosing closure", self.tcx.hir().name(id) ); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "captured variable is valid for ", sup, "", ); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "closure is valid for ", @@ -311,7 +323,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { E0475, "index of slice outside its lifetime" ); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "the slice is only valid for ", @@ -328,14 +341,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { "lifetime of the source pointer does not outlive \ lifetime bound of the object type" ); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "object type is valid for ", sub, "", ); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "source pointer is only valid for ", @@ -354,14 +369,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.ty_to_string(ty) ); match *sub { - ty::ReStatic => self.tcx.note_and_explain_region( + ty::ReStatic => note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "type must satisfy ", sub, "", ), - _ => self.tcx.note_and_explain_region( + _ => note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "type must outlive ", @@ -374,14 +391,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { infer::RelateRegionParamBound(span) => { let mut err = struct_span_err!(self.tcx.sess, span, E0478, "lifetime bound not satisfied"); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "lifetime parameter instantiated with ", sup, "", ); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "but lifetime parameter must outlive ", @@ -399,7 +418,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { parameter) is not valid at this point", self.ty_to_string(ty) ); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "type must outlive ", @@ -416,7 +436,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { "lifetime of method receiver does not outlive the \ method call" ); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "the receiver is only valid for ", @@ -433,7 +454,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { "lifetime of function argument does not outlive \ the function call" ); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "the function argument is only valid for ", @@ -450,7 +472,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { "lifetime of return value does not outlive the \ function call" ); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "the return value is only valid for ", @@ -467,7 +490,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { "lifetime of operand does not outlive the \ operation" ); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "the operand is only valid for ", @@ -483,7 +507,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { E0484, "reference is not valid at the time of borrow" ); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "the borrow is only valid for ", @@ -500,7 +525,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { "automatically reference is not valid at the time \ of borrow" ); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "the automatic borrow is only valid for ", @@ -518,7 +544,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { not valid during the expression: `{}`", self.ty_to_string(t) ); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "type is only valid for ", @@ -536,14 +563,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { called while references are dead" ); // FIXME (22171): terms "super/subregion" are suboptimal - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "superregion: ", sup, "", ); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "subregion: ", @@ -560,7 +589,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { "lifetime of variable does not enclose its \ declaration" ); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "the variable is only valid for ", @@ -576,7 +606,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { E0489, "type/lifetime parameter not in scope here" ); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "the parameter is only valid for ", @@ -593,14 +624,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { "a value of type `{}` is borrowed for too long", self.ty_to_string(ty) ); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "the type is valid for ", sub, "", ); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "but the borrow lasts for ", @@ -618,14 +651,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { than the data it references", self.ty_to_string(ty) ); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "the pointer is valid for ", sub, "", ); - self.tcx.note_and_explain_region( + note_and_explain_region( + self.tcx, region_scope_tree, &mut err, "but the referenced data is only valid for ", diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index e9b1ebbd3f6..834b8e8e72e 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -1,3 +1,4 @@ +use crate::infer::error_reporting::{note_and_explain_free_region, note_and_explain_region}; use crate::infer::outlives::free_region_map::FreeRegionRelations; use crate::infer::{self, InferCtxt, InferOk, TypeVariableOrigin, TypeVariableOriginKind}; use crate::middle::region; @@ -624,7 +625,8 @@ pub fn unexpected_hidden_region_diagnostic( // // (*) if not, the `tainted_by_errors` flag would be set to // true in any case, so we wouldn't be here at all. - tcx.note_and_explain_free_region( + note_and_explain_free_region( + tcx, &mut err, &format!("hidden type `{}` captures ", hidden_ty), hidden_region, @@ -649,7 +651,8 @@ pub fn unexpected_hidden_region_diagnostic( // If the `region_scope_tree` is available, this is being // invoked from the "region inferencer error". We can at // least report a really cryptic error for now. - tcx.note_and_explain_region( + note_and_explain_region( + tcx, region_scope_tree, &mut err, &format!("hidden type `{}` captures ", hidden_ty),