Skip to content

Commit

Permalink
WIP container trait bounds
Browse files Browse the repository at this point in the history
  • Loading branch information
AZWN committed Oct 23, 2024
1 parent 6790225 commit c5b1f6f
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 57 deletions.
19 changes: 13 additions & 6 deletions scopegraphs/src/containers/path.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
use crate::future_wrapper::FutureWrapper;
use crate::resolve::{Env, Path, ResolvedPath};
use crate::resolve::{DataEquivalence, Env, Path, ResolvedPath};

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

View workflow job for this annotation

GitHub Actions / clippy

unused import: `DataEquivalence`

error: unused import: `DataEquivalence` --> scopegraphs/src/containers/path.rs:2:22 | 2 | use crate::resolve::{DataEquivalence, Env, Path, ResolvedPath}; | ^^^^^^^^^^^^^^^ | = note: `-D unused-imports` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(unused_imports)]`
use futures::future::join_all;
use std::hash::Hash;
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>: 'rslv {
pub trait PathContainer<'sg, 'rslv, LABEL: 'sg, DATA: 'sg, DWFO>: Debug + 'rslv
{
/// Type returned by resolving a path to its sub-environment.
type EnvContainer;
type EnvContainer: EnvContainer<'sg, 'rslv, LABEL, DATA, DWFO>;

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

impl<'rslv, 'sg, LABEL: 'sg, DATA: 'sg> PathContainer<'sg, 'rslv, LABEL, DATA> for Vec<Path<LABEL>>
impl<'rslv, 'sg, LABEL: Debug + 'sg, DATA: 'sg, DWFO> PathContainer<'sg, 'rslv, LABEL, DATA, DWFO> 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 @@ -30,13 +35,14 @@ where

// TODO: can this be generalized to arbitrary results of PathContainers?
// (challenge is converting between the different `::EnvContainer`s.)
impl<'rslv, 'sg, LABEL: 'sg, DATA: 'sg, E: 'rslv> PathContainer<'sg, 'rslv, LABEL, DATA>
impl<'rslv, 'sg, LABEL: Debug + 'sg, DATA: 'sg, E: Debug + 'rslv, DWFO> PathContainer<'sg, 'rslv, LABEL, DATA, DWFO>
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 @@ -49,12 +55,13 @@ where
})
}
}
impl<'sg, 'rslv, LABEL: 'sg, DATA: 'sg> PathContainer<'sg, 'rslv, LABEL, DATA>
impl<'sg, 'rslv, LABEL: 'sg, DATA: 'sg, DWFO> PathContainer<'sg, 'rslv, LABEL, DATA, DWFO>
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
31 changes: 22 additions & 9 deletions scopegraphs/src/containers/scope.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
use std::hash::Hash;
use std::fmt::Debug;

use crate::future_wrapper::FutureWrapper;
use crate::resolve::Path;
use crate::Scope;

use super::PathContainer;

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

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

View workflow job for this annotation

GitHub Actions / clippy

type parameter `DWFO_INNER` should have an upper camel case name

error: type parameter `DWFO_INNER` should have an upper camel case name --> scopegraphs/src/containers/scope.rs:13:24 | 13 | type PathContainer<DWFO_INNER> : PathContainer<'sg, 'rslv, LABEL, DATA, DWFO>; | ^^^^^^^^^^ help: convert the identifier to upper camel case: `DwfoInner` | = note: `-D non-camel-case-types` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(non_camel_case_types)]`

/// 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(self, lbl: LABEL, prefix: Path<LABEL>) -> Self::PathContainer;
fn lift_step<DWFO_INNER>(self, lbl: LABEL, prefix: Path<LABEL>) -> Self::PathContainer<DWFO_INNER>;

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

View workflow job for this annotation

GitHub Actions / clippy

type parameter `DWFO_INNER` should have an upper camel case name

error: type parameter `DWFO_INNER` should have an upper camel case name --> scopegraphs/src/containers/scope.rs:19:18 | 19 | fn lift_step<DWFO_INNER>(self, lbl: LABEL, prefix: Path<LABEL>) -> Self::PathContainer<DWFO_INNER>; | ^^^^^^^^^^ help: convert the identifier to upper camel case: `DwfoInner`
}

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

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

View workflow job for this annotation

GitHub Actions / clippy

type `PathContainer` has 0 type parameters but its trait declaration has 1 type parameter

error[E0049]: type `PathContainer` has 0 type parameters but its trait declaration has 1 type parameter --> scopegraphs/src/containers/scope.rs:26:23 | 13 | type PathContainer<DWFO_INNER> : PathContainer<'sg, 'rslv, LABEL, DATA, DWFO>; | ---------- expected 1 type parameter ... 26 | type PathContainer = Vec<Path<LABEL>>; | ^ found 0 type parameters

fn lift_step(self, lbl: LABEL, prefix: Path<LABEL>) -> Self::PathContainer {

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

View workflow job for this annotation

GitHub Actions / clippy

method `lift_step` has 0 type parameters but its trait declaration has 1 type parameter

error[E0049]: method `lift_step` has 0 type parameters but its trait declaration has 1 type parameter --> scopegraphs/src/containers/scope.rs:28:17 | 19 | fn lift_step<DWFO_INNER>(self, lbl: LABEL, prefix: Path<LABEL>) -> Self::PathContainer<DWFO_INNER>; | ---------- expected 1 type parameter ... 28 | fn lift_step(self, lbl: LABEL, prefix: Path<LABEL>) -> Self::PathContainer { | ^ found 0 type parameters

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

View workflow job for this annotation

GitHub Actions / clippy

missing generics for associated type `containers::scope::ScopeContainer::PathContainer`

error[E0107]: missing generics for associated type `containers::scope::ScopeContainer::PathContainer` --> scopegraphs/src/containers/scope.rs:28:66 | 28 | fn lift_step(self, lbl: LABEL, prefix: Path<LABEL>) -> Self::PathContainer { | ^^^^^^^^^^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `DWFO_INNER` --> scopegraphs/src/containers/scope.rs:13:10 | 13 | type PathContainer<DWFO_INNER> : PathContainer<'sg, 'rslv, LABEL, DATA, DWFO>; | ^^^^^^^^^^^^^ ---------- help: add missing generic argument | 28 | fn lift_step(self, lbl: LABEL, prefix: Path<LABEL>) -> Self::PathContainer<DWFO_INNER> { | ++++++++++++
Expand All @@ -24,25 +32,30 @@ impl<LABEL: Copy> ScopeContainer<LABEL> for Vec<Scope> {
}
}

impl<LABEL, SC: ScopeContainer<LABEL>, E> ScopeContainer<LABEL> for Result<SC, E> {
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>
where
Result<SC::PathContainer, E>: PathContainer<'sg, 'rslv, LABEL, DATA, DWFO>

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

View workflow job for this annotation

GitHub Actions / clippy

missing generics for associated type `containers::scope::ScopeContainer::PathContainer`

error[E0107]: missing generics for associated type `containers::scope::ScopeContainer::PathContainer` --> scopegraphs/src/containers/scope.rs:37:20 | 37 | Result<SC::PathContainer, E>: PathContainer<'sg, 'rslv, LABEL, DATA, DWFO> | ^^^^^^^^^^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `DWFO_INNER` --> scopegraphs/src/containers/scope.rs:13:10 | 13 | type PathContainer<DWFO_INNER> : PathContainer<'sg, 'rslv, LABEL, DATA, DWFO>; | ^^^^^^^^^^^^^ ---------- help: add missing generic argument | 37 | Result<SC::PathContainer<DWFO_INNER>, E>: PathContainer<'sg, 'rslv, LABEL, DATA, DWFO> | ++++++++++++
{
type PathContainer = Result<SC::PathContainer, E>;

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

View workflow job for this annotation

GitHub Actions / clippy

type `PathContainer` has 0 type parameters but its trait declaration has 1 type parameter

error[E0049]: type `PathContainer` has 0 type parameters but its trait declaration has 1 type parameter --> scopegraphs/src/containers/scope.rs:39:23 | 13 | type PathContainer<DWFO_INNER> : PathContainer<'sg, 'rslv, LABEL, DATA, DWFO>; | ---------- expected 1 type parameter ... 39 | type PathContainer = Result<SC::PathContainer, E>; | ^ found 0 type parameters

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

View workflow job for this annotation

GitHub Actions / clippy

missing generics for associated type `containers::scope::ScopeContainer::PathContainer`

error[E0107]: missing generics for associated type `containers::scope::ScopeContainer::PathContainer` --> scopegraphs/src/containers/scope.rs:39:37 | 39 | type PathContainer = Result<SC::PathContainer, E>; | ^^^^^^^^^^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `DWFO_INNER` --> scopegraphs/src/containers/scope.rs:13:10 | 13 | type PathContainer<DWFO_INNER> : PathContainer<'sg, 'rslv, LABEL, DATA, DWFO>; | ^^^^^^^^^^^^^ ---------- help: add missing generic argument | 39 | type PathContainer = Result<SC::PathContainer<DWFO_INNER>, E>; | ++++++++++++

fn lift_step(self, lbl: LABEL, prefix: Path<LABEL>) -> Self::PathContainer {

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

View workflow job for this annotation

GitHub Actions / clippy

method `lift_step` has 0 type parameters but its trait declaration has 1 type parameter

error[E0049]: method `lift_step` has 0 type parameters but its trait declaration has 1 type parameter --> scopegraphs/src/containers/scope.rs:41:17 | 19 | fn lift_step<DWFO_INNER>(self, lbl: LABEL, prefix: Path<LABEL>) -> Self::PathContainer<DWFO_INNER>; | ---------- expected 1 type parameter ... 41 | fn lift_step(self, lbl: LABEL, prefix: Path<LABEL>) -> Self::PathContainer { | ^ found 0 type parameters

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

View workflow job for this annotation

GitHub Actions / clippy

missing generics for associated type `containers::scope::ScopeContainer::PathContainer`

error[E0107]: missing generics for associated type `containers::scope::ScopeContainer::PathContainer` --> scopegraphs/src/containers/scope.rs:41:66 | 41 | fn lift_step(self, lbl: LABEL, prefix: Path<LABEL>) -> Self::PathContainer { | ^^^^^^^^^^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `DWFO_INNER` --> scopegraphs/src/containers/scope.rs:13:10 | 13 | type PathContainer<DWFO_INNER> : PathContainer<'sg, 'rslv, LABEL, DATA, DWFO>; | ^^^^^^^^^^^^^ ---------- help: add missing generic argument | 41 | fn lift_step(self, lbl: LABEL, prefix: Path<LABEL>) -> Self::PathContainer<DWFO_INNER> { | ++++++++++++
self.map(|sc| sc.lift_step(lbl, prefix))
}
}

impl<'rslv, LABEL, SC: ScopeContainer<LABEL> + Clone> ScopeContainer<LABEL>
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>
for FutureWrapper<'rslv, SC>
where
LABEL: Copy,
SC::PathContainer: Clone,
Self: 'rslv,
LABEL: 'rslv,
{
type PathContainer = FutureWrapper<'rslv, SC::PathContainer>;
type PathContainer<DWFO_INNER> = FutureWrapper<'rslv, SC::PathContainer<DWFO_INNER>>

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

View workflow job for this annotation

GitHub Actions / clippy

type parameter `DWFO_INNER` should have an upper camel case name

error: type parameter `DWFO_INNER` should have an upper camel case name --> scopegraphs/src/containers/scope.rs:53:24 | 53 | type PathContainer<DWFO_INNER> = FutureWrapper<'rslv, SC::PathContainer<DWFO_INNER>> | ^^^^^^^^^^ help: convert the identifier to upper camel case: `DwfoInner`
where
SC::PathContainer<DWFO_INNER>: PathContainer<'sg, 'rslv, LABEL, DATA, DWFO_INNER> + Clone

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

View workflow job for this annotation

GitHub Actions / clippy

impl has stricter requirements than trait

error[E0276]: impl has stricter requirements than trait --> scopegraphs/src/containers/scope.rs:55:93 | 13 | type PathContainer<DWFO_INNER> : PathContainer<'sg, 'rslv, LABEL, DATA, DWFO>; | ----------------------------------------------------------------------------- definition of `PathContainer` from trait ... 55 | SC::PathContainer<DWFO_INNER>: PathContainer<'sg, 'rslv, LABEL, DATA, DWFO_INNER> + Clone | ^^^^^ impl has extra requirement `<SC as containers::scope::ScopeContainer<'sg, 'rslv, LABEL, DATA, DWFO>>::PathContainer<DWFO_INNER>: std::clone::Clone`

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

View workflow job for this annotation

GitHub Actions / clippy

impl has stricter requirements than trait

error[E0276]: impl has stricter requirements than trait --> scopegraphs/src/containers/scope.rs:55:40 | 13 | type PathContainer<DWFO_INNER> : PathContainer<'sg, 'rslv, LABEL, DATA, DWFO>; | ----------------------------------------------------------------------------- definition of `PathContainer` from trait ... 55 | SC::PathContainer<DWFO_INNER>: PathContainer<'sg, 'rslv, LABEL, DATA, DWFO_INNER> + Clone | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `<SC as containers::scope::ScopeContainer<'sg, 'rslv, LABEL, DATA, DWFO>>::PathContainer<DWFO_INNER>: containers::path::PathContainer<'sg, 'rslv, LABEL, DATA, DWFO_INNER>`
;

fn lift_step(self, lbl: LABEL, prefix: Path<LABEL>) -> Self::PathContainer {
fn lift_step<DWFO_INNER>(self, lbl: LABEL, prefix: Path<LABEL>) -> Self::PathContainer<DWFO_INNER> {

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

View workflow job for this annotation

GitHub Actions / clippy

type parameter `DWFO_INNER` should have an upper camel case name

error: type parameter `DWFO_INNER` should have an upper camel case name --> scopegraphs/src/containers/scope.rs:58:18 | 58 | fn lift_step<DWFO_INNER>(self, lbl: LABEL, prefix: Path<LABEL>) -> Self::PathContainer<DWFO_INNER> { | ^^^^^^^^^^ help: convert the identifier to upper camel case: `DwfoInner`
FutureWrapper::new(async move { self.0.await.lift_step(lbl, prefix.clone()) })

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

View workflow job for this annotation

GitHub Actions / clippy

the trait bound `<SC as containers::scope::ScopeContainer<'sg, 'rslv, LABEL, DATA, DWFO>>::PathContainer<_>: std::clone::Clone` is not satisfied

error[E0277]: the trait bound `<SC as containers::scope::ScopeContainer<'sg, 'rslv, LABEL, DATA, DWFO>>::PathContainer<_>: std::clone::Clone` is not satisfied --> scopegraphs/src/containers/scope.rs:59:9 | 59 | FutureWrapper::new(async move { self.0.await.lift_step(lbl, prefix.clone()) }) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `<SC as containers::scope::ScopeContainer<'sg, 'rslv, LABEL, DATA, DWFO>>::PathContainer<_>` | note: required by a bound in `future_wrapper::FutureWrapper::<'fut, T>::new` --> scopegraphs/src/future_wrapper.rs:20:15 | 20 | impl<'fut, T: Clone> FutureWrapper<'fut, T> { | ^^^^^ required by this bound in `FutureWrapper::<'fut, T>::new` 21 | pub fn new(f: impl Future<Output = T> + 'fut) -> Self { | --- required by a bound in this associated function
}
}
1 change: 1 addition & 0 deletions scopegraphs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#![allow(unknown_lints)]
#![allow(unexpected_cfgs)]
#![allow(clippy::empty_docs)]
#![feature(type_alias_impl_trait)]

#[cfg(feature = "documentation")]
pub mod concepts;
Expand Down
82 changes: 40 additions & 42 deletions scopegraphs/src/resolve/lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,7 @@ where
LABEL: Label + Copy + Debug + Hash,
DATA: Debug,
CMPL: Completeness<LABEL, DATA>,
CMPL::GetEdgesResult<'rslv>: ScopeContainer<LABEL>,
<CMPL::GetEdgesResult<'rslv> as ScopeContainer<LABEL>>::PathContainer:
PathContainer<'sg, 'rslv, LABEL, DATA>,
<<CMPL::GetEdgesResult<'rslv> as ScopeContainer<LABEL>>::PathContainer as PathContainer<
'sg,
'rslv,
LABEL,
DATA,
>>::EnvContainer: EnvContainer<'sg, 'rslv, LABEL, DATA, <DWF as DataWellformedness<'sg, DATA>>::Output>
+ Debug,
CMPL::GetEdgesResult<'rslv> : ScopeContainer<'sg, 'rslv, LABEL, DATA, DWF::Output>,
PWF: for<'a> RegexMatcher<&'a LABEL> + 'rslv,
DWF: DataWellformedness<'sg, DATA> + 'rslv,

Expand All @@ -48,7 +39,7 @@ where
Path<LABEL>: Clone,
{
type EnvContainer
= EnvC<'sg, 'rslv, CMPL, LABEL, DATA>
= EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWF::Output>
where
'sg: 'rslv,
Self: 'rslv;
Expand Down Expand Up @@ -104,9 +95,9 @@ struct ResolutionContext<'storage, 'sg: 'rslv, 'rslv, LABEL: Label, DATA, CMPL,
data_equiv: &'rslv DEq,
}

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

Check failure on line 100 in scopegraphs/src/resolve/lookup.rs

View workflow job for this annotation

GitHub Actions / clippy

missing generics for associated type `containers::scope::ScopeContainer::PathContainer`

error[E0107]: missing generics for associated type `containers::scope::ScopeContainer::PathContainer` --> scopegraphs/src/resolve/lookup.rs:100:54 | 100 | > as ScopeContainer<'sg, 'rslv, LABEL, DATA, DWFO>>::PathContainer as PathContainer<'sg, 'rslv, LABEL, DATA, DWFO>>::EnvContainer; | ^^^^^^^^^^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `DWFO_INNER` --> scopegraphs/src/containers/scope.rs:13:10 | 13 | type PathContainer<DWFO_INNER> : PathContainer<'sg, 'rslv, LABEL, DATA, DWFO>; | ^^^^^^^^^^^^^ ---------- help: add missing generic argument | 100 | > as ScopeContainer<'sg, 'rslv, LABEL, DATA, DWFO>>::PathContainer<DWFO_INNER> as PathContainer<'sg, 'rslv, LABEL, DATA, DWFO>>::EnvContainer; | ++++++++++++

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

Expand All @@ -117,16 +108,7 @@ where
DATA: Debug,
ResolvedPath<'sg, LABEL, DATA>: Hash + Eq,
CMPL: Completeness<LABEL, DATA>,
CMPL::GetEdgesResult<'rslv>: ScopeContainer<LABEL>,
<CMPL::GetEdgesResult<'rslv> as ScopeContainer<LABEL>>::PathContainer:
PathContainer<'sg, 'rslv, LABEL, DATA>,
<<CMPL::GetEdgesResult<'rslv> as ScopeContainer<LABEL>>::PathContainer as PathContainer<
'sg,
'rslv,
LABEL,
DATA,
>>::EnvContainer: EnvContainer<'sg, 'rslv, LABEL, DATA, <DWF as DataWellformedness<'sg, DATA>>::Output>
+ Debug,
CMPL::GetEdgesResult<'rslv> : ScopeContainer<'sg, 'rslv, LABEL, DATA, DWF::Output>,
DEq: DataEquivalence<DATA>,
DWF: DataWellformedness<'sg, DATA>,
LO: LabelOrder<LABEL>,
Expand All @@ -140,7 +122,7 @@ where
self: &Arc<Self>,
path_wellformedness: impl for<'a> RegexMatcher<&'a LABEL> + 'rslv,
path: Path<LABEL>,
) -> EnvC<'sg, 'rslv, CMPL, LABEL, DATA> {
) -> EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWF::Output> {
let edges: Vec<_> = self
.all_edges
.iter()
Expand All @@ -164,15 +146,15 @@ where
path_wellformedness: impl for<'a> RegexMatcher<&'a LABEL> + 'rslv,
edges: &[EdgeOrData<LABEL>],
path: Path<LABEL>,
cache: &EnvCache<LABEL, EnvC<'sg, 'rslv, CMPL, LABEL, DATA>>,
) -> EnvC<'sg, 'rslv, CMPL, LABEL, DATA> {
cache: &EnvCache<LABEL, EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWF::Output>>,
) -> EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWF::Output> {
// set of labels that are to be resolved last
let max = self.max(edges);
let tgt = path.target();
log::info!("Resolving max-edges {:?} in {:?}", max, tgt);

max.into_iter()
.map::<Rc<EnvC<'sg, 'rslv, CMPL, LABEL, DATA>>, _>(|edge| {
.map::<Rc<EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWF::Output>>, _>(|edge| {
if let Some(env) = cache.borrow().get(&edge) {
log::info!("Reuse {:?}-environment from cache", edge);
return env.clone();
Expand Down Expand Up @@ -201,7 +183,7 @@ where
let mut merged_env = agg_env.clone();
env2.flat_map(move |new_env| {
merged_env.merge(new_env);
<EnvC<'sg, 'rslv, CMPL, LABEL, DATA> as From<Env<'sg, LABEL, DATA>>>::from(
<EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWF::Output> as From<Env<'sg, LABEL, DATA>>>::from(
merged_env,
)
})
Expand All @@ -220,16 +202,16 @@ where
edge: EdgeOrData<LABEL>, // current max label
edges: &[EdgeOrData<LABEL>], // smaller set of `edge`
path: Path<LABEL>,
cache: &EnvCache<LABEL, EnvC<'sg, 'rslv, CMPL, LABEL, DATA>>,
) -> Rc<EnvC<'sg, 'rslv, CMPL, LABEL, DATA>> {
cache: &EnvCache<LABEL, EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWF::Output>>,
) -> Rc<EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWF::Output>> {
// base environment
let base_env: EnvC<'sg, 'rslv, CMPL, LABEL, DATA> =
let base_env: EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWF::Output> =
self.resolve_edges(path_wellformedness.clone(), edges, path.clone(), cache);
let local_self = Arc::clone(self);
// environment of current (max) label, which might be shadowed by the base environment
Rc::new(base_env.flat_map(move |base_env| {
if !base_env.is_empty() && local_self.data_equiv.always_equivalent() {
<EnvC<'sg, 'rslv, CMPL, LABEL, DATA> as From<Env<'sg, LABEL, DATA>>>::from(
<EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWF::Output> as From<Env<'sg, LABEL, DATA>>>::from(
base_env.clone(),
)
} else {
Expand Down Expand Up @@ -263,7 +245,7 @@ where
for path in filtered_env {
new_env.insert(path.clone())
}
<EnvC<'sg, 'rslv, CMPL, LABEL, DATA> as From<Env<'sg, LABEL, DATA>>>::from(
<EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWF::Output> as From<Env<'sg, LABEL, DATA>>>::from(
new_env,
)
})
Expand All @@ -277,7 +259,7 @@ where
path_wellformedness: impl for<'a> RegexMatcher<&'a LABEL> + 'rslv,
edge: EdgeOrData<LABEL>,
path: Path<LABEL>,
) -> EnvC<'sg, 'rslv, CMPL, LABEL, DATA> {
) -> EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWF::Output> {
match edge {
EdgeOrData::Edge(label) => {
let mut new_path_wellformedness = path_wellformedness.clone();
Expand All @@ -297,24 +279,24 @@ where
path_wellformedness: impl for<'a> RegexMatcher<&'a LABEL> + 'rslv,
label: LABEL,
path: Path<LABEL>,
) -> EnvC<'sg, 'rslv, CMPL, LABEL, DATA> {
) -> EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWF::Output> {
let source = path.target();
let targets = self.sg.get_edges(source, label);
let path_set = targets.lift_step(label, path.clone());
let local_ctx = Arc::clone(self);
let env: EnvC<'sg, 'rslv, CMPL, LABEL, DATA> = path_set.map_into_env::<_>(move |p| {
let env: EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWF::Output> = path_set.map_into_env::<_>(move |p| {
local_ctx.resolve_all(path_wellformedness.clone(), p.clone())
});
env
}

/// Creates single-path environment if the data `path.target()` is matching, or an empty environment otherwise.
fn resolve_data(&self, path: Path<LABEL>) -> EnvC<'sg, 'rslv, CMPL, LABEL, DATA> {
fn resolve_data(&self, path: Path<LABEL>) -> EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWF::Output> {
let data = self.sg.get_data(path.target());
let path = path.clone().resolve(data);
let data_ok = self.data_wellformedness.data_wf(data);

<EnvC<'sg, 'rslv, CMPL, LABEL, DATA> as EnvContainer<
<EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWF::Output> as EnvContainer<
'sg,
'rslv,
LABEL,
Expand Down Expand Up @@ -351,8 +333,8 @@ where
smaller
}

fn empty_env_container() -> EnvC<'sg, 'rslv, CMPL, LABEL, DATA> {
<EnvC<'sg, 'rslv, CMPL, LABEL, DATA> as EnvContainer<
fn empty_env_container() -> EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWF::Output> {
<EnvC<'sg, 'rslv, CMPL, LABEL, DATA, DWF::Output> as EnvContainer<
'sg,
'rslv,
LABEL,
Expand All @@ -374,7 +356,7 @@ mod tests {
},
future_wrapper::FutureWrapper,
query_regex,
resolve::{Resolve, ResolvedPath},
resolve::{DataWellformedness, Resolve, ResolvedPath},
storage::Storage,
Label, ScopeGraph,
};
Expand Down Expand Up @@ -478,7 +460,19 @@ mod tests {
.with_path_wellformedness(query_regex!(Lbl: Lex* Imp? Def))
.with_data_wellformedness(TData::matcher_fut("x"))
.with_label_order(label_order!(Lbl: Def < Imp < Lex));
let env = query.resolve(s_let).await;
type DWF = impl for<'sg> DataWellformedness<'sg, TData<'sg>, Output = FutureWrapper<'sg, bool>>;
let env = crate::resolve::Query::<
'_,
'_,
'_,
_,
_,
_,
_,
DWF,
_,
_
>::resolve(&query, s_let).await;

let env_vec = env.into_iter().collect::<Vec<_>>();
assert_eq!(1, env_vec.len());
Expand All @@ -490,6 +484,10 @@ 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 c5b1f6f

Please sign in to comment.