Skip to content

Commit a2d6790

Browse files
authored
Merge pull request #496 from brendanzab/distillation-cleanups
Make it easier to distill/pretty print values
2 parents 505176a + 817cc41 commit a2d6790

File tree

4 files changed

+59
-120
lines changed

4 files changed

+59
-120
lines changed

fathom/src/surface.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,6 @@ fn format_expected(expected: &[impl std::fmt::Display]) -> Option<String> {
516516
#[cfg(test)]
517517
mod tests {
518518
use super::*;
519-
use crate::source::ByteRange;
520519

521520
#[test]
522521
fn no_drop() {

fathom/src/surface/distillation.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ pub struct Context<'arena, 'env> {
4141
/// Item name environment.
4242
item_names: &'env UniqueEnv<Symbol>,
4343
/// Local name environment.
44-
local_names: &'env mut UniqueEnv<Option<Symbol>>,
44+
local_names: UniqueEnv<Option<Symbol>>,
4545
/// Metavariable sources.
4646
meta_sources: &'env UniqueEnv<MetaSource>,
4747
}
@@ -51,7 +51,7 @@ impl<'arena, 'env> Context<'arena, 'env> {
5151
pub fn new(
5252
scope: &'arena Scope<'arena>,
5353
item_names: &'env UniqueEnv<Symbol>,
54-
local_names: &'env mut UniqueEnv<Option<Symbol>>,
54+
local_names: UniqueEnv<Option<Symbol>>,
5555
meta_sources: &'env UniqueEnv<MetaSource>,
5656
) -> Context<'arena, 'env> {
5757
Context {

fathom/src/surface/elaboration.rs

Lines changed: 30 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ use std::sync::Arc;
2525

2626
use scoped_arena::Scope;
2727

28-
use super::ExprField;
2928
use crate::alloc::SliceVec;
3029
use crate::core::semantics::{self, ArcValue, Head, Telescope, Value};
3130
use crate::core::{self, prim, Const, Plicity, Prim, UIntStyle};
@@ -34,7 +33,7 @@ use crate::files::FileId;
3433
use crate::source::{BytePos, ByteRange, FileRange, Span, Spanned};
3534
use crate::surface::elaboration::reporting::Message;
3635
use crate::surface::{
37-
distillation, pretty, BinOp, FormatField, Item, Module, Param, Pattern, Term,
36+
distillation, pretty, BinOp, ExprField, FormatField, Item, Module, Param, Pattern, Term,
3837
};
3938
use crate::symbol::Symbol;
4039

@@ -375,19 +374,7 @@ impl<'arena> Context<'arena> {
375374
(None, source) => on_message(Message::UnsolvedMetaVar { source }),
376375
// Yield messages of solved named holes
377376
(Some(expr), MetaSource::HoleExpr(range, name)) => {
378-
let term = self.quote_env().quote(self.scope, expr);
379-
let surface_term = distillation::Context::new(
380-
self.scope,
381-
&self.item_env.names,
382-
&mut self.local_env.names,
383-
&self.meta_env.sources,
384-
)
385-
.check(&term);
386-
387-
let pretty_context = pretty::Context::new(self.scope);
388-
let doc = pretty_context.term(&surface_term).into_doc();
389-
let expr = doc.pretty(usize::MAX).to_string();
390-
377+
let expr = self.pretty_value(expr);
391378
on_message(Message::HoleSolution { range, name, expr });
392379
}
393380
// Ignore solutions of anything else
@@ -420,24 +407,22 @@ impl<'arena> Context<'arena> {
420407
}
421408

422409
pub fn distillation_context<'out_arena>(
423-
&mut self,
410+
&self,
424411
scope: &'out_arena Scope<'out_arena>,
425412
) -> distillation::Context<'out_arena, '_> {
426413
distillation::Context::new(
427414
scope,
428415
&self.item_env.names,
429-
&mut self.local_env.names,
416+
self.local_env.names.clone(),
430417
&self.meta_env.sources,
431418
)
432419
}
433420

434-
fn pretty_print_value(&mut self, value: &ArcValue<'_>) -> String {
435-
let scope = self.scope;
436-
437-
let term = self.quote_env().unfolding_metas().quote(scope, value);
438-
let surface_term = self.distillation_context(scope).check(&term);
421+
fn pretty_value(&self, value: &ArcValue<'_>) -> String {
422+
let term = self.quote_env().unfolding_metas().quote(self.scope, value);
423+
let surface_term = self.distillation_context(self.scope).check(&term);
439424

440-
pretty::Context::new(scope)
425+
pretty::Context::new(self.scope)
441426
.term(&surface_term)
442427
.pretty(usize::MAX)
443428
.to_string()
@@ -625,12 +610,10 @@ impl<'arena> Context<'arena> {
625610
}
626611
};
627612

628-
let from = self.pretty_print_value(&from);
629-
let to = self.pretty_print_value(&to);
630613
self.push_message(Message::FailedToUnify {
631614
range,
632-
found: from,
633-
expected: to,
615+
found: self.pretty_value(&from),
616+
expected: self.pretty_value(&to),
634617
error,
635618
});
636619
core::Term::Prim(span, Prim::ReportedError)
@@ -757,10 +740,9 @@ impl<'arena> Context<'arena> {
757740
// Some((Prim::Array64Type, [len, _])) => todo!(),
758741
Some((Prim::ReportedError, _)) => None,
759742
_ => {
760-
let expected_type = self.pretty_print_value(expected_type);
761743
self.push_message(Message::StringLiteralNotSupported {
762744
range: file_range,
763-
expected_type,
745+
expected_type: self.pretty_value(expected_type),
764746
});
765747
None
766748
}
@@ -785,10 +767,9 @@ impl<'arena> Context<'arena> {
785767
Some((Prim::F64Type, [])) => self.parse_number(*range, *lit, Const::F64),
786768
Some((Prim::ReportedError, _)) => None,
787769
_ => {
788-
let expected_type = self.pretty_print_value(expected_type);
789770
self.push_message(Message::NumericLiteralNotSupported {
790771
range: file_range,
791-
expected_type,
772+
expected_type: self.pretty_value(expected_type),
792773
});
793774
None
794775
}
@@ -875,12 +856,10 @@ impl<'arena> Context<'arena> {
875856
match self.unification_context().unify(&r#type, expected_type) {
876857
Ok(()) => self.check_pattern(pattern, &r#type),
877858
Err(error) => {
878-
let lhs = self.pretty_print_value(&r#type);
879-
let rhs = self.pretty_print_value(expected_type);
880859
self.push_message(Message::FailedToUnify {
881860
range: file_range,
882-
found: lhs,
883-
expected: rhs,
861+
found: self.pretty_value(&r#type),
862+
expected: self.pretty_value(expected_type),
884863
error,
885864
});
886865
CheckedPattern::ReportedError(file_range)
@@ -1178,10 +1157,9 @@ impl<'arena> Context<'arena> {
11781157
return core::Term::Prim(file_range.into(), Prim::ReportedError)
11791158
}
11801159
_ => {
1181-
let expected_type = self.pretty_print_value(&expected_type);
11821160
self.push_message(Message::ArrayLiteralNotSupported {
11831161
range: file_range,
1184-
expected_type,
1162+
expected_type: self.pretty_value(&expected_type),
11851163
});
11861164
return core::Term::Prim(file_range.into(), Prim::ReportedError);
11871165
}
@@ -1213,11 +1191,10 @@ impl<'arena> Context<'arena> {
12131191
self.check(elem_expr, elem_type);
12141192
}
12151193

1216-
let expected_len = self.pretty_print_value(len_value.unwrap());
12171194
self.push_message(Message::MismatchedArrayLength {
12181195
range: file_range,
12191196
found_len: elem_exprs.len(),
1220-
expected_len,
1197+
expected_len: self.pretty_value(len_value.unwrap()),
12211198
});
12221199

12231200
core::Term::Prim(file_range.into(), Prim::ReportedError)
@@ -1236,10 +1213,9 @@ impl<'arena> Context<'arena> {
12361213
// Some((Prim::Array64Type, [len, _])) => todo!(),
12371214
Some((Prim::ReportedError, _)) => None,
12381215
_ => {
1239-
let expected_type = self.pretty_print_value(&expected_type);
12401216
self.push_message(Message::StringLiteralNotSupported {
12411217
range: file_range,
1242-
expected_type,
1218+
expected_type: self.pretty_value(&expected_type),
12431219
});
12441220
None
12451221
}
@@ -1264,10 +1240,9 @@ impl<'arena> Context<'arena> {
12641240
Some((Prim::F64Type, [])) => self.parse_number(*range, *lit, Const::F64),
12651241
Some((Prim::ReportedError, _)) => None,
12661242
_ => {
1267-
let expected_type = self.pretty_print_value(&expected_type);
12681243
self.push_message(Message::NumericLiteralNotSupported {
12691244
range: file_range,
1270-
expected_type,
1245+
expected_type: self.pretty_value(&expected_type),
12711246
});
12721247
return core::Term::Prim(file_range.into(), Prim::ReportedError);
12731248
}
@@ -1354,20 +1329,16 @@ impl<'arena> Context<'arena> {
13541329
return (core::Term::Prim(file_range.into(), prim), r#type.clone());
13551330
}
13561331

1357-
let candidates = self
1358-
.local_env
1359-
.names
1360-
.iter()
1361-
.flatten()
1362-
.copied()
1363-
.chain(self.item_env.names.iter().copied());
1364-
let suggestion = suggest_name(*name, candidates);
1365-
13661332
self.push_message(Message::UnboundName {
13671333
range: file_range,
13681334
name: *name,
1369-
suggestion,
1335+
suggested_name: {
1336+
let item_names = self.item_env.names.iter().copied();
1337+
let local_names = self.local_env.names.iter().flatten().copied();
1338+
suggest_name(*name, item_names.chain(local_names))
1339+
},
13701340
});
1341+
13711342
self.synth_reported_error(*range)
13721343
}
13731344
Term::Hole(_, name) => {
@@ -1521,11 +1492,10 @@ impl<'arena> Context<'arena> {
15211492
if arg.plicity == *plicity {
15221493
(param_type, body_type)
15231494
} else {
1524-
let head_type = self.pretty_print_value(&head_type);
15251495
self.messages.push(Message::PlicityArgumentMismatch {
15261496
head_range: self.file_range(head_range),
15271497
head_plicity: Plicity::Explicit,
1528-
head_type,
1498+
head_type: self.pretty_value(&head_type),
15291499
arg_range: self.file_range(arg.term.range()),
15301500
arg_plicity: arg.plicity,
15311501
});
@@ -1542,10 +1512,9 @@ impl<'arena> Context<'arena> {
15421512
_ => {
15431513
// NOTE: We could try to infer that this is a function type,
15441514
// but this takes more work to prevent cascading type errors
1545-
let head_type = self.pretty_print_value(&head_type);
15461515
self.push_message(Message::UnexpectedArgument {
15471516
head_range: self.file_range(head_range),
1548-
head_type,
1517+
head_type: self.pretty_value(&head_type),
15491518
arg_range: self.file_range(arg.term.range()),
15501519
});
15511520
return self.synth_reported_error(*range);
@@ -1681,15 +1650,12 @@ impl<'arena> Context<'arena> {
16811650
_ => {}
16821651
}
16831652

1684-
let head_type = self.pretty_print_value(&head_type);
1685-
let suggestion =
1686-
suggest_name(*proj_label, labels.iter().map(|(_, label)| *label));
16871653
self.push_message(Message::UnknownField {
16881654
head_range: self.file_range(head_range),
1689-
head_type,
1655+
head_type: self.pretty_value(&head_type),
16901656
label_range: self.file_range(*label_range),
16911657
label: *proj_label,
1692-
suggestion,
1658+
suggested_label: suggest_name(*proj_label, labels.iter().map(|(_, l)| *l)),
16931659
});
16941660
return self.synth_reported_error(*range);
16951661
}
@@ -2005,15 +1971,13 @@ impl<'arena> Context<'arena> {
20051971
(Gte(_), Some(((S64Type, []), (S64Type, [])))) => (S64Gte, BoolType),
20061972

20071973
_ => {
2008-
let lhs_pretty = self.pretty_print_value(&lhs_type);
2009-
let rhs_pretty = self.pretty_print_value(&rhs_type);
20101974
self.push_message(Message::BinOpMismatchedTypes {
20111975
range: self.file_range(range),
20121976
lhs_range: self.file_range(lhs.range()),
20131977
rhs_range: self.file_range(rhs.range()),
20141978
op: op.map_range(|range| self.file_range(range)),
2015-
lhs: lhs_pretty,
2016-
rhs: rhs_pretty,
1979+
lhs: self.pretty_value(&lhs_type),
1980+
rhs: self.pretty_value(&rhs_type),
20171981
});
20181982
return self.synth_reported_error(range);
20191983
}

0 commit comments

Comments
 (0)