diff options
author | Patrick Hurst <phurst@mit.edu> | 2014-02-15 01:04:31 -0500 |
---|---|---|
committer | Patrick Hurst <phurst@mit.edu> | 2014-02-15 01:04:31 -0500 |
commit | 5fae727e3373c4ee82c3acd409a8052e5fda7f04 (patch) | |
tree | 13ed850e0cf5b41f67376f35e0b2de3ebf299359 | |
parent | 946bb6b8dc7c7e5cfd4021cda1102a7819f6f8ad (diff) | |
parent | 6a907ba38d008761d8b5260bcfd721ead0626e08 (diff) |
Merge in upstream
-rw-r--r-- | src/elaborate.sml | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/src/elaborate.sml b/src/elaborate.sml index 0c8db756..959a6cd1 100644 --- a/src/elaborate.sml +++ b/src/elaborate.sml @@ -4481,9 +4481,28 @@ and elabStr (env, denv) (str, loc) = case #1 (hnormSgn env ran) of L'.SgnError => (strerror, sgnerror, []) | L'.SgnConst sgis => - ((L'.StrApp (str1', str2'), loc), - (L'.SgnConst ((L'.SgiStr (m, n, selfifyAt env {str = str2', sgn = sgn2}), loc) :: sgis), loc), - gs1 @ gs2) + let + (* This code handles a tricky case that led to a very nasty bug. + * An invariant about signatures of elaborated modules is that no + * identifier that could appear directly in a program is defined + * twice. We add "?" in front of identifiers where necessary to + * maintain the invariant, but the code below, to extend a functor + * body with a binding for the functor argument, wasn't written + * with the invariant in mind. Luckily for us, references to + * an identifier later within a signature work by globally + * unique index, so we just need to change the string name in the + * new declaration. *) + val m = + if List.exists (fn (L'.SgiStr (x, _, _), _) => x = m + | _ => false) sgis then + "?" ^ m + else + m + in + ((L'.StrApp (str1', str2'), loc), + (L'.SgnConst ((L'.SgiStr (m, n, selfifyAt env {str = str2', sgn = sgn2}), loc) :: sgis), loc), + gs1 @ gs2) + end | _ => raise Fail "Unable to hnormSgn in functor application") | _ => (strError env (NotFunctor sgn1); (strerror, sgnerror, [])) |