summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNadrieril2019-03-16 23:21:51 +0100
committerNadrieril2019-03-16 23:21:51 +0100
commit05454ab9936514409e1b3c97e36f3fb476d532ba (patch)
tree9ce983a7d76f861b22a6b8dabb68f34a80db15ac
parent0f33caf4c1ee4d1f95d6ac3a41b5cf2f8efa7b54 (diff)
Use Rc instead of Box in AST to allow structural sharing
Closes #29
Diffstat (limited to '')
-rw-r--r--dhall/src/binary.rs3
-rw-r--r--dhall/src/normalize.rs1
-rw-r--r--dhall/src/typecheck.rs13
-rw-r--r--dhall_core/src/core.rs80
-rw-r--r--dhall_core/src/parser.rs67
-rw-r--r--dhall_generator/src/lib.rs15
6 files changed, 93 insertions, 86 deletions
diff --git a/dhall/src/binary.rs b/dhall/src/binary.rs
index fbd343b..08bdba4 100644
--- a/dhall/src/binary.rs
+++ b/dhall/src/binary.rs
@@ -1,8 +1,9 @@
use dhall_core::*;
use itertools::*;
+use std::rc::Rc;
use serde_cbor::value::value as cbor;
-type ParsedExpr = Box<Expr<X, Import>>;
+type ParsedExpr = Rc<Expr<X, Import>>;
#[derive(Debug)]
pub enum DecodeError {
diff --git a/dhall/src/normalize.rs b/dhall/src/normalize.rs
index c49d313..40112f1 100644
--- a/dhall/src/normalize.rs
+++ b/dhall/src/normalize.rs
@@ -2,6 +2,7 @@
use dhall_core::core::*;
use dhall_generator::dhall_expr;
use std::fmt;
+use std::rc::Rc;
/// Reduce an expression to its weak head normal form, i.e. normalize
/// just enough to get the first constructor of the final expression
diff --git a/dhall/src/typecheck.rs b/dhall/src/typecheck.rs
index ca0d5af..f5670f7 100644
--- a/dhall/src/typecheck.rs
+++ b/dhall/src/typecheck.rs
@@ -2,6 +2,7 @@
use std::collections::BTreeMap;
use std::collections::HashSet;
use std::fmt;
+use std::rc::Rc;
use crate::normalize;
use dhall_core::context::Context;
@@ -415,7 +416,7 @@ where
}
ListLit(ref t, ref xs) => {
let mut iter = xs.iter().enumerate();
- let t: Box<Expr<_, _>> = match t {
+ let t: Rc<Expr<_, _>> = match t {
Some(t) => t.clone(),
None => {
let (_, first_x) = iter.next().unwrap();
@@ -426,7 +427,7 @@ where
let s = normalize::<_, S, _>(&type_with(ctx, &t)?);
match s {
Const(Type) => {}
- _ => return Err(TypeError::new(ctx, e, InvalidListType(*t))),
+ _ => return Err(TypeError::new(ctx, e, InvalidListType(t))),
}
for (i, x) in iter {
let t2 = type_with(ctx, x)?;
@@ -474,7 +475,7 @@ where
)),
OptionalLit(ref t, ref xs) => {
let mut iter = xs.iter();
- let t: Box<Expr<_, _>> = match t {
+ let t: Rc<Expr<_, _>> = match t {
Some(t) => t.clone(),
None => {
let x = iter.next().unwrap();
@@ -489,7 +490,7 @@ where
return Err(TypeError::new(
ctx,
e,
- InvalidOptionalType(*t),
+ InvalidOptionalType(t),
));
}
}
@@ -689,10 +690,10 @@ pub enum TypeMessage<S> {
AnnotMismatch(Expr<S, X>, Expr<S, X>, Expr<S, X>),
Untyped,
InvalidListElement(usize, Expr<S, X>, Expr<S, X>, Expr<S, X>),
- InvalidListType(Expr<S, X>),
+ InvalidListType(Rc<Expr<S, X>>),
InvalidOptionalElement(Expr<S, X>, Expr<S, X>, Expr<S, X>),
InvalidOptionalLiteral(usize),
- InvalidOptionalType(Expr<S, X>),
+ InvalidOptionalType(Rc<Expr<S, X>>),
InvalidPredicate(Expr<S, X>, Expr<S, X>),
IfBranchMismatch(Expr<S, X>, Expr<S, X>, Expr<S, X>, Expr<S, X>),
IfBranchMustBeTerm(bool, Expr<S, X>, Expr<S, X>, Expr<S, X>),
diff --git a/dhall_core/src/core.rs b/dhall_core/src/core.rs
index 34738bb..f5da1df 100644
--- a/dhall_core/src/core.rs
+++ b/dhall_core/src/core.rs
@@ -176,13 +176,13 @@ pub enum BinOp {
#[derive(Debug, Clone, PartialEq)]
pub struct InterpolatedText<Note, Embed> {
head: String,
- tail: Vec<(Box<Expr<Note, Embed>>, String)>,
+ tail: Vec<(Rc<Expr<Note, Embed>>, String)>,
}
-impl<N, E> From<(String, Vec<(Box<Expr<N, E>>, String)>)>
+impl<N, E> From<(String, Vec<(Rc<Expr<N, E>>, String)>)>
for InterpolatedText<N, E>
{
- fn from(x: (String, Vec<(Box<Expr<N, E>>, String)>)) -> Self {
+ fn from(x: (String, Vec<(Rc<Expr<N, E>>, String)>)) -> Self {
InterpolatedText {
head: x.0,
tail: x.1,
@@ -203,7 +203,7 @@ impl<N, E> From<String> for InterpolatedText<N, E> {
// This one is needed when parsing, because we need to own the Expr
pub enum OwnedInterpolatedTextContents<'a, Note, Embed> {
Text(&'a str),
- Expr(Box<Expr<Note, Embed>>),
+ Expr(Rc<Expr<Note, Embed>>),
}
// This one is needed everywhere else, because we don't want Clone traits bounds
@@ -231,7 +231,7 @@ impl<'a, N: Clone + 'a, E: Clone + 'a>
impl<N, E> InterpolatedText<N, E> {
pub fn map<N2, E2, F>(&self, mut f: F) -> InterpolatedText<N2, E2>
where
- F: FnMut(&Box<Expr<N, E>>) -> Box<Expr<N2, E2>>,
+ F: FnMut(&Rc<Expr<N, E>>) -> Rc<Expr<N2, E2>>,
{
InterpolatedText {
head: self.head.clone(),
@@ -299,33 +299,33 @@ pub enum Expr<Note, Embed> {
/// `Var (V x n) ~ x@n`
Var(V),
/// `Lam x A b ~ λ(x : A) -> b`
- Lam(Label, Box<Expr<Note, Embed>>, Box<Expr<Note, Embed>>),
+ Lam(Label, Rc<Expr<Note, Embed>>, Rc<Expr<Note, Embed>>),
/// `Pi "_" A B ~ A -> B`
/// `Pi x A B ~ ∀(x : A) -> B`
- Pi(Label, Box<Expr<Note, Embed>>, Box<Expr<Note, Embed>>),
+ Pi(Label, Rc<Expr<Note, Embed>>, Rc<Expr<Note, Embed>>),
/// `App f A ~ f A`
- App(Box<Expr<Note, Embed>>, Vec<Box<Expr<Note, Embed>>>),
+ App(Rc<Expr<Note, Embed>>, Vec<Rc<Expr<Note, Embed>>>),
/// `Let x Nothing r e ~ let x = r in e`
/// `Let x (Just t) r e ~ let x : t = r in e`
Let(
Label,
- Option<Box<Expr<Note, Embed>>>,
- Box<Expr<Note, Embed>>,
- Box<Expr<Note, Embed>>,
+ Option<Rc<Expr<Note, Embed>>>,
+ Rc<Expr<Note, Embed>>,
+ Rc<Expr<Note, Embed>>,
),
/// `Annot x t ~ x : t`
- Annot(Box<Expr<Note, Embed>>, Box<Expr<Note, Embed>>),
+ Annot(Rc<Expr<Note, Embed>>, Rc<Expr<Note, Embed>>),
/// Built-in values
Builtin(Builtin),
// Binary operations
- BinOp(BinOp, Box<Expr<Note, Embed>>, Box<Expr<Note, Embed>>),
+ BinOp(BinOp, Rc<Expr<Note, Embed>>, Rc<Expr<Note, Embed>>),
/// `BoolLit b ~ b`
BoolLit(bool),
/// `BoolIf x y z ~ if x then y else z`
BoolIf(
- Box<Expr<Note, Embed>>,
- Box<Expr<Note, Embed>>,
- Box<Expr<Note, Embed>>,
+ Rc<Expr<Note, Embed>>,
+ Rc<Expr<Note, Embed>>,
+ Rc<Expr<Note, Embed>>,
),
/// `NaturalLit n ~ +n`
NaturalLit(Natural),
@@ -336,35 +336,35 @@ pub enum Expr<Note, Embed> {
/// `TextLit t ~ t`
TextLit(InterpolatedText<Note, Embed>),
/// `ListLit t [x, y, z] ~ [x, y, z] : List t`
- ListLit(Option<Box<Expr<Note, Embed>>>, Vec<Box<Expr<Note, Embed>>>),
+ ListLit(Option<Rc<Expr<Note, Embed>>>, Vec<Rc<Expr<Note, Embed>>>),
/// `OptionalLit t [e] ~ [e] : Optional t`
/// `OptionalLit t [] ~ [] : Optional t`
OptionalLit(
- Option<Box<Expr<Note, Embed>>>,
- Option<Box<Expr<Note, Embed>>>,
+ Option<Rc<Expr<Note, Embed>>>,
+ Option<Rc<Expr<Note, Embed>>>,
),
/// `Record [(k1, t1), (k2, t2)] ~ { k1 : t1, k2 : t1 }`
- Record(BTreeMap<Label, Box<Expr<Note, Embed>>>),
+ Record(BTreeMap<Label, Rc<Expr<Note, Embed>>>),
/// `RecordLit [(k1, v1), (k2, v2)] ~ { k1 = v1, k2 = v2 }`
- RecordLit(BTreeMap<Label, Box<Expr<Note, Embed>>>),
+ RecordLit(BTreeMap<Label, Rc<Expr<Note, Embed>>>),
/// `Union [(k1, t1), (k2, t2)] ~ < k1 : t1, k2 : t2 >`
- Union(BTreeMap<Label, Box<Expr<Note, Embed>>>),
+ Union(BTreeMap<Label, Rc<Expr<Note, Embed>>>),
/// `UnionLit (k1, v1) [(k2, t2), (k3, t3)] ~ < k1 = t1, k2 : t2, k3 : t3 >`
UnionLit(
Label,
- Box<Expr<Note, Embed>>,
- BTreeMap<Label, Box<Expr<Note, Embed>>>,
+ Rc<Expr<Note, Embed>>,
+ BTreeMap<Label, Rc<Expr<Note, Embed>>>,
),
/// `Merge x y t ~ merge x y : t`
Merge(
- Box<Expr<Note, Embed>>,
- Box<Expr<Note, Embed>>,
- Option<Box<Expr<Note, Embed>>>,
+ Rc<Expr<Note, Embed>>,
+ Rc<Expr<Note, Embed>>,
+ Option<Rc<Expr<Note, Embed>>>,
),
/// `Field e x ~ e.x`
- Field(Box<Expr<Note, Embed>>, Label),
+ Field(Rc<Expr<Note, Embed>>, Label),
/// Annotation on the AST. Unused for now but could hold e.g. file location information
- Note(Note, Box<Expr<Note, Embed>>),
+ Note(Note, Rc<Expr<Note, Embed>>),
/// Embeds an import or the result of resolving the import
Embed(Embed),
}
@@ -848,14 +848,13 @@ where
Expr::Pi(var.into(), bx(ty.into()), bx(value.into()))
}
-pub fn app<S, A, Ef, Ex>(f: Ef, x: Vec<Box<Ex>>) -> Expr<S, A>
+pub fn app<S, A, Ef>(f: Ef, x: Vec<Rc<Expr<S, A>>>) -> Expr<S, A>
where
Ef: Into<Expr<S, A>>,
- Ex: Into<Expr<S, A>>,
{
Expr::App(
bx(f.into()),
- x.into_iter().map(|x| bx((*x).into())).collect(),
+ x,
)
}
@@ -874,8 +873,11 @@ impl Display for X {
}
}
-pub fn bx<T>(x: T) -> Box<T> {
- Box::new(x)
+pub fn bx<T>(x: T) -> Rc<T> {
+ Rc::new(x)
+}
+pub fn rc<T>(x: T) -> Rc<T> {
+ Rc::new(x)
}
fn add_ui(u: usize, i: isize) -> usize {
@@ -904,8 +906,8 @@ where
F4: Fn(&Label) -> Label,
{
use crate::Expr::*;
- let bxmap = |x: &Expr<S, A>| -> Box<Expr<T, B>> { bx(map(x)) };
- let bxbxmap = |x: &Box<Expr<S, A>>| -> Box<Expr<T, B>> { bx(map(&**x)) };
+ let bxmap = |x: &Expr<S, A>| -> Rc<Expr<T, B>> { bx(map(x)) };
+ let bxbxmap = |x: &Rc<Expr<S, A>>| -> Rc<Expr<T, B>> { bx(map(&**x)) };
let opt = |x| map_opt_box(x, &map);
match *e {
Const(k) => Const(k),
@@ -980,7 +982,7 @@ where
it.into_iter().map(|(k, v)| (g(k), f(v))).collect()
}
-pub fn map_opt_box<T, U, F>(x: &Option<Box<T>>, f: F) -> Option<Box<U>>
+pub fn map_opt_box<T, U, F>(x: &Option<Rc<T>>, f: F) -> Option<Rc<U>>
where
F: FnOnce(&T) -> U,
{
@@ -1153,7 +1155,7 @@ fn shift_op2<S, T, A, F>(
b: &Expr<S, A>,
) -> Expr<T, A>
where
- F: FnOnce(Box<Expr<T, A>>, Box<Expr<T, A>>) -> Expr<T, A>,
+ F: FnOnce(Rc<Expr<T, A>>, Rc<Expr<T, A>>) -> Expr<T, A>,
A: Clone,
{
map_op2(f, |x| bx(shift(d, v, x)), a, b)
@@ -1258,7 +1260,7 @@ fn subst_op2<S, T, A, F>(
b: &Expr<T, A>,
) -> Expr<S, A>
where
- F: FnOnce(Box<Expr<S, A>>, Box<Expr<S, A>>) -> Expr<S, A>,
+ F: FnOnce(Rc<Expr<S, A>>, Rc<Expr<S, A>>) -> Expr<S, A>,
S: Clone,
A: Clone,
{
diff --git a/dhall_core/src/parser.rs b/dhall_core/src/parser.rs
index b2955fb..682e081 100644
--- a/dhall_core/src/parser.rs
+++ b/dhall_core/src/parser.rs
@@ -2,6 +2,7 @@ use pest::iterators::Pair;
use pest::Parser;
use std::collections::BTreeMap;
use std::path::PathBuf;
+use std::rc::Rc;
use dhall_parser::{DhallParser, Rule};
@@ -16,7 +17,7 @@ use crate::core::*;
pub type ParsedExpr = Expr<X, Import>;
pub type ParsedText = InterpolatedText<X, Import>;
pub type ParsedTextContents<'a> = OwnedInterpolatedTextContents<'a, X, Import>;
-pub type BoxExpr = Box<ParsedExpr>;
+pub type RcExpr = Rc<ParsedExpr>;
pub type ParseError = pest::error::Error<Rule>;
@@ -455,7 +456,7 @@ rule!(escaped_quote_pair<&'a str>;
rule!(escaped_interpolation<&'a str>;
children!() => "${"
);
-rule!(interpolation<BoxExpr>;
+rule!(interpolation<RcExpr>;
children!(e: expression) => e
);
@@ -556,7 +557,7 @@ rule!(import_hashed_raw<(ImportLocation, Option<()>)>;
}
);
-rule!(import_raw<BoxExpr>;
+rule!(import_raw<RcExpr>;
// TODO: handle "as Text"
children!(import: import_hashed_raw) => {
let (location, hash) = import;
@@ -568,7 +569,7 @@ rule!(import_raw<BoxExpr>;
}
);
-rule_group!(expression<BoxExpr>;
+rule_group!(expression<RcExpr>;
identifier_raw,
lambda_expression,
ifthenelse_expression,
@@ -605,47 +606,47 @@ rule_group!(expression<BoxExpr>;
final_expression
);
-rule!(lambda_expression<BoxExpr>;
+rule!(lambda_expression<RcExpr>;
children!(l: label, typ: expression, body: expression) => {
bx(Expr::Lam(l, typ, body))
}
);
-rule!(ifthenelse_expression<BoxExpr>;
+rule!(ifthenelse_expression<RcExpr>;
children!(cond: expression, left: expression, right: expression) => {
bx(Expr::BoolIf(cond, left, right))
}
);
-rule!(let_expression<BoxExpr>;
+rule!(let_expression<RcExpr>;
children!(bindings*: let_binding, final_expr: expression) => {
bindings.fold(final_expr, |acc, x| bx(Expr::Let(x.0, x.1, x.2, acc)))
}
);
-rule!(let_binding<(Label, Option<BoxExpr>, BoxExpr)>;
+rule!(let_binding<(Label, Option<RcExpr>, RcExpr)>;
children!(name: label, annot?: expression, expr: expression) => (name, annot, expr)
);
-rule!(forall_expression<BoxExpr>;
+rule!(forall_expression<RcExpr>;
children!(l: label, typ: expression, body: expression) => {
bx(Expr::Pi(l, typ, body))
}
);
-rule!(arrow_expression<BoxExpr>;
+rule!(arrow_expression<RcExpr>;
children!(typ: expression, body: expression) => {
bx(Expr::Pi("_".into(), typ, body))
}
);
-rule!(merge_expression<BoxExpr>;
+rule!(merge_expression<RcExpr>;
children!(x: expression, y: expression, z?: expression) => {
bx(Expr::Merge(x, y, z))
}
);
-rule!(empty_collection<BoxExpr>;
+rule!(empty_collection<RcExpr>;
children!(x: str, y: expression) => {
match x {
"Optional" => bx(Expr::OptionalLit(Some(y), None)),
@@ -655,7 +656,7 @@ rule!(empty_collection<BoxExpr>;
}
);
-rule!(non_empty_optional<BoxExpr>;
+rule!(non_empty_optional<RcExpr>;
children!(x: expression, _y: str, z: expression) => {
bx(Expr::OptionalLit(Some(z), Some(x)))
}
@@ -686,7 +687,7 @@ fn can_be_shortcutted(rule: Rule) -> bool {
macro_rules! binop {
($rule:ident, $op:ident) => {
- rule!($rule<BoxExpr>;
+ rule!($rule<RcExpr>;
raw_pair!(pair) => {
// This all could be a trivial fold, but to avoid stack explosion
// we try to cut down on the recursion level here, by consuming
@@ -737,14 +738,14 @@ binop!(times_expression, NaturalTimes);
binop!(equal_expression, BoolEQ);
binop!(not_equal_expression, BoolNE);
-rule!(annotated_expression<BoxExpr>;
+rule!(annotated_expression<RcExpr>;
children!(e: expression, annot: expression) => {
bx(Expr::Annot(e, annot))
},
children!(e: expression) => e,
);
-rule!(application_expression<BoxExpr>;
+rule!(application_expression<RcExpr>;
children!(first: expression, rest*: expression) => {
let rest: Vec<_> = rest.collect();
if rest.is_empty() {
@@ -755,13 +756,13 @@ rule!(application_expression<BoxExpr>;
}
);
-rule!(selector_expression_raw<BoxExpr>;
+rule!(selector_expression_raw<RcExpr>;
children!(first: expression, rest*: label) => {
rest.fold(first, |acc, e| bx(Expr::Field(acc, e)))
}
);
-rule!(literal_expression_raw<BoxExpr>;
+rule!(literal_expression_raw<RcExpr>;
children!(n: double_literal_raw) => bx(Expr::DoubleLit(n)),
children!(n: minus_infinity_literal) => bx(Expr::DoubleLit(std::f64::NEG_INFINITY)),
children!(n: plus_infinity_literal) => bx(Expr::DoubleLit(std::f64::INFINITY)),
@@ -773,7 +774,7 @@ rule!(literal_expression_raw<BoxExpr>;
children!(e: expression) => e,
);
-rule!(identifier_raw<BoxExpr>;
+rule!(identifier_raw<RcExpr>;
children!(name: str, idx?: natural_literal_raw) => {
match Builtin::parse(name) {
Some(b) => bx(Expr::Builtin(b)),
@@ -788,15 +789,15 @@ rule!(identifier_raw<BoxExpr>;
}
);
-rule!(empty_record_literal<BoxExpr>;
+rule!(empty_record_literal<RcExpr>;
children!() => bx(Expr::RecordLit(BTreeMap::new()))
);
-rule!(empty_record_type<BoxExpr>;
+rule!(empty_record_type<RcExpr>;
children!() => bx(Expr::Record(BTreeMap::new()))
);
-rule!(non_empty_record_type_or_literal<BoxExpr>;
+rule!(non_empty_record_type_or_literal<RcExpr>;
children!(first_label: label, rest: non_empty_record_type) => {
let (first_expr, mut map) = rest;
map.insert(first_label, first_expr);
@@ -809,25 +810,25 @@ rule!(non_empty_record_type_or_literal<BoxExpr>;
},
);
-rule!(non_empty_record_type<(BoxExpr, BTreeMap<Label, BoxExpr>)>;
+rule!(non_empty_record_type<(RcExpr, BTreeMap<Label, RcExpr>)>;
self!(x: partial_record_entries) => x
);
-named!(partial_record_entries<(BoxExpr, BTreeMap<Label, BoxExpr>)>;
+named!(partial_record_entries<(RcExpr, BTreeMap<Label, RcExpr>)>;
children!(expr: expression, entries*: record_entry) => {
(expr, entries.collect())
}
);
-named!(record_entry<(Label, BoxExpr)>;
+named!(record_entry<(Label, RcExpr)>;
children!(name: label, expr: expression) => (name, expr)
);
-rule!(non_empty_record_literal<(BoxExpr, BTreeMap<Label, BoxExpr>)>;
+rule!(non_empty_record_literal<(RcExpr, BTreeMap<Label, RcExpr>)>;
self!(x: partial_record_entries) => x
);
-rule!(union_type_or_literal<BoxExpr>;
+rule!(union_type_or_literal<RcExpr>;
children!(_e: empty_union_type) => {
bx(Expr::Union(BTreeMap::new()))
},
@@ -842,7 +843,7 @@ rule!(union_type_or_literal<BoxExpr>;
rule!(empty_union_type<()>; children!() => ());
rule!(non_empty_union_type_or_literal
- <(Option<(Label, BoxExpr)>, BTreeMap<Label, BoxExpr>)>;
+ <(Option<(Label, RcExpr)>, BTreeMap<Label, RcExpr>)>;
children!(l: label, e: expression, entries: union_type_entries) => {
(Some((l, e)), entries)
},
@@ -858,27 +859,27 @@ rule!(non_empty_union_type_or_literal
},
);
-rule!(union_type_entries<BTreeMap<Label, BoxExpr>>;
+rule!(union_type_entries<BTreeMap<Label, RcExpr>>;
children!(entries*: union_type_entry) => {
entries.collect()
}
);
-rule!(union_type_entry<(Label, BoxExpr)>;
+rule!(union_type_entry<(Label, RcExpr)>;
children!(name: label, expr: expression) => (name, expr)
);
-rule!(non_empty_list_literal_raw<BoxExpr>;
+rule!(non_empty_list_literal_raw<RcExpr>;
children!(items*: expression) => {
bx(Expr::ListLit(None, items.collect()))
}
);
-rule!(final_expression<BoxExpr>;
+rule!(final_expression<RcExpr>;
children!(e: expression, _eoi: EOI) => e
);
-pub fn parse_expr(s: &str) -> ParseResult<BoxExpr> {
+pub fn parse_expr(s: &str) -> ParseResult<RcExpr> {
let pairs = DhallParser::parse(Rule::final_expression, s)?;
// Match the only item in the pairs iterator
// println!("{}", debug_pair(pairs.clone().next().unwrap()));
diff --git a/dhall_generator/src/lib.rs b/dhall_generator/src/lib.rs
index 1a74f4f..26be4c4 100644
--- a/dhall_generator/src/lib.rs
+++ b/dhall_generator/src/lib.rs
@@ -4,11 +4,12 @@ use dhall_core::*;
use proc_macro2::TokenStream;
use quote::quote;
use std::collections::BTreeMap;
+use std::rc::Rc;
#[proc_macro]
pub fn dhall_expr(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input_str = input.to_string();
- let expr: Box<Expr<X, Import>> = parser::parse_expr(&input_str).unwrap();
+ let expr: Rc<Expr<X, Import>> = parser::parse_expr(&input_str).unwrap();
let no_import =
|_: &Import| -> X { panic!("Don't use import in dhall!()") };
let expr = expr.map_embed(&no_import);
@@ -17,7 +18,7 @@ pub fn dhall_expr(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
}
// Returns an expression of type Expr<_, _>. Expects input variables
-// to be of type Box<Expr<_, _>> (future-proof for structural sharing).
+// to be of type Rc<Expr<_, _>>.
fn dhall_to_tokenstream(
expr: &Expr<X, X>,
ctx: &Context<Label, ()>,
@@ -77,7 +78,7 @@ fn dhall_to_tokenstream(
}
}
-// Returns an expression of type Box<Expr<_, _>>
+// Returns an expression of type Rc<Expr<_, _>>
fn dhall_to_tokenstream_bx(
expr: &Expr<X, X>,
ctx: &Context<Label, ()>,
@@ -97,7 +98,7 @@ fn dhall_to_tokenstream_bx(
// TODO: insert appropriate shifts ?
let v: TokenStream = s.parse().unwrap();
quote! { {
- let x: Box<Expr<_, _>> = #v.clone();
+ let x: Rc<Expr<_, _>> = #v.clone();
x
} }
}
@@ -125,7 +126,7 @@ fn label_to_tokenstream(l: &Label) -> TokenStream {
}
fn map_to_tokenstream(
- m: &BTreeMap<Label, Box<Expr<X, X>>>,
+ m: &BTreeMap<Label, Rc<Expr<X, X>>>,
ctx: &Context<Label, ()>,
) -> TokenStream {
let (keys, values): (Vec<TokenStream>, Vec<TokenStream>) = m
@@ -142,7 +143,7 @@ fn map_to_tokenstream(
}
fn option_to_tokenstream(
- e: &Option<Box<Expr<X, X>>>,
+ e: &Option<Rc<Expr<X, X>>>,
ctx: &Context<Label, ()>,
) -> TokenStream {
let e = e.as_ref().map(|x| dhall_to_tokenstream_bx(x, ctx));
@@ -153,7 +154,7 @@ fn option_to_tokenstream(
}
fn vec_to_tokenstream(
- e: &Vec<Box<Expr<X, X>>>,
+ e: &Vec<Rc<Expr<X, X>>>,
ctx: &Context<Label, ()>,
) -> TokenStream {
let e = e.iter().map(|x| dhall_to_tokenstream_bx(&**x, ctx));