Skip to content

Commit

Permalink
Add enum discriminants (#337) (#437)
Browse files Browse the repository at this point in the history
* Remove nightly from rustdoc v28 test matrix, since that's now v29. (#332)

* Rust 1.78 is no longer beta. (#334)

* Add enum discriminants

* discriminant clone to lifetime annotation

* complicate test examples

* improved discriminant docs

* hedge bets against placeholder representation



* finally got implicit discriminants working

* remove sync structs

* move to Cow<'a, str> for discriminants

* Various clean-ups, still fighting closure bounds

*sigh*

error[E0521]: borrowed data escapes outside of closure
   --> src/adapter/edges.rs:304:28
    |
260 |   pub(super) fn resolve_variant_edge<'a, V: AsVertex<Vertex<'a>> + 'a>(
    |                                      -- lifetime `'a` defined here
...
302 |           "discriminant" => resolve_neighbors_with(contexts, move |vertex: &'_ Vertex<'a>| {
    |                                                                    ------  - let's call the lifetime of this reference `'1`
    |                                                                    |
    |                                                                    `vertex` is a reference that is only valid in the closure body
303 |               let origin = vertex.origin;
304 |               let enum_var = vertex
    |  ____________________________^
305 | |                 .as_variant()
    | |                             ^
    | |                             |
    | |_____________________________`vertex` escapes the closure body here
    |                               argument requires that `'1` must outlive `'a`

* Actually clone Cow; same error as before, though...

* Got the sucker.

* Wrap up

* Better dcocs for discriminant



* Finish up docs, improve tests

* Add name back.

---------

Co-authored-by: Kyle Anthony Williams <kyle.anthony.williams2@gmail.com>
  • Loading branch information
obi1kenobi and SuperSonicHub1 committed Sep 1, 2024
1 parent 83efc64 commit 50cf644
Show file tree
Hide file tree
Showing 10 changed files with 742 additions and 16 deletions.
50 changes: 45 additions & 5 deletions src/adapter/edges.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use rustdoc_types::{GenericBound::TraitBound, Id, ItemEnum, VariantKind};
use std::rc::Rc;
use trustfall::provider::{
resolve_neighbors_with, AsVertex, ContextIterator, ContextOutcomeIterator, ResolveEdgeInfo,
VertexIterator,
};

use crate::{adapter::supported_item_kind, attributes::Attribute, IndexedCrate};

use super::{optimizations, origin::Origin, vertex::Vertex, RustdocAdapter};
use super::{
enum_variant::LazyDiscriminants, optimizations, origin::Origin, vertex::Vertex, RustdocAdapter,
};

pub(super) fn resolve_crate_diff_edge<'a, V: AsVertex<Vertex<'a>> + 'a>(
contexts: ContextIterator<'a, V>,
Expand Down Expand Up @@ -263,7 +266,10 @@ pub(super) fn resolve_variant_edge<'a, V: AsVertex<Vertex<'a>> + 'a>(
match edge_name {
"field" => resolve_neighbors_with(contexts, move |vertex| {
let origin = vertex.origin;
let item = vertex.as_variant().expect("vertex was not a Variant");
let item = vertex
.as_variant()
.expect("vertex was not a Variant")
.variant();
let item_index = match origin {
Origin::CurrentCrate => &current_crate.inner.index,
Origin::PreviousCrate => {
Expand Down Expand Up @@ -293,6 +299,14 @@ pub(super) fn resolve_variant_edge<'a, V: AsVertex<Vertex<'a>> + 'a>(
})),
}
}),
"discriminant" => resolve_neighbors_with(contexts, move |vertex: &'_ Vertex<'a>| {
let origin = vertex.origin;
let enum_var = vertex.as_variant().expect("vertex was not a Variant");
let discriminant = enum_var.discriminant();
Box::new(std::iter::once(
origin.make_discriminant_vertex(discriminant),
))
}),
_ => unreachable!("resolve_variant_edge {edge_name}"),
}
}
Expand All @@ -317,9 +331,35 @@ pub(super) fn resolve_enum_edge<'a, V: AsVertex<Vertex<'a>> + 'a>(
.index
}
};
Box::new(enum_item.variants.iter().map(move |field_id| {
origin.make_item_vertex(item_index.get(field_id).expect("missing item"))
}))

let discriminants = {
let variants = enum_item
.variants
.iter()
.map(move |field_id| {
let inner = &item_index.get(field_id).expect("missing item").inner;
match inner {
ItemEnum::Variant(v) => v,
_ => unreachable!("Item {inner:?} not a Variant"),
}
})
.collect();
Rc::new(LazyDiscriminants::new(variants))
};

Box::new(
enum_item
.variants
.iter()
.enumerate()
.map(move |(index, field_id)| {
origin.make_variant_vertex(
item_index.get(field_id).expect("missing item"),
discriminants.clone(),
index,
)
}),
)
}),
_ => unreachable!("resolve_enum_edge {edge_name}"),
}
Expand Down
Loading

0 comments on commit 50cf644

Please sign in to comment.