Skip to content

Commit

Permalink
Make rustc::infer::error_reporting::{note_and_explain_free_region, no…
Browse files Browse the repository at this point in the history
…te_and_explain_region} free functions.
  • Loading branch information
cjgillot committed Jan 7, 2020
1 parent 7118e33 commit d53bf7a
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 125 deletions.
177 changes: 89 additions & 88 deletions src/librustc/infer/error_reporting/mod.rs
Expand Up @@ -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: &region::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: &region::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(
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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 ",
Expand All @@ -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 ",
Expand All @@ -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 ",
Expand Down

0 comments on commit d53bf7a

Please sign in to comment.