Inline and remove DescriptionCtx::from_early_bound_and_free_regions
.
It has a single call site, and the code is clearer with all region kinds handled in one function, instead of splitting the handling across two functions. The commit also changes `DescriptionCtx::new` to use a more declarative style, instead of creating a default `DescriptionCtx` and modifying it, which I find easier to read.
This commit is contained in:
parent
c9b0635679
commit
877777f5bc
1 changed files with 55 additions and 78 deletions
|
@ -4,7 +4,6 @@ use rustc_errors::{self, AddToDiagnostic, Diagnostic, IntoDiagnosticArg, Subdiag
|
||||||
use rustc_middle::ty::{self, TyCtxt};
|
use rustc_middle::ty::{self, TyCtxt};
|
||||||
use rustc_span::{symbol::kw, Span};
|
use rustc_span::{symbol::kw, Span};
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
struct DescriptionCtx<'a> {
|
struct DescriptionCtx<'a> {
|
||||||
span: Option<Span>,
|
span: Option<Span>,
|
||||||
kind: &'a str,
|
kind: &'a str,
|
||||||
|
@ -17,19 +16,63 @@ impl<'a> DescriptionCtx<'a> {
|
||||||
region: ty::Region<'tcx>,
|
region: ty::Region<'tcx>,
|
||||||
alt_span: Option<Span>,
|
alt_span: Option<Span>,
|
||||||
) -> Option<Self> {
|
) -> Option<Self> {
|
||||||
let mut me = DescriptionCtx::default();
|
let (span, kind, arg) = match *region {
|
||||||
me.span = alt_span;
|
ty::ReEarlyBound(ref br) => {
|
||||||
match *region {
|
let scope = region.free_region_binding_scope(tcx).expect_local();
|
||||||
ty::ReEarlyBound(_) | ty::ReFree(_) => {
|
let span = if let Some(param) =
|
||||||
return Self::from_early_bound_and_free_regions(tcx, region);
|
tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(br.name))
|
||||||
|
{
|
||||||
|
param.span
|
||||||
|
} else {
|
||||||
|
tcx.def_span(scope)
|
||||||
|
};
|
||||||
|
if br.has_name() {
|
||||||
|
(Some(span), "as_defined", br.name.to_string())
|
||||||
|
} else {
|
||||||
|
(Some(span), "as_defined_anon", String::new())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ty::ReFree(ref fr) => {
|
||||||
|
if !fr.bound_region.is_named()
|
||||||
|
&& let Some((ty, _)) = find_anon_type(tcx, region, &fr.bound_region)
|
||||||
|
{
|
||||||
|
(Some(ty.span), "defined_here", String::new())
|
||||||
|
} else {
|
||||||
|
let scope = region.free_region_binding_scope(tcx).expect_local();
|
||||||
|
match fr.bound_region {
|
||||||
|
ty::BoundRegionKind::BrNamed(_, name) => {
|
||||||
|
let span = if let Some(param) = tcx
|
||||||
|
.hir()
|
||||||
|
.get_generics(scope)
|
||||||
|
.and_then(|generics| generics.get_named(name))
|
||||||
|
{
|
||||||
|
param.span
|
||||||
|
} else {
|
||||||
|
tcx.def_span(scope)
|
||||||
|
};
|
||||||
|
if name == kw::UnderscoreLifetime {
|
||||||
|
(Some(span), "as_defined_anon", String::new())
|
||||||
|
} else {
|
||||||
|
(Some(span), "as_defined", name.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ty::BrAnon(span) => {
|
||||||
|
let span = match span {
|
||||||
|
Some(_) => span,
|
||||||
|
None => Some(tcx.def_span(scope)),
|
||||||
|
};
|
||||||
|
(span, "defined_here", String::new())
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
(Some(tcx.def_span(scope)), "defined_here_reg", region.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ty::ReStatic => {
|
|
||||||
me.kind = "restatic";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::RePlaceholder(_) => return None,
|
ty::ReStatic => (alt_span, "restatic", String::new()),
|
||||||
|
|
||||||
ty::ReError(_) => return None,
|
ty::RePlaceholder(_) | ty::ReError(_) => return None,
|
||||||
|
|
||||||
// FIXME(#13998) RePlaceholder should probably print like
|
// FIXME(#13998) RePlaceholder should probably print like
|
||||||
// ReFree rather than dumping Debug output on the user.
|
// ReFree rather than dumping Debug output on the user.
|
||||||
|
@ -37,76 +80,10 @@ impl<'a> DescriptionCtx<'a> {
|
||||||
// We shouldn't really be having unification failures with ReVar
|
// We shouldn't really be having unification failures with ReVar
|
||||||
// and ReLateBound though.
|
// and ReLateBound though.
|
||||||
ty::ReVar(_) | ty::ReLateBound(..) | ty::ReErased => {
|
ty::ReVar(_) | ty::ReLateBound(..) | ty::ReErased => {
|
||||||
me.kind = "revar";
|
(alt_span, "revar", format!("{:?}", region))
|
||||||
me.arg = format!("{:?}", region);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Some(me)
|
Some(DescriptionCtx { span, kind, arg })
|
||||||
}
|
|
||||||
|
|
||||||
fn from_early_bound_and_free_regions<'tcx>(
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
region: ty::Region<'tcx>,
|
|
||||||
) -> Option<Self> {
|
|
||||||
let mut me = DescriptionCtx::default();
|
|
||||||
let scope = region.free_region_binding_scope(tcx).expect_local();
|
|
||||||
match *region {
|
|
||||||
ty::ReEarlyBound(ref br) => {
|
|
||||||
let mut sp = tcx.def_span(scope);
|
|
||||||
if let Some(param) =
|
|
||||||
tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(br.name))
|
|
||||||
{
|
|
||||||
sp = param.span;
|
|
||||||
}
|
|
||||||
if br.has_name() {
|
|
||||||
me.kind = "as_defined";
|
|
||||||
me.arg = br.name.to_string();
|
|
||||||
} else {
|
|
||||||
me.kind = "as_defined_anon";
|
|
||||||
};
|
|
||||||
me.span = Some(sp)
|
|
||||||
}
|
|
||||||
ty::ReFree(ref fr) => {
|
|
||||||
if !fr.bound_region.is_named()
|
|
||||||
&& let Some((ty, _)) = find_anon_type(tcx, region, &fr.bound_region)
|
|
||||||
{
|
|
||||||
me.kind = "defined_here";
|
|
||||||
me.span = Some(ty.span);
|
|
||||||
} else {
|
|
||||||
match fr.bound_region {
|
|
||||||
ty::BoundRegionKind::BrNamed(_, name) => {
|
|
||||||
let mut sp = tcx.def_span(scope);
|
|
||||||
if let Some(param) =
|
|
||||||
tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(name))
|
|
||||||
{
|
|
||||||
sp = param.span;
|
|
||||||
}
|
|
||||||
if name == kw::UnderscoreLifetime {
|
|
||||||
me.kind = "as_defined_anon";
|
|
||||||
} else {
|
|
||||||
me.kind = "as_defined";
|
|
||||||
me.arg = name.to_string();
|
|
||||||
};
|
|
||||||
me.span = Some(sp);
|
|
||||||
}
|
|
||||||
ty::BrAnon(span) => {
|
|
||||||
me.kind = "defined_here";
|
|
||||||
me.span = match span {
|
|
||||||
Some(_) => span,
|
|
||||||
None => Some(tcx.def_span(scope)),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
me.kind = "defined_here_reg";
|
|
||||||
me.arg = region.to_string();
|
|
||||||
me.span = Some(tcx.def_span(scope));
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => bug!(),
|
|
||||||
}
|
|
||||||
Some(me)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue