Skip to content

Commit 8f4c410

Browse files
committed
Suppress erasable warning for props.
1 parent d79ac67 commit 8f4c410

File tree

5 files changed

+42
-7
lines changed

5 files changed

+42
-7
lines changed

src/typechecker/FStarC.TypeChecker.Env.fst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,6 +1056,13 @@ let rec non_informative env t =
10561056
| Tm_meta {tm} -> non_informative env tm
10571057
| _ -> None
10581058

1059+
let rec non_informative_sort t =
1060+
match (U.unrefine t).n with
1061+
| Tm_fvar fv when fv_eq_lid fv Const.prop_lid -> true
1062+
| Tm_arrow {comp=c} -> non_informative_sort (comp_result c)
1063+
| Tm_meta {tm} -> non_informative_sort tm
1064+
| _ -> false
1065+
10591066
let num_effect_indices env name r =
10601067
let sig_t = name |> lookup_effect_lid env |> SS.compress in
10611068
match sig_t.n with

src/typechecker/FStarC.TypeChecker.Env.fsti

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,11 @@ val fv_has_erasable_attr : env -> fv -> bool
347347
and any `x: t ...` can be erased to `i`. *)
348348
val non_informative : env -> typ -> option term
349349

350+
(* `non_informative_sort t` is `true` if the type family `t: ... -> Type` only ranges over noninformative types,
351+
i.e., any `x: s ...` such that `s ... : t ...` can be erased.
352+
(practically, this means that `t` is of the form `... -> prop`) *)
353+
val non_informative_sort : typ -> bool
354+
350355
val try_lookup_effect_lid : env -> lident -> option term
351356
val lookup_effect_lid : env -> lident -> term
352357
val lookup_effect_abbrev : env -> universes -> lident -> option (binders & comp)

src/typechecker/FStarC.TypeChecker.Normalize.fst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2831,6 +2831,21 @@ let non_info_norm env t =
28312831
in
28322832
non_informative env (normalize steps env t)
28332833

2834+
let non_info_sort_norm env t =
2835+
let steps = [UnfoldUntil (Env.delta_depth_of_fv env (S.fvconst PC.prop_lid)); // do not unfold prop
2836+
AllowUnboundUniverses;
2837+
EraseUniverses;
2838+
Primops;
2839+
Beta; Iota;
2840+
HNF;
2841+
(* We could use Weak too were it not that we need
2842+
* to descend in the codomain of arrows. *)
2843+
Unascribe; //remove ascriptions
2844+
ForExtraction //and refinement types
2845+
]
2846+
in
2847+
non_informative_sort (normalize steps env t)
2848+
28342849
(*
28352850
* Ghost T to Pure T promotion
28362851
*

src/typechecker/FStarC.TypeChecker.Normalize.fsti

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ val unfold_whnf': steps -> Env.env -> term -> term
3535
val unfold_whnf: Env.env -> term -> term
3636
val reduce_uvar_solutions:Env.env -> term -> term
3737
val non_info_norm: Env.env -> term -> option term
38+
val non_info_sort_norm: Env.env -> term -> bool
3839

3940
(*
4041
* The maybe versions of ghost_to_pure only promote

src/typechecker/FStarC.TypeChecker.Quals.fst

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -210,13 +210,20 @@ let check_erasable env quals (r:Range.range) se =
210210
let has_iface_val = match DsEnv.iface_decls (Env.dsenv env) (Env.current_module env) with
211211
| Some iface_decls -> iface_decls |> BU.for_some (Parser.AST.decl_is_val (ident_of_lid lbname.fv_name.v))
212212
| None -> false in
213-
let _, body, _ = U.abs_formals lb.lbdef in
214-
if has_iface_val && Some? (non_info_norm_weak env body) then log_issue lbname Error_MustEraseMissing [
215-
text (BU.format1 "Values of type `%s` will be erased during extraction, \
216-
but its interface hides this fact." (show lbname));
217-
text (BU.format1 "Add the `erasable` \
218-
attribute to the `val %s` declaration for this symbol in the interface" (show lbname));
219-
]
213+
let val_decl = Env.try_lookup_val_decl env lbname.fv_name.v in
214+
if has_iface_val && Some? val_decl then
215+
let _, body, _ = U.abs_formals lb.lbdef in
216+
let Some ((us, t), _) = val_decl in
217+
let known_to_be_erasable =
218+
let env = Env.push_univ_vars env us in
219+
N.non_info_sort_norm env t in
220+
if not known_to_be_erasable && Some? (non_info_norm_weak env body) then
221+
log_issue lbname Error_MustEraseMissing [
222+
text (BU.format1 "Values of type `%s` will be erased during extraction, \
223+
but its interface hides this fact." (show lbname));
224+
text (BU.format1 "Add the `erasable` \
225+
attribute to the `val %s` declaration for this symbol in the interface" (show lbname));
226+
]
220227
| _ -> ()
221228
end;
222229
if se_has_erasable_attr

0 commit comments

Comments
 (0)