Put interfaces behind a compiler flag (#18791)

* Add flag

* Add flag for bazel macro daml_compile

* Add flag for bazel macro daml_test

* LF Conversion: fail if interfaces or interface instances are defined without --enable-interfaces=yes

* Add --enable-interfaces=yes where needed
This commit is contained in:
Moisés Ackerman 2024-03-20 16:49:32 +01:00 committed by GitHub
parent 17119166ab
commit aaff75e276
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 80 additions and 16 deletions

View File

@ -266,10 +266,10 @@ generateRawDalfRule =
-- Generate the map from package names to package hashes
PackageMap pkgMap <- use_ GeneratePackageMap file
stablePkgs <- useNoFile_ GenerateStablePackages
DamlEnv{envEnableScenarios, envAllowLargeTuples} <- getDamlServiceEnv
DamlEnv{envEnableScenarios, envEnableInterfaces, envAllowLargeTuples} <- getDamlServiceEnv
modIface <- hm_iface . tmrModInfo <$> use_ TypeCheck file
-- GHC Core to Daml-LF
case convertModule lfVersion envEnableScenarios envAllowLargeTuples pkgMap (Map.map LF.dalfPackageId stablePkgs) file core modIface details of
case convertModule lfVersion envEnableScenarios envEnableInterfaces envAllowLargeTuples pkgMap (Map.map LF.dalfPackageId stablePkgs) file core modIface details of
Left e -> return ([e], Nothing)
Right (v, conversionWarnings) -> do
WhnfPackage pkg <- use_ GeneratePackageDeps file
@ -424,11 +424,11 @@ generateSerializedDalfRule options =
-- lf conversion
PackageMap pkgMap <- use_ GeneratePackageMap file
stablePkgs <- useNoFile_ GenerateStablePackages
DamlEnv{envEnableScenarios, envAllowLargeTuples} <- getDamlServiceEnv
DamlEnv{envEnableScenarios, envEnableInterfaces, envAllowLargeTuples} <- getDamlServiceEnv
let modInfo = tmrModInfo tm
details = hm_details modInfo
modIface = hm_iface modInfo
case convertModule lfVersion envEnableScenarios envAllowLargeTuples pkgMap (Map.map LF.dalfPackageId stablePkgs) file core modIface details of
case convertModule lfVersion envEnableScenarios envEnableInterfaces envAllowLargeTuples pkgMap (Map.map LF.dalfPackageId stablePkgs) file core modIface details of
Left e -> pure ([e], Nothing)
Right (rawDalf, conversionWarnings) -> do
-- LF postprocessing

View File

@ -56,6 +56,7 @@ data DamlEnv = DamlEnv
, envDamlLfVersion :: LF.Version
, envSkipScenarioValidation :: SkipScenarioValidation
, envEnableScenarios :: EnableScenarios
, envEnableInterfaces :: EnableInterfaces
, envAllowLargeTuples :: AllowLargeTuples
, envStudioAutorunAllScenarios :: StudioAutorunAllScenarios
, envTestFilter :: T.Text -> Bool
@ -77,6 +78,7 @@ mkDamlEnv opts autorunAllScenarios scenarioService = do
, envDamlLfVersion = optDamlLfVersion opts
, envSkipScenarioValidation = optSkipScenarioValidation opts
, envEnableScenarios = optEnableScenarios opts
, envEnableInterfaces = optEnableInterfaces opts
, envAllowLargeTuples = optAllowLargeTuples opts
, envStudioAutorunAllScenarios = autorunAllScenarios
, envTestFilter = optTestFilter opts

View File

@ -101,7 +101,7 @@ import Control.Monad.Extra
import Control.Monad.State.Strict
import DA.Daml.LF.Ast as LF
import DA.Daml.LF.Ast.Numeric
import DA.Daml.Options.Types (EnableScenarios (..), AllowLargeTuples (..))
import DA.Daml.Options.Types (EnableScenarios (..), EnableInterfaces (..), AllowLargeTuples (..))
import qualified Data.Decimal as Decimal
import Data.Foldable (foldlM)
import Data.Int
@ -145,6 +145,7 @@ data Env = Env
-- packages does not cause performance issues.
,envLfVersion :: LF.Version
,envEnableScenarios :: EnableScenarios
,envEnableInterfaces :: EnableInterfaces
,envAllowLargeTuples :: AllowLargeTuples
,envUserWrittenTuple :: Bool
,envTypeVars :: !(MS.Map Var TypeVarName)
@ -157,12 +158,13 @@ data Env = Env
mkEnv ::
LF.Version
-> EnableScenarios
-> EnableInterfaces
-> AllowLargeTuples
-> MS.Map UnitId DalfPackage
-> MS.Map (UnitId, LF.ModuleName) PackageId
-> GHC.Module
-> Env
mkEnv envLfVersion envEnableScenarios envAllowLargeTuples envPkgMap envStablePackages ghcModule = do
mkEnv envLfVersion envEnableScenarios envEnableInterfaces envAllowLargeTuples envPkgMap envStablePackages ghcModule = do
let
envGHCModuleName = GHC.moduleName ghcModule
envModuleUnitId = GHC.moduleUnitId ghcModule
@ -675,6 +677,7 @@ convertInterface env mc intName ib =
convertDefInterfaceDataType :: ConvertM Definition
convertDefInterfaceDataType = do
checkInterfacesEnabled env
unless (null (tyConTyVars tyCon)) do
unhandled "interface type constructor with type parameters" tyCon
pure $ DDataType DefDataType
@ -734,6 +737,7 @@ convertModule
:: SdkVersioned
=> LF.Version
-> EnableScenarios
-> EnableInterfaces
-> AllowLargeTuples
-> MS.Map UnitId DalfPackage
-> MS.Map (GHC.UnitId, LF.ModuleName) LF.PackageId
@ -743,9 +747,9 @@ convertModule
-- ^ Only used for information that isn't available in ModDetails.
-> ModDetails
-> Either FileDiagnostic (LF.Module, [FileDiagnostic])
convertModule lfVersion enableScenarios allowLargeTuples pkgMap stablePackages file coreModule modIface details = runConvertM (ConversionEnv file Nothing) $ do
convertModule lfVersion enableScenarios enableInterfaces allowLargeTuples pkgMap stablePackages file coreModule modIface details = runConvertM (ConversionEnv file Nothing) $ do
let
env = mkEnv lfVersion enableScenarios allowLargeTuples pkgMap stablePackages (cm_module coreModule)
env = mkEnv lfVersion enableScenarios enableInterfaces allowLargeTuples pkgMap stablePackages (cm_module coreModule)
mc = extractModuleContents env coreModule modIface details
defs <- convertModuleContents env mc
pure (LF.moduleFromDefinitions (envLFModuleName env) (Just $ fromNormalizedFilePath file) flags defs)
@ -1161,6 +1165,7 @@ convertInterfaceInstance ::
-> InterfaceInstanceBinds
-> ConvertM TemplateImplements
convertInterfaceInstance parent env iib = withRange (iibLoc iib) do
checkInterfacesEnabled env
interfaceQualTypeCon <- qualifyInterfaceCon (iibInterface iib)
templateQualTypeCon <- qualifyTemplateCon (iibTemplate iib)
checkParent templateQualTypeCon
@ -2641,6 +2646,18 @@ ctorLabels con =
flv = tyConFlavour (dataConTyCon con)
lbls = dataConFieldLabels con
---------------------------------------------------------------------
-- Checks
checkInterfacesEnabled :: Env -> ConvertM ()
checkInterfacesEnabled env =
unless (getEnableInterfaces (envEnableInterfaces env)) do
unsupported
"Interfaces are forbidden by default. To enable them, add \
\`--enable-interfaces=yes` to `build-options` in the project's \
\`daml.yaml` file."
()
---------------------------------------------------------------------
-- SIMPLE WRAPPERS

View File

@ -8,6 +8,7 @@ module DA.Daml.Options.Types
( Options(..)
, EnableScenarioService(..)
, EnableScenarios(..)
, EnableInterfaces(..)
, AllowLargeTuples(..)
, StudioAutorunAllScenarios(..)
, SkipScenarioValidation(..)
@ -90,6 +91,8 @@ data Options = Options
, optEnableScenarios :: EnableScenarios
-- ^ Whether old-style scenarios should be run by the scenario service.
-- This will be switched to False by default once scenarios are no longer supported in 2.0.
, optEnableInterfaces :: EnableInterfaces
-- ^ Whether interfaces should be allowed as a language feature. Off by default.
, optTestFilter :: T.Text -> Bool
-- ^ Only execute tests with a name for which the given predicate holds.
, optSkipScenarioValidation :: SkipScenarioValidation
@ -187,6 +190,9 @@ newtype AllowLargeTuples = AllowLargeTuples { getAllowLargeTuples :: Bool }
newtype StudioAutorunAllScenarios = StudioAutorunAllScenarios { getStudioAutorunAllScenarios :: Bool }
deriving Show
newtype EnableInterfaces = EnableInterfaces { getEnableInterfaces :: Bool }
deriving Show
damlArtifactDir :: FilePath
damlArtifactDir = ".daml"
@ -251,6 +257,7 @@ defaultOptions mbVersion =
, optGhcCustomOpts = []
, optScenarioService = EnableScenarioService True
, optEnableScenarios = EnableScenarios False
, optEnableInterfaces = EnableInterfaces False
, optTestFilter = const True
, optSkipScenarioValidation = SkipScenarioValidation False
, optDlintUsage = DlintDisabled

View File

@ -262,6 +262,15 @@ enableScenariosOpt = EnableScenarios <$>
"Enable/disable support for scenarios as a language feature. \
\If disabled, defining top-level scenarios is a compile-time error"
enableInterfacesOpt :: Parser EnableInterfaces
enableInterfacesOpt = EnableInterfaces <$>
flagYesNoAuto "enable-interfaces" False desc internal
where
desc =
"Enable/disable support for interfaces as a language feature. \
\If disabled, defining interfaces and interface instances is a compile-time error. \
\Off by default."
allowLargeTuplesOpt :: Parser AllowLargeTuples
allowLargeTuplesOpt = AllowLargeTuples <$>
flagYesNoAuto "disable-warn-large-tuples" False desc internal
@ -426,6 +435,7 @@ optionsParser numProcessors enableScenarioService parsePkgName parseDlintUsage =
let optEnableOfInterestRule = False
optCppPath <- optCppPath
optEnableScenarios <- enableScenariosOpt
optEnableInterfaces <- enableInterfacesOpt
optAllowLargeTuples <- allowLargeTuplesOpt
optTestFilter <- compilePatternExpr <$> optTestPattern

View File

@ -1017,6 +1017,7 @@ daml_compile(
dependencies = [
"//daml-script/daml3:daml3-script-2.dev.dar",
],
enable_interfaces = True,
project_name = "try-submit-test",
target = "2.dev",
visibility = ["//visibility:public"],

View File

@ -329,6 +329,7 @@ getIntegrationTests registerTODO scenarioService (packageDbPath, packageFlags) =
}
, optPackageImports = packageFlags
, optDetailLevel = PrettyLevel (-1)
, optEnableInterfaces = EnableInterfaces True
}
mkIde options = do

View File

@ -2252,7 +2252,7 @@ tests TestArgs{..} =
damlYamlBody name extraDeps dataDeps = unlines
[ "sdk-version: " <> sdkVersion
, "name: " <> name
, "build-options: [--target="<> LF.renderVersion targetDevVersion <>"]"
, "build-options: [--target="<> LF.renderVersion targetDevVersion <>", --enable-interfaces=yes]"
, "source: ."
, "version: 0.1.0"
, "dependencies: [" <> intercalate ", " (["daml-prim", "daml-stdlib"] <> fmap show extraDeps) <> "]"
@ -2703,15 +2703,20 @@ tests TestArgs{..} =
]
where
defTestOptions :: DataDependenciesTestOptions
defTestOptions = DataDependenciesTestOptions [] []
defTestOptions = DataDependenciesTestOptions
{ buildOptions =
[ "--target=" <> LF.renderVersion targetDevVersion
, "--enable-interfaces=yes"
]
, extraDeps = []
}
optionsDev :: DataDependenciesTestOptions
optionsDev = defTestOptions {buildOptions = ["--target=" <> LF.renderVersion targetDevVersion]}
optionsDev = defTestOptions
optionsDevScript :: DataDependenciesTestOptions
optionsDevScript = defTestOptions
{ buildOptions = ["--target=" <> LF.renderVersion targetDevVersion]
, extraDeps = [scriptDevDar]
{ extraDeps = [scriptDevDar]
}
simpleImportTest :: String -> [String] -> [String] -> TestTree

View File

@ -22,7 +22,7 @@ import System.Environment.Blank (setEnv)
import Control.Monad.IO.Class
import qualified DA.Daml.LF.Ast.Version as LF
import qualified DA.Daml.Options.Types as Daml (Options (..))
import qualified DA.Daml.Options.Types as Daml (Options (..), EnableInterfaces (..))
import DA.Daml.LF.ScenarioServiceClient as SS
import DA.Test.Util (withResourceCps)
import Development.IDE.Types.Diagnostics
@ -80,6 +80,7 @@ addScriptOpts lfVersion = maybe id $ \(packageDbPath, packageFlags) opts -> opts
{ Daml.optPackageDbs = [packageDbPath]
, Daml.optPackageImports = packageFlags
, Daml.optDamlLfVersion = lfVersion
, Daml.optEnableInterfaces = Daml.EnableInterfaces True
}
-- | Tasty test case from a ShakeTest.

View File

@ -103,6 +103,7 @@ testsForDamlcValidate damlc = testGroup "damlc validate-dar"
, "version: 0.0.1"
, "source: ."
, "dependencies: [daml-prim, daml-stdlib]"
, "build-options: [--enable-interfaces=yes]"
]
writeFileUTF8 (projDir </> "Good.daml") $ unlines
[ "module Good where"
@ -128,6 +129,7 @@ testsForDamlcValidate damlc = testGroup "damlc validate-dar"
, "version: 0.0.1"
, "source: ."
, "dependencies: [daml-prim, daml-stdlib]"
, "build-options: [--enable-interfaces=yes]"
]
writeFileUTF8 (projDir </> "Interface.daml") $ unlines
[ "module Interface where"

View File

@ -50,6 +50,7 @@ da_scala_library(
daml_compile(
name = "InterfaceTestPackage",
srcs = glob(["src/test/daml/**/*.daml"]),
enable_interfaces = True,
target = lf_version_configuration.get("default"),
)

View File

@ -39,6 +39,7 @@ load("@os_info//:os_info.bzl", "is_intel")
daml_compile(
name = "Interfaces-v{}".format(major),
srcs = ["Interfaces.daml"],
enable_interfaces = True,
target = lf_version_default_or_latest(major),
visibility = ["//daml-lf:__subpackages__"],
)
@ -49,6 +50,7 @@ load("@os_info//:os_info.bzl", "is_intel")
daml_compile(
name = "InterfaceViews-v{}".format(major),
srcs = ["InterfaceViews.daml"],
enable_interfaces = True,
target = lf_version_default_or_latest(major),
visibility = ["//daml-lf:__subpackages__"],
)

View File

@ -71,6 +71,7 @@ dependencies:
- daml{scriptVersion}-script-{target}.dar
build-options:
- --target={target}
- --enable-interfaces=yes
EOF
$(location //compiler/damlc) build --project-root=$$TMP_DIR --ghc-option=-Werror -o $$PWD/$(location script{scriptVersion}-test-v{name}.dar)
rm -rf $$TMP_DIR

View File

@ -409,6 +409,7 @@ daml_test(
daml_test(
name = "bindings-java-daml-test",
srcs = glob(["source/app-dev/bindings-java/code-snippets/**/*.daml"]),
enable_interfaces = True,
# FIXME: https://github.com/digital-asset/daml/issues/12051
# remove target, once interfaces are stable.
target = lf_version_configuration.get("latest"),
@ -448,6 +449,7 @@ daml_test(
name = "daml-ref-daml-test-{}".format(version),
timeout = "long",
srcs = glob(["source/daml/code-snippets-dev/**/*.daml"]),
enable_interfaces = True,
target = version,
)
for version in LF_DEV_VERSIONS
@ -501,6 +503,7 @@ daml_test(
srcs = glob(
["source/daml/intro/daml/daml-intro-13/**/*.daml"],
),
enable_interfaces = True,
target = "2.1",
deps = ["//daml-script/daml:daml-script-2.1.dar"],
)
@ -510,6 +513,7 @@ daml_test(
srcs = glob(
["source/daml/intro/daml/daml-intro-12-part1/**/*.daml"],
),
enable_interfaces = True,
target = "2.1",
deps = ["//daml-script/daml:daml-script-2.1.dar"],
)
@ -520,6 +524,7 @@ daml_compile(
["source/daml/intro/daml/daml-intro-12-part1/**/*.daml"],
),
dependencies = ["//daml-script/daml:daml-script-2.1.dar"],
enable_interfaces = True,
target = "2.1",
)
@ -529,6 +534,7 @@ daml_test(
["source/daml/intro/daml/daml-intro-12-part2/**/*.daml"],
),
data_deps = ["daml-intro12-part1.dar"],
enable_interfaces = True,
target = "2.1",
deps = ["//daml-script/daml:daml-script-2.1.dar"],
)

View File

@ -5,6 +5,7 @@ version: 0.0.1
# script-build-options-begin
build-options:
- --target=2.1
- --enable-interfaces=yes
# script-build-options-end
# script-dependencies-begin
dependencies:

View File

@ -380,6 +380,7 @@ java_test(
daml_compile(
name = "ledger-tests-model",
srcs = glob(["src/ledger-tests/daml/**/*.daml"]),
enable_interfaces = True,
# TODO(https://github.com/digital-asset/daml/issues/18457): split the dar into a 2.dev one using
# keys, and a default one without keys.
target = "2.dev",

View File

@ -15,6 +15,7 @@ daml_compile(
["daml/**/*.daml"],
exclude = ["daml/Hidden.daml"],
),
enable_interfaces = True,
# TODO(https://github.com/digital-asset/daml/issues/18457): remove contract keys from these
# daml files or split the test into two tests, one with contract keys and without, and revert
# to the default target version.
@ -26,6 +27,7 @@ daml_compile(
name = "hidden",
srcs = ["daml/Hidden.daml"],
data_dependencies = ["//language-support/ts/codegen/tests:build-and-lint.dar"],
enable_interfaces = True,
# TODO(https://github.com/digital-asset/daml/issues/18457): remove contract keys from these
# daml files or split the test into two tests, one with contract keys and without, and revert
# to the default target version.

View File

@ -317,6 +317,7 @@ def daml_compile(
project_name = None,
ghc_options = default_damlc_opts,
enable_scenarios = False,
enable_interfaces = False,
dependencies = [],
data_dependencies = [],
module_prefixes = None,
@ -349,7 +350,8 @@ def daml_compile(
dar = name + ".dar",
ghc_options =
ghc_options +
(["--enable-scenarios=yes"] if enable_scenarios and (target == None or _supports_scenarios(target)) else []),
(["--enable-scenarios=yes"] if enable_scenarios and (target == None or _supports_scenarios(target)) else []) +
(["--enable-interfaces=yes"] if enable_interfaces else []),
damlc = damlc_for_target(target),
**kwargs
)
@ -487,6 +489,7 @@ def daml_test(
deps = [],
data_deps = [],
damlc = "//compiler/damlc:damlc",
enable_interfaces = False,
additional_compiler_flags = [],
target = None,
**kwargs):
@ -515,13 +518,14 @@ EOF
cat $$tmpdir/daml.yaml
{cp_srcs}
cd $$tmpdir
$$DAMLC test {damlc_opts} --files {files}
$$DAMLC test {enable_interfaces} {damlc_opts} --files {files}
""".format(
damlc = damlc,
files = " ".join(["$(rootpaths %s)" % src for src in srcs]),
sdk_version = sdk_version,
deps = " ".join(["$(rootpaths %s)" % dep for dep in deps]),
data_deps = " ".join(["$(rootpaths %s)" % dep for dep in data_deps]),
enable_interfaces = "--enable-interfaces=yes" if enable_interfaces else "",
damlc_opts = " ".join(default_damlc_opts + additional_compiler_flags),
cp_srcs = "\n".join([
"mkdir -p $$(dirname {dest}); cp -f {src} {dest}".format(