Rollup merge of #144988 - amandasystems:more-detailed-region-graph, r=lcnr
Add annotations to the graphviz region graph on region origins
This adds
- `(ex<'e>)` for regions whose origin is existential, with name if one exists,
- `(for<'p>)` for regions whose origin is a placeholder, with name if one exists
For any region whose name we don't know, use `'_`.
This has helped _my_ debugging and it doesn't create too bad clutter, I feel.
The change ~~is~~was ridiculously small, but I turned it into a separate PR so we can bikeshed the format.
The following snippet:
```rust
struct Co<'a>(&'a ());
struct Contra<'a>(fn(&'a ()));
// `exists<'e> forall<'p> 'p: 'e` -> ERROR
fn p_outlives_e(
x: for<'e> fn(for<'p> fn(fn(fn(Contra<'e>, Co<'p>)))),
) -> fn(fn(fn(for<'unify> fn(Contra<'unify>, Co<'unify>)))) {
x
```
Gives this graph:

This commit is contained in:
commit
35f2fb9453
6 changed files with 22 additions and 6 deletions
|
|
@ -157,7 +157,7 @@ fn region_definitions<'tcx>(
|
|||
for info in var_infos.iter() {
|
||||
let origin = match info.origin {
|
||||
RegionVariableOrigin::Nll(origin) => origin,
|
||||
_ => NllRegionVariableOrigin::Existential { from_forall: false },
|
||||
_ => NllRegionVariableOrigin::Existential { from_forall: false, name: None },
|
||||
};
|
||||
|
||||
let definition = RegionDefinition { origin, universe: info.universe, external_name: None };
|
||||
|
|
|
|||
|
|
@ -41,7 +41,22 @@ fn render_region_vid<'tcx>(
|
|||
"".to_string()
|
||||
};
|
||||
|
||||
format!("{:?}{universe_str}{external_name_str}", rvid)
|
||||
let extra_info = match regioncx.region_definition(rvid).origin {
|
||||
NllRegionVariableOrigin::FreeRegion => "".to_string(),
|
||||
NllRegionVariableOrigin::Placeholder(p) => match p.bound.kind {
|
||||
ty::BoundRegionKind::Named(def_id) => {
|
||||
format!(" (for<{}>)", tcx.item_name(def_id))
|
||||
}
|
||||
ty::BoundRegionKind::ClosureEnv | ty::BoundRegionKind::Anon => " (for<'_>)".to_string(),
|
||||
ty::BoundRegionKind::NamedAnon(_) => {
|
||||
bug!("only used for pretty printing")
|
||||
}
|
||||
},
|
||||
NllRegionVariableOrigin::Existential { name: Some(name), .. } => format!(" (ex<{name}>)"),
|
||||
NllRegionVariableOrigin::Existential { .. } => format!(" (ex<'_>)"),
|
||||
};
|
||||
|
||||
format!("{:?}{universe_str}{external_name_str}{extra_info}", rvid)
|
||||
}
|
||||
|
||||
impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
|
|
|
|||
|
|
@ -1940,9 +1940,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
// and here we prefer to blame the source (the y = x statement).
|
||||
let blame_source = match from_region_origin {
|
||||
NllRegionVariableOrigin::FreeRegion
|
||||
| NllRegionVariableOrigin::Existential { from_forall: false } => true,
|
||||
| NllRegionVariableOrigin::Existential { from_forall: false, name: _ } => true,
|
||||
NllRegionVariableOrigin::Placeholder(_)
|
||||
| NllRegionVariableOrigin::Existential { from_forall: true } => false,
|
||||
| NllRegionVariableOrigin::Existential { from_forall: true, name: _ } => false,
|
||||
};
|
||||
|
||||
// To pick a constraint to blame, we organize constraints by how interesting we expect them
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ impl<'a, 'tcx> RegionRenumberer<'a, 'tcx> {
|
|||
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||
F: Fn() -> RegionCtxt,
|
||||
{
|
||||
let origin = NllRegionVariableOrigin::Existential { from_forall: false };
|
||||
let origin = NllRegionVariableOrigin::Existential { from_forall: false, name: None };
|
||||
fold_regions(self.infcx.tcx, value, |_region, _depth| {
|
||||
self.infcx.next_nll_region_var(origin, || region_ctxt_fn())
|
||||
})
|
||||
|
|
|
|||
|
|
@ -249,7 +249,7 @@ impl<'a, 'b, 'tcx> NllTypeRelating<'a, 'b, 'tcx> {
|
|||
from_forall: bool,
|
||||
name: Option<Symbol>,
|
||||
) -> ty::Region<'tcx> {
|
||||
let origin = NllRegionVariableOrigin::Existential { from_forall };
|
||||
let origin = NllRegionVariableOrigin::Existential { name, from_forall };
|
||||
|
||||
let reg_var =
|
||||
self.type_checker.infcx.next_nll_region_var(origin, || RegionCtxt::Existential(name));
|
||||
|
|
|
|||
|
|
@ -484,6 +484,7 @@ pub enum NllRegionVariableOrigin {
|
|||
Placeholder(ty::PlaceholderRegion),
|
||||
|
||||
Existential {
|
||||
name: Option<Symbol>,
|
||||
/// If this is true, then this variable was created to represent a lifetime
|
||||
/// bound in a `for` binder. For example, it might have been created to
|
||||
/// represent the lifetime `'a` in a type like `for<'a> fn(&'a u32)`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue