Every -X feature flag is an accept-and-warn no-op: the language features
they used to gate are unconditionally on. Passing -X<name> for any of the
16 names listed below still parses successfully (downstream build.tur
files keep compiling unchanged) but emits TUR-W0050 and otherwise does
nothing.
The diagnostic and debug flags below (--strict-effects, --keep-contracts,
--no-contracts, --dump-*, --emit-abi-trace, --warn-unused-result,
--lint-panic, etc.) are real and still control compiler behavior.
| Flag | Feature is now standard; see |
|---|---|
-Xlinear |
substructural-types-guide.md |
-Xsubstructural |
substructural-types-guide.md |
-Xunique-types |
uniqueness-types-guide.md |
-Xgadt |
gadts-guide.md |
-Xunion-types |
union-intersection-types-guide.md |
-Xintersection-types |
union-intersection-types-guide.md |
-Xeffect-types |
effects-system-guide.md |
-Xcontracts |
contract-types-guide.md |
-Xsessions |
session-types-guide.md |
-Xdynamic-vars |
dynamic-vars-guide.md |
-Xcallcc |
effects-system-guide.md |
-Xsized-types |
sized-types-guide.md |
-Xdata-literals |
data-literals-guide.md |
-Xjson-reader |
json-guide.md |
-Xschema-reader |
schema-guide.md |
-Xsymbols |
symbols-guide.md |
Each prints warning [TUR-W0050]: -X<name> is no longer needed; the feature is on by default and is otherwise ignored. The recognizer stays so
old build.tur files keep compiling; a future cleanup may retire it with
its own deprecation window.
Note. The
-X<name>prefix is retired for good -- none of the 16 names above will be reused. For genuinely experimental features (the kind that are half-built, in-flux, or carry a known cost), the surface is--enable=<name>with a built-in expiry policy. See experimental-flags-guide.md.
--strict-effects is opt-in. Effect typing is always on, but the
warnings on unannotated effectful functions fire only when you pass
--strict-effects (or -Werror=strict-effects) explicitly.TUR-E0260, etc.) fire unchanged.These are real flags, not deprecated.
--strict-effectsEmits warnings on functions whose inferred effect row is non-empty but
whose signature carries no explicit #fx{...} annotation or forall [e]
quantification (TUR-W0030), and on a declared row variable that is always
bound to a concrete row (TUR-W0032). A fn literal is described by its
enclosing function -- anonymous function in 'dfs-or' -- rather than by the
compiler's internal name for it. Opt-in.
-Werror=strict-effectsPromotes the --strict-effects warnings to errors, so a build fails on an
unannotated effectful function. Implies --strict-effects, the way gcc's
-Werror=<x> implies -W<x>. --Werror=strict-effects is accepted too.
--lint-effects (deprecated)An alias for --strict-effects that prints TUR-W0050. It used to be a
second, byte-identical copy of the TUR-W0030 check, documented as the
"advisory" form of a strict flag that could not in fact be made strict.
--keep-contractsRetains contract checks in release builds: programs compiled by a Release
tur (tur run release builds one into build-release/). Without this
flag, a Release tur elides contract-type checks -- #refine{...} types
and :pre/:post annotations (contracts are on by default in debug). The
assert!/require!/ensure! macros run in both builds: stripping them is
not implemented yet (stdlib/contract.tur). Per-contract ^always granularity
may be added later.
--no-contracts (C2)Strips all contracts at elaboration time -- the
assert!/require!/ensure!/invariant! macros and { x : T | pred }
refinement-type checks -- so predicates are never evaluated. Folds
contract-enabled? to false and sets TUR_CONTRACTS_ENABLED 0 in the
C preamble. Build a stripped program with tur run release-stripped <file>
(i.e. tur --no-contracts build <file> -O2).
--warn-unused-result (R6a)Warns when a result-shaped (ptr<void>) value is computed in statement
position and discarded. Silence with ignore!, a let binding, or by
using the value (e.g. the ? operator). Off by default.
--lint-panic (R6b)Emits TUR-W0038 at panic call sites (panic/tur_panic, the contract
macros, result-unwrap/option-unwrap). *-unwrap also gets a
soft-deprecation hint toward *-must. Silence with a
;; #lint-panic-allow comment (top-of-file = whole file;
immediately-preceding = single call). Off by default.
--panic-trace (retired)Accepted and ignored, with TUR-W0050. It used to print the live
defer-frame chain as raw pointers when a program panicked -- not a call stack,
and only when a defer was live. A panic now names its own .tur file and
line (panic at boom.tur:3: ...); for a stack, build with --debug and use
tur debug or lldb (docs/guides/debugging-guide.md).
--timings[=<path>]Prints where the compile's time went, phase by phase (read, module-load,
macro-expand, elaborate, typeclass, each core pass, refine, emit, cc, ...),
as exclusive time that sums to the wall clock; with a path it also writes
the same as tur-profile/1 JSON. Works on build, check, emit-c,
run and jit, and changes nothing that is compiled. See
performance-guide.md for
the phases, the JSON shape and how to read it.
--dump-kindsPrints the kind of every bound type to stdout after the kind-checking pass. Useful for debugging HKT typeclass definitions.
--dump-effectsPrints the inferred effect row for every function after elaboration, e.g.:
run-twice : forall [e]. (fn [(fn [] #{e} int)] #{e} int)
--dump-sizes (SZ8)Prints the inferred type-level size index for each sized-GADT constructor
application, e.g. size: SVCons : (SizedVec 2); an un-inferable index
prints (SizedVec ?).
--emit-abi-tracePrints, for each resolved call site, which C-level ABI path the emitter
takes to reach the callee. Codegen-time diagnostic: fires for
tur emit-c and tur build (the tur run interpreter still emits C
under the hood, so it also prints). Output goes to stderr, one line
per call:
abi-trace <line>:<col> <callee> <path>[ <clone-name>]
The <path> is one of four forms:
| Path | Meaning | When |
|---|---|---|
concrete-clone |
A monomorphized variant is called. The clone's mangled name is appended (e.g. cube__spec__double_double). |
A polymorphic global is instantiated at a concrete type whose C ABI differs from the carrier (Phases F/G/H). |
carrier |
The generic int64_t carrier ABI is used; the value round-trips through the universal 64-bit handle. |
Genuinely polymorphic call sites, type-erased containers, and instantiations whose C type matches the carrier (e.g. cube at :int). |
dictionary |
A typeclass method is dispatched through the instance machinery (dict_arg is set on the call). The callee name is the instance impl, e.g. __inst_Eq_eq__Tuple2. |
Any (.method ...) typeclass dispatch, whether resolved to a direct instance call (Phase H) or a dictionary vtable load. |
polymorphic-wrapper |
The call goes through a tur_poly_fn_t rank-2 wrapper rather than a direct C function. |
Calling a forall-quantified function parameter inside a rank-2/rank-N body. |
Example, against a file that exercises all four (see
tests/fixtures/emit-abi-trace/):
$ tur emit-c --emit-abi-trace input.tur >/dev/null
...
abi-trace 26:11 cube carrier
abi-trace 29:11 cube concrete-clone cube__spec__double_double
abi-trace 17:12 f polymorphic-wrapper
abi-trace 36:9 __inst_Eq_eq__Tuple2 dictionary
Notes:
concrete-clone exactly when emit_call_name would resolve
it to a specialization.Use this flag to verify that a fully-typed hot path is being monomorphized rather than silently falling back to the carrier ABI -- specialization is best-effort and otherwise silent on fallback.
-X flag surface.