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-13708
main
Mike Gerwitz 2023-04-04 14:32:20 -04:00
parent f1495f8cf4
commit 3660c15d5a
8 changed files with 112 additions and 9 deletions

View File

@ -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;

View File

@ -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,

View File

@ -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},

View File

@ -26,7 +26,7 @@
use super::{
Ident, Object, ObjectIndex, ObjectIndexRelTo, ObjectRel, ObjectRelFrom,
ObjectRelTy, ObjectRelatable, Tpl,
ObjectRelTy, ObjectRelatable, ObjectTreeRelTo, Tpl,
};
use crate::{
asg::Asg,

View File

@ -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;

View File

@ -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(),
}
}
}
}

View File

@ -23,7 +23,7 @@ use std::fmt::Display;
use super::{
Ident, Object, ObjectIndex, ObjectRel, ObjectRelFrom, ObjectRelTy,
ObjectRelatable, Pkg,
ObjectRelatable, ObjectTreeRelTo, Pkg,
};
#[cfg(doc)]

View File

@ -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,