Skip to content

Commit ecf72b2

Browse files
committed
Avoid item names when freshening names
1 parent 43793c0 commit ecf72b2

File tree

3 files changed

+50
-2
lines changed

3 files changed

+50
-2
lines changed

fathom/src/surface/distillation.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ impl<'interner, 'arena, 'env> Context<'interner, 'arena, 'env> {
4646
}
4747
}
4848

49+
fn is_bound(&self, name: StringId) -> bool {
50+
(self.local_names.iter()).any(|local_name| *local_name == Some(name))
51+
|| self.item_names.iter().any(|item_name| *item_name == name)
52+
}
53+
4954
fn local_len(&mut self) -> EnvLen {
5055
self.local_names.len()
5156
}
@@ -85,12 +90,12 @@ impl<'interner, 'arena, 'env> Context<'interner, 'arena, 'env> {
8590
}
8691
}
8792

88-
/// Generate a fresh name that does not appear in `self.local_names`
93+
/// Generate a fresh name that is not currently bound in the context
8994
fn gen_fresh_name(&mut self) -> StringId {
9095
let mut counter = 0;
9196
loop {
9297
let name = self.interner.borrow_mut().get_alphabetic_name(counter);
93-
match self.local_names.iter().any(|symbol| *symbol == Some(name)) {
98+
match self.is_bound(name) {
9499
true => counter += 1,
95100
false => return name,
96101
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//~ mode = "module"
2+
3+
// An item to throw off fresh name generation
4+
def a = {};
5+
6+
def const1 : fun (@A : _) (@B : _) -> A -> B -> A =
7+
// The binders in the distilled term should use fresh names (starting with
8+
// `a`, `b`, ...), avoiding the binding from the let expression and the
9+
// top-level item
10+
fun @_ @_ x y =>
11+
// The following let bindings will force the type parameters to be
12+
// referenced in the type annotation of the let expressions:
13+
let x1 = x;
14+
let y1 = y;
15+
16+
x;
17+
18+
def const2 : fun (@A : _) (@B : _) -> A -> B -> A =
19+
// A let expression to throw off fresh name generation
20+
let b = {};
21+
22+
// The binders in the distilled term should use fresh names (starting with
23+
// `a`, `b`, ...), avoiding the binding from the let expression and the
24+
// top-level item
25+
fun @_ @_ x y =>
26+
// The following let bindings will force the type parameters to be
27+
// referenced in the type annotation of the let expressions:
28+
let x1 = x;
29+
let y1 = y;
30+
31+
x;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
stdout = '''
2+
def a : () : Type = ();
3+
def const1 : fun (@A : Type) (@B : Type) -> A -> B -> A =
4+
fun @b @c x y => let x1 : b = x;
5+
let y1 : c = y;
6+
x;
7+
def const2 : fun (@A : Type) (@B : Type) -> A -> B -> A = let b : () = ();
8+
fun @c @d x y => let x1 : c = x;
9+
let y1 : d = y;
10+
x;
11+
'''
12+
stderr = ''

0 commit comments

Comments
 (0)