Commit c553fb2e authored by Jeff Smits's avatar Jeff Smits

Removed cloning of program statements

StrategyDef used to own a Strategy. Now it just borrows it. Had to reorder some things so that the preprocess::Def outlive the MutContext, but now context::Scope can hold preprocess::StrategyDef, which has borrows to the list of preprocess::Def.
parent 3c725ab2
......@@ -199,9 +199,9 @@ fn write_primitive_libs(
writeln!(
file,
"\
pub fn eval_prim_ref<'a>(prim_ref: (Libs, usize),
context: &MutContext<'a>,
sargs: Vec<StrategyDef>,
pub fn eval_prim_ref<'d, 'f : 'd>(prim_ref: (Libs, usize),
context: &MutContext<'d, 'f>,
sargs: Vec<StrategyDef<'d>>,
targs: Vec<ATermRef>,
current: ATermRef)
-> Result<ATermRef>
......@@ -266,9 +266,9 @@ fn write_primitives(
file,
"\
#[inline]
fn {}<'a>(offset: usize,
context: &MutContext<'a>,
sargs: Vec<StrategyDef>,
fn {}<'d, 'f : 'd>(offset: usize,
context: &MutContext<'d, 'f>,
sargs: Vec<StrategyDef<'d>>,
targs: Vec<ATermRef>,
current: ATermRef)
-> Result<ATermRef>
......
use error::{Result, Error};
use factory::{ATermFactory, ATerm, ATermRef};
use preprocess::StrategyDef;
use preprocess::{Def, StrategyDef};
use primitives::{Primitives, eval_prim_ref};
use primitives::ssl::State;
......@@ -13,20 +13,20 @@ use std::cell::RefCell;
/// This context is internally mutable in `RefCell` fields. This is just for convenience as we don't
/// want to pass around the mutable fields separately. But the internal mutability is not a hidden
/// thing, there is observable effect, so the name of the context includes `Mut`.
pub struct MutContext<'a> {
pub struct MutContext<'d, 'f : 'd> {
pub stack_tracer: RefCell<StackTracer>,
pub scopes: RefCell<Vec<Scope<ATermRef>>>,
pub factory: &'a ATermFactory,
pub scopes: RefCell<Vec<Scope<'d, ATermRef>>>,
pub factory: &'f ATermFactory,
pub primitives: Vec<&'static Primitives>,
pub ssl_state: RefCell<State>,
}
impl<'a> MutContext<'a> {
impl<'d, 'f : 'd> MutContext<'d, 'f> {
pub fn new(
factory: &'a ATermFactory,
scopes: Vec<Scope<ATermRef>>,
factory: &'f ATermFactory,
scopes: Vec<Scope<'d, ATermRef>>,
primitives: Vec<&'static Primitives>,
) -> MutContext<'a> {
) -> MutContext<'d, 'f> {
MutContext {
stack_tracer: RefCell::new(StackTracer::default()),
factory: factory,
......@@ -39,7 +39,7 @@ impl<'a> MutContext<'a> {
pub fn call_primitive(
&self,
prim_name: &str,
sargs: Vec<StrategyDef>,
sargs: Vec<StrategyDef<'d>>,
targs: Vec<ATermRef>,
current: ATermRef,
) -> Result<ATermRef> {
......@@ -60,13 +60,13 @@ impl<'a> MutContext<'a> {
}
// Should really return a &SDef, but I can't figure out lifetimes that borrowck will accept :(
pub fn get_strategy(&self, strat_name: &str) -> Result<StrategyDef> {
pub fn get_strategy(&self, strat_name: &str) -> Result<StrategyDef<'d>> {
self.scopes
.borrow()
.iter()
.rev()
.flat_map(|scope| scope.strategy.get(strat_name))
.cloned() // >:(
.cloned() // StrategyDef is fairly cheap to clone
.next()
.ok_or_else(|| Error::UndefinedStrategy(strat_name.to_owned()))
}
......@@ -85,7 +85,7 @@ impl<'a> MutContext<'a> {
Scopes::match_term(&mut self.scopes.borrow_mut(), term_name, current)
}
pub fn push_scope(&self, scope: Scope<ATermRef>) {
pub fn push_scope(&self, scope: Scope<'d, ATermRef>) {
self.scopes.borrow_mut().push(scope);
}
......@@ -99,7 +99,7 @@ impl<'a> MutContext<'a> {
self.push_scope(overlay);
}
fn _apply_overlay(&self, scope: Scope<ATermRef>) {
fn _apply_overlay(&self, scope: Scope<'d, ATermRef>) {
debug_assert!(
scope.strategy.is_empty(),
"_apply_overlay: Interpreter bug, overlay is leaking a strategy definition"
......@@ -194,17 +194,17 @@ impl fmt::Display for StackTracer {
}
#[derive(Debug, Default, Clone)]
pub struct Scope<ATerm> {
pub struct Scope<'a, ATerm> {
pub term: HashMap<String, Option<ATerm>>,
pub strategy: HashMap<String, StrategyDef>,
pub strategy: HashMap<String, StrategyDef<'a>>,
is_overlay: bool,
}
impl<ATerm> Scope<ATerm> {
pub fn new<IA, IS>(terms: IA, defs: IS) -> Scope<ATerm>
impl<'a, ATerm> Scope<'a, ATerm> {
pub fn new<IA, IS>(terms: IA, defs: IS) -> Self
where
IA: IntoIterator<Item = (String, ATerm)>,
IS: IntoIterator<Item = (String, StrategyDef)>,
IS: IntoIterator<Item = (String, StrategyDef<'a>)>,
{
Scope {
term: terms.into_iter().map(|(n, a)| (n, Some(a))).collect(),
......@@ -213,36 +213,33 @@ impl<ATerm> Scope<ATerm> {
}
}
pub fn from_defs<I>(defs: I) -> Scope<ATerm>
pub fn from_defs<I>(defs: I) -> Self
where
I: IntoIterator<Item = StrategyDef>,
I: IntoIterator<Item = &'a Def>,
{
Scope {
term: HashMap::default(),
strategy: defs.into_iter()
.map(|sdeft| (sdeft.name(), sdeft))
.map(|def| (def.name.clone(), StrategyDef::from_def(def)))
.collect(),
is_overlay: false,
}
}
pub fn from_let_defs<I>(no_of_scopes: usize, defs: I) -> Scope<ATerm>
pub fn from_let_defs<I>(no_of_scopes: usize, defs: I) -> Self
where
I: IntoIterator<Item = StrategyDef>,
I: IntoIterator<Item=&'a Def>,
{
Scope {
term: HashMap::default(),
strategy: defs.into_iter()
.map(|mut sdeft| {
sdeft.set_scope_on_let_sdef(no_of_scopes);
(sdeft.name(), sdeft)
})
.map(|def| (def.name.clone(), StrategyDef::from_let_def(def, no_of_scopes)))
.collect(),
is_overlay: false,
}
}
pub fn from_fresh_variables<I>(fresh_vars: I) -> Scope<ATerm>
pub fn from_fresh_variables<I>(fresh_vars: I) -> Self
where
I: IntoIterator<Item = String>,
{
......
use ctree;
use context::{MutContext, StackTracer};
use error::{Result, Error};
use factory::{ATermFactory, ATerm, ATermRef};
use preprocess;
use preprocess::Strategy;
use preprocess::{StrategyDef, preprocess};
use primitives::Primitives;
......@@ -90,14 +88,16 @@ pub fn interpret_main(
)
}
pub fn interpret<'a>(
factory: &'a ATermFactory,
pub fn interpret<'f>(
factory: &'f ATermFactory,
program: ATermRef,
libraries: Libraries<ATermRef>,
strategy: &str,
input: ATermRef,
) -> result::Result<ATermRef, TracedError> {
let program: ctree::Module = match b(&program).try_into() {
use context::Scope;
let program = match b(&program).try_into().and_then(preprocess) {
Ok(v) => v,
Err(e) => return Err(TracedError(e, StackTracer::default())),
};
......@@ -105,45 +105,37 @@ pub fn interpret<'a>(
.libs
.into_iter()
.map(|l| b(&l).try_into().and_then(preprocess))
.collect::<Result<_>>() {
.collect::<Result<Vec<_>>>() {
Ok(v) => v,
Err(e) => return Err(TracedError(e, StackTracer::default())),
};
let context = MutContext::new(factory, libs, libraries.prims);
let program = match preprocess(program) {
Ok(v) => v,
Err(e) => return Err(TracedError(e, context.stack_tracer.into_inner())),
};
context.push_scope(program);
let base_scopes = libs.iter().map(Scope::from_defs).collect();
let context = MutContext::new(factory, base_scopes, libraries.prims);
context.push_scope(Scope::from_defs(&program));
let main = match context.get_strategy(strategy) {
Ok(v) => v,
Err(e) => return Err(TracedError(e, context.stack_tracer.into_inner())),
};
match eval_sdef(&main, &context, Vec::new(), Vec::new(), input) {
let result = eval_sdef(&main, &context, Vec::new(), Vec::new(), input);
match result {
Ok(v) => Ok(v),
Err(e) => Err(TracedError(e, context.stack_tracer.into_inner())),
}
}
pub trait Eval<'a> {
fn eval(&self, context: &MutContext<'a>, current: ATermRef) -> Result<ATermRef>;
pub trait Eval<'d, 'f> {
fn eval(&'d self, context: &MutContext<'d, 'f>, current: ATermRef) -> Result<ATermRef>;
}
impl<'a> Eval<'a> for StrategyDef {
fn eval(&self, context: &MutContext<'a>, current: ATermRef) -> Result<ATermRef> {
eval_sdef(self, context, Vec::new(), Vec::new(), current)
}
}
impl<'a> Eval<'a> for preprocess::Strategy {
fn eval(&self, context: &MutContext<'a>, current: ATermRef) -> Result<ATermRef> {
impl<'d, 'f : 'd> Eval<'d, 'f> for preprocess::Strategy {
fn eval(&'d self, context: &MutContext<'d, 'f>, current: ATermRef) -> Result<ATermRef> {
use preprocess::Strategy::*;
use context;
match *self {
Let(ref defs, ref body) => {
// note the + 1, because `let`s allow recursive definitions
let no_of_scopes = context.scopes.borrow().len() + 1;
context.push_scope(context::Scope::from_let_defs(no_of_scopes, defs.clone()));
context.push_scope(context::Scope::from_let_defs(no_of_scopes, defs.iter()));
let result = body.eval(context, current);
context.pop_scope();
result
......@@ -152,7 +144,6 @@ impl<'a> Eval<'a> for preprocess::Strategy {
let sdeft = context.get_strategy(name)?;
let sargs = sargs
.into_iter()
.cloned()
.enumerate()
.map(|(n, s)| strategy_def_from_strategy(context, name, n, s))
.collect::<Result<_>>()?;
......@@ -174,7 +165,6 @@ impl<'a> Eval<'a> for preprocess::Strategy {
let sdeft = context.get_strategy(&strategy_name)?;
let sargs = sargs
.into_iter()
.cloned()
.enumerate()
.map(|(n, s)| {
strategy_def_from_strategy(context, &strategy_name, n, s)
......@@ -232,7 +222,6 @@ impl<'a> Eval<'a> for preprocess::Strategy {
PrimT(ref name, ref sargs, ref targs) => {
let sargs = sargs
.into_iter()
.cloned()
.enumerate()
.map(|(n, s)| strategy_def_from_strategy(context, name, n, s))
.collect::<Result<_>>()?;
......@@ -263,8 +252,8 @@ impl<'a> Eval<'a> for preprocess::Strategy {
}
}
fn eval_match<'a>(
context: &MutContext<'a>,
fn eval_match<'d, 'f : 'd>(
context: &MutContext<'d, 'f>,
match_term: &preprocess::MatchTerm,
current: &ATermRef,
) -> Result<()> {
......@@ -381,9 +370,9 @@ fn eval_match<'a>(
}
}
fn eval_some<'a>(
strat: &preprocess::Strategy,
context: &MutContext<'a>,
fn eval_some<'d, 'f : 'd>(
strat: &'d preprocess::Strategy,
context: &MutContext<'d, 'f>,
current: ATermRef,
) -> Result<ATermRef> {
use aterm::Term::*;
......@@ -415,9 +404,9 @@ fn eval_some<'a>(
}
}
fn eval_one<'a>(
strat: &preprocess::Strategy,
context: &MutContext<'a>,
fn eval_one<'d, 'f : 'd>(
strat: &'d preprocess::Strategy,
context: &MutContext<'d, 'f>,
current: ATermRef,
) -> Result<ATermRef> {
use aterm::Term::*;
......@@ -449,9 +438,9 @@ fn eval_one<'a>(
}
}
fn eval_all<'a>(
strat: &preprocess::Strategy,
context: &MutContext<'a>,
fn eval_all<'d, 'f : 'd>(
strat: &'d preprocess::Strategy,
context: &MutContext<'d, 'f>,
current: ATermRef,
) -> Result<ATermRef> {
use aterm::Term::*;
......@@ -483,10 +472,10 @@ fn eval_all<'a>(
}
}
fn one_rec<'a>(
fn one_rec<'d, 'f : 'd>(
r: &Box<[ATermRef]>,
strat: &preprocess::Strategy,
context: &MutContext<'a>,
strat: &'d preprocess::Strategy,
context: &MutContext<'d, 'f>,
) -> Result<Box<[ATermRef]>> {
let mut result = Vec::with_capacity(r.len());
let mut iter = r.into_iter();
......@@ -508,10 +497,10 @@ fn one_rec<'a>(
}
}
fn some_rec<'a>(
fn some_rec<'d, 'f : 'd>(
r: &Box<[ATermRef]>,
strat: &preprocess::Strategy,
context: &MutContext<'a>,
strat: &'d preprocess::Strategy,
context: &MutContext<'d, 'f>,
) -> Result<Box<[ATermRef]>> {
let mut result = Vec::with_capacity(r.len());
let mut success = false;
......@@ -530,10 +519,10 @@ fn some_rec<'a>(
}
}
fn all_rec<'a>(
fn all_rec<'d, 'f : 'd>(
r: &Box<[ATermRef]>,
strat: &preprocess::Strategy,
context: &MutContext<'a>,
strat: &'d preprocess::Strategy,
context: &MutContext<'d, 'f>,
) -> Result<Box<[ATermRef]>> {
r.into_iter()
.cloned()
......@@ -542,15 +531,15 @@ fn all_rec<'a>(
.map(Vec::into_boxed_slice)
}
pub fn eval_sdef<'a>(
strategy_def: &StrategyDef,
context: &MutContext<'a>,
actual_sargs: Vec<StrategyDef>,
pub fn eval_sdef<'d, 'f : 'd>(
strategy_def: &StrategyDef<'d>,
context: &MutContext<'d, 'f>,
actual_sargs: Vec<StrategyDef<'d>>,
actual_targs: Vec<ATermRef>,
current: ATermRef,
) -> Result<ATermRef> {
let name = strategy_def.name();
if !strategy_def.inner.matching_counts(
if !strategy_def.matching_counts(
actual_sargs.len(),
actual_targs.len(),
)
......@@ -558,11 +547,15 @@ pub fn eval_sdef<'a>(
Err(Error::UndefinedStrategy(name))
} else {
context.stack_tracer.borrow_mut().push(name);
let popped_scopes = strategy_def.no_of_scopes.map_or_else(Vec::new, |n| {
let popped_scopes = strategy_def.no_of_scopes().map_or_else(Vec::new, |n| {
context.scopes.borrow_mut().split_off(n)
});
context.push_scope(strategy_def.inner.build_scope(actual_sargs, actual_targs));
let result = strategy_def.body.eval(context, current);
context.push_scope(strategy_def.build_scope(actual_sargs, actual_targs));
let result = match *strategy_def {
StrategyDef::TopLevel(def) => def.body.eval(context, current),
StrategyDef::Predefined { def, .. } => def.body.eval(context, current),
StrategyDef::Anonymous { body, .. } => body.eval(context, current),
};
context.pop_scope();
context.scopes.borrow_mut().extend_from_slice(
&popped_scopes,
......@@ -576,26 +569,27 @@ pub fn eval_sdef<'a>(
}
}
pub fn strategy_def_from_strategy(
context: &MutContext,
pub fn strategy_def_from_strategy<'d, 'f : 'd>(
context: &MutContext<'d, 'f>,
name: &str,
number: usize,
body: Strategy,
) -> Result<StrategyDef> {
body: &'d preprocess::Strategy,
) -> Result<StrategyDef<'d>> {
use preprocess::Strategy;
let no_of_scopes = context.scopes.borrow().len();
// NOTE: this is not an optimisation but a necessary semantic distinction to allow
// strategies that take arguments to be passed as strategy arguments!
match body {
match *body {
Strategy::CallT(ref name, ref sargs, ref targs) if sargs.is_empty() && targs.is_empty() => {
context.get_strategy(name)
}
_ => {
Ok(StrategyDef::anonymous(
name.to_owned(),
number,
body,
no_of_scopes,
))
Ok(StrategyDef::Anonymous {
argument_of: name.to_owned(),
argument_no: number,
body: body,
no_of_scopes: no_of_scopes,
})
}
}
}
......@@ -10,12 +10,12 @@ use try_from::{TryInto, TryFrom};
use std::result;
pub fn preprocess(program: ctree::Module) -> Result<Scope<ATermRef>> {
pub fn preprocess<'a>(program: ctree::Module) -> Result<Vec<Def>> {
let decls = match program {
ctree::Module::Module(_, decls) |
ctree::Module::Specification(decls) => decls,
};
let defs = decls
decls
.into_iter()
.flat_map(|decl| match decl {
ctree::Decl::Strategies(defs) => defs.into_iter(),
......@@ -24,76 +24,75 @@ pub fn preprocess(program: ctree::Module) -> Result<Scope<ATermRef>> {
.map(TryInto::try_into)
// TODO: find nicer way to filter out external strategy definitions
.filter(Result::is_ok)
.collect::<Result<Vec<StrategyDef>>>()?;
Ok(Scope::from_defs(defs))
.collect()
}
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub struct StrategyDef {
pub body: Strategy,
pub no_of_scopes: Option<usize>,
pub inner: StrategyDefInner,
}
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub enum StrategyDefInner {
pub enum StrategyDef<'a> {
TopLevel(&'a Def),
Predefined {
name: String,
sargs: Vec<String>,
targs: Vec<String>,
def: &'a Def,
no_of_scopes: usize,
},
Anonymous {
argument_of: String,
argument_no: usize,
body: &'a Strategy,
no_of_scopes: usize,
},
}
impl StrategyDefInner {
impl<'a> StrategyDef<'a> {
pub fn no_of_scopes(&self) -> Option<usize> {
match *self {
StrategyDef::TopLevel(_) => None,
StrategyDef::Predefined { no_of_scopes, .. } => Some(no_of_scopes),
StrategyDef::Anonymous { no_of_scopes, .. } => Some(no_of_scopes),
}
}
pub fn matching_counts(&self, c_sargs: usize, c_targs: usize) -> bool {
match *self {
StrategyDefInner::Predefined {
ref sargs,
ref targs,
StrategyDef::TopLevel(ref def) =>
def.sargs.len() == c_sargs && def.targs.len() == c_targs,
StrategyDef::Predefined {
def,
..
} => sargs.len() == c_sargs && targs.len() == c_targs,
StrategyDefInner::Anonymous { .. } => c_sargs == 0 && c_targs == 0,
} => def.sargs.len() == c_sargs && def.targs.len() == c_targs,
StrategyDef::Anonymous { .. } => c_sargs == 0 && c_targs == 0,
}
}
pub fn build_scope<ATerm>(
&self,
actual_sargs: Vec<StrategyDef>,
actual_sargs: Vec<StrategyDef<'a>>,
actual_targs: Vec<ATerm>,
) -> Scope<ATerm> {
) -> Scope<'a, ATerm> {
match *self {
StrategyDefInner::Predefined {
ref sargs,
ref targs,
StrategyDef::TopLevel(ref def) => {
Scope::new(
def.targs.iter().cloned().zip(actual_targs),
def.sargs.iter().cloned().zip(actual_sargs),
)
}
StrategyDef::Predefined {
def,
..
} => {
Scope::new(
targs.iter().cloned().zip(actual_targs),
sargs.iter().cloned().zip(actual_sargs),
def.targs.iter().cloned().zip(actual_targs),
def.sargs.iter().cloned().zip(actual_sargs),
)
}
StrategyDefInner::Anonymous { .. } => Scope::new(Vec::new(), Vec::new()),
StrategyDef::Anonymous { .. } => Scope::new(Vec::new(), Vec::new()),
}
}
}
impl StrategyDef {
pub fn set_scope_on_let_sdef(&mut self, no_of_scopes: usize) {
debug_assert!(
self.no_of_scopes.is_none(),
"set_scope_on_let_sdef called on already scoped predefined strategy or anonymous strategy"
);
self.no_of_scopes = Some(no_of_scopes);
}
pub fn name(&self) -> String {
match self.inner {
StrategyDefInner::Predefined { ref name, .. } => name.clone(),
StrategyDefInner::Anonymous {
match *self {
StrategyDef::TopLevel(ref def) => def.name.clone(),
StrategyDef::Predefined { def, .. } => def.name.clone(),
StrategyDef::Anonymous {
ref argument_of,
ref argument_no,
..
......@@ -101,55 +100,39 @@ impl StrategyDef {
}
}
pub fn predefined(
name: String,
sargs: Vec<String>,
targs: Vec<String>,
body: Strategy,
no_of_scopes: Option<usize>,
) -> Self {
StrategyDef {
body: body,
no_of_scopes: no_of_scopes,
inner: StrategyDefInner::Predefined {
name: name,
sargs: sargs,
targs: targs,
},
}
pub fn from_def(def: &'a Def) -> Self {
StrategyDef::TopLevel(def)
}
pub fn anonymous(
argument_of: String,
argument_no: usize,
body: Strategy,
no_of_scopes: usize,
) -> Self {
StrategyDef {
body: body,
no_of_scopes: Some(no_of_scopes),
inner: StrategyDefInner::Anonymous {
argument_of: argument_of,
argument_no: argument_no,
},
pub fn from_let_def(def: &'a Def, no_of_scopes: usize) -> Self {
StrategyDef::Predefined {
def: def,
no_of_scopes: no_of_scopes,
}
}
}
impl TryFrom<ctree::Def> for StrategyDef {
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub struct Def {
pub name: String,
pub sargs: Vec<String>,
pub targs: Vec<String>,
pub body: Strategy,
}
impl TryFrom<ctree::Def> for Def {
type Err = Error;
fn try_from(value: ctree::Def) -> result::Result<Self, Self::Err> {
match value {
ctree::Def::SDefT(name, sargs, targs, body) => {
body.try_into().map(|body| {
Self::predefined(
name,
sargs.into_iter().map(|vardec| vardec.0).collect(),
targs.into_iter().map(|vardec| vardec.0).collect(),
body,
None,
)
Def {
name: name,
sargs: sargs.into_iter().map( | vardec| vardec.0).collect(),
targs: targs.into_iter().map(|vardec| vardec.0).collect(),
body: body,
}
})
}
ctree::Def::ExtSDef(_, _, _) => Err(Error::CTreeParse("Unknown behaviour: ExtSDef")),
......@@ -170,7 +153,7 @@ impl TryFrom<ctree::Def> for StrategyDef {
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub enum Strategy {
Let(Vec<StrategyDef>, Box<Strategy>),
Let(Vec<Def>, Box<Strategy>),
CallT(String, Vec<Strategy>, Vec<BuildTerm>),
CallDynamic(String, Vec<Strategy>, Vec<BuildTerm>),
Fail,
......@@ -195,9 +178,6 @@ impl TryFrom<ctree::Strategy> for Strategy {
use self::Strategy as O;
match value {
I::Let(defs, body) => {
// NOTE: This is why we cannot have nice things! strategy definitions in a let are
// already turned into `SDefT`s here, there is no term environment being saved in
// a closure during interpretation.
let defs = try_into_vec(defs)?;
try_into_box(body).map(|s| O::Let(defs, s))
}
......@@ -314,13 +294,13 @@ impl TryFrom<ctree::PreTerm> for BuildTerm {
}
impl BuildTerm {
pub fn build<'a>(&self, context: &MutContext<'a>) -> Result<ATermRef> {
pub fn build<'d, 'f : 'd>(&self, context: &MutContext<'d, 'f>) -> Result<ATermRef> {
self.build_with_annos(context, None)
}
fn build_with_annos<'a>(
fn build_with_annos<'d, 'f : 'd>(
&self,
context: &MutContext<'a>,
context: &MutContext<'d, 'f>,
annos: Option<Vec<ATermRef>>,
) -> Result<ATermRef> {
use self::BuildTerm::*;
......@@ -428,7 +408,7 @@ impl BuildTerm {
}
/// Lifts `build` over a vector
fn build_vec<'a>(context: &MutContext<'a>, vec: &[BuildTerm]) -> Result<Vec<ATermRef>> {
fn build_vec<'d, 'f : 'd>(context: &MutContext<'d, 'f>, vec: &[BuildTerm]) -> Result<Vec<ATermRef>> {
vec.into_iter().map(|t| t.build(context)).collect()
}
......@@ -510,8 +490,8 @@ impl TryFrom<ctree::PreTerm> for MatchTerm {
}
fn try_into_vec<T1, T2: TryFrom<T1>>(
v: Vec<T1>,
pub fn try_into_vec<T1, T2: TryFrom<T1>, I: IntoIterator<Item=T1>>(
v: I,
) -> result::Result<Vec<T2>, <T2 as TryFrom<T1>>::Err> {
v.into_iter()
.map(TryInto::try_into)
......
......@@ -26,9 +26,9 @@ impl HashTableState {
}
}
pub fn table_hashtable<'a>(
context: &MutContext<'a>,
sargs: Vec<StrategyDef>,