Skip to content

Commit fd53851

Browse files
committed
Switch to an explicitly typed core language
1 parent 9d75e85 commit fd53851

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+690
-500
lines changed

fathom/src/core.rs

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,6 @@ pub enum Term<'arena> {
122122
// - https://lib.rs/crates/smallbitvec
123123
// - https://lib.rs/crates/bit-vec
124124
InsertedMeta(Span, Level, &'arena [LocalInfo]),
125-
/// Annotated expressions.
126-
Ann(Span, &'arena Term<'arena>, &'arena Term<'arena>),
127125
/// Let expressions.
128126
Let(
129127
Span,
@@ -148,7 +146,12 @@ pub enum Term<'arena> {
148146
/// Function literals.
149147
///
150148
/// Also known as: lambda expressions, anonymous functions.
151-
FunLit(Span, Option<StringId>, &'arena Term<'arena>),
149+
FunLit(
150+
Span,
151+
Option<StringId>,
152+
&'arena Term<'arena>,
153+
&'arena Term<'arena>,
154+
),
152155
/// Function applications.
153156
FunApp(Span, &'arena Term<'arena>, &'arena Term<'arena>),
154157

@@ -190,26 +193,25 @@ impl<'arena> Term<'arena> {
190193
/// Get the source span of the term.
191194
pub fn span(&self) -> Span {
192195
match self {
193-
Term::ItemVar(span, _)
194-
| Term::LocalVar(span, _)
195-
| Term::MetaVar(span, _)
196-
| Term::InsertedMeta(span, _, _)
197-
| Term::Ann(span, _, _)
198-
| Term::Let(span, _, _, _, _)
196+
Term::ItemVar(span, ..)
197+
| Term::LocalVar(span, ..)
198+
| Term::MetaVar(span, ..)
199+
| Term::InsertedMeta(span, ..)
200+
| Term::Let(span, ..)
199201
| Term::Universe(span)
200-
| Term::FunType(span, _, _, _)
201-
| Term::FunLit(span, _, _)
202-
| Term::FunApp(span, _, _)
203-
| Term::RecordType(span, _, _)
204-
| Term::RecordLit(span, _, _)
205-
| Term::RecordProj(span, _, _)
206-
| Term::ArrayLit(span, _)
207-
| Term::FormatRecord(span, _, _)
208-
| Term::FormatCond(span, _, _, _)
209-
| Term::FormatOverlap(span, _, _)
210-
| Term::Prim(span, _)
211-
| Term::ConstLit(span, _)
212-
| Term::ConstMatch(span, _, _, _) => *span,
202+
| Term::FunType(span, ..)
203+
| Term::FunLit(span, ..)
204+
| Term::FunApp(span, ..)
205+
| Term::RecordType(span, ..)
206+
| Term::RecordLit(span, ..)
207+
| Term::RecordProj(span, ..)
208+
| Term::ArrayLit(span, ..)
209+
| Term::FormatRecord(span, ..)
210+
| Term::FormatCond(span, ..)
211+
| Term::FormatOverlap(span, ..)
212+
| Term::Prim(span, ..)
213+
| Term::ConstLit(span, ..)
214+
| Term::ConstMatch(span, ..) => *span,
213215
}
214216
}
215217

@@ -224,7 +226,6 @@ impl<'arena> Term<'arena> {
224226
| Term::Prim(_, _)
225227
| Term::ConstLit(_, _) => false,
226228

227-
Term::Ann(_, expr, r#type) => expr.binds_local(var) || r#type.binds_local(var),
228229
Term::Let(_, _, def_type, def_expr, body_expr) => {
229230
def_type.binds_local(var)
230231
|| def_expr.binds_local(var)
@@ -233,7 +234,9 @@ impl<'arena> Term<'arena> {
233234
Term::FunType(_, _, param_type, body_type) => {
234235
param_type.binds_local(var) || body_type.binds_local(var.prev())
235236
}
236-
Term::FunLit(_, _, body_expr) => body_expr.binds_local(var.prev()),
237+
Term::FunLit(_, _, param_type, body_expr) => {
238+
param_type.binds_local(var) || body_expr.binds_local(var.prev())
239+
}
237240
Term::FunApp(_, head_expr, arg_expr) => {
238241
head_expr.binds_local(var) || arg_expr.binds_local(var)
239242
}

fathom/src/core/binary.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -380,12 +380,12 @@ impl<'arena, 'data> Context<'arena, 'data> {
380380
Value::Stuck(Head::LocalVar(_), _)
381381
| Value::Stuck(Head::MetaVar(_), _)
382382
| Value::Universe
383-
| Value::FunType(_, _, _)
384-
| Value::FunLit(_, _)
385-
| Value::RecordType(_, _)
386-
| Value::RecordLit(_, _)
387-
| Value::ArrayLit(_)
388-
| Value::ConstLit(_) => Err(ReadError::InvalidFormat(format.span())),
383+
| Value::FunType(..)
384+
| Value::FunLit(..)
385+
| Value::RecordType(..)
386+
| Value::RecordLit(..)
387+
| Value::ArrayLit(..)
388+
| Value::ConstLit(..) => Err(ReadError::InvalidFormat(format.span())),
389389
}
390390
}
391391

fathom/src/core/semantics.rs

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub enum Value<'arena> {
3030
/// Dependent function types.
3131
FunType(Option<StringId>, ArcValue<'arena>, Closure<'arena>),
3232
/// Function literals.
33-
FunLit(Option<StringId>, Closure<'arena>),
33+
FunLit(Option<StringId>, ArcValue<'arena>, Closure<'arena>),
3434

3535
/// Record types.
3636
RecordType(&'arena [StringId], Telescope<'arena>),
@@ -291,7 +291,6 @@ impl<'arena, 'env> EvalEnv<'arena, 'env> {
291291
let head_expr = self.eval(&Term::MetaVar(*span, *var));
292292
self.apply_local_infos(head_expr, local_infos)
293293
}
294-
Term::Ann(span, expr, _) => Spanned::merge(*span, self.eval(expr)),
295294
Term::Let(span, _, _, def_expr, body_expr) => {
296295
let def_expr = self.eval(def_expr);
297296
self.local_exprs.push(def_expr);
@@ -310,10 +309,11 @@ impl<'arena, 'env> EvalEnv<'arena, 'env> {
310309
Closure::new(self.local_exprs.clone(), body_type),
311310
)),
312311
),
313-
Term::FunLit(span, param_name, body_expr) => Spanned::new(
312+
Term::FunLit(span, param_name, param_type, body_expr) => Spanned::new(
314313
*span,
315314
Arc::new(Value::FunLit(
316315
*param_name,
316+
self.eval(param_type),
317317
Closure::new(self.local_exprs.clone(), body_expr),
318318
)),
319319
),
@@ -498,7 +498,7 @@ impl<'arena, 'env> ElimEnv<'arena, 'env> {
498498
) -> ArcValue<'arena> {
499499
match Arc::make_mut(&mut head_expr) {
500500
// Beta-reduction
501-
Value::FunLit(_, body_expr) => self.apply_closure(body_expr, arg_expr), // FIXME: use span from head/arg exprs?
501+
Value::FunLit(_, _, body_expr) => self.apply_closure(body_expr, arg_expr), // FIXME: use span from head/arg exprs?
502502
// The computation is stuck, preventing further reduction
503503
Value::Stuck(head, spine) => {
504504
spine.push(Elim::FunApp(arg_expr));
@@ -689,9 +689,12 @@ impl<'in_arena, 'env> QuoteEnv<'in_arena, 'env> {
689689
scope.to_scope(self.quote(scope, param_type)),
690690
self.quote_closure(scope, body_type),
691691
),
692-
Value::FunLit(param_name, body_expr) => {
693-
Term::FunLit(span, *param_name, self.quote_closure(scope, body_expr))
694-
}
692+
Value::FunLit(param_name, param_type, body_expr) => Term::FunLit(
693+
span,
694+
*param_name,
695+
scope.to_scope(self.quote(scope, param_type)),
696+
self.quote_closure(scope, body_expr),
697+
),
695698

696699
Value::RecordType(labels, types) => Term::RecordType(
697700
span,
@@ -842,11 +845,6 @@ impl<'arena, 'env> EvalEnv<'arena, 'env> {
842845
None => panic_any(Error::UnboundMetaVar),
843846
}
844847
}
845-
Term::Ann(span, expr, r#type) => Term::Ann(
846-
*span,
847-
scope.to_scope(self.unfold_metas(scope, expr)),
848-
scope.to_scope(self.unfold_metas(scope, r#type)),
849-
),
850848
Term::Let(span, def_name, def_type, def_expr, body_expr) => Term::Let(
851849
*span,
852850
*def_name,
@@ -863,9 +861,10 @@ impl<'arena, 'env> EvalEnv<'arena, 'env> {
863861
scope.to_scope(self.unfold_metas(scope, param_type)),
864862
self.unfold_bound_metas(scope, body_type),
865863
),
866-
Term::FunLit(span, param_name, body_expr) => Term::FunLit(
864+
Term::FunLit(span, param_name, param_type, body_expr) => Term::FunLit(
867865
*span,
868866
*param_name,
867+
scope.to_scope(self.unfold_metas(scope, param_type)),
869868
self.unfold_bound_metas(scope, body_expr),
870869
),
871870

@@ -1095,11 +1094,15 @@ impl<'arena, 'env> ConversionEnv<'arena, 'env> {
10951094
self.is_equal(param_type0, param_type1)
10961095
&& self.is_equal_closures(body_type0, body_type1)
10971096
}
1098-
(Value::FunLit(_, body_expr0), Value::FunLit(_, body_expr1)) => {
1099-
self.is_equal_closures(body_expr0, body_expr1)
1097+
(
1098+
Value::FunLit(_, param_type0, body_expr0),
1099+
Value::FunLit(_, param_type1, body_expr1),
1100+
) => {
1101+
self.is_equal(param_type0, param_type1)
1102+
&& self.is_equal_closures(body_expr0, body_expr1)
11001103
}
1101-
(Value::FunLit(_, body_expr), _) => self.is_equal_fun_lit(body_expr, &value1),
1102-
(_, Value::FunLit(_, body_expr)) => self.is_equal_fun_lit(body_expr, &value0),
1104+
(Value::FunLit(_, _, body_expr), _) => self.is_equal_fun_lit(body_expr, &value1),
1105+
(_, Value::FunLit(_, _, body_expr)) => self.is_equal_fun_lit(body_expr, &value0),
11031106

11041107
(Value::RecordType(labels0, types0), Value::RecordType(labels1, types1)) => {
11051108
labels0 == labels1 && self.is_equal_telescopes(types0, types1)
@@ -1275,7 +1278,7 @@ mod tests {
12751278
Value::Stuck(_, _) => {}
12761279
Value::Universe => {}
12771280
Value::FunType(_, _, _) => {}
1278-
Value::FunLit(_, _) => {}
1281+
Value::FunLit(_, _, _) => {}
12791282
Value::RecordType(_, _) => {}
12801283
Value::RecordLit(_, _) => {}
12811284
Value::ArrayLit(_) => {}

fathom/src/surface/distillation.rs

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -203,10 +203,6 @@ impl<'interner, 'arena, 'env> Context<'interner, 'arena, 'env> {
203203
/// Distill a core term into a surface term, in a 'checkable' context.
204204
pub fn check(&mut self, core_term: &core::Term<'_>) -> Term<'arena, ()> {
205205
match core_term {
206-
core::Term::Ann(_span, expr, _) => {
207-
// Avoid adding extraneous type annotations!
208-
self.check(expr)
209-
}
210206
core::Term::Let(_span, def_name, def_type, def_expr, body_expr) => {
211207
let def_type = self.check(def_type);
212208
let def_expr = self.check(def_expr);
@@ -223,20 +219,24 @@ impl<'interner, 'arena, 'env> Context<'interner, 'arena, 'env> {
223219
self.scope.to_scope(body_expr),
224220
)
225221
}
226-
core::Term::FunLit(_, param_name, mut body_expr) => {
222+
core::Term::FunLit(..) => {
227223
let initial_local_len = self.local_len();
228-
let mut param_names = vec![self.push_local(*param_name)];
229-
while let core::Term::FunLit(_, param_name, next_body_expr) = body_expr {
230-
param_names.push(self.push_local(*param_name));
224+
let mut param_names = Vec::new();
225+
let mut body_expr = core_term;
226+
227+
while let core::Term::FunLit(_, param_name, param_type, next_body_expr) = body_expr
228+
{
229+
param_names.push((self.push_local(*param_name), self.check(param_type)));
231230
body_expr = next_body_expr;
232231
}
233232

234233
let body_expr = self.check(body_expr);
235234
self.truncate_local(initial_local_len);
236235

237-
let patterns = param_names
238-
.into_iter()
239-
.map(|name| (Pattern::Name((), name), None));
236+
let patterns = param_names.into_iter().map(|(name, r#type)| {
237+
let r#type = self.scope.to_scope(r#type) as &_;
238+
(Pattern::Name((), name), Some(r#type))
239+
});
240240

241241
Term::FunLiteral(
242242
(),
@@ -394,12 +394,6 @@ impl<'interner, 'arena, 'env> Context<'interner, 'arena, 'env> {
394394
Term::App((), head_expr, arg_exprs.into())
395395
}
396396
}
397-
core::Term::Ann(_span, expr, r#type) => {
398-
let r#type = self.check(r#type);
399-
let expr = self.check(expr);
400-
401-
Term::Ann((), self.scope.to_scope(expr), self.scope.to_scope(r#type))
402-
}
403397
core::Term::Let(_span, def_name, def_type, def_expr, body_expr) => {
404398
let def_type = self.check(def_type);
405399
let def_expr = self.check(def_expr);
@@ -474,17 +468,19 @@ impl<'interner, 'arena, 'env> Context<'interner, 'arena, 'env> {
474468
let mut param_names = Vec::new();
475469
let mut body_expr = core_term;
476470

477-
while let core::Term::FunLit(_, param_name, next_body_expr) = body_expr {
478-
param_names.push(self.push_local(*param_name));
471+
while let core::Term::FunLit(_, param_name, param_type, next_body_expr) = body_expr
472+
{
473+
param_names.push((self.push_local(*param_name), self.check(param_type)));
479474
body_expr = next_body_expr;
480475
}
481476

482477
let body_expr = self.synth(body_expr);
483478
self.truncate_local(initial_local_len);
484479

485-
let patterns = param_names
486-
.into_iter()
487-
.map(|name| (Pattern::Name((), name), None));
480+
let patterns = param_names.into_iter().map(|(name, r#type)| {
481+
let r#type = self.scope.to_scope(r#type) as &_;
482+
(Pattern::Name((), name), Some(r#type))
483+
});
488484

489485
Term::FunLiteral(
490486
(),

fathom/src/surface/elaboration.rs

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,18 +1239,11 @@ impl<'interner, 'arena> Context<'interner, 'arena> {
12391239

12401240
(expr, r#type)
12411241
}
1242-
Term::Ann(range, expr, r#type) => {
1242+
Term::Ann(_, expr, r#type) => {
12431243
let r#type = self.check(r#type, &self.universe.clone());
12441244
let type_value = self.eval_env().eval(&r#type);
1245-
let expr = self.check(expr, &type_value);
12461245

1247-
let ann_expr = core::Term::Ann(
1248-
range.into(),
1249-
self.scope.to_scope(expr),
1250-
self.scope.to_scope(r#type),
1251-
);
1252-
1253-
(ann_expr, type_value)
1246+
(self.check(expr, &type_value), type_value)
12541247
}
12551248
Term::Let(range, def_pattern, def_type, def_expr, body_expr) => {
12561249
let (def_pattern, def_type_value) = self.synth_ann_pattern(def_pattern, *def_type);
@@ -1589,7 +1582,13 @@ impl<'interner, 'arena> Context<'interner, 'arena> {
15891582
self.check_fun_lit(range, next_patterns, body_expr, &body_type);
15901583
self.local_env.pop();
15911584

1592-
core::Term::FunLit(range.into(), name, self.scope.to_scope(body_expr))
1585+
let param_type = self.quote_env().quote(self.scope, param_type);
1586+
core::Term::FunLit(
1587+
range.into(),
1588+
name,
1589+
self.scope.to_scope(param_type),
1590+
self.scope.to_scope(body_expr),
1591+
)
15931592
}
15941593
// Attempt to elaborate the the body of the function in synthesis
15951594
// mode if we are checking against a metavariable.
@@ -1654,13 +1653,10 @@ impl<'interner, 'arena> Context<'interner, 'arena> {
16541653

16551654
// Construct the function literal and type from the parameters in reverse
16561655
for (range, name, r#type) in params.into_iter().rev() {
1657-
fun_lit = core::Term::FunLit(range.into(), name, self.scope.to_scope(fun_lit));
1658-
fun_type = core::Term::FunType(
1659-
Span::Empty,
1660-
name,
1661-
self.scope.to_scope(r#type),
1662-
self.scope.to_scope(fun_type),
1663-
);
1656+
let r#type = self.scope.to_scope(r#type);
1657+
fun_lit = core::Term::FunLit(range.into(), name, r#type, self.scope.to_scope(fun_lit));
1658+
fun_type =
1659+
core::Term::FunType(Span::Empty, name, r#type, self.scope.to_scope(fun_type));
16641660
}
16651661

16661662
(fun_lit, self.eval_env().eval(&fun_type))

0 commit comments

Comments
 (0)