Skip to content

Commit

Permalink
Towards an implementation of proper early error messages
Browse files Browse the repository at this point in the history
  • Loading branch information
AZWN committed Oct 25, 2024
1 parent c5b1f6f commit 2caae92
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 31 deletions.
32 changes: 24 additions & 8 deletions scopegraphs/src/containers/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ use std::fmt::Debug;
use super::EnvContainer;

/// Interface for path containers that support the operations required for query resolution.
pub trait PathContainer<'sg, 'rslv, LABEL: 'sg, DATA: 'sg, DWFO>: Debug + 'rslv
pub trait PathContainer<'sg, 'rslv, LABEL: 'sg, DATA: 'sg>: Debug + 'rslv
{
/// Type returned by resolving a path to its sub-environment.
type EnvContainer: EnvContainer<'sg, 'rslv, LABEL, DATA, DWFO>;
type EnvContainer;

/// Computes sub-environments for each path in the container.
fn map_into_env<F: 'rslv + FnMut(Path<LABEL>) -> Self::EnvContainer>(
Expand All @@ -19,12 +19,30 @@ pub trait PathContainer<'sg, 'rslv, LABEL: 'sg, DATA: 'sg, DWFO>: Debug + 'rslv
) -> Self::EnvContainer;
}

impl<'rslv, 'sg, LABEL: Debug + 'sg, DATA: 'sg, DWFO> PathContainer<'sg, 'rslv, LABEL, DATA, DWFO> for Vec<Path<LABEL>>
pub trait PathContainerWf<'sg, 'rslv, LABEL: 'sg, DATA: 'sg, DWFO>: PathContainer<'sg, 'rslv, LABEL, DATA, EnvContainer = Self::EnvContainerWf> {

Check failure on line 22 in scopegraphs/src/containers/path.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a trait

error: missing documentation for a trait --> scopegraphs/src/containers/path.rs:22:1 | 22 | pub trait PathContainerWf<'sg, 'rslv, LABEL: 'sg, DATA: 'sg, DWFO>: PathContainer<'sg, 'rslv, LABEL, DATA, EnvContainer = Self::EnvContainerWf... | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

type EnvContainerWf: EnvContainer<'sg, 'rslv, LABEL, DATA, DWFO>;

Check failure on line 24 in scopegraphs/src/containers/path.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for an associated type

error: missing documentation for an associated type --> scopegraphs/src/containers/path.rs:24:5 | 24 | type EnvContainerWf: EnvContainer<'sg, 'rslv, LABEL, DATA, DWFO>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

}


impl<'sg, 'rslv, LABEL, DATA, DWFO, T> PathContainerWf<'sg, 'rslv, LABEL, DATA, DWFO> for T
where
LABEL: Debug + 'sg,
DATA: 'sg,
T: PathContainer<'sg, 'rslv, LABEL, DATA>,
Self::EnvContainer: EnvContainer<'sg, 'rslv, LABEL, DATA, DWFO>
{
type EnvContainerWf = Self::EnvContainer;
}



impl<'rslv, 'sg, LABEL: Debug + 'sg, DATA: 'sg> PathContainer<'sg, 'rslv, LABEL, DATA> for Vec<Path<LABEL>>
where
Self: 'rslv,
LABEL: Clone + Hash + Eq,
DATA: Hash + Eq,
Env<'sg, LABEL, DATA>: EnvContainer<'sg, 'rslv, LABEL, DATA, DWFO>
{
type EnvContainer = Env<'sg, LABEL, DATA>;

Expand All @@ -35,14 +53,13 @@ where

// TODO: can this be generalized to arbitrary results of PathContainers?
// (challenge is converting between the different `::EnvContainer`s.)
impl<'rslv, 'sg, LABEL: Debug + 'sg, DATA: 'sg, E: Debug + 'rslv, DWFO> PathContainer<'sg, 'rslv, LABEL, DATA, DWFO>
impl<'rslv, 'sg, LABEL: Debug + 'sg, DATA: 'sg, E: Debug + 'rslv> PathContainer<'sg, 'rslv, LABEL, DATA>
for Result<Vec<Path<LABEL>>, E>
where
Self: 'rslv,
LABEL: Clone + Hash,
DATA: Hash,
for<'a> ResolvedPath<'a, LABEL, DATA>: Hash + Eq,
Result<Env<'sg, LABEL, DATA>, E>: EnvContainer<'sg, 'rslv, LABEL, DATA, DWFO>
{
type EnvContainer = Result<Env<'sg, LABEL, DATA>, E>;

Expand All @@ -55,13 +72,12 @@ where
})
}
}
impl<'sg, 'rslv, LABEL: 'sg, DATA: 'sg, DWFO> PathContainer<'sg, 'rslv, LABEL, DATA, DWFO>
impl<'sg, 'rslv, LABEL: 'sg, DATA: 'sg> PathContainer<'sg, 'rslv, LABEL, DATA>
for FutureWrapper<'rslv, Vec<Path<LABEL>>>
where
Self: 'rslv,
LABEL: Clone + Hash,
DATA: Hash,
FutureWrapper<'rslv, Env<'sg, LABEL, DATA>>: EnvContainer<'sg, 'rslv, LABEL, DATA, DWFO>,
for<'a> ResolvedPath<'a, LABEL, DATA>: Hash + Eq,
{
type EnvContainer = FutureWrapper<'rslv, Env<'sg, LABEL, DATA>>;
Expand Down
109 changes: 95 additions & 14 deletions scopegraphs/src/containers/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,106 @@ use crate::future_wrapper::FutureWrapper;
use crate::resolve::Path;
use crate::Scope;

use super::PathContainer;
use super::{PathContainer, PathContainerWf};

/// Interface for scope containers that support the operations required for query resolution.
pub trait ScopeContainer<'sg, 'rslv, LABEL: Debug + 'sg, DATA: 'sg, DWFO>: Debug {
pub trait ScopeContainer<'sg, 'rslv, LABEL: Debug + 'sg, DATA: 'sg>: Debug {
/// The type containing paths obtained after stepping to this scope.
type PathContainer<DWFO_INNER> : PathContainer<'sg, 'rslv, LABEL, DATA, DWFO>;
type PathContainer;

/// Lift the [`Path::step`] operation into this container.
///
/// Should retain the contract that for all scopes `s` in `self`, `prefix.step(lbl, s)` is
/// included in the resulting path container (except cyclic paths).
fn lift_step<DWFO_INNER>(self, lbl: LABEL, prefix: Path<LABEL>) -> Self::PathContainer<DWFO_INNER>;
fn lift_step(self, lbl: LABEL, prefix: Path<LABEL>) -> Self::PathContainer;
}

impl<'sg: 'rslv, 'rslv, LABEL: Debug + Copy + Eq + Hash + 'sg, DATA: Eq + Hash + 'sg, DWFO> ScopeContainer<'sg, 'rslv, LABEL, DATA, DWFO> for Vec<Scope>
/// Trait that is auto-implemented for any [ScopeContainer] implementation that yields a valid [PathContainer].
///
/// This trait is implemented for:
/// - `Vec<Scope>`,
/// - [Result] of scope containers, and
/// - [FutureWrapper] of scope containers.
/// ```
/// # use scopegraphs::containers::ScopeContainerWf;
/// # use scopegraphs::future_wrapper::FutureWrapper;
/// # use scopegraphs::Scope;
/// # use std::fmt::Debug;
/// # use std::hash::Hash;
///
/// # trait LBound<'sg>: Copy + Hash + Eq + Debug + 'sg {}
/// # trait DBound<'sg>: Hash + Eq + 'sg {}
///
/// fn test<'sg, 'rslv, LABEL: LBound<'sg>, DATA: DBound<'sg>, DWFO>(
/// cont: impl ScopeContainerWf<'sg, 'rslv, LABEL, DATA, DWFO>
/// ) { }
///
/// # fn scope_vec<'sg, 'rslv, LABEL: LBound<'sg>, DATA: DBound<'sg>>() {
/// let vec: Vec<Scope> = todo!();
/// test::<'_, '_, LABEL, DATA, bool>(vec);
/// # }
///
/// # fn result<'sg, 'rslv, LABEL: LBound<'sg>, DATA: DBound<'sg>, E: Debug + Clone>() {
/// let result: Result<Vec<Scope>, E> = todo!();
/// test::<'_, '_, LABEL, DATA, bool>(result);
/// test::<'_, '_, LABEL, DATA, Result<bool, E>>(result);
/// # }
///
/// # fn future<'sg, 'rslv, LABEL: LBound<'sg>, DATA: DBound<'sg>>() {
/// let future: FutureWrapper<Vec<Scope>> = todo!();
/// test::<'_, '_, LABEL, DATA, bool>(future);
/// test::<'_, '_, LABEL, DATA, FutureWrapper<'_, bool>>(result);
/// # }
/// ```
///
/// ```no_run
/// # use scopegraphs::containers::ScopeContainerWf;
/// # use scopegraphs::Scope;
/// # use std::fmt::Debug;
/// # use std::hash::Hash;
///
///
/// fn test<'sg, 'rslv, LABEL: Hash + Eq + Debug + 'sg, DATA: Hash + Eq + 'sg, DWFO>(cont: impl ScopeContainerWf<'sg, 'rslv, LABEL, DATA, DWFO>) {
///
/// }
/// ```
///
/// ```no_run
/// # use scopegraphs::containers::ScopeContainerWf;
/// # use scopegraphs::Scope;
/// # use std::fmt::Debug;
/// # use std::hash::Hash;
///
/// test::<'_, '_, (), (), bool>(Result::<_, ()>::Ok(Vec::<Scope>::new()));
/// test::<'_, '_, (), (), Result<bool, ()>>(Result::<_, ()>::Ok(Vec::<Scope>::new()));
///
/// fn test<'sg, 'rslv, LABEL: Hash + Eq + Debug + 'sg, DATA: Hash + Eq + 'sg, DWFO>(cont: impl ScopeContainerWf<'sg, 'rslv, LABEL, DATA, DWFO>) {
///
/// }
/// ```
///
pub trait ScopeContainerWf<'sg, 'rslv, LABEL, DATA, DWFO>: ScopeContainer<'sg, 'rslv, LABEL, DATA, PathContainer = Self::PathContainerWf>
where
Vec<Path<LABEL>>: PathContainer<'sg, 'rslv, LABEL, DATA, DWFO>
LABEL: Debug + 'sg,
DATA: 'sg
{
type PathContainerWf: PathContainerWf<'sg, 'rslv, LABEL, DATA, DWFO>;

Check failure on line 91 in scopegraphs/src/containers/scope.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for an associated type

error: missing documentation for an associated type --> scopegraphs/src/containers/scope.rs:91:5 | 91 | type PathContainerWf: PathContainerWf<'sg, 'rslv, LABEL, DATA, DWFO>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}

impl<'sg, 'rslv, LABEL, DATA, DWFO, T> ScopeContainerWf<'sg, 'rslv, LABEL, DATA, DWFO> for T
where
LABEL: Debug + 'sg,
DATA: 'sg,
T: ScopeContainer<'sg, 'rslv, LABEL, DATA>,
Self::PathContainer: PathContainerWf<'sg, 'rslv, LABEL, DATA, DWFO>
{
type PathContainerWf = Self::PathContainer;
}


impl<'sg: 'rslv, 'rslv, LABEL: Debug + Copy + Eq + Hash + 'sg, DATA: Eq + Hash + 'sg> ScopeContainer<'sg, 'rslv, LABEL, DATA> for Vec<Scope>
where
Vec<Path<LABEL>>: PathContainer<'sg, 'rslv, LABEL, DATA>
{
type PathContainer = Vec<Path<LABEL>>;

Expand All @@ -32,9 +115,9 @@ impl<'sg: 'rslv, 'rslv, LABEL: Debug + Copy + Eq + Hash + 'sg, DATA: Eq + Hash +
}
}

impl<'sg: 'rslv, 'rslv, LABEL: Debug + Copy + Eq + Hash + 'sg, DATA: Eq + Hash + 'sg, DWFO, SC: ScopeContainer<'sg, 'rslv, LABEL, DATA, DWFO>, E: Debug> ScopeContainer<'sg, 'rslv, LABEL, DATA, DWFO> for Result<SC, E>
impl<'sg: 'rslv, 'rslv, LABEL: Debug + Copy + Eq + Hash + 'sg, DATA: Eq + Hash + 'sg, SC: ScopeContainer<'sg, 'rslv, LABEL, DATA>, E: Debug> ScopeContainer<'sg, 'rslv, LABEL, DATA> for Result<SC, E>
where
Result<SC::PathContainer, E>: PathContainer<'sg, 'rslv, LABEL, DATA, DWFO>
Result<SC::PathContainer, E>: PathContainer<'sg, 'rslv, LABEL, DATA>
{
type PathContainer = Result<SC::PathContainer, E>;

Expand All @@ -43,19 +126,17 @@ impl<'sg: 'rslv, 'rslv, LABEL: Debug + Copy + Eq + Hash + 'sg, DATA: Eq + Hash +
}
}

impl<'sg: 'rslv, 'rslv, LABEL: Debug + Copy + Eq + Hash + 'sg, DATA: Eq + Hash + 'sg, DWFO, SC: ScopeContainer<'sg, 'rslv, LABEL, DATA, DWFO> + Clone> ScopeContainer<'sg, 'rslv, LABEL, DATA, DWFO>
impl<'sg: 'rslv, 'rslv, LABEL: Debug + Copy + Eq + Hash + 'sg, DATA: Eq + Hash + 'sg, SC: ScopeContainer<'sg, 'rslv, LABEL, DATA> + Clone> ScopeContainer<'sg, 'rslv, LABEL, DATA>
for FutureWrapper<'rslv, SC>
where
LABEL: Copy,
Self: 'rslv,
LABEL: 'rslv,
SC::PathContainer: Clone
{
type PathContainer<DWFO_INNER> = FutureWrapper<'rslv, SC::PathContainer<DWFO_INNER>>
where
SC::PathContainer<DWFO_INNER>: PathContainer<'sg, 'rslv, LABEL, DATA, DWFO_INNER> + Clone
;
type PathContainer = FutureWrapper<'rslv, SC::PathContainer>;

fn lift_step<DWFO_INNER>(self, lbl: LABEL, prefix: Path<LABEL>) -> Self::PathContainer<DWFO_INNER> {
fn lift_step(self, lbl: LABEL, prefix: Path<LABEL>) -> Self::PathContainer {
FutureWrapper::new(async move { self.0.await.lift_step(lbl, prefix.clone()) })
}
}
5 changes: 4 additions & 1 deletion scopegraphs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ pub use scopegraphs_regular_expressions::*;

pub mod completeness;
pub mod containers;
mod future_wrapper;
// #[cfg(test)]
pub mod future_wrapper;

Check failure on line 34 in scopegraphs/src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a module

error: missing documentation for a module --> scopegraphs/src/lib.rs:34:1 | 34 | pub mod future_wrapper; | ^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D missing-docs` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(missing_docs)]`
// #[cfg(not(test))]
// mod future_wrapper;

pub mod resolve;

Expand Down
12 changes: 4 additions & 8 deletions scopegraphs/src/resolve/lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use std::rc::Rc;
use std::sync::Arc;

use crate::completeness::Completeness;
use crate::containers::{EnvContainer, PathContainer, ScopeContainer};
use crate::containers::{EnvContainer, PathContainer, PathContainerWf, ScopeContainer, ScopeContainerWf};
use crate::resolve::{
DataEquivalence, DataWellformedness, EdgeOrData, Env, LabelOrder, Path, Query, Resolve,
ResolvedPath,
Expand All @@ -28,7 +28,7 @@ where
LABEL: Label + Copy + Debug + Hash,
DATA: Debug,
CMPL: Completeness<LABEL, DATA>,
CMPL::GetEdgesResult<'rslv> : ScopeContainer<'sg, 'rslv, LABEL, DATA, DWF::Output>,
CMPL::GetEdgesResult<'rslv> : ScopeContainerWf<'sg, 'rslv, LABEL, DATA, DWF::Output>,
PWF: for<'a> RegexMatcher<&'a LABEL> + 'rslv,
DWF: DataWellformedness<'sg, DATA> + 'rslv,

Expand Down Expand Up @@ -97,7 +97,7 @@ struct ResolutionContext<'storage, 'sg: 'rslv, 'rslv, LABEL: Label, DATA, CMPL,

type EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWFO> = <<<CMPL as Completeness<LABEL, DATA>>::GetEdgesResult<
'rslv,
> as ScopeContainer<'sg, 'rslv, LABEL, DATA, DWFO>>::PathContainer as PathContainer<'sg, 'rslv, LABEL, DATA, DWFO>>::EnvContainer;
> as ScopeContainerWf<'sg, 'rslv, LABEL, DATA, DWFO>>::PathContainerWf as PathContainerWf<'sg, 'rslv, LABEL, DATA, DWFO>>::EnvContainerWf;

type EnvCache<LABEL, ENVC> = RefCell<HashMap<EdgeOrData<LABEL>, Rc<ENVC>>>;

Expand All @@ -108,7 +108,7 @@ where
DATA: Debug,
ResolvedPath<'sg, LABEL, DATA>: Hash + Eq,
CMPL: Completeness<LABEL, DATA>,
CMPL::GetEdgesResult<'rslv> : ScopeContainer<'sg, 'rslv, LABEL, DATA, DWF::Output>,
CMPL::GetEdgesResult<'rslv> : ScopeContainerWf<'sg, 'rslv, LABEL, DATA, DWF::Output>,
DEq: DataEquivalence<DATA>,
DWF: DataWellformedness<'sg, DATA>,
LO: LabelOrder<LABEL>,
Expand Down Expand Up @@ -484,10 +484,6 @@ mod tests {
});
}

fn explicate_dwf_impl<'sg, DATA: 'sg>(dwf: impl for<'b> Fn(&'b DATA) -> FutureWrapper<'b, bool> ) -> impl DataWellformedness<'sg, DATA> {
dwf
}

#[test]
fn test_match_data() {
let storage = Storage::new();
Expand Down

0 comments on commit 2caae92

Please sign in to comment.