tamer: asg::graph::rel::ObjectIndexTreeRelTo: New trait and related
This creates another trait and struct `ObjectIndexToTree` that assert a stronger invariant than `ObjectIndexRelTo`---that not only does it uphold the invariants of `ObjectIndexRelTo`, but also that it represents a _tree_ edge, which indicates _ownership_ rather than just a reference. This will be used to statically infer what can serve as a scope boundary for upcoming changes. Specifically, anything that can own an `Ident` introduces a new level of scope. DEV-13708main
parent
f1495f8cf4
commit
3660c15d5a
|
@ -143,8 +143,9 @@ pub use ident::Ident;
|
|||
pub use meta::Meta;
|
||||
pub use pkg::Pkg;
|
||||
pub use rel::{
|
||||
DynObjectRel, ObjectIndexRelTo, ObjectIndexTo, ObjectRel, ObjectRelFrom,
|
||||
ObjectRelTo, ObjectRelTy, ObjectRelatable,
|
||||
DynObjectRel, ObjectIndexRelTo, ObjectIndexTo, ObjectIndexToTree,
|
||||
ObjectIndexTreeRelTo, ObjectRel, ObjectRelFrom, ObjectRelTo, ObjectRelTy,
|
||||
ObjectRelatable, ObjectTreeRelTo,
|
||||
};
|
||||
pub use root::Root;
|
||||
pub use tpl::Tpl;
|
||||
|
|
|
@ -23,7 +23,7 @@ use std::fmt::Display;
|
|||
|
||||
use super::{
|
||||
Asg, Ident, Object, ObjectIndex, ObjectIndexRelTo, ObjectRel,
|
||||
ObjectRelFrom, ObjectRelTy, ObjectRelatable,
|
||||
ObjectRelFrom, ObjectRelTy, ObjectRelatable, ObjectTreeRelTo,
|
||||
};
|
||||
use crate::{
|
||||
f::Functor,
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
use super::{
|
||||
super::{Asg, AsgError, ObjectIndex, ObjectKind},
|
||||
Expr, Meta, Object, ObjectIndexRelTo, ObjectRel, ObjectRelFrom,
|
||||
ObjectRelTo, ObjectRelTy, ObjectRelatable, Pkg, Tpl,
|
||||
ObjectRelTo, ObjectRelTy, ObjectRelatable, ObjectTreeRelTo, Pkg, Tpl,
|
||||
};
|
||||
use crate::{
|
||||
diagnose::{Annotate, Diagnostic},
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
use super::{
|
||||
Ident, Object, ObjectIndex, ObjectIndexRelTo, ObjectRel, ObjectRelFrom,
|
||||
ObjectRelTy, ObjectRelatable, Tpl,
|
||||
ObjectRelTy, ObjectRelatable, ObjectTreeRelTo, Tpl,
|
||||
};
|
||||
use crate::{
|
||||
asg::Asg,
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
use super::{
|
||||
Ident, Object, ObjectIndex, ObjectRel, ObjectRelFrom, ObjectRelTy,
|
||||
ObjectRelatable, Tpl,
|
||||
ObjectRelatable, ObjectTreeRelTo, Tpl,
|
||||
};
|
||||
use crate::{asg::Asg, f::Functor, span::Span};
|
||||
use std::fmt::Display;
|
||||
|
|
|
@ -129,6 +129,8 @@ macro_rules! object_rel {
|
|||
Self::$kind(value)
|
||||
}
|
||||
}
|
||||
|
||||
object_rel!{ @impl_rel_to $from $ety $kind }
|
||||
)*
|
||||
}};
|
||||
|
||||
|
@ -147,6 +149,19 @@ macro_rules! object_rel {
|
|||
// an edge only needs supplemental span information if there is
|
||||
// another context in which that object is referenced.
|
||||
(@is_cross_edge dyn $rel:ident) => { $rel.ctx_span().is_some() };
|
||||
|
||||
// Similar to above but providing _static_ information to the type
|
||||
// system.
|
||||
// The above could be rolled into this at some point.
|
||||
(@impl_rel_to $from:ident cross $kind:ident) => {};
|
||||
(@impl_rel_to $from:ident tree $kind:ident) => {
|
||||
impl ObjectTreeRelTo<$kind> for $from {}
|
||||
};
|
||||
(@impl_rel_to $from:ident dyn $kind:ident) => {
|
||||
// It _could_ be a tree edge;
|
||||
// we can't know statically.
|
||||
impl ObjectTreeRelTo<$kind> for $from {}
|
||||
};
|
||||
}
|
||||
|
||||
/// A dynamic relationship (edge) from one object to another before it has
|
||||
|
@ -370,6 +385,18 @@ pub trait ObjectRelTo<OB: ObjectKind + ObjectRelatable> =
|
|||
pub trait ObjectRelFrom<OA: ObjectKind + ObjectRelatable> =
|
||||
ObjectRelatable where <OA as ObjectRelatable>::Rel: From<ObjectIndex<Self>>;
|
||||
|
||||
/// Indicate that an [`ObjectKind`] `Self` _could possibly take ownership
|
||||
/// over_ an [`ObjectKind`] `OB`.
|
||||
///
|
||||
/// This is a stronger assertion than [`ObjectRelTo`];
|
||||
/// see that trait for more information.
|
||||
/// This trait is intended to be used in contexts where the distinction
|
||||
/// between reference and ownership is important.
|
||||
pub trait ObjectTreeRelTo<OB: ObjectKind + ObjectRelatable>:
|
||||
ObjectRelTo<OB>
|
||||
{
|
||||
}
|
||||
|
||||
/// Identify [`Self::Rel`] as a sum type consisting of the subset of
|
||||
/// [`Object`] variants representing the valid _target_ edges of
|
||||
/// [`Self`].
|
||||
|
@ -719,6 +746,20 @@ impl<OB: ObjectRelatable> ObjectIndexRelTo<OB> for ObjectIndexTo<OB> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<OB: ObjectRelatable> ObjectIndexRelTo<OB> for ObjectIndexToTree<OB> {
|
||||
fn src_rel_ty(&self) -> ObjectRelTy {
|
||||
match self {
|
||||
Self(oito) => oito.src_rel_ty(),
|
||||
}
|
||||
}
|
||||
|
||||
fn widen(&self) -> ObjectIndex<Object> {
|
||||
match self {
|
||||
Self(oito) => oito.widen(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<OB: ObjectRelatable> From<ObjectIndexTo<OB>> for ObjectIndex<Object> {
|
||||
fn from(oi_rel: ObjectIndexTo<OB>) -> Self {
|
||||
oi_rel.widen()
|
||||
|
@ -733,7 +774,29 @@ impl<OB: ObjectRelatable> AsRef<ObjectIndex<Object>> for ObjectIndexTo<OB> {
|
|||
}
|
||||
}
|
||||
|
||||
pub use private::ObjectIndexTo;
|
||||
/// An [`ObjectIndex`]-like object that is able to create a _tree_ edge to
|
||||
/// [`ObjectKind`] `OB`.
|
||||
///
|
||||
/// This allows for generic graph operations that operate on ownership
|
||||
/// relationships without having to know the type of the source
|
||||
/// object (`Self`).
|
||||
///
|
||||
/// This is a specialization of [`ObjectIndexRelTo`].
|
||||
pub trait ObjectIndexTreeRelTo<OB: ObjectRelatable>:
|
||||
ObjectIndexRelTo<OB> + Into<ObjectIndexToTree<OB>>
|
||||
{
|
||||
}
|
||||
|
||||
impl<OB: ObjectRelatable> ObjectIndexTreeRelTo<OB> for ObjectIndexToTree<OB> {}
|
||||
|
||||
impl<O: ObjectRelatable, OB: ObjectRelatable> ObjectIndexTreeRelTo<OB>
|
||||
for ObjectIndex<O>
|
||||
where
|
||||
O: ObjectTreeRelTo<OB>,
|
||||
{
|
||||
}
|
||||
|
||||
pub use private::{ObjectIndexTo, ObjectIndexToTree};
|
||||
|
||||
/// Private inner module to ensure that nothing is able to bypass invariants
|
||||
/// by constructing [`ObjectIndexTo`] manually.
|
||||
|
@ -806,4 +869,43 @@ mod private {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Some [`ObjectIndex`] that can create a _tree_ edge to `OB`.
|
||||
///
|
||||
/// This is a specialization of
|
||||
/// (and contains)
|
||||
/// [`ObjectIndexTo`];
|
||||
/// see that for more information.
|
||||
///
|
||||
/// See also [`ObjectIndexTreeRelTo`].
|
||||
#[derive(Debug)]
|
||||
pub struct ObjectIndexToTree<OB: ObjectRelatable>(ObjectIndexTo<OB>);
|
||||
|
||||
impl<OB: ObjectRelatable, O: ObjectRelatable> From<ObjectIndex<O>>
|
||||
for ObjectIndexToTree<OB>
|
||||
where
|
||||
O: ObjectTreeRelTo<OB>,
|
||||
{
|
||||
fn from(oi: ObjectIndex<O>) -> Self {
|
||||
Self(oi.into())
|
||||
}
|
||||
}
|
||||
|
||||
// Deriving any of the below were introducing trait bounds on `OB`.
|
||||
|
||||
impl<OB: ObjectRelatable> Clone for ObjectIndexToTree<OB> {
|
||||
fn clone(&self) -> Self {
|
||||
Self(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<OB: ObjectRelatable> Copy for ObjectIndexToTree<OB> {}
|
||||
|
||||
impl<OB: ObjectRelatable> From<ObjectIndexToTree<OB>> for Span {
|
||||
fn from(oi: ObjectIndexToTree<OB>) -> Self {
|
||||
match oi {
|
||||
ObjectIndexToTree(inner) => inner.span(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ use std::fmt::Display;
|
|||
|
||||
use super::{
|
||||
Ident, Object, ObjectIndex, ObjectRel, ObjectRelFrom, ObjectRelTy,
|
||||
ObjectRelatable, Pkg,
|
||||
ObjectRelatable, ObjectTreeRelTo, Pkg,
|
||||
};
|
||||
|
||||
#[cfg(doc)]
|
||||
|
|
|
@ -23,7 +23,7 @@ use std::fmt::Display;
|
|||
|
||||
use super::{
|
||||
Expr, Ident, Object, ObjectIndex, ObjectIndexRelTo, ObjectRel,
|
||||
ObjectRelFrom, ObjectRelTy, ObjectRelatable,
|
||||
ObjectRelFrom, ObjectRelTy, ObjectRelatable, ObjectTreeRelTo,
|
||||
};
|
||||
use crate::{
|
||||
asg::Asg,
|
||||
|
|
Loading…
Reference in New Issue